Add categories chart
Benjamin Renard

Benjamin Renard commited on 2014-07-22 23:59:56
Showing 113 changed files, with 42222 additions and 1 deletions.

... ...
@@ -0,0 +1,1498 @@
1
+# Flot Reference #
2
+
3
+**Table of Contents**
4
+
5
+[Introduction](#introduction)
6
+| [Data Format](#data-format)
7
+| [Plot Options](#plot-options)
8
+| [Customizing the legend](#customizing-the-legend)
9
+| [Customizing the axes](#customizing-the-axes)
10
+| [Multiple axes](#multiple-axes)
11
+| [Time series data](#time-series-data)
12
+| [Customizing the data series](#customizing-the-data-series)
13
+| [Customizing the grid](#customizing-the-grid)
14
+| [Specifying gradients](#specifying-gradients)
15
+| [Plot Methods](#plot-methods)
16
+| [Hooks](#hooks)
17
+| [Plugins](#plugins)
18
+| [Version number](#version-number)
19
+
20
+---
21
+
22
+## Introduction ##
23
+
24
+Consider a call to the plot function:
25
+
26
+```js
27
+var plot = $.plot(placeholder, data, options)
28
+```
29
+
30
+The placeholder is a jQuery object or DOM element or jQuery expression
31
+that the plot will be put into. This placeholder needs to have its
32
+width and height set as explained in the [README](README.md) (go read that now if
33
+you haven't, it's short). The plot will modify some properties of the
34
+placeholder so it's recommended you simply pass in a div that you
35
+don't use for anything else. Make sure you check any fancy styling
36
+you apply to the div, e.g. background images have been reported to be a
37
+problem on IE 7.
38
+
39
+The plot function can also be used as a jQuery chainable property.  This form
40
+naturally can't return the plot object directly, but you can still access it
41
+via the 'plot' data key, like this:
42
+
43
+```js
44
+var plot = $("#placeholder").plot(data, options).data("plot");
45
+```
46
+
47
+The format of the data is documented below, as is the available
48
+options. The plot object returned from the call has some methods you
49
+can call. These are documented separately below.
50
+
51
+Note that in general Flot gives no guarantees if you change any of the
52
+objects you pass in to the plot function or get out of it since
53
+they're not necessarily deep-copied.
54
+
55
+
56
+## Data Format ##
57
+
58
+The data is an array of data series:
59
+
60
+```js
61
+[ series1, series2, ... ]
62
+```
63
+
64
+A series can either be raw data or an object with properties. The raw
65
+data format is an array of points:
66
+
67
+```js
68
+[ [x1, y1], [x2, y2], ... ]
69
+```
70
+
71
+E.g.
72
+
73
+```js
74
+[ [1, 3], [2, 14.01], [3.5, 3.14] ]
75
+```
76
+
77
+Note that to simplify the internal logic in Flot both the x and y
78
+values must be numbers (even if specifying time series, see below for
79
+how to do this). This is a common problem because you might retrieve
80
+data from the database and serialize them directly to JSON without
81
+noticing the wrong type. If you're getting mysterious errors, double
82
+check that you're inputting numbers and not strings.
83
+
84
+If a null is specified as a point or if one of the coordinates is null
85
+or couldn't be converted to a number, the point is ignored when
86
+drawing. As a special case, a null value for lines is interpreted as a
87
+line segment end, i.e. the points before and after the null value are
88
+not connected.
89
+
90
+Lines and points take two coordinates. For filled lines and bars, you
91
+can specify a third coordinate which is the bottom of the filled
92
+area/bar (defaults to 0).
93
+
94
+The format of a single series object is as follows:
95
+
96
+```js
97
+{
98
+    color: color or number
99
+    data: rawdata
100
+    label: string
101
+    lines: specific lines options
102
+    bars: specific bars options
103
+    points: specific points options
104
+    xaxis: number
105
+    yaxis: number
106
+    clickable: boolean
107
+    hoverable: boolean
108
+    shadowSize: number
109
+    highlightColor: color or number
110
+}
111
+```
112
+
113
+You don't have to specify any of them except the data, the rest are
114
+options that will get default values. Typically you'd only specify
115
+label and data, like this:
116
+
117
+```js
118
+{
119
+    label: "y = 3",
120
+    data: [[0, 3], [10, 3]]
121
+}
122
+```
123
+
124
+The label is used for the legend, if you don't specify one, the series
125
+will not show up in the legend.
126
+
127
+If you don't specify color, the series will get a color from the
128
+auto-generated colors. The color is either a CSS color specification
129
+(like "rgb(255, 100, 123)") or an integer that specifies which of
130
+auto-generated colors to select, e.g. 0 will get color no. 0, etc.
131
+
132
+The latter is mostly useful if you let the user add and remove series,
133
+in which case you can hard-code the color index to prevent the colors
134
+from jumping around between the series.
135
+
136
+The "xaxis" and "yaxis" options specify which axis to use. The axes
137
+are numbered from 1 (default), so { yaxis: 2} means that the series
138
+should be plotted against the second y axis.
139
+
140
+"clickable" and "hoverable" can be set to false to disable
141
+interactivity for specific series if interactivity is turned on in
142
+the plot, see below.
143
+
144
+The rest of the options are all documented below as they are the same
145
+as the default options passed in via the options parameter in the plot
146
+commmand. When you specify them for a specific data series, they will
147
+override the default options for the plot for that data series.
148
+
149
+Here's a complete example of a simple data specification:
150
+
151
+```js
152
+[ { label: "Foo", data: [ [10, 1], [17, -14], [30, 5] ] },
153
+  { label: "Bar", data: [ [11, 13], [19, 11], [30, -7] ] }
154
+]
155
+```
156
+
157
+
158
+## Plot Options ##
159
+
160
+All options are completely optional. They are documented individually
161
+below, to change them you just specify them in an object, e.g.
162
+
163
+```js
164
+var options = {
165
+    series: {
166
+        lines: { show: true },
167
+        points: { show: true }
168
+    }
169
+};
170
+	
171
+$.plot(placeholder, data, options);
172
+```
173
+
174
+
175
+## Customizing the legend ##
176
+
177
+```js
178
+legend: {
179
+    show: boolean
180
+    labelFormatter: null or (fn: string, series object -> string)
181
+    labelBoxBorderColor: color
182
+    noColumns: number
183
+    position: "ne" or "nw" or "se" or "sw"
184
+    margin: number of pixels or [x margin, y margin]
185
+    backgroundColor: null or color
186
+    backgroundOpacity: number between 0 and 1
187
+    container: null or jQuery object/DOM element/jQuery expression
188
+    sorted: null/false, true, "ascending", "descending", "reverse", or a comparator
189
+}
190
+```
191
+
192
+The legend is generated as a table with the data series labels and
193
+small label boxes with the color of the series. If you want to format
194
+the labels in some way, e.g. make them to links, you can pass in a
195
+function for "labelFormatter". Here's an example that makes them
196
+clickable:
197
+
198
+```js
199
+labelFormatter: function(label, series) {
200
+    // series is the series object for the label
201
+    return '<a href="#' + label + '">' + label + '</a>';
202
+}
203
+```
204
+
205
+To prevent a series from showing up in the legend, simply have the function
206
+return null.
207
+
208
+"noColumns" is the number of columns to divide the legend table into.
209
+"position" specifies the overall placement of the legend within the
210
+plot (top-right, top-left, etc.) and margin the distance to the plot
211
+edge (this can be either a number or an array of two numbers like [x,
212
+y]). "backgroundColor" and "backgroundOpacity" specifies the
213
+background. The default is a partly transparent auto-detected
214
+background.
215
+
216
+If you want the legend to appear somewhere else in the DOM, you can
217
+specify "container" as a jQuery object/expression to put the legend
218
+table into. The "position" and "margin" etc. options will then be
219
+ignored. Note that Flot will overwrite the contents of the container.
220
+
221
+Legend entries appear in the same order as their series by default. If "sorted"
222
+is "reverse" then they appear in the opposite order from their series. To sort
223
+them alphabetically, you can specify true, "ascending" or "descending", where
224
+true and "ascending" are equivalent.
225
+
226
+You can also provide your own comparator function that accepts two
227
+objects with "label" and "color" properties, and returns zero if they
228
+are equal, a positive value if the first is greater than the second,
229
+and a negative value if the first is less than the second.
230
+
231
+```js
232
+sorted: function(a, b) {
233
+    // sort alphabetically in ascending order
234
+    return a.label == b.label ? 0 : (
235
+        a.label > b.label ? 1 : -1
236
+    )
237
+}
238
+```
239
+
240
+
241
+## Customizing the axes ##
242
+
243
+```js
244
+xaxis, yaxis: {
245
+    show: null or true/false
246
+    position: "bottom" or "top" or "left" or "right"
247
+    mode: null or "time" ("time" requires jquery.flot.time.js plugin)
248
+    timezone: null, "browser" or timezone (only makes sense for mode: "time")
249
+
250
+    color: null or color spec
251
+    tickColor: null or color spec
252
+    font: null or font spec object
253
+
254
+    min: null or number
255
+    max: null or number
256
+    autoscaleMargin: null or number
257
+    
258
+    transform: null or fn: number -> number
259
+    inverseTransform: null or fn: number -> number
260
+    
261
+    ticks: null or number or ticks array or (fn: axis -> ticks array)
262
+    tickSize: number or array
263
+    minTickSize: number or array
264
+    tickFormatter: (fn: number, object -> string) or string
265
+    tickDecimals: null or number
266
+
267
+    labelWidth: null or number
268
+    labelHeight: null or number
269
+    reserveSpace: null or true
270
+    
271
+    tickLength: null or number
272
+
273
+    alignTicksWithAxis: null or number
274
+}
275
+```
276
+
277
+All axes have the same kind of options. The following describes how to
278
+configure one axis, see below for what to do if you've got more than
279
+one x axis or y axis.
280
+
281
+If you don't set the "show" option (i.e. it is null), visibility is
282
+auto-detected, i.e. the axis will show up if there's data associated
283
+with it. You can override this by setting the "show" option to true or
284
+false.
285
+
286
+The "position" option specifies where the axis is placed, bottom or
287
+top for x axes, left or right for y axes. The "mode" option determines
288
+how the data is interpreted, the default of null means as decimal
289
+numbers. Use "time" for time series data; see the time series data
290
+section. The time plugin (jquery.flot.time.js) is required for time
291
+series support.
292
+
293
+The "color" option determines the color of the line and ticks for the axis, and
294
+defaults to the grid color with transparency. For more fine-grained control you
295
+can also set the color of the ticks separately with "tickColor".
296
+
297
+You can customize the font and color used to draw the axis tick labels with CSS
298
+or directly via the "font" option. When "font" is null - the default - each
299
+tick label is given the 'flot-tick-label' class. For compatibility with Flot
300
+0.7 and earlier the labels are also given the 'tickLabel' class, but this is
301
+deprecated and scheduled to be removed with the release of version 1.0.0.
302
+
303
+To enable more granular control over styles, labels are divided between a set
304
+of text containers, with each holding the labels for one axis. These containers
305
+are given the classes 'flot-[x|y]-axis', and 'flot-[x|y]#-axis', where '#' is
306
+the number of the axis when there are multiple axes.  For example, the x-axis
307
+labels for a simple plot with only a single x-axis might look like this:
308
+
309
+```html
310
+<div class='flot-x-axis flot-x1-axis'>
311
+    <div class='flot-tick-label'>January 2013</div>
312
+    ...
313
+</div>
314
+```
315
+
316
+For direct control over label styles you can also provide "font" as an object
317
+with this format:
318
+
319
+```js
320
+{
321
+    size: 11,
322
+    lineHeight: 13,
323
+    style: "italic",
324
+    weight: "bold",
325
+    family: "sans-serif",
326
+    variant: "small-caps",
327
+    color: "#545454"
328
+}
329
+```
330
+
331
+The size and lineHeight must be expressed in pixels; CSS units such as 'em'
332
+or 'smaller' are not allowed.
333
+
334
+The options "min"/"max" are the precise minimum/maximum value on the
335
+scale. If you don't specify either of them, a value will automatically
336
+be chosen based on the minimum/maximum data values. Note that Flot
337
+always examines all the data values you feed to it, even if a
338
+restriction on another axis may make some of them invisible (this
339
+makes interactive use more stable).
340
+
341
+The "autoscaleMargin" is a bit esoteric: it's the fraction of margin
342
+that the scaling algorithm will add to avoid that the outermost points
343
+ends up on the grid border. Note that this margin is only applied when
344
+a min or max value is not explicitly set. If a margin is specified,
345
+the plot will furthermore extend the axis end-point to the nearest
346
+whole tick. The default value is "null" for the x axes and 0.02 for y
347
+axes which seems appropriate for most cases.
348
+
349
+"transform" and "inverseTransform" are callbacks you can put in to
350
+change the way the data is drawn. You can design a function to
351
+compress or expand certain parts of the axis non-linearly, e.g.
352
+suppress weekends or compress far away points with a logarithm or some
353
+other means. When Flot draws the plot, each value is first put through
354
+the transform function. Here's an example, the x axis can be turned
355
+into a natural logarithm axis with the following code:
356
+
357
+```js
358
+xaxis: {
359
+    transform: function (v) { return Math.log(v); },
360
+    inverseTransform: function (v) { return Math.exp(v); }
361
+}
362
+```
363
+
364
+Similarly, for reversing the y axis so the values appear in inverse
365
+order:
366
+
367
+```js
368
+yaxis: {
369
+    transform: function (v) { return -v; },
370
+    inverseTransform: function (v) { return -v; }
371
+}
372
+```
373
+
374
+Note that for finding extrema, Flot assumes that the transform
375
+function does not reorder values (it should be monotone).
376
+
377
+The inverseTransform is simply the inverse of the transform function
378
+(so v == inverseTransform(transform(v)) for all relevant v). It is
379
+required for converting from canvas coordinates to data coordinates,
380
+e.g. for a mouse interaction where a certain pixel is clicked. If you
381
+don't use any interactive features of Flot, you may not need it.
382
+
383
+
384
+The rest of the options deal with the ticks.
385
+
386
+If you don't specify any ticks, a tick generator algorithm will make
387
+some for you. The algorithm has two passes. It first estimates how
388
+many ticks would be reasonable and uses this number to compute a nice
389
+round tick interval size. Then it generates the ticks.
390
+
391
+You can specify how many ticks the algorithm aims for by setting
392
+"ticks" to a number. The algorithm always tries to generate reasonably
393
+round tick values so even if you ask for three ticks, you might get
394
+five if that fits better with the rounding. If you don't want any
395
+ticks at all, set "ticks" to 0 or an empty array.
396
+
397
+Another option is to skip the rounding part and directly set the tick
398
+interval size with "tickSize". If you set it to 2, you'll get ticks at
399
+2, 4, 6, etc. Alternatively, you can specify that you just don't want
400
+ticks at a size less than a specific tick size with "minTickSize".
401
+Note that for time series, the format is an array like [2, "month"],
402
+see the next section.
403
+
404
+If you want to completely override the tick algorithm, you can specify
405
+an array for "ticks", either like this:
406
+
407
+```js
408
+ticks: [0, 1.2, 2.4]
409
+```
410
+
411
+Or like this where the labels are also customized:
412
+
413
+```js
414
+ticks: [[0, "zero"], [1.2, "one mark"], [2.4, "two marks"]]
415
+```
416
+
417
+You can mix the two if you like.
418
+  
419
+For extra flexibility you can specify a function as the "ticks"
420
+parameter. The function will be called with an object with the axis
421
+min and max and should return a ticks array. Here's a simplistic tick
422
+generator that spits out intervals of pi, suitable for use on the x
423
+axis for trigonometric functions:
424
+
425
+```js
426
+function piTickGenerator(axis) {
427
+    var res = [], i = Math.floor(axis.min / Math.PI);
428
+    do {
429
+        var v = i * Math.PI;
430
+        res.push([v, i + "\u03c0"]);
431
+        ++i;
432
+    } while (v < axis.max);
433
+    return res;
434
+}
435
+```
436
+
437
+You can control how the ticks look like with "tickDecimals", the
438
+number of decimals to display (default is auto-detected).
439
+
440
+Alternatively, for ultimate control over how ticks are formatted you can
441
+provide a function to "tickFormatter". The function is passed two
442
+parameters, the tick value and an axis object with information, and
443
+should return a string. The default formatter looks like this:
444
+
445
+```js
446
+function formatter(val, axis) {
447
+    return val.toFixed(axis.tickDecimals);
448
+}
449
+```
450
+
451
+The axis object has "min" and "max" with the range of the axis,
452
+"tickDecimals" with the number of decimals to round the value to and
453
+"tickSize" with the size of the interval between ticks as calculated
454
+by the automatic axis scaling algorithm (or specified by you). Here's
455
+an example of a custom formatter:
456
+
457
+```js
458
+function suffixFormatter(val, axis) {
459
+    if (val > 1000000)
460
+        return (val / 1000000).toFixed(axis.tickDecimals) + " MB";
461
+    else if (val > 1000)
462
+        return (val / 1000).toFixed(axis.tickDecimals) + " kB";
463
+    else
464
+        return val.toFixed(axis.tickDecimals) + " B";
465
+}
466
+```
467
+
468
+"labelWidth" and "labelHeight" specifies a fixed size of the tick
469
+labels in pixels. They're useful in case you need to align several
470
+plots. "reserveSpace" means that even if an axis isn't shown, Flot
471
+should reserve space for it - it is useful in combination with
472
+labelWidth and labelHeight for aligning multi-axis charts.
473
+
474
+"tickLength" is the length of the tick lines in pixels. By default, the
475
+innermost axes will have ticks that extend all across the plot, while
476
+any extra axes use small ticks. A value of null means use the default,
477
+while a number means small ticks of that length - set it to 0 to hide
478
+the lines completely.
479
+
480
+If you set "alignTicksWithAxis" to the number of another axis, e.g.
481
+alignTicksWithAxis: 1, Flot will ensure that the autogenerated ticks
482
+of this axis are aligned with the ticks of the other axis. This may
483
+improve the looks, e.g. if you have one y axis to the left and one to
484
+the right, because the grid lines will then match the ticks in both
485
+ends. The trade-off is that the forced ticks won't necessarily be at
486
+natural places.
487
+
488
+
489
+## Multiple axes ##
490
+
491
+If you need more than one x axis or y axis, you need to specify for
492
+each data series which axis they are to use, as described under the
493
+format of the data series, e.g. { data: [...], yaxis: 2 } specifies
494
+that a series should be plotted against the second y axis.
495
+
496
+To actually configure that axis, you can't use the xaxis/yaxis options
497
+directly - instead there are two arrays in the options:
498
+
499
+```js
500
+xaxes: []
501
+yaxes: []
502
+```
503
+
504
+Here's an example of configuring a single x axis and two y axes (we
505
+can leave options of the first y axis empty as the defaults are fine):
506
+
507
+```js
508
+{
509
+    xaxes: [ { position: "top" } ],
510
+    yaxes: [ { }, { position: "right", min: 20 } ]
511
+}
512
+```
513
+
514
+The arrays get their default values from the xaxis/yaxis settings, so
515
+say you want to have all y axes start at zero, you can simply specify
516
+yaxis: { min: 0 } instead of adding a min parameter to all the axes.
517
+
518
+Generally, the various interfaces in Flot dealing with data points
519
+either accept an xaxis/yaxis parameter to specify which axis number to
520
+use (starting from 1), or lets you specify the coordinate directly as
521
+x2/x3/... or x2axis/x3axis/... instead of "x" or "xaxis".
522
+
523
+
524
+## Time series data ##
525
+
526
+Please note that it is now required to include the time plugin,
527
+jquery.flot.time.js, for time series support.
528
+
529
+Time series are a bit more difficult than scalar data because
530
+calendars don't follow a simple base 10 system. For many cases, Flot
531
+abstracts most of this away, but it can still be a bit difficult to
532
+get the data into Flot. So we'll first discuss the data format.
533
+
534
+The time series support in Flot is based on Javascript timestamps,
535
+i.e. everywhere a time value is expected or handed over, a Javascript
536
+timestamp number is used. This is a number, not a Date object. A
537
+Javascript timestamp is the number of milliseconds since January 1,
538
+1970 00:00:00 UTC. This is almost the same as Unix timestamps, except it's
539
+in milliseconds, so remember to multiply by 1000!
540
+
541
+You can see a timestamp like this
542
+
543
+```js
544
+alert((new Date()).getTime())
545
+```
546
+
547
+There are different schools of thought when it comes to display of
548
+timestamps. Many will want the timestamps to be displayed according to
549
+a certain time zone, usually the time zone in which the data has been
550
+produced. Some want the localized experience, where the timestamps are
551
+displayed according to the local time of the visitor. Flot supports
552
+both. Optionally you can include a third-party library to get
553
+additional timezone support.
554
+
555
+Default behavior is that Flot always displays timestamps according to
556
+UTC. The reason being that the core Javascript Date object does not
557
+support other fixed time zones. Often your data is at another time
558
+zone, so it may take a little bit of tweaking to work around this
559
+limitation.
560
+
561
+The easiest way to think about it is to pretend that the data
562
+production time zone is UTC, even if it isn't. So if you have a
563
+datapoint at 2002-02-20 08:00, you can generate a timestamp for eight
564
+o'clock UTC even if it really happened eight o'clock UTC+0200.
565
+
566
+In PHP you can get an appropriate timestamp with:
567
+
568
+```php
569
+strtotime("2002-02-20 UTC") * 1000
570
+```
571
+
572
+In Python you can get it with something like:
573
+
574
+```python
575
+calendar.timegm(datetime_object.timetuple()) * 1000
576
+```
577
+In Ruby you can get it using the `#to_i` method on the
578
+[`Time`](http://apidock.com/ruby/Time/to_i) object. If you're using the
579
+`active_support` gem (default for Ruby on Rails applications) `#to_i` is also
580
+available on the `DateTime` and `ActiveSupport::TimeWithZone` objects. You
581
+simply need to multiply the result by 1000:
582
+
583
+```ruby
584
+Time.now.to_i * 1000     # => 1383582043000
585
+# ActiveSupport examples:
586
+DateTime.now.to_i * 1000 # => 1383582043000
587
+ActiveSupport::TimeZone.new('Asia/Shanghai').now.to_i * 1000
588
+# => 1383582043000
589
+```
590
+
591
+In .NET you can get it with something like:
592
+
593
+```aspx
594
+public static int GetJavascriptTimestamp(System.DateTime input)
595
+{
596
+    System.TimeSpan span = new System.TimeSpan(System.DateTime.Parse("1/1/1970").Ticks);
597
+    System.DateTime time = input.Subtract(span);
598
+    return (long)(time.Ticks / 10000);
599
+}
600
+```
601
+
602
+Javascript also has some support for parsing date strings, so it is
603
+possible to generate the timestamps manually client-side.
604
+
605
+If you've already got the real UTC timestamp, it's too late to use the
606
+pretend trick described above. But you can fix up the timestamps by
607
+adding the time zone offset, e.g. for UTC+0200 you would add 2 hours
608
+to the UTC timestamp you got. Then it'll look right on the plot. Most
609
+programming environments have some means of getting the timezone
610
+offset for a specific date (note that you need to get the offset for
611
+each individual timestamp to account for daylight savings).
612
+
613
+The alternative with core Javascript is to interpret the timestamps
614
+according to the time zone that the visitor is in, which means that
615
+the ticks will shift with the time zone and daylight savings of each
616
+visitor. This behavior is enabled by setting the axis option
617
+"timezone" to the value "browser".
618
+
619
+If you need more time zone functionality than this, there is still
620
+another option. If you include the "timezone-js" library
621
+<https://github.com/mde/timezone-js> in the page and set axis.timezone
622
+to a value recognized by said library, Flot will use timezone-js to
623
+interpret the timestamps according to that time zone.
624
+
625
+Once you've gotten the timestamps into the data and specified "time"
626
+as the axis mode, Flot will automatically generate relevant ticks and
627
+format them. As always, you can tweak the ticks via the "ticks" option
628
+- just remember that the values should be timestamps (numbers), not
629
+Date objects.
630
+
631
+Tick generation and formatting can also be controlled separately
632
+through the following axis options:
633
+
634
+```js
635
+minTickSize: array
636
+timeformat: null or format string
637
+monthNames: null or array of size 12 of strings
638
+dayNames: null or array of size 7 of strings
639
+twelveHourClock: boolean
640
+```
641
+
642
+Here "timeformat" is a format string to use. You might use it like
643
+this:
644
+
645
+```js
646
+xaxis: {
647
+    mode: "time",
648
+    timeformat: "%Y/%m/%d"
649
+}
650
+```
651
+
652
+This will result in tick labels like "2000/12/24". A subset of the
653
+standard strftime specifiers are supported (plus the nonstandard %q):
654
+
655
+```js
656
+%a: weekday name (customizable)
657
+%b: month name (customizable)
658
+%d: day of month, zero-padded (01-31)
659
+%e: day of month, space-padded ( 1-31)
660
+%H: hours, 24-hour time, zero-padded (00-23)
661
+%I: hours, 12-hour time, zero-padded (01-12)
662
+%m: month, zero-padded (01-12)
663
+%M: minutes, zero-padded (00-59)
664
+%q: quarter (1-4)
665
+%S: seconds, zero-padded (00-59)
666
+%y: year (two digits)
667
+%Y: year (four digits)
668
+%p: am/pm
669
+%P: AM/PM (uppercase version of %p)
670
+%w: weekday as number (0-6, 0 being Sunday)
671
+```
672
+
673
+Flot 0.8 switched from %h to the standard %H hours specifier. The %h specifier
674
+is still available, for backwards-compatibility, but is deprecated and
675
+scheduled to be removed permanently with the release of version 1.0.
676
+
677
+You can customize the month names with the "monthNames" option. For
678
+instance, for Danish you might specify:
679
+
680
+```js
681
+monthNames: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"]
682
+```
683
+
684
+Similarly you can customize the weekday names with the "dayNames"
685
+option. An example in French:
686
+
687
+```js
688
+dayNames: ["dim", "lun", "mar", "mer", "jeu", "ven", "sam"]
689
+```
690
+
691
+If you set "twelveHourClock" to true, the autogenerated timestamps
692
+will use 12 hour AM/PM timestamps instead of 24 hour. This only
693
+applies if you have not set "timeformat". Use the "%I" and "%p" or
694
+"%P" options if you want to build your own format string with 12-hour
695
+times.
696
+
697
+If the Date object has a strftime property (and it is a function), it
698
+will be used instead of the built-in formatter. Thus you can include
699
+a strftime library such as http://hacks.bluesmoon.info/strftime/ for
700
+more powerful date/time formatting.
701
+
702
+If everything else fails, you can control the formatting by specifying
703
+a custom tick formatter function as usual. Here's a simple example
704
+which will format December 24 as 24/12:
705
+
706
+```js
707
+tickFormatter: function (val, axis) {
708
+    var d = new Date(val);
709
+    return d.getUTCDate() + "/" + (d.getUTCMonth() + 1);
710
+}
711
+```
712
+
713
+Note that for the time mode "tickSize" and "minTickSize" are a bit
714
+special in that they are arrays on the form "[value, unit]" where unit
715
+is one of "second", "minute", "hour", "day", "month" and "year". So
716
+you can specify
717
+
718
+```js
719
+minTickSize: [1, "month"]
720
+```
721
+
722
+to get a tick interval size of at least 1 month and correspondingly,
723
+if axis.tickSize is [2, "day"] in the tick formatter, the ticks have
724
+been produced with two days in-between.
725
+
726
+
727
+## Customizing the data series ##
728
+
729
+```js
730
+series: {
731
+    lines, points, bars: {
732
+        show: boolean
733
+        lineWidth: number
734
+        fill: boolean or number
735
+        fillColor: null or color/gradient
736
+    }
737
+
738
+    lines, bars: {
739
+        zero: boolean
740
+    }
741
+
742
+    points: {
743
+        radius: number
744
+        symbol: "circle" or function
745
+    }
746
+
747
+    bars: {
748
+        barWidth: number
749
+        align: "left", "right" or "center"
750
+        horizontal: boolean
751
+    }
752
+
753
+    lines: {
754
+        steps: boolean
755
+    }
756
+
757
+    shadowSize: number
758
+    highlightColor: color or number
759
+}
760
+
761
+colors: [ color1, color2, ... ]
762
+```
763
+
764
+The options inside "series: {}" are copied to each of the series. So
765
+you can specify that all series should have bars by putting it in the
766
+global options, or override it for individual series by specifying
767
+bars in a particular the series object in the array of data.
768
+  
769
+The most important options are "lines", "points" and "bars" that
770
+specify whether and how lines, points and bars should be shown for
771
+each data series. In case you don't specify anything at all, Flot will
772
+default to showing lines (you can turn this off with
773
+lines: { show: false }). You can specify the various types
774
+independently of each other, and Flot will happily draw each of them
775
+in turn (this is probably only useful for lines and points), e.g.
776
+
777
+```js
778
+var options = {
779
+    series: {
780
+        lines: { show: true, fill: true, fillColor: "rgba(255, 255, 255, 0.8)" },
781
+        points: { show: true, fill: false }
782
+    }
783
+};
784
+```
785
+
786
+"lineWidth" is the thickness of the line or outline in pixels. You can
787
+set it to 0 to prevent a line or outline from being drawn; this will
788
+also hide the shadow.
789
+
790
+"fill" is whether the shape should be filled. For lines, this produces
791
+area graphs. You can use "fillColor" to specify the color of the fill.
792
+If "fillColor" evaluates to false (default for everything except
793
+points which are filled with white), the fill color is auto-set to the
794
+color of the data series. You can adjust the opacity of the fill by
795
+setting fill to a number between 0 (fully transparent) and 1 (fully
796
+opaque).
797
+
798
+For bars, fillColor can be a gradient, see the gradient documentation
799
+below. "barWidth" is the width of the bars in units of the x axis (or
800
+the y axis if "horizontal" is true), contrary to most other measures
801
+that are specified in pixels. For instance, for time series the unit
802
+is milliseconds so 24 * 60 * 60 * 1000 produces bars with the width of
803
+a day. "align" specifies whether a bar should be left-aligned
804
+(default), right-aligned or centered on top of the value it represents. 
805
+When "horizontal" is on, the bars are drawn horizontally, i.e. from the 
806
+y axis instead of the x axis; note that the bar end points are still
807
+defined in the same way so you'll probably want to swap the
808
+coordinates if you've been plotting vertical bars first.
809
+
810
+Area and bar charts normally start from zero, regardless of the data's range.
811
+This is because they convey information through size, and starting from a
812
+different value would distort their meaning. In cases where the fill is purely
813
+for decorative purposes, however, "zero" allows you to override this behavior.
814
+It defaults to true for filled lines and bars; setting it to false tells the
815
+series to use the same automatic scaling as an un-filled line.
816
+
817
+For lines, "steps" specifies whether two adjacent data points are
818
+connected with a straight (possibly diagonal) line or with first a
819
+horizontal and then a vertical line. Note that this transforms the
820
+data by adding extra points.
821
+
822
+For points, you can specify the radius and the symbol. The only
823
+built-in symbol type is circles, for other types you can use a plugin
824
+or define them yourself by specifying a callback:
825
+
826
+```js
827
+function cross(ctx, x, y, radius, shadow) {
828
+    var size = radius * Math.sqrt(Math.PI) / 2;
829
+    ctx.moveTo(x - size, y - size);
830
+    ctx.lineTo(x + size, y + size);
831
+    ctx.moveTo(x - size, y + size);
832
+    ctx.lineTo(x + size, y - size);
833
+}
834
+```
835
+
836
+The parameters are the drawing context, x and y coordinates of the
837
+center of the point, a radius which corresponds to what the circle
838
+would have used and whether the call is to draw a shadow (due to
839
+limited canvas support, shadows are currently faked through extra
840
+draws). It's good practice to ensure that the area covered by the
841
+symbol is the same as for the circle with the given radius, this
842
+ensures that all symbols have approximately the same visual weight.
843
+
844
+"shadowSize" is the default size of shadows in pixels. Set it to 0 to
845
+remove shadows.
846
+
847
+"highlightColor" is the default color of the translucent overlay used
848
+to highlight the series when the mouse hovers over it.
849
+
850
+The "colors" array specifies a default color theme to get colors for
851
+the data series from. You can specify as many colors as you like, like
852
+this:
853
+
854
+```js
855
+colors: ["#d18b2c", "#dba255", "#919733"]
856
+```
857
+
858
+If there are more data series than colors, Flot will try to generate
859
+extra colors by lightening and darkening colors in the theme.
860
+
861
+
862
+## Customizing the grid ##
863
+
864
+```js
865
+grid: {
866
+    show: boolean
867
+    aboveData: boolean
868
+    color: color
869
+    backgroundColor: color/gradient or null
870
+    margin: number or margin object
871
+    labelMargin: number
872
+    axisMargin: number
873
+    markings: array of markings or (fn: axes -> array of markings)
874
+    borderWidth: number or object with "top", "right", "bottom" and "left" properties with different widths
875
+    borderColor: color or null or object with "top", "right", "bottom" and "left" properties with different colors
876
+    minBorderMargin: number or null
877
+    clickable: boolean
878
+    hoverable: boolean
879
+    autoHighlight: boolean
880
+    mouseActiveRadius: number
881
+}
882
+
883
+interaction: {
884
+    redrawOverlayInterval: number or -1
885
+}
886
+```
887
+
888
+The grid is the thing with the axes and a number of ticks. Many of the
889
+things in the grid are configured under the individual axes, but not
890
+all. "color" is the color of the grid itself whereas "backgroundColor"
891
+specifies the background color inside the grid area, here null means
892
+that the background is transparent. You can also set a gradient, see
893
+the gradient documentation below.
894
+
895
+You can turn off the whole grid including tick labels by setting
896
+"show" to false. "aboveData" determines whether the grid is drawn
897
+above the data or below (below is default).
898
+
899
+"margin" is the space in pixels between the canvas edge and the grid,
900
+which can be either a number or an object with individual margins for
901
+each side, in the form:
902
+
903
+```js
904
+margin: {
905
+    top: top margin in pixels
906
+    left: left margin in pixels
907
+    bottom: bottom margin in pixels
908
+    right: right margin in pixels
909
+}
910
+```
911
+
912
+"labelMargin" is the space in pixels between tick labels and axis
913
+line, and "axisMargin" is the space in pixels between axes when there
914
+are two next to each other.
915
+
916
+"borderWidth" is the width of the border around the plot. Set it to 0
917
+to disable the border. Set it to an object with "top", "right",
918
+"bottom" and "left" properties to use different widths. You can
919
+also set "borderColor" if you want the border to have a different color
920
+than the grid lines. Set it to an object with "top", "right", "bottom"
921
+and "left" properties to use different colors. "minBorderMargin" controls
922
+the default minimum margin around the border - it's used to make sure
923
+that points aren't accidentally clipped by the canvas edge so by default
924
+the value is computed from the point radius.
925
+
926
+"markings" is used to draw simple lines and rectangular areas in the
927
+background of the plot. You can either specify an array of ranges on
928
+the form { xaxis: { from, to }, yaxis: { from, to } } (with multiple
929
+axes, you can specify coordinates for other axes instead, e.g. as
930
+x2axis/x3axis/...) or with a function that returns such an array given
931
+the axes for the plot in an object as the first parameter.
932
+
933
+You can set the color of markings by specifying "color" in the ranges
934
+object. Here's an example array:
935
+
936
+```js
937
+markings: [ { xaxis: { from: 0, to: 2 }, yaxis: { from: 10, to: 10 }, color: "#bb0000" }, ... ]
938
+```
939
+
940
+If you leave out one of the values, that value is assumed to go to the
941
+border of the plot. So for example if you only specify { xaxis: {
942
+from: 0, to: 2 } } it means an area that extends from the top to the
943
+bottom of the plot in the x range 0-2.
944
+
945
+A line is drawn if from and to are the same, e.g.
946
+
947
+```js
948
+markings: [ { yaxis: { from: 1, to: 1 } }, ... ]
949
+```
950
+
951
+would draw a line parallel to the x axis at y = 1. You can control the
952
+line width with "lineWidth" in the range object.
953
+
954
+An example function that makes vertical stripes might look like this:
955
+
956
+```js
957
+markings: function (axes) {
958
+    var markings = [];
959
+    for (var x = Math.floor(axes.xaxis.min); x < axes.xaxis.max; x += 2)
960
+        markings.push({ xaxis: { from: x, to: x + 1 } });
961
+    return markings;
962
+}
963
+```
964
+
965
+If you set "clickable" to true, the plot will listen for click events
966
+on the plot area and fire a "plotclick" event on the placeholder with
967
+a position and a nearby data item object as parameters. The coordinates
968
+are available both in the unit of the axes (not in pixels) and in
969
+global screen coordinates.
970
+
971
+Likewise, if you set "hoverable" to true, the plot will listen for
972
+mouse move events on the plot area and fire a "plothover" event with
973
+the same parameters as the "plotclick" event. If "autoHighlight" is
974
+true (the default), nearby data items are highlighted automatically.
975
+If needed, you can disable highlighting and control it yourself with
976
+the highlight/unhighlight plot methods described elsewhere.
977
+
978
+You can use "plotclick" and "plothover" events like this:
979
+
980
+```js
981
+$.plot($("#placeholder"), [ d ], { grid: { clickable: true } });
982
+
983
+$("#placeholder").bind("plotclick", function (event, pos, item) {
984
+    alert("You clicked at " + pos.x + ", " + pos.y);
985
+    // axis coordinates for other axes, if present, are in pos.x2, pos.x3, ...
986
+    // if you need global screen coordinates, they are pos.pageX, pos.pageY
987
+
988
+    if (item) {
989
+        highlight(item.series, item.datapoint);
990
+        alert("You clicked a point!");
991
+    }
992
+});
993
+```
994
+
995
+The item object in this example is either null or a nearby object on the form:
996
+
997
+```js
998
+item: {
999
+    datapoint: the point, e.g. [0, 2]
1000
+    dataIndex: the index of the point in the data array
1001
+    series: the series object
1002
+    seriesIndex: the index of the series
1003
+    pageX, pageY: the global screen coordinates of the point
1004
+}
1005
+```
1006
+
1007
+For instance, if you have specified the data like this 
1008
+
1009
+```js
1010
+$.plot($("#placeholder"), [ { label: "Foo", data: [[0, 10], [7, 3]] } ], ...);
1011
+```
1012
+
1013
+and the mouse is near the point (7, 3), "datapoint" is [7, 3],
1014
+"dataIndex" will be 1, "series" is a normalized series object with
1015
+among other things the "Foo" label in series.label and the color in
1016
+series.color, and "seriesIndex" is 0. Note that plugins and options
1017
+that transform the data can shift the indexes from what you specified
1018
+in the original data array.
1019
+
1020
+If you use the above events to update some other information and want
1021
+to clear out that info in case the mouse goes away, you'll probably
1022
+also need to listen to "mouseout" events on the placeholder div.
1023
+
1024
+"mouseActiveRadius" specifies how far the mouse can be from an item
1025
+and still activate it. If there are two or more points within this
1026
+radius, Flot chooses the closest item. For bars, the top-most bar
1027
+(from the latest specified data series) is chosen.
1028
+
1029
+If you want to disable interactivity for a specific data series, you
1030
+can set "hoverable" and "clickable" to false in the options for that
1031
+series, like this:
1032
+
1033
+```js
1034
+{ data: [...], label: "Foo", clickable: false }
1035
+```
1036
+
1037
+"redrawOverlayInterval" specifies the maximum time to delay a redraw
1038
+of interactive things (this works as a rate limiting device). The
1039
+default is capped to 60 frames per second. You can set it to -1 to
1040
+disable the rate limiting.
1041
+
1042
+
1043
+## Specifying gradients ##
1044
+
1045
+A gradient is specified like this:
1046
+
1047
+```js
1048
+{ colors: [ color1, color2, ... ] }
1049
+```
1050
+
1051
+For instance, you might specify a background on the grid going from
1052
+black to gray like this:
1053
+
1054
+```js
1055
+grid: {
1056
+    backgroundColor: { colors: ["#000", "#999"] }
1057
+}
1058
+```
1059
+
1060
+For the series you can specify the gradient as an object that
1061
+specifies the scaling of the brightness and the opacity of the series
1062
+color, e.g.
1063
+
1064
+```js
1065
+{ colors: [{ opacity: 0.8 }, { brightness: 0.6, opacity: 0.8 } ] }
1066
+```
1067
+
1068
+where the first color simply has its alpha scaled, whereas the second
1069
+is also darkened. For instance, for bars the following makes the bars
1070
+gradually disappear, without outline:
1071
+
1072
+```js
1073
+bars: {
1074
+    show: true,
1075
+    lineWidth: 0,
1076
+    fill: true,
1077
+    fillColor: { colors: [ { opacity: 0.8 }, { opacity: 0.1 } ] }
1078
+}
1079
+```
1080
+
1081
+Flot currently only supports vertical gradients drawn from top to
1082
+bottom because that's what works with IE.
1083
+
1084
+
1085
+## Plot Methods ##
1086
+
1087
+The Plot object returned from the plot function has some methods you
1088
+can call:
1089
+
1090
+ - highlight(series, datapoint)
1091
+
1092
+    Highlight a specific datapoint in the data series. You can either
1093
+    specify the actual objects, e.g. if you got them from a
1094
+    "plotclick" event, or you can specify the indices, e.g.
1095
+    highlight(1, 3) to highlight the fourth point in the second series
1096
+    (remember, zero-based indexing).
1097
+
1098
+ - unhighlight(series, datapoint) or unhighlight()
1099
+
1100
+    Remove the highlighting of the point, same parameters as
1101
+    highlight.
1102
+
1103
+    If you call unhighlight with no parameters, e.g. as
1104
+    plot.unhighlight(), all current highlights are removed.
1105
+
1106
+ - setData(data)
1107
+
1108
+    You can use this to reset the data used. Note that axis scaling,
1109
+    ticks, legend etc. will not be recomputed (use setupGrid() to do
1110
+    that). You'll probably want to call draw() afterwards.
1111
+
1112
+    You can use this function to speed up redrawing a small plot if
1113
+    you know that the axes won't change. Put in the new data with
1114
+    setData(newdata), call draw(), and you're good to go. Note that
1115
+    for large datasets, almost all the time is consumed in draw()
1116
+    plotting the data so in this case don't bother.
1117
+
1118
+ - setupGrid()
1119
+
1120
+    Recalculate and set axis scaling, ticks, legend etc.
1121
+
1122
+    Note that because of the drawing model of the canvas, this
1123
+    function will immediately redraw (actually reinsert in the DOM)
1124
+    the labels and the legend, but not the actual tick lines because
1125
+    they're drawn on the canvas. You need to call draw() to get the
1126
+    canvas redrawn.
1127
+
1128
+ - draw()
1129
+
1130
+    Redraws the plot canvas.
1131
+
1132
+ - triggerRedrawOverlay()
1133
+
1134
+    Schedules an update of an overlay canvas used for drawing
1135
+    interactive things like a selection and point highlights. This
1136
+    is mostly useful for writing plugins. The redraw doesn't happen
1137
+    immediately, instead a timer is set to catch multiple successive
1138
+    redraws (e.g. from a mousemove). You can get to the overlay by
1139
+    setting up a drawOverlay hook.
1140
+
1141
+ - width()/height()
1142
+
1143
+    Gets the width and height of the plotting area inside the grid.
1144
+    This is smaller than the canvas or placeholder dimensions as some
1145
+    extra space is needed (e.g. for labels).
1146
+
1147
+ - offset()
1148
+
1149
+    Returns the offset of the plotting area inside the grid relative
1150
+    to the document, useful for instance for calculating mouse
1151
+    positions (event.pageX/Y minus this offset is the pixel position
1152
+    inside the plot).
1153
+
1154
+ - pointOffset({ x: xpos, y: ypos })
1155
+
1156
+    Returns the calculated offset of the data point at (x, y) in data
1157
+    space within the placeholder div. If you are working with multiple
1158
+    axes, you can specify the x and y axis references, e.g. 
1159
+
1160
+    ```js
1161
+      o = pointOffset({ x: xpos, y: ypos, xaxis: 2, yaxis: 3 })
1162
+      // o.left and o.top now contains the offset within the div
1163
+    ````
1164
+
1165
+ - resize()
1166
+
1167
+    Tells Flot to resize the drawing canvas to the size of the
1168
+    placeholder. You need to run setupGrid() and draw() afterwards as
1169
+    canvas resizing is a destructive operation. This is used
1170
+    internally by the resize plugin.
1171
+
1172
+ - shutdown()
1173
+
1174
+    Cleans up any event handlers Flot has currently registered. This
1175
+    is used internally.
1176
+
1177
+There are also some members that let you peek inside the internal
1178
+workings of Flot which is useful in some cases. Note that if you change
1179
+something in the objects returned, you're changing the objects used by
1180
+Flot to keep track of its state, so be careful.
1181
+
1182
+  - getData()
1183
+
1184
+    Returns an array of the data series currently used in normalized
1185
+    form with missing settings filled in according to the global
1186
+    options. So for instance to find out what color Flot has assigned
1187
+    to the data series, you could do this:
1188
+
1189
+    ```js
1190
+    var series = plot.getData();
1191
+    for (var i = 0; i < series.length; ++i)
1192
+        alert(series[i].color);
1193
+    ```
1194
+
1195
+    A notable other interesting field besides color is datapoints
1196
+    which has a field "points" with the normalized data points in a
1197
+    flat array (the field "pointsize" is the increment in the flat
1198
+    array to get to the next point so for a dataset consisting only of
1199
+    (x,y) pairs it would be 2).
1200
+
1201
+  - getAxes()
1202
+
1203
+    Gets an object with the axes. The axes are returned as the
1204
+    attributes of the object, so for instance getAxes().xaxis is the
1205
+    x axis.
1206
+
1207
+    Various things are stuffed inside an axis object, e.g. you could
1208
+    use getAxes().xaxis.ticks to find out what the ticks are for the
1209
+    xaxis. Two other useful attributes are p2c and c2p, functions for
1210
+    transforming from data point space to the canvas plot space and
1211
+    back. Both returns values that are offset with the plot offset.
1212
+    Check the Flot source code for the complete set of attributes (or
1213
+    output an axis with console.log() and inspect it).
1214
+
1215
+    With multiple axes, the extra axes are returned as x2axis, x3axis,
1216
+    etc., e.g. getAxes().y2axis is the second y axis. You can check
1217
+    y2axis.used to see whether the axis is associated with any data
1218
+    points and y2axis.show to see if it is currently shown. 
1219
+ 
1220
+  - getPlaceholder()
1221
+
1222
+    Returns placeholder that the plot was put into. This can be useful
1223
+    for plugins for adding DOM elements or firing events.
1224
+
1225
+  - getCanvas()
1226
+
1227
+    Returns the canvas used for drawing in case you need to hack on it
1228
+    yourself. You'll probably need to get the plot offset too.
1229
+  
1230
+  - getPlotOffset()
1231
+
1232
+    Gets the offset that the grid has within the canvas as an object
1233
+    with distances from the canvas edges as "left", "right", "top",
1234
+    "bottom". I.e., if you draw a circle on the canvas with the center
1235
+    placed at (left, top), its center will be at the top-most, left
1236
+    corner of the grid.
1237
+
1238
+  - getOptions()
1239
+
1240
+    Gets the options for the plot, normalized, with default values
1241
+    filled in. You get a reference to actual values used by Flot, so
1242
+    if you modify the values in here, Flot will use the new values.
1243
+    If you change something, you probably have to call draw() or
1244
+    setupGrid() or triggerRedrawOverlay() to see the change.
1245
+    
1246
+
1247
+## Hooks ##
1248
+
1249
+In addition to the public methods, the Plot object also has some hooks
1250
+that can be used to modify the plotting process. You can install a
1251
+callback function at various points in the process, the function then
1252
+gets access to the internal data structures in Flot.
1253
+
1254
+Here's an overview of the phases Flot goes through:
1255
+
1256
+  1. Plugin initialization, parsing options
1257
+  
1258
+  2. Constructing the canvases used for drawing
1259
+
1260
+  3. Set data: parsing data specification, calculating colors,
1261
+     copying raw data points into internal format,
1262
+     normalizing them, finding max/min for axis auto-scaling
1263
+
1264
+  4. Grid setup: calculating axis spacing, ticks, inserting tick
1265
+     labels, the legend
1266
+
1267
+  5. Draw: drawing the grid, drawing each of the series in turn
1268
+
1269
+  6. Setting up event handling for interactive features
1270
+
1271
+  7. Responding to events, if any
1272
+
1273
+  8. Shutdown: this mostly happens in case a plot is overwritten 
1274
+
1275
+Each hook is simply a function which is put in the appropriate array.
1276
+You can add them through the "hooks" option, and they are also available
1277
+after the plot is constructed as the "hooks" attribute on the returned
1278
+plot object, e.g.
1279
+
1280
+```js
1281
+  // define a simple draw hook
1282
+  function hellohook(plot, canvascontext) { alert("hello!"); };
1283
+
1284
+  // pass it in, in an array since we might want to specify several
1285
+  var plot = $.plot(placeholder, data, { hooks: { draw: [hellohook] } });
1286
+
1287
+  // we can now find it again in plot.hooks.draw[0] unless a plugin
1288
+  // has added other hooks
1289
+```
1290
+
1291
+The available hooks are described below. All hook callbacks get the
1292
+plot object as first parameter. You can find some examples of defined
1293
+hooks in the plugins bundled with Flot.
1294
+
1295
+ - processOptions  [phase 1]
1296
+
1297
+    ```function(plot, options)```
1298
+   
1299
+    Called after Flot has parsed and merged options. Useful in the
1300
+    instance where customizations beyond simple merging of default
1301
+    values is needed. A plugin might use it to detect that it has been
1302
+    enabled and then turn on or off other options.
1303
+
1304
+ 
1305
+ - processRawData  [phase 3]
1306
+
1307
+    ```function(plot, series, data, datapoints)```
1308
+ 
1309
+    Called before Flot copies and normalizes the raw data for the given
1310
+    series. If the function fills in datapoints.points with normalized
1311
+    points and sets datapoints.pointsize to the size of the points,
1312
+    Flot will skip the copying/normalization step for this series.
1313
+   
1314
+    In any case, you might be interested in setting datapoints.format,
1315
+    an array of objects for specifying how a point is normalized and
1316
+    how it interferes with axis scaling. It accepts the following options:
1317
+
1318
+    ```js
1319
+    {
1320
+        x, y: boolean,
1321
+        number: boolean,
1322
+        required: boolean,
1323
+        defaultValue: value,
1324
+        autoscale: boolean
1325
+    }
1326
+    ```
1327
+
1328
+    "x" and "y" specify whether the value is plotted against the x or y axis,
1329
+    and is currently used only to calculate axis min-max ranges. The default
1330
+    format array, for example, looks like this:
1331
+
1332
+    ```js
1333
+    [
1334
+        { x: true, number: true, required: true },
1335
+        { y: true, number: true, required: true }
1336
+    ]
1337
+    ```
1338
+
1339
+    This indicates that a point, i.e. [0, 25], consists of two values, with the
1340
+    first being plotted on the x axis and the second on the y axis.
1341
+
1342
+    If "number" is true, then the value must be numeric, and is set to null if
1343
+    it cannot be converted to a number.
1344
+
1345
+    "defaultValue" provides a fallback in case the original value is null. This
1346
+    is for instance handy for bars, where one can omit the third coordinate
1347
+    (the bottom of the bar), which then defaults to zero.
1348
+
1349
+    If "required" is true, then the value must exist (be non-null) for the
1350
+    point as a whole to be valid. If no value is provided, then the entire
1351
+    point is cleared out with nulls, turning it into a gap in the series.
1352
+
1353
+    "autoscale" determines whether the value is considered when calculating an
1354
+    automatic min-max range for the axes that the value is plotted against.
1355
+
1356
+ - processDatapoints  [phase 3]
1357
+
1358
+    ```function(plot, series, datapoints)```
1359
+
1360
+    Called after normalization of the given series but before finding
1361
+    min/max of the data points. This hook is useful for implementing data
1362
+    transformations. "datapoints" contains the normalized data points in
1363
+    a flat array as datapoints.points with the size of a single point
1364
+    given in datapoints.pointsize. Here's a simple transform that
1365
+    multiplies all y coordinates by 2:
1366
+
1367
+    ```js
1368
+    function multiply(plot, series, datapoints) {
1369
+        var points = datapoints.points, ps = datapoints.pointsize;
1370
+        for (var i = 0; i < points.length; i += ps)
1371
+            points[i + 1] *= 2;
1372
+    }
1373
+    ```
1374
+
1375
+    Note that you must leave datapoints in a good condition as Flot
1376
+    doesn't check it or do any normalization on it afterwards.
1377
+
1378
+ - processOffset  [phase 4]
1379
+
1380
+    ```function(plot, offset)```
1381
+
1382
+    Called after Flot has initialized the plot's offset, but before it
1383
+    draws any axes or plot elements. This hook is useful for customizing
1384
+    the margins between the grid and the edge of the canvas. "offset" is
1385
+    an object with attributes "top", "bottom", "left" and "right",
1386
+    corresponding to the margins on the four sides of the plot.
1387
+
1388
+ - drawBackground [phase 5]
1389
+
1390
+    ```function(plot, canvascontext)```
1391
+
1392
+    Called before all other drawing operations. Used to draw backgrounds
1393
+    or other custom elements before the plot or axes have been drawn.
1394
+
1395
+ - drawSeries  [phase 5]
1396
+
1397
+    ```function(plot, canvascontext, series)```
1398
+
1399
+    Hook for custom drawing of a single series. Called just before the
1400
+    standard drawing routine has been called in the loop that draws
1401
+    each series.
1402
+
1403
+ - draw  [phase 5]
1404
+
1405
+    ```function(plot, canvascontext)```
1406
+
1407
+    Hook for drawing on the canvas. Called after the grid is drawn
1408
+    (unless it's disabled or grid.aboveData is set) and the series have
1409
+    been plotted (in case any points, lines or bars have been turned
1410
+    on). For examples of how to draw things, look at the source code.
1411
+
1412
+ - bindEvents  [phase 6]
1413
+
1414
+    ```function(plot, eventHolder)```
1415
+
1416
+    Called after Flot has setup its event handlers. Should set any
1417
+    necessary event handlers on eventHolder, a jQuery object with the
1418
+    canvas, e.g.
1419
+
1420
+    ```js
1421
+    function (plot, eventHolder) {
1422
+        eventHolder.mousedown(function (e) {
1423
+            alert("You pressed the mouse at " + e.pageX + " " + e.pageY);
1424
+        });
1425
+    }
1426
+    ```
1427
+
1428
+    Interesting events include click, mousemove, mouseup/down. You can
1429
+    use all jQuery events. Usually, the event handlers will update the
1430
+    state by drawing something (add a drawOverlay hook and call
1431
+    triggerRedrawOverlay) or firing an externally visible event for
1432
+    user code. See the crosshair plugin for an example.
1433
+     
1434
+    Currently, eventHolder actually contains both the static canvas
1435
+    used for the plot itself and the overlay canvas used for
1436
+    interactive features because some versions of IE get the stacking
1437
+    order wrong. The hook only gets one event, though (either for the
1438
+    overlay or for the static canvas).
1439
+
1440
+    Note that custom plot events generated by Flot are not generated on
1441
+    eventHolder, but on the div placeholder supplied as the first
1442
+    argument to the plot call. You can get that with
1443
+    plot.getPlaceholder() - that's probably also the one you should use
1444
+    if you need to fire a custom event.
1445
+
1446
+ - drawOverlay  [phase 7]
1447
+
1448
+    ```function (plot, canvascontext)```
1449
+
1450
+    The drawOverlay hook is used for interactive things that need a
1451
+    canvas to draw on. The model currently used by Flot works the way
1452
+    that an extra overlay canvas is positioned on top of the static
1453
+    canvas. This overlay is cleared and then completely redrawn
1454
+    whenever something interesting happens. This hook is called when
1455
+    the overlay canvas is to be redrawn.
1456
+
1457
+    "canvascontext" is the 2D context of the overlay canvas. You can
1458
+    use this to draw things. You'll most likely need some of the
1459
+    metrics computed by Flot, e.g. plot.width()/plot.height(). See the
1460
+    crosshair plugin for an example.
1461
+
1462
+ - shutdown  [phase 8]
1463
+
1464
+    ```function (plot, eventHolder)```
1465
+
1466
+    Run when plot.shutdown() is called, which usually only happens in
1467
+    case a plot is overwritten by a new plot. If you're writing a
1468
+    plugin that adds extra DOM elements or event handlers, you should
1469
+    add a callback to clean up after you. Take a look at the section in
1470
+    the [PLUGINS](PLUGINS.md) document for more info.
1471
+
1472
+   
1473
+## Plugins ##
1474
+
1475
+Plugins extend the functionality of Flot. To use a plugin, simply
1476
+include its Javascript file after Flot in the HTML page.
1477
+
1478
+If you're worried about download size/latency, you can concatenate all
1479
+the plugins you use, and Flot itself for that matter, into one big file
1480
+(make sure you get the order right), then optionally run it through a
1481
+Javascript minifier such as YUI Compressor.
1482
+
1483
+Here's a brief explanation of how the plugin plumbings work:
1484
+
1485
+Each plugin registers itself in the global array $.plot.plugins. When
1486
+you make a new plot object with $.plot, Flot goes through this array
1487
+calling the "init" function of each plugin and merging default options
1488
+from the "option" attribute of the plugin. The init function gets a
1489
+reference to the plot object created and uses this to register hooks
1490
+and add new public methods if needed.
1491
+
1492
+See the [PLUGINS](PLUGINS.md) document for details on how to write a plugin. As the
1493
+above description hints, it's actually pretty easy.
1494
+
1495
+
1496
+## Version number ##
1497
+
1498
+The version number of Flot is available in ```$.plot.version```.
... ...
@@ -0,0 +1,98 @@
1
+## Contributing to Flot ##
2
+
3
+We welcome all contributions, but following these guidelines results in less
4
+work for us, and a faster and better response.
5
+
6
+### Issues ###
7
+
8
+Issues are not a way to ask general questions about Flot. If you see unexpected
9
+behavior but are not 100% certain that it is a bug, please try posting to the
10
+[forum](http://groups.google.com/group/flot-graphs) first, and confirm that
11
+what you see is really a Flot problem before creating a new issue for it.  When
12
+reporting a bug, please include a working demonstration of the problem, if
13
+possible, or at least a clear description of the options you're using and the
14
+environment (browser and version, jQuery version, other libraries) that you're
15
+running under.
16
+
17
+If you have suggestions for new features, or changes to existing ones, we'd
18
+love to hear them! Please submit each suggestion as a separate new issue.
19
+
20
+If you would like to work on an existing issue, please make sure it is not
21
+already assigned to someone else. If an issue is assigned to someone, that
22
+person has already started working on it. So, pick unassigned issues to prevent
23
+duplicated effort.
24
+
25
+### Pull Requests ###
26
+
27
+To make merging as easy as possible, please keep these rules in mind:
28
+
29
+ 1. Submit new features or architectural changes to the *&lt;version&gt;-work*
30
+    branch for the next major release.  Submit bug fixes to the master branch.
31
+
32
+ 2. Divide larger changes into a series of small, logical commits with
33
+    descriptive messages.
34
+
35
+ 3. Rebase, if necessary, before submitting your pull request, to reduce the
36
+    work we need to do to merge it.
37
+
38
+ 4. Format your code according to the style guidelines below.
39
+
40
+### Flot Style Guidelines ###
41
+
42
+Flot follows the [jQuery Core Style Guidelines](http://docs.jquery.com/JQuery_Core_Style_Guidelines),
43
+with the following updates and exceptions:
44
+
45
+#### Spacing ####
46
+
47
+Use four-space indents, no tabs.  Do not add horizontal space around parameter
48
+lists, loop definitions, or array/object indices. For example:
49
+
50
+```js
51
+    for ( var i = 0; i < data.length; i++ ) {  // This block is wrong!
52
+        if ( data[ i ] > 1 ) {
53
+            data[ i ] = 2;
54
+        }
55
+    }
56
+
57
+    for (var i = 0; i < data.length; i++) {  // This block is correct!
58
+        if (data[i] > 1) {
59
+            data[i] = 2;
60
+        }
61
+    }
62
+```
63
+
64
+#### Comments ####
65
+
66
+Use [jsDoc](http://usejsdoc.org) comments for all file and function headers.
67
+Use // for all inline and block comments, regardless of length.
68
+
69
+All // comment blocks should have an empty line above *and* below them. For
70
+example:
71
+
72
+```js
73
+    var a = 5;
74
+
75
+    // We're going to loop here
76
+    // TODO: Make this loop faster, better, stronger!
77
+
78
+    for (var x = 0; x < 10; x++) {}
79
+```
80
+
81
+#### Wrapping ####
82
+
83
+Block comments should be wrapped at 80 characters.
84
+
85
+Code should attempt to wrap at 80 characters, but may run longer if wrapping
86
+would hurt readability more than having to scroll horizontally.  This is a
87
+judgement call made on a situational basis.
88
+
89
+Statements containing complex logic should not be wrapped arbitrarily if they
90
+do not exceed 80 characters. For example:
91
+
92
+```js
93
+    if (a == 1 &&    // This block is wrong!
94
+        b == 2 &&
95
+        c == 3) {}
96
+
97
+    if (a == 1 && b == 2 && c == 3) {}  // This block is correct!
98
+```
... ...
@@ -0,0 +1,75 @@
1
+## Frequently asked questions ##
2
+
3
+#### How much data can Flot cope with? ####
4
+
5
+Flot will happily draw everything you send to it so the answer
6
+depends on the browser. The excanvas emulation used for IE (built with
7
+VML) makes IE by far the slowest browser so be sure to test with that
8
+if IE users are in your target group (for large plots in IE, you can
9
+also check out Flashcanvas which may be faster).
10
+
11
+1000 points is not a problem, but as soon as you start having more
12
+points than the pixel width, you should probably start thinking about
13
+downsampling/aggregation as this is near the resolution limit of the
14
+chart anyway. If you downsample server-side, you also save bandwidth.
15
+
16
+
17
+#### Flot isn't working when I'm using JSON data as source! ####
18
+
19
+Actually, Flot loves JSON data, you just got the format wrong.
20
+Double check that you're not inputting strings instead of numbers,
21
+like [["0", "-2.13"], ["5", "4.3"]]. This is most common mistake, and
22
+the error might not show up immediately because Javascript can do some
23
+conversion automatically.
24
+
25
+
26
+#### Can I export the graph? ####
27
+
28
+You can grab the image rendered by the canvas element used by Flot
29
+as a PNG or JPEG (remember to set a background). Note that it won't
30
+include anything not drawn in the canvas (such as the legend). And it
31
+doesn't work with excanvas which uses VML, but you could try
32
+Flashcanvas.
33
+
34
+
35
+#### The bars are all tiny in time mode? ####
36
+
37
+It's not really possible to determine the bar width automatically.
38
+So you have to set the width with the barWidth option which is NOT in
39
+pixels, but in the units of the x axis (or the y axis for horizontal
40
+bars). For time mode that's milliseconds so the default value of 1
41
+makes the bars 1 millisecond wide.
42
+
43
+
44
+#### Can I use Flot with libraries like Mootools or Prototype? ####
45
+
46
+Yes, Flot supports it out of the box and it's easy! Just use jQuery
47
+instead of $, e.g. call jQuery.plot instead of $.plot and use
48
+jQuery(something) instead of $(something). As a convenience, you can
49
+put in a DOM element for the graph placeholder where the examples and
50
+the API documentation are using jQuery objects.
51
+
52
+Depending on how you include jQuery, you may have to add one line of
53
+code to prevent jQuery from overwriting functions from the other
54
+libraries, see the documentation in jQuery ("Using jQuery with other
55
+libraries") for details.
56
+
57
+
58
+#### Flot doesn't work with [insert name of Javascript UI framework]! ####
59
+
60
+Flot is using standard HTML to make charts. If this is not working,
61
+it's probably because the framework you're using is doing something
62
+weird with the DOM or with the CSS that is interfering with Flot.
63
+
64
+A common problem is that there's display:none on a container until the
65
+user does something. Many tab widgets work this way, and there's
66
+nothing wrong with it - you just can't call Flot inside a display:none
67
+container as explained in the README so you need to hold off the Flot
68
+call until the container is actually displayed (or use
69
+visibility:hidden instead of display:none or move the container
70
+off-screen).
71
+
72
+If you find there's a specific thing we can do to Flot to help, feel
73
+free to submit a bug report. Otherwise, you're welcome to ask for help
74
+on the forum/mailing list, but please don't submit a bug report to
75
+Flot.
... ...
@@ -0,0 +1,22 @@
1
+Copyright (c) 2007-2014 IOLA and Ole Laursen
2
+
3
+Permission is hereby granted, free of charge, to any person
4
+obtaining a copy of this software and associated documentation
5
+files (the "Software"), to deal in the Software without
6
+restriction, including without limitation the rights to use,
7
+copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+copies of the Software, and to permit persons to whom the
9
+Software is furnished to do so, subject to the following
10
+conditions:
11
+
12
+The above copyright notice and this permission notice shall be
13
+included in all copies or substantial portions of the Software.
14
+
15
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+OTHER DEALINGS IN THE SOFTWARE.
... ...
@@ -0,0 +1,12 @@
1
+# Makefile for generating minified files
2
+
3
+.PHONY: all
4
+
5
+# we cheat and process all .js files instead of an exhaustive list
6
+all: $(patsubst %.js,%.min.js,$(filter-out %.min.js,$(wildcard *.js)))
7
+
8
+%.min.js: %.js
9
+	yui-compressor $< -o $@
10
+
11
+test:
12
+	./node_modules/.bin/jshint *jquery.flot.js
... ...
@@ -0,0 +1,1026 @@
1
+## Flot 0.8.3 ##
2
+
3
+### Changes ###
4
+
5
+- Updated example code to avoid encouraging unnecessary re-plots.
6
+  (patch by soenter, pull request #1221)
7
+
8
+### Bug fixes ###
9
+
10
+ - Added a work-around to disable the allocation of extra space for first and
11
+   last axis ticks, allowing plots to span the full width of their container.
12
+   A proper solution for this bug will be implemented in the 0.9 release.
13
+   (reported by Josh Pigford and andig, issue #1212, pull request #1290)
14
+
15
+ - Fixed a regression introduced in 0.8.1, where the last tick label would
16
+   sometimes wrap rather than extending the plot's offset to create space.
17
+   (reported by Elite Gamer, issue #1283)
18
+
19
+ - Fixed a regression introduced in 0.8.2, where the resize plugin would use
20
+   unexpectedly high amounts of CPU even when idle.
21
+   (reported by tommie, issue #1277, pull request #1289)
22
+
23
+ - Fixed the selection example to work with jQuery 1.9.x and later.
24
+   (reported by EGLadona and dmfalke, issue #1250, pull request #1285)
25
+
26
+ - Added a detach shim to fix support for jQuery versions earlier than 1.4.x.
27
+   (reported by ngavard, issue #1240, pull request #1286)
28
+
29
+ - Fixed a rare 'Uncaught TypeError' when using the resize plugin in IE 7/8.
30
+   (reported by tleish, issue #1265, pull request #1289)
31
+
32
+ - Fixed zoom constraints to apply only in the direction of the zoom.
33
+   (patch by Neil Katin, issue #1204, pull request #1205)
34
+
35
+ - Markings lines are no longer blurry when drawn on pixel boundaries.
36
+   (reported by btccointicker and Rouillard, issue #1210)
37
+
38
+ - Don't discard original pie data-series values when combining slices.
39
+   (patch by Phil Tsarik, pull request #1238)
40
+
41
+ - Fixed broken auto-scale behavior when using deprecated [x|y]2axis options.
42
+   (reported by jorese, issue #1228, pull request #1284)
43
+
44
+ - Exposed the dateGenerator function on the plot object, as it used to be
45
+   before time-mode was moved into a separate plugin.
46
+   (patch by Paolo Valleri, pull request #1028)
47
+
48
+
49
+## Flot 0.8.2 ##
50
+
51
+### Changes ###
52
+
53
+ - Added a plot.destroy method as a way to free memory when emptying the plot
54
+   placeholder and then re-using it for some other purpose.
55
+   (patch by Thodoris Greasidis, issue #1129, pull request #1130)
56
+
57
+ - Added a table of contents and PLUGINS link to the API documentation.
58
+   (patches by Brian Peiris, pull requests #1064 and #1127)
59
+
60
+ - Added Ruby code examples for time conversion.
61
+   (patch by Mike Połtyn, pull request #1182)
62
+
63
+ - Minor improvements to API.md and README.md.
64
+   (patches by Patrik Ragnarsson, pull requests #1085 and #1086)
65
+
66
+ - Updated inlined jQuery Resize to the latest version to fix errors.
67
+   (reported by Matthew Sabol and sloker, issues #997 ad #1081)
68
+
69
+### Bug fixes ###
70
+
71
+ - Fixed an unexpected change in behavior that resulted in duplicate tick
72
+   labels when using a plugin, like flot-tickrotor, that overrode tick labels.
73
+   (patch by Mark Cote, pull request #1091)
74
+
75
+ - Fixed a regression from 0.7 where axis labels were given the wrong width,
76
+   causing them to overlap at certain scales and ignore the labelWidth option.
77
+   (patch by Benjamin Gram, pull request #1177)
78
+
79
+ - Fixed a bug where the second axis in an xaxes/yaxes array incorrectly had
80
+   its 'innermost' property set to false or undefined, even if it was on the
81
+   other side of the plot from the first axis. This resulted in the axis bar
82
+   being visible when it shouldn't have been, which was especially obvious
83
+   when the grid had a left/right border width of zero.
84
+   (reported by Teq1, fix researched by ryleyb, issue #1056)
85
+
86
+ - Fixed an error when using a placeholder that has no font-size property.
87
+   (patch by Craig Oldford, pull request #1135)
88
+
89
+ - Fixed a regression from 0.7 where nulls at the end of a series were ignored
90
+   for purposes of determing the range of the x-axis.
91
+   (reported by Munsifali Rashid, issue #1095)
92
+
93
+ - If a font size is provided, base the default lineHeight on that size rather
94
+   that the font size of the plot placeholder, which may be very different.
95
+   (reported by Daniel Hoffmann Bernardes, issue #1131, pull request #1199)
96
+
97
+ - Fix broken highlighting for right-aligned bars.
98
+   (reported by BeWiBu and Mihai Stanciu, issues #975 and #1093, with further
99
+   assistance by Eric Byers, pull request #1120)
100
+
101
+ - Prevent white circles from sometimes showing up inside of pie charts.
102
+   (reported by Pierre Dubois and Jack Klink, issues #1128 and #1073)
103
+
104
+ - Label formatting no longer breaks when a page contains multiple pie charts.
105
+   (reported by Brend Wanders, issue #1055)
106
+
107
+ - When using multiple axes on opposite sides of the plot, the innermost axis
108
+   coming later in the list no longer has its bar drawn incorrectly.
109
+   (reported by ryleyb, issue #1056)
110
+
111
+ - When removing series labels and redrawing the plot, the legend now updates
112
+   correctly even when using an external container.
113
+   (patch by Luis Silva, issue #1159, pull request #1160)
114
+
115
+ - The pie plugin no longer ignores the value of the left offset option.
116
+   (reported by melanker, issue #1136)
117
+
118
+ - Fixed a regression from 0.7, where extra padding was added unnecessarily to
119
+   sides of the plot where there was no last tick label.
120
+   (reported by sknob001, issue #1048, pull request #1200)
121
+
122
+ - Fixed incorrect tooltip behavior in the interacting example.
123
+   (patch by cleroux, issue #686, pull request #1074)
124
+
125
+ - Fixed an error in CSS color extraction with elements outside the DOM.
126
+   (patch by execjosh, pull request #1084)
127
+
128
+ - Fixed :not selector error when using jQuery without Sizzle.
129
+   (patch by Anthony Ryan, pull request #1180)
130
+
131
+ - Worked around a browser issue that caused bars to appear un-filled.
132
+   (reported by irbian, issue #915)
133
+
134
+## Flot 0.8.1 ##
135
+
136
+### Bug fixes ###
137
+
138
+ - Fixed a regression in the time plugin, introduced in 0.8, that caused dates
139
+   to align to the minute rather than to the highest appropriate unit. This
140
+   caused many x-axes in 0.8 to have different ticks than they did in 0.7.
141
+   (reported by Tom Sheppard, patch by Daniel Shapiro, issue #1017, pull
142
+   request #1023)
143
+
144
+ - Fixed a regression in text rendering, introduced in 0.8, that caused axis
145
+   labels with the same text as another label on the same axis to disappear.
146
+   More generally, it's again possible to have the same text in two locations.
147
+   (issue #1032)
148
+
149
+ - Fixed a regression in text rendering, introduced in 0.8, where axis labels
150
+   were no longer assigned an explicit width, and their text could not wrap.
151
+   (reported by sabregreen, issue #1019)
152
+
153
+ - Fixed a regression in the pie plugin, introduced in 0.8, that prevented it
154
+   from accepting data in the format '[[x, y]]'.
155
+   (patch by Nicolas Morel, pull request #1024)
156
+
157
+ - The 'zero' series option and 'autoscale' format option are no longer
158
+   ignored when the series contains a null value.
159
+   (reported by Daniel Shapiro, issue #1033)
160
+
161
+ - Avoid triggering the time-mode plugin exception when there are zero series.
162
+   (reported by Daniel Rothig, patch by Mark Raymond, issue #1016)
163
+
164
+ - When a custom color palette has fewer colors than the default palette, Flot
165
+   no longer fills out the colors with the remainder of the default.
166
+   (patch by goorpy, issue #1031, pull request #1034)
167
+
168
+ - Fixed missing update for bar highlights after a zoom or other redraw.
169
+   (reported by Paolo Valleri, issue #1030)
170
+
171
+ - Fixed compatibility with jQuery versions earlier than 1.7.
172
+   (patch by Lee Willis, issue #1027, pull request #1027)
173
+
174
+ - The mouse wheel no longer scrolls the page when using the navigate plugin.
175
+   (patch by vird, pull request #1020)
176
+
177
+ - Fixed missing semicolons in the core library.
178
+   (reported by Michal Zglinski)
179
+
180
+
181
+## Flot 0.8.0 ##
182
+
183
+### API changes ###
184
+
185
+Support for time series has been moved into a plugin, jquery.flot.time.js.
186
+This results in less code if time series are not used. The functionality
187
+remains the same (plus timezone support, as described below); however, the
188
+plugin must be included if axis.mode is set to "time".
189
+
190
+When the axis mode is "time", the axis option "timezone" can be set to null,
191
+"browser", or a particular timezone (e.g. "America/New_York") to control how
192
+the dates are displayed. If null, the dates are displayed as UTC. If
193
+"browser", the dates are displayed in the time zone of the user's browser.
194
+
195
+Date/time formatting has changed and now follows a proper subset of the
196
+standard strftime specifiers, plus one nonstandard specifier for quarters.
197
+Additionally, if a strftime function is found in the Date object's prototype,
198
+it will be used instead of the built-in formatter.
199
+
200
+Axis tick labels now use the class 'flot-tick-label' instead of 'tickLabel'.
201
+The text containers  for each axis now use the classes 'flot-[x|y]-axis' and
202
+'flot-[x|y]#-axis' instead of '[x|y]Axis' and '[x|y]#Axis'. For compatibility
203
+with Flot 0.7 and earlier text will continue to use the old classes as well,
204
+but they are considered deprecated and will be removed in a future version.
205
+
206
+In previous versions the axis 'color' option was used to set the color of tick
207
+marks and their label text. It now controls the color of the axis line, which
208
+previously could not be changed separately, and continues to act as a default
209
+for the tick-mark color.  The color of tick label text is now set either by
210
+overriding the 'flot-tick-label' CSS rule or via the axis 'font' option.
211
+
212
+A new plugin, jquery.flot.canvas.js, allows axis tick labels to be rendered
213
+directly to the canvas, rather than using HTML elements. This feature can be
214
+toggled with a simple option, making it easy to create interactive plots in the
215
+browser using HTML, then re-render them to canvas for export as an image.
216
+
217
+The plugin tries to remain as faithful as possible to the original HTML render,
218
+and goes so far as to automatically extract styles from CSS, to avoid having to
219
+provide a separate set of styles when rendering to canvas. Due to limitations
220
+of the canvas text API, the plugin cannot reproduce certain features, including
221
+HTML markup embedded in labels, and advanced text styles such as 'em' units.
222
+
223
+The plugin requires support for canvas text, which may not be present in some
224
+older browsers, even if they support the canvas tag itself. To use the plugin
225
+with these browsers try using a shim such as canvas-text or FlashCanvas.
226
+
227
+The base and overlay canvas are now using the CSS classes "flot-base" and
228
+"flot-overlay" to prevent accidental clashes (issue 540).
229
+
230
+### Changes ###
231
+
232
+ - Addition of nonstandard %q specifier to date/time formatting. (patch
233
+   by risicle, issue 49)
234
+
235
+ - Date/time formatting follows proper subset of strftime specifiers, and
236
+   support added for Date.prototype.strftime, if found. (patch by Mark Cote,
237
+   issues 419 and 558)
238
+
239
+ - Fixed display of year ticks. (patch by Mark Cote, issue 195)
240
+
241
+ - Support for time series moved to plugin. (patch by Mark Cote)
242
+
243
+ - Display time series in different time zones. (patch by Knut Forkalsrud,
244
+   issue 141)
245
+
246
+ - Added a canvas plugin to enable rendering axis tick labels to the canvas.
247
+   (sponsored by YCharts.com, implementation by Ole Laursen and David Schnur)
248
+
249
+ - Support for setting the interval between redraws of the overlay canvas with
250
+   redrawOverlayInterval. (suggested in issue 185)
251
+
252
+ - Support for multiple thresholds in thresholds plugin. (patch by Arnaud
253
+   Bellec, issue 523)
254
+
255
+ - Support for plotting categories/textual data directly with new categories
256
+   plugin.
257
+
258
+ - Tick generators now get the whole axis rather than just min/max.
259
+
260
+ - Added processOffset and drawBackground hooks. (suggested in issue 639)
261
+
262
+ - Added a grid "margin" option to set the space between the canvas edge and
263
+   the grid.
264
+
265
+ - Prevent the pie example page from generating single-slice pies. (patch by
266
+   Shane Reustle)
267
+
268
+ - In addition to "left" and "center", bars now recognize "right" as an
269
+   alignment option. (patch by Michael Mayer, issue 520)
270
+
271
+ - Switched from toFixed to a much faster default tickFormatter. (patch by
272
+   Clemens Stolle)
273
+
274
+ - Added to a more helpful error when using a time-mode axis without including
275
+   the flot.time plugin. (patch by Yael Elmatad)
276
+
277
+ - Added a legend "sorted" option to control sorting of legend entries
278
+   independent of their series order. (patch by Tom Cleaveland)
279
+
280
+ - Added a series "highlightColor" option to control the color of the
281
+   translucent overlay that identifies the dataset when the mouse hovers over
282
+   it. (patch by Eric Wendelin and Nate Abele, issues 168 and 299)
283
+
284
+ - Added a plugin jquery.flot.errorbars, with an accompanying example, that
285
+   adds the ability to plot error bars, commonly used in many kinds of
286
+   statistical data visualizations. (patch by Rui Pereira, issue 215)
287
+
288
+ - The legend now omits entries whose labelFormatter returns null.  (patch by
289
+   Tom Cleaveland, Christopher Lambert, and Simon Strandgaard)
290
+
291
+ - Added support for high pixel density (retina) displays, resulting in much
292
+   crisper charts on such devices. (patch by Olivier Guerriat, additional
293
+   fixes by Julien Thomas, maimairel, and Lau Bech Lauritzen)
294
+
295
+ - Added the ability to control pie shadow position and alpha via a new pie
296
+   'shadow' option. (patch by Julien Thomas, pull request #78)
297
+
298
+ - Added the ability to set width and color for individual sides of the grid.
299
+   (patch by Ara Anjargolian, additional fixes by Karl Swedberg, pull requests #855
300
+   and #880)
301
+
302
+ - The selection plugin's getSelection now returns null when the selection
303
+   has been cleared. (patch by Nick Campbell, pull request #852)
304
+
305
+ - Added a new option called 'zero' to bars and filled lines series, to control
306
+   whether the y-axis minimum is scaled to fit the data or set to zero.
307
+   (patch by David Schnur, issues #316, #529, and #856, pull request #911)
308
+
309
+ - The plot function is now also a jQuery chainable property.
310
+   (patch by David Schnur, issues #734 and #816, pull request #953)
311
+
312
+ - When only a single pie slice is beneath the combine threshold it is no longer
313
+   replaced by an 'other' slice. (suggested by Devin Bayer, issue #638)
314
+
315
+ - Added lineJoin and minSize options to the selection plugin to control the
316
+   corner style and minimum size of the selection, respectively.
317
+   (patch by Ruth Linehan, pull request #963)
318
+
319
+### Bug fixes ###
320
+
321
+ - Fix problem with null values and pie plugin. (patch by gcruxifix,
322
+   issue 500)
323
+
324
+ - Fix problem with threshold plugin and bars. (based on patch by
325
+   kaarlenkaski, issue 348)
326
+
327
+ - Fix axis box calculations so the boxes include the outermost part of the
328
+   labels too.
329
+
330
+ - Fix problem with event clicking and hovering in IE 8 by updating Excanvas
331
+   and removing previous work-around. (test case by Ara Anjargolian)
332
+
333
+ - Fix issues with blurry 1px border when some measures aren't integer.
334
+   (reported by Ara Anjargolian)
335
+
336
+ - Fix bug with formats in the data processor. (reported by Peter Hull,
337
+   issue 534)
338
+
339
+ - Prevent i from being declared global in extractRange. (reported by
340
+   Alexander Obukhov, issue 627)
341
+
342
+ - Throw errors in a more cross-browser-compatible manner. (patch by
343
+   Eddie Kay)
344
+
345
+ - Prevent pie slice outlines from being drawn when the stroke width is zero.
346
+   (reported by Chris Minett, issue 585)
347
+
348
+ - Updated the navigate plugin's inline copy of jquery.mousewheel to fix
349
+   Webkit zoom problems. (reported by Hau Nguyen, issue 685)
350
+
351
+ - Axis labels no longer appear as decimals rather than integers in certain
352
+   cases. (patch by Clemens Stolle, issue 541)
353
+
354
+ - Automatic color generation no longer produces only whites and blacks when
355
+   there are many series. (patch by David Schnur and Tom Cleaveland)
356
+
357
+ - Fixed an error when custom tick labels weren't provided as strings. (patch
358
+   by Shad Downey)
359
+
360
+ - Prevented the local insertSteps and fmt variables from becoming global.
361
+   (first reported by Marc Bennewitz and Szymon Barglowski, patch by Nick
362
+   Campbell, issues #825 and #831, pull request #851)
363
+
364
+ - Prevented several threshold plugin variables from becoming global. (patch
365
+   by Lasse Dahl Ebert)
366
+
367
+ - Fixed various jQuery 1.8 compatibility issues. (issues #814 and #819,
368
+   pull request #877)
369
+
370
+ - Pie charts with a slice equal to or approaching 100% of the pie no longer
371
+   appear invisible. (patch by David Schnur, issues #444, #658, #726, #824
372
+   and #850, pull request #879)
373
+
374
+ - Prevented several local variables from becoming global. (patch by aaa707)
375
+
376
+ - Ensure that the overlay and primary canvases remain aligned. (issue #670,
377
+   pull request #901)
378
+
379
+ - Added support for jQuery 1.9 by removing and replacing uses of $.browser.
380
+   (analysis and patch by Anthony Ryan, pull request #905)
381
+
382
+ - Pie charts no longer disappear when redrawn during a resize or update.
383
+   (reported by Julien Bec, issue #656, pull request #910)
384
+
385
+ - Avoided floating-point precision errors when calculating pie percentages.
386
+   (patch by James Ward, pull request #918)
387
+
388
+ - Fixed compatibility with jQuery 1.2.6, which has no 'mouseleave' shortcut.
389
+   (reported by Bevan, original pull request #920, replaced by direct patch)
390
+
391
+ - Fixed sub-pixel rendering issues with crosshair and selection lines.
392
+   (patches by alanayoub and Daniel Shapiro, pull requests #17 and #925)
393
+
394
+ - Fixed rendering issues when using the threshold plugin with several series.
395
+   (patch by Ivan Novikov, pull request #934)
396
+
397
+ - Pie charts no longer disappear when redrawn after calling setData().
398
+   (reported by zengge1984 and pareeohnos, issues #810 and #945)
399
+
400
+ - Added a work-around for the problem where points with a lineWidth of zero
401
+   still showed up with a visible line. (reported by SalvoSav, issue #842,
402
+   patch by Jamie Hamel-Smith, pull request #937)
403
+
404
+ - Pie charts now accept values in string form, like other plot types.
405
+   (reported by laerdal.no, issue #534)
406
+
407
+ - Avoid rounding errors in the threshold plugin.
408
+   (reported by jerikojerk, issue #895)
409
+
410
+ - Fixed an error when using the navigate plugin with jQuery 1.9.x or later.
411
+   (reported by Paolo Valleri, issue #964)
412
+
413
+ - Fixed inconsistencies between the highlight and unhighlight functions.
414
+   (reported by djamshed, issue #987)
415
+
416
+ - Fixed recalculation of tickSize and tickDecimals on calls to setupGrid.
417
+   (patch by thecountofzero, pull request #861, issues #860, #1000)
418
+
419
+
420
+## Flot 0.7 ##
421
+
422
+### API changes ###
423
+
424
+Multiple axes support. Code using dual axes should be changed from using
425
+x2axis/y2axis in the options to using an array (although backwards-
426
+compatibility hooks are in place). For instance,
427
+
428
+```js
429
+{
430
+    xaxis: { ... }, x2axis: { ... },
431
+    yaxis: { ... }, y2axis: { ... }
432
+}
433
+```
434
+
435
+becomes
436
+
437
+```js
438
+{
439
+    xaxes: [ { ... }, { ... } ],
440
+    yaxes: [ { ... }, { ... } ]
441
+}
442
+```
443
+
444
+Note that if you're just using one axis, continue to use the xaxis/yaxis
445
+directly (it now sets the default settings for the arrays). Plugins touching
446
+the axes must be ported to take the extra axes into account, check the source
447
+to see some examples.
448
+
449
+A related change is that the visibility of axes is now auto-detected. So if
450
+you were relying on an axis to show up even without any data in the chart, you
451
+now need to set the axis "show" option explicitly.
452
+
453
+"tickColor" on the grid options is now deprecated in favour of a corresponding
454
+option on the axes, so:
455
+
456
+```js
457
+{ grid: { tickColor: "#000" }}
458
+```
459
+
460
+becomes
461
+
462
+```js
463
+{ xaxis: { tickColor: "#000"}, yaxis: { tickColor: "#000"} }
464
+```
465
+
466
+But if you just configure a base color Flot will now autogenerate a tick color
467
+by adding transparency. Backwards-compatibility hooks are in place.
468
+
469
+Final note: now that IE 9 is coming out with canvas support, you may want to
470
+adapt the excanvas include to skip loading it in IE 9 (the examples have been
471
+adapted thanks to Ryley Breiddal). An alternative to excanvas using Flash has
472
+also surfaced, if your graphs are slow in IE, you may want to give it a spin:
473
+
474
+    http://code.google.com/p/flashcanvas/
475
+
476
+### Changes ###
477
+
478
+ - Support for specifying a bottom for each point for line charts when filling
479
+   them, this means that an arbitrary bottom can be used instead of just the x
480
+   axis. (based on patches patiently provided by Roman V. Prikhodchenko)
481
+
482
+ - New fillbetween plugin that can compute a bottom for a series from another
483
+   series, useful for filling areas between lines.
484
+
485
+   See new example percentiles.html for a use case.
486
+
487
+ - More predictable handling of gaps for the stacking plugin, now all
488
+   undefined ranges are skipped.
489
+
490
+ - Stacking plugin can stack horizontal bar charts.
491
+
492
+ - Navigate plugin now redraws the plot while panning instead of only after
493
+   the fact. (raised by lastthemy, issue 235)
494
+
495
+   Can be disabled by setting the pan.frameRate option to null.
496
+
497
+ - Date formatter now accepts %0m and %0d to get a zero-padded month or day.
498
+   (issue raised by Maximillian Dornseif)
499
+
500
+ - Revamped internals to support an unlimited number of axes, not just dual.
501
+   (sponsored by Flight Data Services, www.flightdataservices.com)
502
+
503
+ - New setting on axes, "tickLength", to control the size of ticks or turn
504
+   them off without turning off the labels.
505
+
506
+ - Axis labels are now put in container divs with classes, for instance labels
507
+   in the x axes can be reached via ".xAxis .tickLabel".
508
+
509
+ - Support for setting the color of an axis. (sponsored by Flight Data
510
+   Services, www.flightdataservices.com)
511
+
512
+ - Tick color is now auto-generated as the base color with some transparency,
513
+   unless you override it.
514
+
515
+ - Support for aligning ticks in the axes with "alignTicksWithAxis" to ensure
516
+   that they appear next to each other rather than in between, at the expense
517
+   of possibly awkward tick steps. (sponsored by Flight Data Services,
518
+   www.flightdataservices.com)
519
+
520
+ - Support for customizing the point type through a callback when plotting
521
+   points and new symbol plugin with some predefined point types. (sponsored
522
+   by Utility Data Corporation)
523
+
524
+ - Resize plugin for automatically redrawing when the placeholder changes
525
+   size, e.g. on window resizes. (sponsored by Novus Partners)
526
+
527
+   A resize() method has been added to plot object facilitate this.
528
+
529
+ - Support Infinity/-Infinity for plotting asymptotes by hacking it into
530
+   +/-Number.MAX_VALUE. (reported by rabaea.mircea)
531
+
532
+ - Support for restricting navigate plugin to not pan/zoom an axis. (based on
533
+   patch by kkaefer)
534
+
535
+ - Support for providing the drag cursor for the navigate plugin as an option.
536
+   (based on patch by Kelly T. Moore)
537
+
538
+ - Options for controlling whether an axis is shown or not (suggestion by Timo
539
+   Tuominen) and whether to reserve space for it even if it isn't shown.
540
+
541
+ - New attribute $.plot.version with the Flot version as a string.
542
+
543
+ - The version comment is now included in the minified jquery.flot.min.js.
544
+
545
+ - New options.grid.minBorderMargin for adjusting the minimum margin provided
546
+   around the border (based on patch by corani, issue 188).
547
+
548
+ - Refactor replot behaviour so Flot tries to reuse the existing canvas,
549
+   adding shutdown() methods to the plot. (based on patch by Ryley Breiddal,
550
+   issue 269)
551
+   
552
+   This prevents a memory leak in Chrome and hopefully makes replotting faster
553
+   for those who are using $.plot instead of .setData()/.draw(). Also update
554
+   jQuery to 1.5.1 to prevent IE leaks fixed in jQuery.
555
+
556
+ - New real-time line chart example.
557
+
558
+ - New hooks: drawSeries, shutdown.
559
+
560
+### Bug fixes ###
561
+
562
+ - Fixed problem with findNearbyItem and bars on top of each other. (reported
563
+   by ragingchikn, issue 242)
564
+
565
+ - Fixed problem with ticks and the border. (based on patch from
566
+   ultimatehustler69, issue 236)
567
+
568
+ - Fixed problem with plugins adding options to the series objects.
569
+
570
+ - Fixed a problem introduced in 0.6 with specifying a gradient with:
571
+
572
+   ```{brightness: x, opacity: y }```
573
+
574
+ - Don't use $.browser.msie, check for getContext on the created canvas element
575
+   instead and try to use excanvas if it's not found.
576
+
577
+   Fixes IE 9 compatibility.
578
+
579
+ - highlight(s, index) was looking up the point in the original s.data instead
580
+   of in the computed datapoints array, which breaks with plugins that modify
581
+   the datapoints, such as the stacking plugin. (reported by curlypaul924,
582
+   issue 316)
583
+
584
+ - More robust handling of axis from data passed in from getData(). (reported)
585
+   by Morgan)
586
+
587
+ - Fixed problem with turning off bar outline. (fix by Jordi Castells,
588
+   issue 253)
589
+
590
+ - Check the selection passed into setSelection in the selection
591
+   plugin, to guard against errors when synchronizing plots (fix by Lau
592
+   Bech Lauritzen).
593
+
594
+ - Fix bug in crosshair code with mouseout resetting the crosshair even
595
+   if it is locked (fix by Lau Bech Lauritzen and Banko Adam).
596
+
597
+ - Fix bug with points plotting using line width from lines rather than
598
+   points.
599
+
600
+ - Fix bug with passing non-array 0 data (for plugins that don't expect
601
+   arrays, patch by vpapp1).
602
+
603
+ - Fix errors in JSON in examples so they work with jQuery 1.4.2
604
+   (fix reported by honestbleeps, issue 357).
605
+
606
+ - Fix bug with tooltip in interacting.html, this makes the tooltip
607
+   much smoother (fix by bdkahn). Fix related bug inside highlighting
608
+   handler in Flot.
609
+
610
+ - Use closure trick to make inline colorhelpers plugin respect
611
+   jQuery.noConflict(true), renaming the global jQuery object (reported
612
+   by Nick Stielau).
613
+
614
+ - Listen for mouseleave events and fire a plothover event with empty
615
+   item when it occurs to drop highlights when the mouse leaves the
616
+   plot (reported by by outspirit).
617
+
618
+ - Fix bug with using aboveData with a background (reported by
619
+   amitayd).
620
+
621
+ - Fix possible excanvas leak (report and suggested fix by tom9729).
622
+
623
+ - Fix bug with backwards compatibility for shadowSize = 0 (report and
624
+   suggested fix by aspinak).
625
+
626
+ - Adapt examples to skip loading excanvas (fix by Ryley Breiddal).
627
+
628
+ - Fix bug that prevent a simple f(x) = -x transform from working
629
+   correctly (fix by Mike, issue 263).
630
+
631
+ - Fix bug in restoring cursor in navigate plugin (reported by Matteo
632
+   Gattanini, issue 395).
633
+
634
+ - Fix bug in picking items when transform/inverseTransform is in use
635
+   (reported by Ofri Raviv, and patches and analysis by Jan and Tom
636
+   Paton, issue 334 and 467).
637
+
638
+ - Fix problem with unaligned ticks and hover/click events caused by
639
+   padding on the placeholder by hardcoding the placeholder padding to
640
+   0 (reported by adityadineshsaxena, Matt Sommer, Daniel Atos and some
641
+   other people, issue 301).
642
+
643
+ - Update colorhelpers plugin to avoid dying when trying to parse an
644
+   invalid string (reported by cadavor, issue 483).
645
+
646
+
647
+
648
+## Flot 0.6 ##
649
+
650
+### API changes ###
651
+
652
+Selection support has been moved to a plugin. Thus if you're passing
653
+selection: { mode: something }, you MUST include the file
654
+jquery.flot.selection.js after jquery.flot.js. This reduces the size of
655
+base Flot and makes it easier to customize the selection as well as
656
+improving code clarity. The change is based on a patch from andershol.
657
+
658
+In the global options specified in the $.plot command, "lines", "points",
659
+"bars" and "shadowSize" have been moved to a sub-object called "series":
660
+
661
+```js
662
+$.plot(placeholder, data, { lines: { show: true }})
663
+```
664
+
665
+should be changed to
666
+
667
+```js
668
+  $.plot(placeholder, data, { series: { lines: { show: true }}})
669
+```
670
+
671
+All future series-specific options will go into this sub-object to
672
+simplify plugin writing. Backward-compatibility code is in place, so
673
+old code should not break.
674
+
675
+"plothover" no longer provides the original data point, but instead a
676
+normalized one, since there may be no corresponding original point.
677
+
678
+Due to a bug in previous versions of jQuery, you now need at least
679
+jQuery 1.2.6. But if you can, try jQuery 1.3.2 as it got some improvements
680
+in event handling speed.
681
+
682
+## Changes ##
683
+
684
+ - Added support for disabling interactivity for specific data series.
685
+   (request from Ronald Schouten and Steve Upton)
686
+
687
+ - Flot now calls $() on the placeholder and optional legend container passed
688
+   in so you can specify DOM elements or CSS expressions to make it easier to
689
+   use Flot with libraries like Prototype or Mootools or through raw JSON from
690
+   Ajax responses.
691
+
692
+ - A new "plotselecting" event is now emitted while the user is making a
693
+   selection.
694
+
695
+ - The "plothover" event is now emitted immediately instead of at most 10
696
+   times per second, you'll have to put in a setTimeout yourself if you're
697
+   doing something really expensive on this event.
698
+
699
+ - The built-in date formatter can now be accessed as $.plot.formatDate(...)
700
+   (suggestion by Matt Manela) and even replaced.
701
+
702
+ - Added "borderColor" option to the grid. (patches from Amaury Chamayou and
703
+   Mike R. Williamson)
704
+
705
+ - Added support for gradient backgrounds for the grid. (based on patch from
706
+   Amaury Chamayou, issue 90)
707
+
708
+   The "setting options" example provides a demonstration.
709
+
710
+ - Gradient bars. (suggestion by stefpet)
711
+  
712
+ - Added a "plotunselected" event which is triggered when the selection is
713
+   removed, see "selection" example. (suggestion by Meda Ugo)
714
+
715
+ - The option legend.margin can now specify horizontal and vertical margins
716
+   independently. (suggestion by someone who's annoyed)
717
+
718
+ - Data passed into Flot is now copied to a new canonical format to enable
719
+   further processing before it hits the drawing routines. As a side-effect,
720
+   this should make Flot more robust in the face of bad data. (issue 112)
721
+
722
+ - Step-wise charting: line charts have a new option "steps" that when set to
723
+   true connects the points with horizontal/vertical steps instead of diagonal
724
+   lines.
725
+
726
+ - The legend labelFormatter now passes the series in addition to just the
727
+   label. (suggestion by Vincent Lemeltier)
728
+
729
+ - Horizontal bars (based on patch by Jason LeBrun).
730
+
731
+ - Support for partial bars by specifying a third coordinate, i.e. they don't
732
+   have to start from the axis. This can be used to make stacked bars.
733
+
734
+ - New option to disable the (grid.show).
735
+
736
+ - Added pointOffset method for converting a point in data space to an offset
737
+   within the placeholder.
738
+  
739
+ - Plugin system: register an init method in the $.flot.plugins array to get
740
+   started, see PLUGINS.txt for details on how to write plugins (it's easy).
741
+   There are also some extra methods to enable access to internal state.
742
+
743
+ - Hooks: you can register functions that are called while Flot is crunching
744
+   the data and doing the plot. This can be used to modify Flot without
745
+   changing the source, useful for writing plugins. Some hooks are defined,
746
+   more are likely to come.
747
+  
748
+ - Threshold plugin: you can set a threshold and a color, and the data points
749
+   below that threshold will then get the color. Useful for marking data
750
+   below 0, for instance.
751
+
752
+ - Stack plugin: you can specify a stack key for each series to have them
753
+   summed. This is useful for drawing additive/cumulative graphs with bars and
754
+   (currently unfilled) lines.
755
+
756
+ - Crosshairs plugin: trace the mouse position on the axes, enable with
757
+   crosshair: { mode: "x"} (see the new tracking example for a use).
758
+
759
+ - Image plugin: plot prerendered images.
760
+
761
+ - Navigation plugin for panning and zooming a plot.
762
+
763
+ - More configurable grid.
764
+
765
+ - Axis transformation support, useful for non-linear plots, e.g. log axes and
766
+   compressed time axes (like omitting weekends).
767
+
768
+ - Support for twelve-hour date formatting (patch by Forrest Aldridge).
769
+
770
+ - The color parsing code in Flot has been cleaned up and split out so it's
771
+   now available as a separate jQuery plugin. It's included inline in the Flot
772
+   source to make dependency managing easier. This also makes it really easy
773
+   to use the color helpers in Flot plugins.
774
+
775
+## Bug fixes ##
776
+
777
+ - Fixed two corner-case bugs when drawing filled curves. (report and analysis
778
+   by Joshua Varner)
779
+
780
+ - Fix auto-adjustment code when setting min to 0 for an axis where the
781
+   dataset is completely flat on that axis. (report by chovy)
782
+
783
+ - Fixed a bug with passing in data from getData to setData when the secondary
784
+   axes are used. (reported by nperelman, issue 65)
785
+
786
+ - Fixed so that it is possible to turn lines off when no other chart type is
787
+   shown (based on problem reported by Glenn Vanderburg), and fixed so that
788
+   setting lineWidth to 0 also hides the shadow. (based on problem reported by
789
+   Sergio Nunes)
790
+
791
+ - Updated mousemove position expression to the latest from jQuery. (reported
792
+   by meyuchas)
793
+
794
+ - Use CSS borders instead of background in legend. (issues 25 and 45)
795
+
796
+ - Explicitly convert axis min/max to numbers.
797
+
798
+ - Fixed a bug with drawing marking lines with different colors. (reported by
799
+   Khurram)
800
+
801
+ - Fixed a bug with returning y2 values in the selection event. (fix by
802
+   exists, issue 75)
803
+
804
+ - Only set position relative on placeholder if it hasn't already a position
805
+   different from static. (reported by kyberneticist, issue 95)
806
+
807
+ - Don't round markings to prevent sub-pixel problems. (reported by
808
+   Dan Lipsitt)
809
+
810
+ - Make the grid border act similarly to a regular CSS border, i.e. prevent
811
+   it from overlapping the plot itself. This also fixes a problem with anti-
812
+   aliasing when the width is 1 pixel. (reported by Anthony Ettinger)
813
+
814
+ - Imported version 3 of excanvas and fixed two issues with the newer version.
815
+   Hopefully, this will make Flot work with IE8. (nudge by Fabien Menager,
816
+   further analysis by Booink, issue 133)
817
+
818
+ - Changed the shadow code for lines to hopefully look a bit better with
819
+   vertical lines.
820
+
821
+ - Round tick positions to avoid possible problems with fractions. (suggestion
822
+   by Fred, issue 130)
823
+
824
+ - Made the heuristic for determining how many ticks to aim for a bit smarter.
825
+
826
+ - Fix for uneven axis margins (report and patch by Paul Kienzle) and snapping
827
+   to ticks. (report and patch by lifthrasiir)
828
+
829
+ - Fixed bug with slicing in findNearbyItems. (patch by zollman)
830
+
831
+ - Make heuristic for x axis label widths more dynamic. (patch by
832
+   rickinhethuis)
833
+
834
+ - Make sure points on top take precedence when finding nearby points when
835
+   hovering. (reported by didroe, issue 224)
836
+
837
+
838
+
839
+## Flot 0.5 ##
840
+
841
+Timestamps are now in UTC. Also "selected" event -> becomes "plotselected"
842
+with new data, the parameters for setSelection are now different (but
843
+backwards compatibility hooks are in place), coloredAreas becomes markings
844
+with a new interface (but backwards compatibility hooks are in place).
845
+
846
+### API changes ###
847
+
848
+Timestamps in time mode are now displayed according to UTC instead of the time
849
+zone of the visitor. This affects the way the timestamps should be input;
850
+you'll probably have to offset the timestamps according to your local time
851
+zone. It also affects any custom date handling code (which basically now
852
+should use the equivalent UTC date mehods, e.g. .setUTCMonth() instead of
853
+.setMonth().
854
+
855
+Markings, previously coloredAreas, are now specified as ranges on the axes,
856
+like ```{ xaxis: { from: 0, to: 10 }}```. Furthermore with markings you can
857
+now draw horizontal/vertical lines by setting from and to to the same
858
+coordinate. (idea from line support patch by by Ryan Funduk)
859
+
860
+Interactivity: added a new "plothover" event and this and the "plotclick"
861
+event now returns the closest data item (based on patch by /david, patch by
862
+Mark Byers for bar support). See the revamped "interacting with the data"
863
+example for some hints on what you can do.
864
+
865
+Highlighting: you can now highlight points and datapoints are autohighlighted
866
+when you hover over them (if hovering is turned on).
867
+
868
+Support for dual axis has been added (based on patch by someone who's annoyed
869
+and /david). For each data series you can specify which axes it belongs to,
870
+and there are two more axes, x2axis and y2axis, to customize. This affects the
871
+"selected" event which has been renamed to "plotselected" and spews out
872
+```{ xaxis: { from: -10, to: 20 } ... },``` setSelection in which the
873
+parameters are on a new form (backwards compatible hooks are in place so old
874
+code shouldn't break) and markings (formerly coloredAreas).
875
+
876
+## Changes ##
877
+
878
+ - Added support for specifying the size of tick labels (axis.labelWidth,
879
+   axis.labelHeight). Useful for specifying a max label size to keep multiple
880
+   plots aligned.
881
+
882
+ - The "fill" option can now be a number that specifies the opacity of the
883
+   fill.
884
+
885
+ - You can now specify a coordinate as null (like [2, null]) and Flot will
886
+   take the other coordinate into account when scaling the axes. (based on
887
+   patch by joebno)
888
+
889
+ - New option for bars "align". Set it to "center" to center the bars on the
890
+   value they represent.
891
+
892
+ - setSelection now takes a second parameter which you can use to prevent the
893
+   method from firing the "plotselected" handler. 
894
+
895
+ - Improved the handling of axis auto-scaling with bars. 
896
+
897
+## Bug fixes ##
898
+
899
+ - Fixed a bug in calculating spacing around the plot. (reported by
900
+   timothytoe)
901
+
902
+ - Fixed a bug in finding max values for all-negative data sets.
903
+ 
904
+ - Prevent the possibility of eternal looping in tick calculations.
905
+
906
+ - Fixed a bug when borderWidth is set to 0. (reported by Rob/sanchothefat)
907
+
908
+ - Fixed a bug with drawing bars extending below 0. (reported by James Hewitt,
909
+   patch by Ryan Funduk).
910
+
911
+ - Fixed a bug with line widths of bars. (reported by MikeM)
912
+
913
+ - Fixed a bug with 'nw' and 'sw' legend positions.
914
+
915
+ - Fixed a bug with multi-line x-axis tick labels. (reported by Luca Ciano,
916
+   IE-fix help by Savage Zhang)
917
+
918
+ - Using the "container" option in legend now overwrites the container element
919
+   instead of just appending to it, fixing the infinite legend bug. (reported
920
+   by several people, fix by Brad Dewey)
921
+
922
+
923
+
924
+## Flot 0.4 ##
925
+
926
+### API changes ###
927
+
928
+Deprecated axis.noTicks in favor of just specifying the number as axis.ticks.
929
+So ```xaxis: { noTicks: 10 }``` becomes ```xaxis: { ticks: 10 }```.
930
+
931
+Time series support. Specify axis.mode: "time", put in Javascript timestamps
932
+as data, and Flot will automatically spit out sensible ticks. Take a look at
933
+the two new examples. The format can be customized with axis.timeformat and
934
+axis.monthNames, or if that fails with axis.tickFormatter.
935
+
936
+Support for colored background areas via grid.coloredAreas. Specify an array
937
+of { x1, y1, x2, y2 } objects or a function that returns these given
938
+{ xmin, xmax, ymin, ymax }.
939
+
940
+More members on the plot object (report by Chris Davies and others).
941
+"getData" for inspecting the assigned settings on data series (e.g. color) and
942
+"setData", "setupGrid" and "draw" for updating the contents without a total
943
+replot.
944
+
945
+The default number of ticks to aim for is now dependent on the size of the
946
+plot in pixels. Support for customizing tick interval sizes directly with
947
+axis.minTickSize and axis.tickSize.
948
+
949
+Cleaned up the automatic axis scaling algorithm and fixed how it interacts
950
+with ticks. Also fixed a couple of tick-related corner case bugs (one reported
951
+by mainstreetmark, another reported by timothytoe).
952
+
953
+The option axis.tickFormatter now takes a function with two parameters, the
954
+second parameter is an optional object with information about the axis. It has
955
+min, max, tickDecimals, tickSize.
956
+
957
+## Changes ##
958
+
959
+ - Added support for segmented lines. (based on patch from Michael MacDonald)
960
+
961
+ - Added support for ignoring null and bad values. (suggestion from Nick
962
+   Konidaris and joshwaihi)
963
+
964
+ - Added support for changing the border width. (thanks to joebno and safoo)
965
+
966
+ - Label colors can be changed via CSS by selecting the tickLabel class.
967
+
968
+## Bug fixes ##
969
+
970
+ - Fixed a bug in handling single-item bar series. (reported by Emil Filipov)
971
+
972
+ - Fixed erratic behaviour when interacting with the plot with IE 7. (reported
973
+   by Lau Bech Lauritzen).
974
+
975
+ - Prevent IE/Safari text selection when selecting stuff on the canvas.
976
+
977
+
978
+
979
+## Flot 0.3 ##
980
+
981
+This is mostly a quick-fix release because jquery.js wasn't included in the
982
+previous zip/tarball.
983
+
984
+## Changes ##
985
+
986
+ - Include jquery.js in the zip/tarball.
987
+
988
+ - Support clicking on the plot. Turn it on with grid: { clickable: true },
989
+   then you get a "plotclick" event on the graph placeholder with the position
990
+   in units of the plot.
991
+
992
+## Bug fixes ##
993
+
994
+ - Fixed a bug in dealing with data where min = max. (thanks to Michael
995
+   Messinides)
996
+
997
+
998
+
999
+## Flot 0.2 ##
1000
+
1001
+The API should now be fully documented.
1002
+
1003
+### API changes ###
1004
+
1005
+Moved labelMargin option to grid from x/yaxis.
1006
+
1007
+## Changes ##
1008
+
1009
+ - Added support for putting a background behind the default legend. The
1010
+   default is the partly transparent background color. Added backgroundColor
1011
+   and backgroundOpacity to the legend options to control this.
1012
+
1013
+ - The ticks options can now be a callback function that takes one parameter,
1014
+   an object with the attributes min and max. The function should return a
1015
+   ticks array.
1016
+
1017
+ - Added labelFormatter option in legend, useful for turning the legend
1018
+   labels into links.
1019
+
1020
+ - Reduced the size of the code. (patch by Guy Fraser)
1021
+
1022
+
1023
+
1024
+## Flot 0.1 ##
1025
+
1026
+First public release.
... ...
@@ -0,0 +1,143 @@
1
+## Writing plugins ##
2
+
3
+All you need to do to make a new plugin is creating an init function
4
+and a set of options (if needed), stuffing it into an object and
5
+putting it in the $.plot.plugins array. For example:
6
+
7
+```js
8
+function myCoolPluginInit(plot) {
9
+    plot.coolstring = "Hello!";
10
+};
11
+
12
+$.plot.plugins.push({ init: myCoolPluginInit, options: { ... } });
13
+
14
+// if $.plot is called, it will return a plot object with the
15
+// attribute "coolstring"
16
+```
17
+
18
+Now, given that the plugin might run in many different places, it's
19
+a good idea to avoid leaking names. The usual trick here is wrap the
20
+above lines in an anonymous function which is called immediately, like
21
+this: (function () { inner code ... })(). To make it even more robust
22
+in case $ is not bound to jQuery but some other Javascript library, we
23
+can write it as
24
+
25
+```js
26
+(function ($) {
27
+    // plugin definition
28
+    // ...
29
+})(jQuery);
30
+```
31
+
32
+There's a complete example below, but you should also check out the
33
+plugins bundled with Flot.
34
+
35
+
36
+## Complete example ##
37
+  
38
+Here is a simple debug plugin which alerts each of the series in the
39
+plot. It has a single option that control whether it is enabled and
40
+how much info to output:
41
+
42
+```js
43
+(function ($) {
44
+    function init(plot) {
45
+        var debugLevel = 1;
46
+
47
+        function checkDebugEnabled(plot, options) {
48
+            if (options.debug) {
49
+                debugLevel = options.debug;
50
+                plot.hooks.processDatapoints.push(alertSeries);
51
+            }
52
+        }
53
+
54
+        function alertSeries(plot, series, datapoints) {
55
+            var msg = "series " + series.label;
56
+            if (debugLevel > 1) {
57
+                msg += " with " + series.data.length + " points";
58
+                alert(msg);
59
+            }
60
+        }
61
+
62
+        plot.hooks.processOptions.push(checkDebugEnabled);
63
+    }
64
+
65
+    var options = { debug: 0 };
66
+      
67
+    $.plot.plugins.push({
68
+        init: init,
69
+        options: options,
70
+        name: "simpledebug",
71
+        version: "0.1"
72
+    });
73
+})(jQuery);
74
+```
75
+
76
+We also define "name" and "version". It's not used by Flot, but might
77
+be helpful for other plugins in resolving dependencies.
78
+  
79
+Put the above in a file named "jquery.flot.debug.js", include it in an
80
+HTML page and then it can be used with:
81
+
82
+```js
83
+    $.plot($("#placeholder"), [...], { debug: 2 });
84
+```
85
+
86
+This simple plugin illustrates a couple of points:
87
+
88
+ - It uses the anonymous function trick to avoid name pollution.
89
+ - It can be enabled/disabled through an option.
90
+ - Variables in the init function can be used to store plot-specific
91
+   state between the hooks.
92
+
93
+The two last points are important because there may be multiple plots
94
+on the same page, and you'd want to make sure they are not mixed up.
95
+
96
+
97
+## Shutting down a plugin ##
98
+
99
+Each plot object has a shutdown hook which is run when plot.shutdown()
100
+is called. This usually mostly happens in case another plot is made on
101
+top of an existing one.
102
+
103
+The purpose of the hook is to give you a chance to unbind any event
104
+handlers you've registered and remove any extra DOM things you've
105
+inserted.
106
+
107
+The problem with event handlers is that you can have registered a
108
+handler which is run in some point in the future, e.g. with
109
+setTimeout(). Meanwhile, the plot may have been shutdown and removed,
110
+but because your event handler is still referencing it, it can't be
111
+garbage collected yet, and worse, if your handler eventually runs, it
112
+may overwrite stuff on a completely different plot.
113
+
114
+ 
115
+## Some hints on the options ##
116
+   
117
+Plugins should always support appropriate options to enable/disable
118
+them because the plugin user may have several plots on the same page
119
+where only one should use the plugin. In most cases it's probably a
120
+good idea if the plugin is turned off rather than on per default, just
121
+like most of the powerful features in Flot.
122
+
123
+If the plugin needs options that are specific to each series, like the
124
+points or lines options in core Flot, you can put them in "series" in
125
+the options object, e.g.
126
+
127
+```js
128
+var options = {
129
+    series: {
130
+        downsample: {
131
+            algorithm: null,
132
+            maxpoints: 1000
133
+        }
134
+    }
135
+}
136
+```
137
+
138
+Then they will be copied by Flot into each series, providing default
139
+values in case none are specified.
140
+
141
+Think hard and long about naming the options. These names are going to
142
+be public API, and code is going to depend on them if the plugin is
143
+successful.
... ...
@@ -0,0 +1,110 @@
1
+# Flot [![Build status](https://travis-ci.org/flot/flot.png)](https://travis-ci.org/flot/flot)
2
+
3
+## About ##
4
+
5
+Flot is a Javascript plotting library for jQuery.  
6
+Read more at the website: <http://www.flotcharts.org/>
7
+
8
+Take a look at the the examples in examples/index.html; they should give a good
9
+impression of what Flot can do, and the source code of the examples is probably
10
+the fastest way to learn how to use Flot.
11
+
12
+
13
+## Installation ##
14
+
15
+Just include the Javascript file after you've included jQuery.
16
+
17
+Generally, all browsers that support the HTML5 canvas tag are
18
+supported.
19
+
20
+For support for Internet Explorer < 9, you can use [Excanvas]
21
+[excanvas], a canvas emulator; this is used in the examples bundled
22
+with Flot. You just include the excanvas script like this:
23
+
24
+```html
25
+<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="excanvas.min.js"></script><![endif]-->
26
+```
27
+
28
+If it's not working on your development IE 6.0, check that it has
29
+support for VML which Excanvas is relying on. It appears that some
30
+stripped down versions used for test environments on virtual machines
31
+lack the VML support.
32
+
33
+You can also try using [Flashcanvas][flashcanvas], which uses Flash to
34
+do the emulation. Although Flash can be a bit slower to load than VML,
35
+if you've got a lot of points, the Flash version can be much faster
36
+overall. Flot contains some wrapper code for activating Excanvas which
37
+Flashcanvas is compatible with.
38
+
39
+You need at least jQuery 1.2.6, but try at least 1.3.2 for interactive
40
+charts because of performance improvements in event handling.
41
+
42
+
43
+## Basic usage ##
44
+
45
+Create a placeholder div to put the graph in:
46
+
47
+```html
48
+<div id="placeholder"></div>
49
+```
50
+
51
+You need to set the width and height of this div, otherwise the plot
52
+library doesn't know how to scale the graph. You can do it inline like
53
+this:
54
+
55
+```html
56
+<div id="placeholder" style="width:600px;height:300px"></div>
57
+```
58
+
59
+You can also do it with an external stylesheet. Make sure that the
60
+placeholder isn't within something with a display:none CSS property -
61
+in that case, Flot has trouble measuring label dimensions which
62
+results in garbled looks and might have trouble measuring the
63
+placeholder dimensions which is fatal (it'll throw an exception).
64
+
65
+Then when the div is ready in the DOM, which is usually on document
66
+ready, run the plot function:
67
+
68
+```js
69
+$.plot($("#placeholder"), data, options);
70
+```
71
+
72
+Here, data is an array of data series and options is an object with
73
+settings if you want to customize the plot. Take a look at the
74
+examples for some ideas of what to put in or look at the 
75
+[API reference](API.md). Here's a quick example that'll draw a line 
76
+from (0, 0) to (1, 1):
77
+
78
+```js
79
+$.plot($("#placeholder"), [ [[0, 0], [1, 1]] ], { yaxis: { max: 1 } });
80
+```
81
+
82
+The plot function immediately draws the chart and then returns a plot
83
+object with a couple of methods.
84
+
85
+
86
+## What's with the name? ##
87
+
88
+First: it's pronounced with a short o, like "plot". Not like "flawed".
89
+
90
+So "Flot" rhymes with "plot".
91
+
92
+And if you look up "flot" in a Danish-to-English dictionary, some of
93
+the words that come up are "good-looking", "attractive", "stylish",
94
+"smart", "impressive", "extravagant". One of the main goals with Flot
95
+is pretty looks.
96
+
97
+
98
+## Notes about the examples ##
99
+
100
+In order to have a useful, functional example of time-series plots using time
101
+zones, date.js from [timezone-js][timezone-js] (released under the Apache 2.0
102
+license) and the [Olson][olson] time zone database (released to the public
103
+domain) have been included in the examples directory.  They are used in
104
+examples/axes-time-zones/index.html.
105
+
106
+
107
+[excanvas]: http://code.google.com/p/explorercanvas/
108
+[flashcanvas]: http://code.google.com/p/flashcanvas/
109
+[timezone-js]: https://github.com/mde/timezone-js
110
+[olson]: http://ftp.iana.org/time-zones
... ...
@@ -0,0 +1,4 @@
1
+{
2
+    "label": "Europe (EU27)",
3
+    "data": [[1999, 3.0], [2000, 3.9]]
4
+}
... ...
@@ -0,0 +1,4 @@
1
+{
2
+    "label": "Europe (EU27)",
3
+    "data": [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2]]
4
+}
... ...
@@ -0,0 +1,4 @@
1
+{
2
+    "label": "Europe (EU27)",
3
+    "data": [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2], [2003, 1.3], [2004, 2.5]]
4
+}
... ...
@@ -0,0 +1,4 @@
1
+{
2
+    "label": "Europe (EU27)",
3
+    "data": [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2], [2003, 1.3], [2004, 2.5], [2005, 2.0], [2006, 3.1]]
4
+}
... ...
@@ -0,0 +1,4 @@
1
+{
2
+    "label": "Europe (EU27)",
3
+    "data": [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2], [2003, 1.3], [2004, 2.5], [2005, 2.0], [2006, 3.1], [2007, 2.9], [2008, 0.9]]
4
+}
... ...
@@ -0,0 +1,4 @@
1
+{
2
+    "label": "Europe (EU27)",
3
+    "data": [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2], [2003, 1.3], [2004, 2.5], [2005, 2.0], [2006, 3.1], [2007, 2.9], [2008, 0.9]]
4
+}
... ...
@@ -0,0 +1,4 @@
1
+{
2
+    "label": "Japan",
3
+    "data": [[1999, -0.1], [2000, 2.9], [2001, 0.2], [2002, 0.3], [2003, 1.4], [2004, 2.7], [2005, 1.9], [2006, 2.0], [2007, 2.3], [2008, -0.7]]
4
+}
... ...
@@ -0,0 +1,4 @@
1
+{
2
+    "label": "USA",
3
+    "data": [[1999, 4.4], [2000, 3.7], [2001, 0.8], [2002, 1.6], [2003, 2.5], [2004, 3.6], [2005, 2.9], [2006, 2.8], [2007, 2.0], [2008, 1.1]]
4
+}
... ...
@@ -0,0 +1,173 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: AJAX</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script type="text/javascript">
11
+
12
+	$(function() {
13
+
14
+		var options = {
15
+			lines: {
16
+				show: true
17
+			},
18
+			points: {
19
+				show: true
20
+			},
21
+			xaxis: {
22
+				tickDecimals: 0,
23
+				tickSize: 1
24
+			}
25
+		};
26
+
27
+		var data = [];
28
+
29
+		$.plot("#placeholder", data, options);
30
+
31
+		// Fetch one series, adding to what we already have
32
+
33
+		var alreadyFetched = {};
34
+
35
+		$("button.fetchSeries").click(function () {
36
+
37
+			var button = $(this);
38
+
39
+			// Find the URL in the link right next to us, then fetch the data
40
+
41
+			var dataurl = button.siblings("a").attr("href");
42
+
43
+			function onDataReceived(series) {
44
+
45
+				// Extract the first coordinate pair; jQuery has parsed it, so
46
+				// the data is now just an ordinary JavaScript object
47
+
48
+				var firstcoordinate = "(" + series.data[0][0] + ", " + series.data[0][1] + ")";
49
+				button.siblings("span").text("Fetched " + series.label + ", first point: " + firstcoordinate);
50
+
51
+				// Push the new data onto our existing data array
52
+
53
+				if (!alreadyFetched[series.label]) {
54
+					alreadyFetched[series.label] = true;
55
+					data.push(series);
56
+				}
57
+
58
+				$.plot("#placeholder", data, options);
59
+			}
60
+
61
+			$.ajax({
62
+				url: dataurl,
63
+				type: "GET",
64
+				dataType: "json",
65
+				success: onDataReceived
66
+			});
67
+		});
68
+
69
+		// Initiate a recurring data update
70
+
71
+		$("button.dataUpdate").click(function () {
72
+
73
+			data = [];
74
+			alreadyFetched = {};
75
+
76
+			$.plot("#placeholder", data, options);
77
+
78
+			var iteration = 0;
79
+
80
+			function fetchData() {
81
+
82
+				++iteration;
83
+
84
+				function onDataReceived(series) {
85
+
86
+					// Load all the data in one pass; if we only got partial
87
+					// data we could merge it with what we already have.
88
+
89
+					data = [ series ];
90
+					$.plot("#placeholder", data, options);
91
+				}
92
+
93
+				// Normally we call the same URL - a script connected to a
94
+				// database - but in this case we only have static example
95
+				// files, so we need to modify the URL.
96
+
97
+				$.ajax({
98
+					url: "data-eu-gdp-growth-" + iteration + ".json",
99
+					type: "GET",
100
+					dataType: "json",
101
+					success: onDataReceived
102
+				});
103
+
104
+				if (iteration < 5) {
105
+					setTimeout(fetchData, 1000);
106
+				} else {
107
+					data = [];
108
+					alreadyFetched = {};
109
+				}
110
+			}
111
+
112
+			setTimeout(fetchData, 1000);
113
+		});
114
+
115
+		// Load the first series by default, so we don't have an empty plot
116
+
117
+		$("button.fetchSeries:first").click();
118
+
119
+		// Add the Flot version string to the footer
120
+
121
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
122
+	});
123
+
124
+	</script>
125
+</head>
126
+<body>
127
+
128
+	<div id="header">
129
+		<h2>AJAX</h2>
130
+	</div>
131
+
132
+	<div id="content">
133
+
134
+		<div class="demo-container">
135
+			<div id="placeholder" class="demo-placeholder"></div>
136
+		</div>
137
+
138
+		<p>Example of loading data dynamically with AJAX. Percentage change in GDP (source: <a href="http://epp.eurostat.ec.europa.eu/tgm/table.do?tab=table&init=1&plugin=1&language=en&pcode=tsieb020">Eurostat</a>). Click the buttons below:</p>
139
+
140
+		<p>The data is fetched over HTTP, in this case directly from text files. Usually the URL would point to some web server handler (e.g. a PHP page or Java/.NET/Python/Ruby on Rails handler) that extracts it from a database and serializes it to JSON.</p>
141
+
142
+		<p>
143
+			<button class="fetchSeries">First dataset</button>
144
+			[ <a href="data-eu-gdp-growth.json">see data</a> ]
145
+			<span></span>
146
+		</p>
147
+
148
+		<p>
149
+			<button class="fetchSeries">Second dataset</button>
150
+			[ <a href="data-japan-gdp-growth.json">see data</a> ]
151
+			<span></span>
152
+		</p>
153
+
154
+		<p>
155
+			<button class="fetchSeries">Third dataset</button>
156
+			[ <a href="data-usa-gdp-growth.json">see data</a> ]
157
+			<span></span>
158
+		</p>
159
+
160
+		<p>If you combine AJAX with setTimeout, you can poll the server for new data.</p>
161
+
162
+		<p>
163
+			<button class="dataUpdate">Poll for data</button>
164
+		</p>
165
+
166
+	</div>
167
+
168
+	<div id="footer">
169
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
170
+	</div>
171
+
172
+</body>
173
+</html>
... ...
@@ -0,0 +1,87 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Adding Annotations</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script type="text/javascript">
11
+
12
+	$(function() {
13
+
14
+		var d1 = [];
15
+		for (var i = 0; i < 20; ++i) {
16
+			d1.push([i, Math.sin(i)]);
17
+		}
18
+
19
+		var data = [{ data: d1, label: "Pressure", color: "#333" }];
20
+
21
+		var markings = [
22
+			{ color: "#f6f6f6", yaxis: { from: 1 } },
23
+			{ color: "#f6f6f6", yaxis: { to: -1 } },
24
+			{ color: "#000", lineWidth: 1, xaxis: { from: 2, to: 2 } },
25
+			{ color: "#000", lineWidth: 1, xaxis: { from: 8, to: 8 } }
26
+		];
27
+
28
+		var placeholder = $("#placeholder");
29
+
30
+		var plot = $.plot(placeholder, data, {
31
+			bars: { show: true, barWidth: 0.5, fill: 0.9 },
32
+			xaxis: { ticks: [], autoscaleMargin: 0.02 },
33
+			yaxis: { min: -2, max: 2 },
34
+			grid: { markings: markings }
35
+		});
36
+
37
+		var o = plot.pointOffset({ x: 2, y: -1.2});
38
+
39
+		// Append it to the placeholder that Flot already uses for positioning
40
+
41
+		placeholder.append("<div style='position:absolute;left:" + (o.left + 4) + "px;top:" + o.top + "px;color:#666;font-size:smaller'>Warming up</div>");
42
+
43
+		o = plot.pointOffset({ x: 8, y: -1.2});
44
+		placeholder.append("<div style='position:absolute;left:" + (o.left + 4) + "px;top:" + o.top + "px;color:#666;font-size:smaller'>Actual measurements</div>");
45
+
46
+		// Draw a little arrow on top of the last label to demonstrate canvas
47
+		// drawing
48
+
49
+		var ctx = plot.getCanvas().getContext("2d");
50
+		ctx.beginPath();
51
+		o.left += 4;
52
+		ctx.moveTo(o.left, o.top);
53
+		ctx.lineTo(o.left, o.top - 10);
54
+		ctx.lineTo(o.left + 10, o.top - 5);
55
+		ctx.lineTo(o.left, o.top);
56
+		ctx.fillStyle = "#000";
57
+		ctx.fill();
58
+
59
+		// Add the Flot version string to the footer
60
+
61
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
62
+	});
63
+
64
+	</script>
65
+</head>
66
+<body>
67
+
68
+	<div id="header">
69
+		<h2>Adding Annotations</h2>
70
+	</div>
71
+
72
+	<div id="content">
73
+
74
+		<div class="demo-container">
75
+			<div id="placeholder" class="demo-placeholder"></div>
76
+		</div>
77
+
78
+		<p>Flot has support for simple background decorations such as lines and rectangles. They can be useful for marking up certain areas. You can easily add any HTML you need with standard DOM manipulation, e.g. for labels. For drawing custom shapes there is also direct access to the canvas.</p>
79
+
80
+	</div>
81
+
82
+	<div id="footer">
83
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
84
+	</div>
85
+
86
+</body>
87
+</html>
... ...
@@ -0,0 +1,97 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Interacting with axes</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script type="text/javascript">
11
+
12
+	$(function() {
13
+
14
+		function generate(start, end, fn) {
15
+			var res = [];
16
+			for (var i = 0; i <= 100; ++i) {
17
+				var x = start + i / 100 * (end - start);
18
+				res.push([x, fn(x)]);
19
+			}
20
+			return res;
21
+		}
22
+
23
+		var data = [
24
+			{ data: generate(0, 10, function (x) { return Math.sqrt(x);}), xaxis: 1, yaxis:1 },
25
+			{ data: generate(0, 10, function (x) { return Math.sin(x);}), xaxis: 1, yaxis:2 },
26
+			{ data: generate(0, 10, function (x) { return Math.cos(x);}), xaxis: 1, yaxis:3 },
27
+			{ data: generate(2, 10, function (x) { return Math.tan(x);}), xaxis: 2, yaxis: 4 }
28
+		];
29
+
30
+		var plot = $.plot("#placeholder", data, {
31
+			xaxes: [
32
+				{ position: 'bottom' },
33
+				{ position: 'top'}
34
+			],
35
+			yaxes: [
36
+				{ position: 'left' },
37
+				{ position: 'left' },
38
+				{ position: 'right' },
39
+				{ position: 'left' }
40
+			]
41
+		});
42
+
43
+		// Create a div for each axis
44
+
45
+		$.each(plot.getAxes(), function (i, axis) {
46
+			if (!axis.show)
47
+				return;
48
+
49
+			var box = axis.box;
50
+
51
+			$("<div class='axisTarget' style='position:absolute; left:" + box.left + "px; top:" + box.top + "px; width:" + box.width +  "px; height:" + box.height + "px'></div>")
52
+				.data("axis.direction", axis.direction)
53
+				.data("axis.n", axis.n)
54
+				.css({ backgroundColor: "#f00", opacity: 0, cursor: "pointer" })
55
+				.appendTo(plot.getPlaceholder())
56
+				.hover(
57
+					function () { $(this).css({ opacity: 0.10 }) },
58
+					function () { $(this).css({ opacity: 0 }) }
59
+				)
60
+				.click(function () {
61
+					$("#click").text("You clicked the " + axis.direction + axis.n + "axis!")
62
+				});
63
+		});
64
+
65
+		// Add the Flot version string to the footer
66
+
67
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
68
+	});
69
+
70
+	</script>
71
+</head>
72
+<body>
73
+
74
+	<div id="header">
75
+		<h2>Interacting with axes</h2>
76
+	</div>
77
+
78
+	<div id="content">
79
+
80
+		<div class="demo-container">
81
+			<div id="placeholder" class="demo-placeholder"></div>
82
+		</div>
83
+
84
+		<p>With multiple axes, you sometimes need to interact with them. A simple way to do this is to draw the plot, deduce the axis placements and insert a couple of divs on top to catch events.</p>
85
+
86
+		<p>Try clicking an axis.</p>
87
+
88
+		<p id="click"></p>
89
+
90
+	</div>
91
+
92
+	<div id="footer">
93
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
94
+	</div>
95
+
96
+</body>
97
+</html>
... ...
@@ -0,0 +1,77 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Multiple Axes</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.time.js"></script>
11
+	<script type="text/javascript">
12
+
13
+	$(function() {
14
+
15
+		var oilprices = [[1167692400000,61.05], [1167778800000,58.32], [1167865200000,57.35], [1167951600000,56.31], [1168210800000,55.55], [1168297200000,55.64], [1168383600000,54.02], [1168470000000,51.88], [1168556400000,52.99], [1168815600000,52.99], [1168902000000,51.21], [1168988400000,52.24], [1169074800000,50.48], [1169161200000,51.99], [1169420400000,51.13], [1169506800000,55.04], [1169593200000,55.37], [1169679600000,54.23], [1169766000000,55.42], [1170025200000,54.01], [1170111600000,56.97], [1170198000000,58.14], [1170284400000,58.14], [1170370800000,59.02], [1170630000000,58.74], [1170716400000,58.88], [1170802800000,57.71], [1170889200000,59.71], [1170975600000,59.89], [1171234800000,57.81], [1171321200000,59.06], [1171407600000,58.00], [1171494000000,57.99], [1171580400000,59.39], [1171839600000,59.39], [1171926000000,58.07], [1172012400000,60.07], [1172098800000,61.14], [1172444400000,61.39], [1172530800000,61.46], [1172617200000,61.79], [1172703600000,62.00], [1172790000000,60.07], [1173135600000,60.69], [1173222000000,61.82], [1173308400000,60.05], [1173654000000,58.91], [1173740400000,57.93], [1173826800000,58.16], [1173913200000,57.55], [1173999600000,57.11], [1174258800000,56.59], [1174345200000,59.61], [1174518000000,61.69], [1174604400000,62.28], [1174860000000,62.91], [1174946400000,62.93], [1175032800000,64.03], [1175119200000,66.03], [1175205600000,65.87], [1175464800000,64.64], [1175637600000,64.38], [1175724000000,64.28], [1175810400000,64.28], [1176069600000,61.51], [1176156000000,61.89], [1176242400000,62.01], [1176328800000,63.85], [1176415200000,63.63], [1176674400000,63.61], [1176760800000,63.10], [1176847200000,63.13], [1176933600000,61.83], [1177020000000,63.38], [1177279200000,64.58], [1177452000000,65.84], [1177538400000,65.06], [1177624800000,66.46], [1177884000000,64.40], [1178056800000,63.68], [1178143200000,63.19], [1178229600000,61.93], [1178488800000,61.47], [1178575200000,61.55], [1178748000000,61.81], [1178834400000,62.37], [1179093600000,62.46], [1179180000000,63.17], [1179266400000,62.55], [1179352800000,64.94], [1179698400000,66.27], [1179784800000,65.50], [1179871200000,65.77], [1179957600000,64.18], [1180044000000,65.20], [1180389600000,63.15], [1180476000000,63.49], [1180562400000,65.08], [1180908000000,66.30], [1180994400000,65.96], [1181167200000,66.93], [1181253600000,65.98], [1181599200000,65.35], [1181685600000,66.26], [1181858400000,68.00], [1182117600000,69.09], [1182204000000,69.10], [1182290400000,68.19], [1182376800000,68.19], [1182463200000,69.14], [1182722400000,68.19], [1182808800000,67.77], [1182895200000,68.97], [1182981600000,69.57], [1183068000000,70.68], [1183327200000,71.09], [1183413600000,70.92], [1183586400000,71.81], [1183672800000,72.81], [1183932000000,72.19], [1184018400000,72.56], [1184191200000,72.50], [1184277600000,74.15], [1184623200000,75.05], [1184796000000,75.92], [1184882400000,75.57], [1185141600000,74.89], [1185228000000,73.56], [1185314400000,75.57], [1185400800000,74.95], [1185487200000,76.83], [1185832800000,78.21], [1185919200000,76.53], [1186005600000,76.86], [1186092000000,76.00], [1186437600000,71.59], [1186696800000,71.47], [1186956000000,71.62], [1187042400000,71.00], [1187301600000,71.98], [1187560800000,71.12], [1187647200000,69.47], [1187733600000,69.26], [1187820000000,69.83], [1187906400000,71.09], [1188165600000,71.73], [1188338400000,73.36], [1188511200000,74.04], [1188856800000,76.30], [1189116000000,77.49], [1189461600000,78.23], [1189548000000,79.91], [1189634400000,80.09], [1189720800000,79.10], [1189980000000,80.57], [1190066400000,81.93], [1190239200000,83.32], [1190325600000,81.62], [1190584800000,80.95], [1190671200000,79.53], [1190757600000,80.30], [1190844000000,82.88], [1190930400000,81.66], [1191189600000,80.24], [1191276000000,80.05], [1191362400000,79.94], [1191448800000,81.44], [1191535200000,81.22], [1191794400000,79.02], [1191880800000,80.26], [1191967200000,80.30], [1192053600000,83.08], [1192140000000,83.69], [1192399200000,86.13], [1192485600000,87.61], [1192572000000,87.40], [1192658400000,89.47], [1192744800000,88.60], [1193004000000,87.56], [1193090400000,87.56], [1193176800000,87.10], [1193263200000,91.86], [1193612400000,93.53], [1193698800000,94.53], [1193871600000,95.93], [1194217200000,93.98], [1194303600000,96.37], [1194476400000,95.46], [1194562800000,96.32], [1195081200000,93.43], [1195167600000,95.10], [1195426800000,94.64], [1195513200000,95.10], [1196031600000,97.70], [1196118000000,94.42], [1196204400000,90.62], [1196290800000,91.01], [1196377200000,88.71], [1196636400000,88.32], [1196809200000,90.23], [1196982000000,88.28], [1197241200000,87.86], [1197327600000,90.02], [1197414000000,92.25], [1197586800000,90.63], [1197846000000,90.63], [1197932400000,90.49], [1198018800000,91.24], [1198105200000,91.06], [1198191600000,90.49], [1198710000000,96.62], [1198796400000,96.00], [1199142000000,99.62], [1199314800000,99.18], [1199401200000,95.09], [1199660400000,96.33], [1199833200000,95.67], [1200351600000,91.90], [1200438000000,90.84], [1200524400000,90.13], [1200610800000,90.57], [1200956400000,89.21], [1201042800000,86.99], [1201129200000,89.85], [1201474800000,90.99], [1201561200000,91.64], [1201647600000,92.33], [1201734000000,91.75], [1202079600000,90.02], [1202166000000,88.41], [1202252400000,87.14], [1202338800000,88.11], [1202425200000,91.77], [1202770800000,92.78], [1202857200000,93.27], [1202943600000,95.46], [1203030000000,95.46], [1203289200000,101.74], [1203462000000,98.81], [1203894000000,100.88], [1204066800000,99.64], [1204153200000,102.59], [1204239600000,101.84], [1204498800000,99.52], [1204585200000,99.52], [1204671600000,104.52], [1204758000000,105.47], [1204844400000,105.15], [1205103600000,108.75], [1205276400000,109.92], [1205362800000,110.33], [1205449200000,110.21], [1205708400000,105.68], [1205967600000,101.84], [1206313200000,100.86], [1206399600000,101.22], [1206486000000,105.90], [1206572400000,107.58], [1206658800000,105.62], [1206914400000,101.58], [1207000800000,100.98], [1207173600000,103.83], [1207260000000,106.23], [1207605600000,108.50], [1207778400000,110.11], [1207864800000,110.14], [1208210400000,113.79], [1208296800000,114.93], [1208383200000,114.86], [1208728800000,117.48], [1208815200000,118.30], [1208988000000,116.06], [1209074400000,118.52], [1209333600000,118.75], [1209420000000,113.46], [1209592800000,112.52], [1210024800000,121.84], [1210111200000,123.53], [1210197600000,123.69], [1210543200000,124.23], [1210629600000,125.80], [1210716000000,126.29], [1211148000000,127.05], [1211320800000,129.07], [1211493600000,132.19], [1211839200000,128.85], [1212357600000,127.76], [1212703200000,138.54], [1212962400000,136.80], [1213135200000,136.38], [1213308000000,134.86], [1213653600000,134.01], [1213740000000,136.68], [1213912800000,135.65], [1214172000000,134.62], [1214258400000,134.62], [1214344800000,134.62], [1214431200000,139.64], [1214517600000,140.21], [1214776800000,140.00], [1214863200000,140.97], [1214949600000,143.57], [1215036000000,145.29], [1215381600000,141.37], [1215468000000,136.04], [1215727200000,146.40], [1215986400000,145.18], [1216072800000,138.74], [1216159200000,134.60], [1216245600000,129.29], [1216332000000,130.65], [1216677600000,127.95], [1216850400000,127.95], [1217282400000,122.19], [1217455200000,124.08], [1217541600000,125.10], [1217800800000,121.41], [1217887200000,119.17], [1217973600000,118.58], [1218060000000,120.02], [1218405600000,114.45], [1218492000000,113.01], [1218578400000,116.00], [1218751200000,113.77], [1219010400000,112.87], [1219096800000,114.53], [1219269600000,114.98], [1219356000000,114.98], [1219701600000,116.27], [1219788000000,118.15], [1219874400000,115.59], [1219960800000,115.46], [1220306400000,109.71], [1220392800000,109.35], [1220565600000,106.23], [1220824800000,106.34]];
16
+
17
+		var exchangerates = [[1167606000000,0.7580], [1167692400000,0.7580], [1167778800000,0.75470], [1167865200000,0.75490], [1167951600000,0.76130], [1168038000000,0.76550], [1168124400000,0.76930], [1168210800000,0.76940], [1168297200000,0.76880], [1168383600000,0.76780], [1168470000000,0.77080], [1168556400000,0.77270], [1168642800000,0.77490], [1168729200000,0.77410], [1168815600000,0.77410], [1168902000000,0.77320], [1168988400000,0.77270], [1169074800000,0.77370], [1169161200000,0.77240], [1169247600000,0.77120], [1169334000000,0.7720], [1169420400000,0.77210], [1169506800000,0.77170], [1169593200000,0.77040], [1169679600000,0.7690], [1169766000000,0.77110], [1169852400000,0.7740], [1169938800000,0.77450], [1170025200000,0.77450], [1170111600000,0.7740], [1170198000000,0.77160], [1170284400000,0.77130], [1170370800000,0.76780], [1170457200000,0.76880], [1170543600000,0.77180], [1170630000000,0.77180], [1170716400000,0.77280], [1170802800000,0.77290], [1170889200000,0.76980], [1170975600000,0.76850], [1171062000000,0.76810], [1171148400000,0.7690], [1171234800000,0.7690], [1171321200000,0.76980], [1171407600000,0.76990], [1171494000000,0.76510], [1171580400000,0.76130], [1171666800000,0.76160], [1171753200000,0.76140], [1171839600000,0.76140], [1171926000000,0.76070], [1172012400000,0.76020], [1172098800000,0.76110], [1172185200000,0.76220], [1172271600000,0.76150], [1172358000000,0.75980], [1172444400000,0.75980], [1172530800000,0.75920], [1172617200000,0.75730], [1172703600000,0.75660], [1172790000000,0.75670], [1172876400000,0.75910], [1172962800000,0.75820], [1173049200000,0.75850], [1173135600000,0.76130], [1173222000000,0.76310], [1173308400000,0.76150], [1173394800000,0.760], [1173481200000,0.76130], [1173567600000,0.76270], [1173654000000,0.76270], [1173740400000,0.76080], [1173826800000,0.75830], [1173913200000,0.75750], [1173999600000,0.75620], [1174086000000,0.7520], [1174172400000,0.75120], [1174258800000,0.75120], [1174345200000,0.75170], [1174431600000,0.7520], [1174518000000,0.75110], [1174604400000,0.7480], [1174690800000,0.75090], [1174777200000,0.75310], [1174860000000,0.75310], [1174946400000,0.75270], [1175032800000,0.74980], [1175119200000,0.74930], [1175205600000,0.75040], [1175292000000,0.750], [1175378400000,0.74910], [1175464800000,0.74910], [1175551200000,0.74850], [1175637600000,0.74840], [1175724000000,0.74920], [1175810400000,0.74710], [1175896800000,0.74590], [1175983200000,0.74770], [1176069600000,0.74770], [1176156000000,0.74830], [1176242400000,0.74580], [1176328800000,0.74480], [1176415200000,0.7430], [1176501600000,0.73990], [1176588000000,0.73950], [1176674400000,0.73950], [1176760800000,0.73780], [1176847200000,0.73820], [1176933600000,0.73620], [1177020000000,0.73550], [1177106400000,0.73480], [1177192800000,0.73610], [1177279200000,0.73610], [1177365600000,0.73650], [1177452000000,0.73620], [1177538400000,0.73310], [1177624800000,0.73390], [1177711200000,0.73440], [1177797600000,0.73270], [1177884000000,0.73270], [1177970400000,0.73360], [1178056800000,0.73330], [1178143200000,0.73590], [1178229600000,0.73590], [1178316000000,0.73720], [1178402400000,0.7360], [1178488800000,0.7360], [1178575200000,0.7350], [1178661600000,0.73650], [1178748000000,0.73840], [1178834400000,0.73950], [1178920800000,0.74130], [1179007200000,0.73970], [1179093600000,0.73960], [1179180000000,0.73850], [1179266400000,0.73780], [1179352800000,0.73660], [1179439200000,0.740], [1179525600000,0.74110], [1179612000000,0.74060], [1179698400000,0.74050], [1179784800000,0.74140], [1179871200000,0.74310], [1179957600000,0.74310], [1180044000000,0.74380], [1180130400000,0.74430], [1180216800000,0.74430], [1180303200000,0.74430], [1180389600000,0.74340], [1180476000000,0.74290], [1180562400000,0.74420], [1180648800000,0.7440], [1180735200000,0.74390], [1180821600000,0.74370], [1180908000000,0.74370], [1180994400000,0.74290], [1181080800000,0.74030], [1181167200000,0.73990], [1181253600000,0.74180], [1181340000000,0.74680], [1181426400000,0.7480], [1181512800000,0.7480], [1181599200000,0.7490], [1181685600000,0.74940], [1181772000000,0.75220], [1181858400000,0.75150], [1181944800000,0.75020], [1182031200000,0.74720], [1182117600000,0.74720], [1182204000000,0.74620], [1182290400000,0.74550], [1182376800000,0.74490], [1182463200000,0.74670], [1182549600000,0.74580], [1182636000000,0.74270], [1182722400000,0.74270], [1182808800000,0.7430], [1182895200000,0.74290], [1182981600000,0.7440], [1183068000000,0.7430], [1183154400000,0.74220], [1183240800000,0.73880], [1183327200000,0.73880], [1183413600000,0.73690], [1183500000000,0.73450], [1183586400000,0.73450], [1183672800000,0.73450], [1183759200000,0.73520], [1183845600000,0.73410], [1183932000000,0.73410], [1184018400000,0.7340], [1184104800000,0.73240], [1184191200000,0.72720], [1184277600000,0.72640], [1184364000000,0.72550], [1184450400000,0.72580], [1184536800000,0.72580], [1184623200000,0.72560], [1184709600000,0.72570], [1184796000000,0.72470], [1184882400000,0.72430], [1184968800000,0.72440], [1185055200000,0.72350], [1185141600000,0.72350], [1185228000000,0.72350], [1185314400000,0.72350], [1185400800000,0.72620], [1185487200000,0.72880], [1185573600000,0.73010], [1185660000000,0.73370], [1185746400000,0.73370], [1185832800000,0.73240], [1185919200000,0.72970], [1186005600000,0.73170], [1186092000000,0.73150], [1186178400000,0.72880], [1186264800000,0.72630], [1186351200000,0.72630], [1186437600000,0.72420], [1186524000000,0.72530], [1186610400000,0.72640], [1186696800000,0.7270], [1186783200000,0.73120], [1186869600000,0.73050], [1186956000000,0.73050], [1187042400000,0.73180], [1187128800000,0.73580], [1187215200000,0.74090], [1187301600000,0.74540], [1187388000000,0.74370], [1187474400000,0.74240], [1187560800000,0.74240], [1187647200000,0.74150], [1187733600000,0.74190], [1187820000000,0.74140], [1187906400000,0.73770], [1187992800000,0.73550], [1188079200000,0.73150], [1188165600000,0.73150], [1188252000000,0.7320], [1188338400000,0.73320], [1188424800000,0.73460], [1188511200000,0.73280], [1188597600000,0.73230], [1188684000000,0.7340], [1188770400000,0.7340], [1188856800000,0.73360], [1188943200000,0.73510], [1189029600000,0.73460], [1189116000000,0.73210], [1189202400000,0.72940], [1189288800000,0.72660], [1189375200000,0.72660], [1189461600000,0.72540], [1189548000000,0.72420], [1189634400000,0.72130], [1189720800000,0.71970], [1189807200000,0.72090], [1189893600000,0.7210], [1189980000000,0.7210], [1190066400000,0.7210], [1190152800000,0.72090], [1190239200000,0.71590], [1190325600000,0.71330], [1190412000000,0.71050], [1190498400000,0.70990], [1190584800000,0.70990], [1190671200000,0.70930], [1190757600000,0.70930], [1190844000000,0.70760], [1190930400000,0.7070], [1191016800000,0.70490], [1191103200000,0.70120], [1191189600000,0.70110], [1191276000000,0.70190], [1191362400000,0.70460], [1191448800000,0.70630], [1191535200000,0.70890], [1191621600000,0.70770], [1191708000000,0.70770], [1191794400000,0.70770], [1191880800000,0.70910], [1191967200000,0.71180], [1192053600000,0.70790], [1192140000000,0.70530], [1192226400000,0.7050], [1192312800000,0.70550], [1192399200000,0.70550], [1192485600000,0.70450], [1192572000000,0.70510], [1192658400000,0.70510], [1192744800000,0.70170], [1192831200000,0.70], [1192917600000,0.69950], [1193004000000,0.69940], [1193090400000,0.70140], [1193176800000,0.70360], [1193263200000,0.70210], [1193349600000,0.70020], [1193436000000,0.69670], [1193522400000,0.6950], [1193612400000,0.6950], [1193698800000,0.69390], [1193785200000,0.6940], [1193871600000,0.69220], [1193958000000,0.69190], [1194044400000,0.69140], [1194130800000,0.68940], [1194217200000,0.68910], [1194303600000,0.69040], [1194390000000,0.6890], [1194476400000,0.68340], [1194562800000,0.68230], [1194649200000,0.68070], [1194735600000,0.68150], [1194822000000,0.68150], [1194908400000,0.68470], [1194994800000,0.68590], [1195081200000,0.68220], [1195167600000,0.68270], [1195254000000,0.68370], [1195340400000,0.68230], [1195426800000,0.68220], [1195513200000,0.68220], [1195599600000,0.67920], [1195686000000,0.67460], [1195772400000,0.67350], [1195858800000,0.67310], [1195945200000,0.67420], [1196031600000,0.67440], [1196118000000,0.67390], [1196204400000,0.67310], [1196290800000,0.67610], [1196377200000,0.67610], [1196463600000,0.67850], [1196550000000,0.68180], [1196636400000,0.68360], [1196722800000,0.68230], [1196809200000,0.68050], [1196895600000,0.67930], [1196982000000,0.68490], [1197068400000,0.68330], [1197154800000,0.68250], [1197241200000,0.68250], [1197327600000,0.68160], [1197414000000,0.67990], [1197500400000,0.68130], [1197586800000,0.68090], [1197673200000,0.68680], [1197759600000,0.69330], [1197846000000,0.69330], [1197932400000,0.69450], [1198018800000,0.69440], [1198105200000,0.69460], [1198191600000,0.69640], [1198278000000,0.69650], [1198364400000,0.69560], [1198450800000,0.69560], [1198537200000,0.6950], [1198623600000,0.69480], [1198710000000,0.69280], [1198796400000,0.68870], [1198882800000,0.68240], [1198969200000,0.67940], [1199055600000,0.67940], [1199142000000,0.68030], [1199228400000,0.68550], [1199314800000,0.68240], [1199401200000,0.67910], [1199487600000,0.67830], [1199574000000,0.67850], [1199660400000,0.67850], [1199746800000,0.67970], [1199833200000,0.680], [1199919600000,0.68030], [1200006000000,0.68050], [1200092400000,0.6760], [1200178800000,0.6770], [1200265200000,0.6770], [1200351600000,0.67360], [1200438000000,0.67260], [1200524400000,0.67640], [1200610800000,0.68210], [1200697200000,0.68310], [1200783600000,0.68420], [1200870000000,0.68420], [1200956400000,0.68870], [1201042800000,0.69030], [1201129200000,0.68480], [1201215600000,0.68240], [1201302000000,0.67880], [1201388400000,0.68140], [1201474800000,0.68140], [1201561200000,0.67970], [1201647600000,0.67690], [1201734000000,0.67650], [1201820400000,0.67330], [1201906800000,0.67290], [1201993200000,0.67580], [1202079600000,0.67580], [1202166000000,0.6750], [1202252400000,0.6780], [1202338800000,0.68330], [1202425200000,0.68560], [1202511600000,0.69030], [1202598000000,0.68960], [1202684400000,0.68960], [1202770800000,0.68820], [1202857200000,0.68790], [1202943600000,0.68620], [1203030000000,0.68520], [1203116400000,0.68230], [1203202800000,0.68130], [1203289200000,0.68130], [1203375600000,0.68220], [1203462000000,0.68020], [1203548400000,0.68020], [1203634800000,0.67840], [1203721200000,0.67480], [1203807600000,0.67470], [1203894000000,0.67470], [1203980400000,0.67480], [1204066800000,0.67330], [1204153200000,0.6650], [1204239600000,0.66110], [1204326000000,0.65830], [1204412400000,0.6590], [1204498800000,0.6590], [1204585200000,0.65810], [1204671600000,0.65780], [1204758000000,0.65740], [1204844400000,0.65320], [1204930800000,0.65020], [1205017200000,0.65140], [1205103600000,0.65140], [1205190000000,0.65070], [1205276400000,0.6510], [1205362800000,0.64890], [1205449200000,0.64240], [1205535600000,0.64060], [1205622000000,0.63820], [1205708400000,0.63820], [1205794800000,0.63410], [1205881200000,0.63440], [1205967600000,0.63780], [1206054000000,0.64390], [1206140400000,0.64780], [1206226800000,0.64810], [1206313200000,0.64810], [1206399600000,0.64940], [1206486000000,0.64380], [1206572400000,0.63770], [1206658800000,0.63290], [1206745200000,0.63360], [1206831600000,0.63330], [1206914400000,0.63330], [1207000800000,0.6330], [1207087200000,0.63710], [1207173600000,0.64030], [1207260000000,0.63960], [1207346400000,0.63640], [1207432800000,0.63560], [1207519200000,0.63560], [1207605600000,0.63680], [1207692000000,0.63570], [1207778400000,0.63540], [1207864800000,0.6320], [1207951200000,0.63320], [1208037600000,0.63280], [1208124000000,0.63310], [1208210400000,0.63420], [1208296800000,0.63210], [1208383200000,0.63020], [1208469600000,0.62780], [1208556000000,0.63080], [1208642400000,0.63240], [1208728800000,0.63240], [1208815200000,0.63070], [1208901600000,0.62770], [1208988000000,0.62690], [1209074400000,0.63350], [1209160800000,0.63920], [1209247200000,0.640], [1209333600000,0.64010], [1209420000000,0.63960], [1209506400000,0.64070], [1209592800000,0.64230], [1209679200000,0.64290], [1209765600000,0.64720], [1209852000000,0.64850], [1209938400000,0.64860], [1210024800000,0.64670], [1210111200000,0.64440], [1210197600000,0.64670], [1210284000000,0.65090], [1210370400000,0.64780], [1210456800000,0.64610], [1210543200000,0.64610], [1210629600000,0.64680], [1210716000000,0.64490], [1210802400000,0.6470], [1210888800000,0.64610], [1210975200000,0.64520], [1211061600000,0.64220], [1211148000000,0.64220], [1211234400000,0.64250], [1211320800000,0.64140], [1211407200000,0.63660], [1211493600000,0.63460], [1211580000000,0.6350], [1211666400000,0.63460], [1211752800000,0.63460], [1211839200000,0.63430], [1211925600000,0.63460], [1212012000000,0.63790], [1212098400000,0.64160], [1212184800000,0.64420], [1212271200000,0.64310], [1212357600000,0.64310], [1212444000000,0.64350], [1212530400000,0.6440], [1212616800000,0.64730], [1212703200000,0.64690], [1212789600000,0.63860], [1212876000000,0.63560], [1212962400000,0.6340], [1213048800000,0.63460], [1213135200000,0.6430], [1213221600000,0.64520], [1213308000000,0.64670], [1213394400000,0.65060], [1213480800000,0.65040], [1213567200000,0.65030], [1213653600000,0.64810], [1213740000000,0.64510], [1213826400000,0.6450], [1213912800000,0.64410], [1213999200000,0.64140], [1214085600000,0.64090], [1214172000000,0.64090], [1214258400000,0.64280], [1214344800000,0.64310], [1214431200000,0.64180], [1214517600000,0.63710], [1214604000000,0.63490], [1214690400000,0.63330], [1214776800000,0.63340], [1214863200000,0.63380], [1214949600000,0.63420], [1215036000000,0.6320], [1215122400000,0.63180], [1215208800000,0.6370], [1215295200000,0.63680], [1215381600000,0.63680], [1215468000000,0.63830], [1215554400000,0.63710], [1215640800000,0.63710], [1215727200000,0.63550], [1215813600000,0.6320], [1215900000000,0.62770], [1215986400000,0.62760], [1216072800000,0.62910], [1216159200000,0.62740], [1216245600000,0.62930], [1216332000000,0.63110], [1216418400000,0.6310], [1216504800000,0.63120], [1216591200000,0.63120], [1216677600000,0.63040], [1216764000000,0.62940], [1216850400000,0.63480], [1216936800000,0.63780], [1217023200000,0.63680], [1217109600000,0.63680], [1217196000000,0.63680], [1217282400000,0.6360], [1217368800000,0.6370], [1217455200000,0.64180], [1217541600000,0.64110], [1217628000000,0.64350], [1217714400000,0.64270], [1217800800000,0.64270], [1217887200000,0.64190], [1217973600000,0.64460], [1218060000000,0.64680], [1218146400000,0.64870], [1218232800000,0.65940], [1218319200000,0.66660], [1218405600000,0.66660], [1218492000000,0.66780], [1218578400000,0.67120], [1218664800000,0.67050], [1218751200000,0.67180], [1218837600000,0.67840], [1218924000000,0.68110], [1219010400000,0.68110], [1219096800000,0.67940], [1219183200000,0.68040], [1219269600000,0.67810], [1219356000000,0.67560], [1219442400000,0.67350], [1219528800000,0.67630], [1219615200000,0.67620], [1219701600000,0.67770], [1219788000000,0.68150], [1219874400000,0.68020], [1219960800000,0.6780], [1220047200000,0.67960], [1220133600000,0.68170], [1220220000000,0.68170], [1220306400000,0.68320], [1220392800000,0.68770], [1220479200000,0.69120], [1220565600000,0.69140], [1220652000000,0.70090], [1220738400000,0.70120], [1220824800000,0.7010], [1220911200000,0.70050]];
18
+
19
+		function euroFormatter(v, axis) {
20
+			return v.toFixed(axis.tickDecimals) + "€";
21
+		}
22
+
23
+		function doPlot(position) {
24
+			$.plot("#placeholder", [
25
+				{ data: oilprices, label: "Oil price ($)" },
26
+				{ data: exchangerates, label: "USD/EUR exchange rate", yaxis: 2 }
27
+			], {
28
+				xaxes: [ { mode: "time" } ],
29
+				yaxes: [ { min: 0 }, {
30
+					// align if we are to the right
31
+					alignTicksWithAxis: position == "right" ? 1 : null,
32
+					position: position,
33
+					tickFormatter: euroFormatter
34
+				} ],
35
+				legend: { position: "sw" }
36
+			});
37
+		}
38
+
39
+		doPlot("right");
40
+
41
+		$("button").click(function () {
42
+			doPlot($(this).text());
43
+		});
44
+
45
+		// Add the Flot version string to the footer
46
+
47
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
48
+	});
49
+
50
+	</script>
51
+</head>
52
+<body>
53
+
54
+	<div id="header">
55
+		<h2>Multiple axes</h2>
56
+	</div>
57
+
58
+	<div id="content">
59
+
60
+		<div class="demo-container">
61
+			<div id="placeholder" class="demo-placeholder"></div>
62
+		</div>
63
+
64
+		<p>Multiple axis support showing the raw oil price in US $/barrel of crude oil vs. the exchange rate from US $ to €.</p>
65
+
66
+		<p>As illustrated, you can put in multiple axes if you need to. For each data series, simply specify the axis number. In the options, you can then configure where you want the extra axes to appear.</p>
67
+
68
+		<p>Position axis <button>left</button> or <button>right</button>.</p>
69
+
70
+	</div>
71
+
72
+	<div id="footer">
73
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
74
+	</div>
75
+
76
+</body>
77
+</html>
... ...
@@ -0,0 +1,893 @@
1
+// -----
2
+// The `timezoneJS.Date` object gives you full-blown timezone support, independent from the timezone set on the end-user's machine running the browser. It uses the Olson zoneinfo files for its timezone data.
3
+//
4
+// The constructor function and setter methods use proxy JavaScript Date objects behind the scenes, so you can use strings like '10/22/2006' with the constructor. You also get the same sensible wraparound behavior with numeric parameters (like setting a value of 14 for the month wraps around to the next March).
5
+//
6
+// The other significant difference from the built-in JavaScript Date is that `timezoneJS.Date` also has named properties that store the values of year, month, date, etc., so it can be directly serialized to JSON and used for data transfer.
7
+
8
+/*
9
+ * Copyright 2010 Matthew Eernisse (mde@fleegix.org)
10
+ * and Open Source Applications Foundation
11
+ *
12
+ * Licensed under the Apache License, Version 2.0 (the "License");
13
+ * you may not use this file except in compliance with the License.
14
+ * You may obtain a copy of the License at
15
+ *
16
+ *   http://www.apache.org/licenses/LICENSE-2.0
17
+ *
18
+ * Unless required by applicable law or agreed to in writing, software
19
+ * distributed under the License is distributed on an "AS IS" BASIS,
20
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
+ * See the License for the specific language governing permissions and
22
+ * limitations under the License.
23
+ *
24
+ * Credits: Ideas included from incomplete JS implementation of Olson
25
+ * parser, "XMLDAte" by Philippe Goetz (philippe.goetz@wanadoo.fr)
26
+ *
27
+ * Contributions:
28
+ * Jan Niehusmann
29
+ * Ricky Romero
30
+ * Preston Hunt (prestonhunt@gmail.com)
31
+ * Dov. B Katz (dov.katz@morganstanley.com)
32
+ * Peter Bergström (pbergstr@mac.com)
33
+ * Long Ho
34
+ */
35
+(function () {
36
+  // Standard initialization stuff to make sure the library is
37
+  // usable on both client and server (node) side.
38
+
39
+  var root = this;
40
+
41
+  var timezoneJS;
42
+  if (typeof exports !== 'undefined') {
43
+    timezoneJS = exports;
44
+  } else {
45
+    timezoneJS = root.timezoneJS = {};
46
+  }
47
+
48
+  timezoneJS.VERSION = '1.0.0';
49
+
50
+  // Grab the ajax library from global context.
51
+  // This can be jQuery, Zepto or fleegix.
52
+  // You can also specify your own transport mechanism by declaring
53
+  // `timezoneJS.timezone.transport` to a `function`. More details will follow
54
+  var $ = root.$ || root.jQuery || root.Zepto
55
+    , fleegix = root.fleegix
56
+  // Declare constant list of days and months. Unfortunately this doesn't leave room for i18n due to the Olson data being in English itself
57
+    , DAYS = timezoneJS.Days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
58
+    , MONTHS = timezoneJS.Months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
59
+    , SHORT_MONTHS = {}
60
+    , SHORT_DAYS = {}
61
+    , EXACT_DATE_TIME = {}
62
+    , TZ_REGEXP = new RegExp('^[a-zA-Z]+/');
63
+
64
+  //`{ "Jan": 0, "Feb": 1, "Mar": 2, "Apr": 3, "May": 4, "Jun": 5, "Jul": 6, "Aug": 7, "Sep": 8, "Oct": 9, "Nov": 10, "Dec": 11 }`
65
+  for (var i = 0; i < MONTHS.length; i++) {
66
+    SHORT_MONTHS[MONTHS[i].substr(0, 3)] = i;
67
+  }
68
+
69
+  //`{ "Sun": 0, "Mon": 1, "Tue": 2, "Wed": 3, "Thu": 4, "Fri": 5, "Sat": 6 }`
70
+  for (i = 0; i < DAYS.length; i++) {
71
+    SHORT_DAYS[DAYS[i].substr(0, 3)] = i;
72
+  }
73
+
74
+
75
+  //Handle array indexOf in IE
76
+  if (!Array.prototype.indexOf) {
77
+    Array.prototype.indexOf = function (el) {
78
+      for (var i = 0; i < this.length; i++ ) {
79
+        if (el === this[i]) return i;
80
+      }
81
+      return -1;
82
+    }
83
+  }
84
+
85
+  // Format a number to the length = digits. For ex:
86
+  //
87
+  // `_fixWidth(2, 2) = '02'`
88
+  //
89
+  // `_fixWidth(1998, 2) = '98'`
90
+  //
91
+  // This is used to pad numbers in converting date to string in ISO standard.
92
+  var _fixWidth = function (number, digits) {
93
+    if (typeof number !== "number") { throw "not a number: " + number; }
94
+    var s = number.toString();
95
+    if (number.length > digits) {
96
+      return number.substr(number.length - digits, number.length);
97
+    }
98
+    while (s.length < digits) {
99
+      s = '0' + s;
100
+    }
101
+    return s;
102
+  };
103
+
104
+  // Abstraction layer for different transport layers, including fleegix/jQuery/Zepto
105
+  //
106
+  // Object `opts` include
107
+  //
108
+  // - `url`: url to ajax query
109
+  //
110
+  // - `async`: true for asynchronous, false otherwise. If false, return value will be response from URL. This is true by default
111
+  //
112
+  // - `success`: success callback function
113
+  //
114
+  // - `error`: error callback function
115
+  // Returns response from URL if async is false, otherwise the AJAX request object itself
116
+  var _transport = function (opts) {
117
+    if ((!fleegix || typeof fleegix.xhr === 'undefined') && (!$ || typeof $.ajax === 'undefined')) {
118
+      throw new Error('Please use the Fleegix.js XHR module, jQuery ajax, Zepto ajax, or define your own transport mechanism for downloading zone files.');
119
+    }
120
+    if (!opts) return;
121
+    if (!opts.url) throw new Error ('URL must be specified');
122
+    if (!('async' in opts)) opts.async = true;
123
+    if (!opts.async) {
124
+      return fleegix && fleegix.xhr
125
+      ? fleegix.xhr.doReq({ url: opts.url, async: false })
126
+      : $.ajax({ url : opts.url, async : false }).responseText;
127
+    }
128
+    return fleegix && fleegix.xhr
129
+    ? fleegix.xhr.send({
130
+      url : opts.url,
131
+      method : 'get',
132
+      handleSuccess : opts.success,
133
+      handleErr : opts.error
134
+    })
135
+    : $.ajax({
136
+      url : opts.url,
137
+      dataType: 'text',
138
+      method : 'GET',
139
+      error : opts.error,
140
+      success : opts.success
141
+    });
142
+  };
143
+
144
+  // Constructor, which is similar to that of the native Date object itself
145
+  timezoneJS.Date = function () {
146
+    var args = Array.prototype.slice.apply(arguments)
147
+    , dt = null
148
+    , tz = null
149
+    , arr = [];
150
+
151
+
152
+    //We support several different constructors, including all the ones from `Date` object
153
+    // with a timezone string at the end.
154
+    //
155
+    //- `[tz]`: Returns object with time in `tz` specified.
156
+    //
157
+    // - `utcMillis`, `[tz]`: Return object with UTC time = `utcMillis`, in `tz`.
158
+    //
159
+    // - `Date`, `[tz]`: Returns object with UTC time = `Date.getTime()`, in `tz`.
160
+    //
161
+    // - `year, month, [date,] [hours,] [minutes,] [seconds,] [millis,] [tz]: Same as `Date` object
162
+    // with tz.
163
+    //
164
+    // - `Array`: Can be any combo of the above.
165
+    //
166
+    //If 1st argument is an array, we can use it as a list of arguments itself
167
+    if (Object.prototype.toString.call(args[0]) === '[object Array]') {
168
+      args = args[0];
169
+    }
170
+    if (typeof args[args.length - 1] === 'string' && TZ_REGEXP.test(args[args.length - 1])) {
171
+      tz = args.pop();
172
+    }
173
+    switch (args.length) {
174
+      case 0:
175
+        dt = new Date();
176
+        break;
177
+      case 1:
178
+        dt = new Date(args[0]);
179
+        break;
180
+      default:
181
+        for (var i = 0; i < 7; i++) {
182
+          arr[i] = args[i] || 0;
183
+        }
184
+        dt = new Date(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6]);
185
+        break;
186
+    }
187
+
188
+    this._useCache = false;
189
+    this._tzInfo = {};
190
+    this._day = 0;
191
+    this.year = 0;
192
+    this.month = 0;
193
+    this.date = 0;
194
+    this.hours = 0;
195
+    this.minutes = 0;
196
+    this.seconds = 0;
197
+    this.milliseconds = 0;
198
+    this.timezone = tz || null;
199
+    //Tricky part:
200
+    // For the cases where there are 1/2 arguments: `timezoneJS.Date(millis, [tz])` and `timezoneJS.Date(Date, [tz])`. The
201
+    // Date `dt` created should be in UTC. Thus the way I detect such cases is to determine if `arr` is not populated & `tz`
202
+    // is specified. Because if `tz` is not specified, `dt` can be in local time.
203
+    if (arr.length) {
204
+       this.setFromDateObjProxy(dt);
205
+    } else {
206
+       this.setFromTimeProxy(dt.getTime(), tz);
207
+    }
208
+  };
209
+
210
+  // Implements most of the native Date object
211
+  timezoneJS.Date.prototype = {
212
+    getDate: function () { return this.date; },
213
+    getDay: function () { return this._day; },
214
+    getFullYear: function () { return this.year; },
215
+    getMonth: function () { return this.month; },
216
+    getYear: function () { return this.year; },
217
+    getHours: function () { return this.hours; },
218
+    getMilliseconds: function () { return this.milliseconds; },
219
+    getMinutes: function () { return this.minutes; },
220
+    getSeconds: function () { return this.seconds; },
221
+    getUTCDate: function () { return this.getUTCDateProxy().getUTCDate(); },
222
+    getUTCDay: function () { return this.getUTCDateProxy().getUTCDay(); },
223
+    getUTCFullYear: function () { return this.getUTCDateProxy().getUTCFullYear(); },
224
+    getUTCHours: function () { return this.getUTCDateProxy().getUTCHours(); },
225
+    getUTCMilliseconds: function () { return this.getUTCDateProxy().getUTCMilliseconds(); },
226
+    getUTCMinutes: function () { return this.getUTCDateProxy().getUTCMinutes(); },
227
+    getUTCMonth: function () { return this.getUTCDateProxy().getUTCMonth(); },
228
+    getUTCSeconds: function () { return this.getUTCDateProxy().getUTCSeconds(); },
229
+    // Time adjusted to user-specified timezone
230
+    getTime: function () {
231
+      return this._timeProxy + (this.getTimezoneOffset() * 60 * 1000);
232
+    },
233
+    getTimezone: function () { return this.timezone; },
234
+    getTimezoneOffset: function () { return this.getTimezoneInfo().tzOffset; },
235
+    getTimezoneAbbreviation: function () { return this.getTimezoneInfo().tzAbbr; },
236
+    getTimezoneInfo: function () {
237
+      if (this._useCache) return this._tzInfo;
238
+      var res;
239
+      // If timezone is specified, get the correct timezone info based on the Date given
240
+      if (this.timezone) {
241
+        res = this.timezone === 'Etc/UTC' || this.timezone === 'Etc/GMT'
242
+          ? { tzOffset: 0, tzAbbr: 'UTC' }
243
+          : timezoneJS.timezone.getTzInfo(this._timeProxy, this.timezone);
244
+      }
245
+      // If no timezone was specified, use the local browser offset
246
+      else {
247
+        res = { tzOffset: this.getLocalOffset(), tzAbbr: null };
248
+      }
249
+      this._tzInfo = res;
250
+      this._useCache = true;
251
+      return res
252
+    },
253
+    getUTCDateProxy: function () {
254
+      var dt = new Date(this._timeProxy);
255
+      dt.setUTCMinutes(dt.getUTCMinutes() + this.getTimezoneOffset());
256
+      return dt;
257
+    },
258
+    setDate: function (n) { this.setAttribute('date', n); },
259
+    setFullYear: function (n) { this.setAttribute('year', n); },
260
+    setMonth: function (n) { this.setAttribute('month', n); },
261
+    setYear: function (n) { this.setUTCAttribute('year', n); },
262
+    setHours: function (n) { this.setAttribute('hours', n); },
263
+    setMilliseconds: function (n) { this.setAttribute('milliseconds', n); },
264
+    setMinutes: function (n) { this.setAttribute('minutes', n); },
265
+    setSeconds: function (n) { this.setAttribute('seconds', n); },
266
+    setTime: function (n) {
267
+      if (isNaN(n)) { throw new Error('Units must be a number.'); }
268
+      this.setFromTimeProxy(n, this.timezone);
269
+    },
270
+    setUTCDate: function (n) { this.setUTCAttribute('date', n); },
271
+    setUTCFullYear: function (n) { this.setUTCAttribute('year', n); },
272
+    setUTCHours: function (n) { this.setUTCAttribute('hours', n); },
273
+    setUTCMilliseconds: function (n) { this.setUTCAttribute('milliseconds', n); },
274
+    setUTCMinutes: function (n) { this.setUTCAttribute('minutes', n); },
275
+    setUTCMonth: function (n) { this.setUTCAttribute('month', n); },
276
+    setUTCSeconds: function (n) { this.setUTCAttribute('seconds', n); },
277
+    setFromDateObjProxy: function (dt) {
278
+      this.year = dt.getFullYear();
279
+      this.month = dt.getMonth();
280
+      this.date = dt.getDate();
281
+      this.hours = dt.getHours();
282
+      this.minutes = dt.getMinutes();
283
+      this.seconds = dt.getSeconds();
284
+      this.milliseconds = dt.getMilliseconds();
285
+      this._day =  dt.getDay();
286
+      this._dateProxy = dt;
287
+      this._timeProxy = Date.UTC(this.year, this.month, this.date, this.hours, this.minutes, this.seconds, this.milliseconds);
288
+      this._useCache = false;
289
+    },
290
+    setFromTimeProxy: function (utcMillis, tz) {
291
+      var dt = new Date(utcMillis);
292
+      var tzOffset;
293
+      tzOffset = tz ? timezoneJS.timezone.getTzInfo(dt, tz).tzOffset : dt.getTimezoneOffset();
294
+      dt.setTime(utcMillis + (dt.getTimezoneOffset() - tzOffset) * 60000);
295
+      this.setFromDateObjProxy(dt);
296
+    },
297
+    setAttribute: function (unit, n) {
298
+      if (isNaN(n)) { throw new Error('Units must be a number.'); }
299
+      var dt = this._dateProxy;
300
+      var meth = unit === 'year' ? 'FullYear' : unit.substr(0, 1).toUpperCase() + unit.substr(1);
301
+      dt['set' + meth](n);
302
+      this.setFromDateObjProxy(dt);
303
+    },
304
+    setUTCAttribute: function (unit, n) {
305
+      if (isNaN(n)) { throw new Error('Units must be a number.'); }
306
+      var meth = unit === 'year' ? 'FullYear' : unit.substr(0, 1).toUpperCase() + unit.substr(1);
307
+      var dt = this.getUTCDateProxy();
308
+      dt['setUTC' + meth](n);
309
+      dt.setUTCMinutes(dt.getUTCMinutes() - this.getTimezoneOffset());
310
+      this.setFromTimeProxy(dt.getTime() + this.getTimezoneOffset() * 60000, this.timezone);
311
+    },
312
+    setTimezone: function (tz) {
313
+      var previousOffset = this.getTimezoneInfo().tzOffset;
314
+      this.timezone = tz;
315
+      this._useCache = false;
316
+      // Set UTC minutes offsets by the delta of the two timezones
317
+      this.setUTCMinutes(this.getUTCMinutes() - this.getTimezoneInfo().tzOffset + previousOffset);
318
+    },
319
+    removeTimezone: function () {
320
+      this.timezone = null;
321
+      this._useCache = false;
322
+    },
323
+    valueOf: function () { return this.getTime(); },
324
+    clone: function () {
325
+      return this.timezone ? new timezoneJS.Date(this.getTime(), this.timezone) : new timezoneJS.Date(this.getTime());
326
+    },
327
+    toGMTString: function () { return this.toString('EEE, dd MMM yyyy HH:mm:ss Z', 'Etc/GMT'); },
328
+    toLocaleString: function () {},
329
+    toLocaleDateString: function () {},
330
+    toLocaleTimeString: function () {},
331
+    toSource: function () {},
332
+    toISOString: function () { return this.toString('yyyy-MM-ddTHH:mm:ss.SSS', 'Etc/UTC') + 'Z'; },
333
+    toJSON: function () { return this.toISOString(); },
334
+    // Allows different format following ISO8601 format:
335
+    toString: function (format, tz) {
336
+      // Default format is the same as toISOString
337
+      if (!format) format = 'yyyy-MM-dd HH:mm:ss';
338
+      var result = format;
339
+      var tzInfo = tz ? timezoneJS.timezone.getTzInfo(this.getTime(), tz) : this.getTimezoneInfo();
340
+      var _this = this;
341
+      // If timezone is specified, get a clone of the current Date object and modify it
342
+      if (tz) {
343
+        _this = this.clone();
344
+        _this.setTimezone(tz);
345
+      }
346
+      var hours = _this.getHours();
347
+      return result
348
+      // fix the same characters in Month names
349
+      .replace(/a+/g, function () { return 'k'; })
350
+      // `y`: year
351
+      .replace(/y+/g, function (token) { return _fixWidth(_this.getFullYear(), token.length); })
352
+      // `d`: date
353
+      .replace(/d+/g, function (token) { return _fixWidth(_this.getDate(), token.length); })
354
+      // `m`: minute
355
+      .replace(/m+/g, function (token) { return _fixWidth(_this.getMinutes(), token.length); })
356
+      // `s`: second
357
+      .replace(/s+/g, function (token) { return _fixWidth(_this.getSeconds(), token.length); })
358
+      // `S`: millisecond
359
+      .replace(/S+/g, function (token) { return _fixWidth(_this.getMilliseconds(), token.length); })
360
+      // `M`: month. Note: `MM` will be the numeric representation (e.g February is 02) but `MMM` will be text representation (e.g February is Feb)
361
+      .replace(/M+/g, function (token) {
362
+        var _month = _this.getMonth(),
363
+        _len = token.length;
364
+        if (_len > 3) {
365
+          return timezoneJS.Months[_month];
366
+        } else if (_len > 2) {
367
+          return timezoneJS.Months[_month].substring(0, _len);
368
+        }
369
+        return _fixWidth(_month + 1, _len);
370
+      })
371
+      // `k`: AM/PM
372
+      .replace(/k+/g, function () {
373
+        if (hours >= 12) {
374
+          if (hours > 12) {
375
+            hours -= 12;
376
+          }
377
+          return 'PM';
378
+        }
379
+        return 'AM';
380
+      })
381
+      // `H`: hour
382
+      .replace(/H+/g, function (token) { return _fixWidth(hours, token.length); })
383
+      // `E`: day
384
+      .replace(/E+/g, function (token) { return DAYS[_this.getDay()].substring(0, token.length); })
385
+      // `Z`: timezone abbreviation
386
+      .replace(/Z+/gi, function () { return tzInfo.tzAbbr; });
387
+    },
388
+    toUTCString: function () { return this.toGMTString(); },
389
+    civilToJulianDayNumber: function (y, m, d) {
390
+      var a;
391
+      // Adjust for zero-based JS-style array
392
+      m++;
393
+      if (m > 12) {
394
+        a = parseInt(m/12, 10);
395
+        m = m % 12;
396
+        y += a;
397
+      }
398
+      if (m <= 2) {
399
+        y -= 1;
400
+        m += 12;
401
+      }
402
+      a = Math.floor(y / 100);
403
+      var b = 2 - a + Math.floor(a / 4)
404
+        , jDt = Math.floor(365.25 * (y + 4716)) + Math.floor(30.6001 * (m + 1)) + d + b - 1524;
405
+      return jDt;
406
+    },
407
+    getLocalOffset: function () {
408
+      return this._dateProxy.getTimezoneOffset();
409
+    }
410
+  };
411
+
412
+
413
+  timezoneJS.timezone = new function () {
414
+    var _this = this
415
+      , regionMap = {'Etc':'etcetera','EST':'northamerica','MST':'northamerica','HST':'northamerica','EST5EDT':'northamerica','CST6CDT':'northamerica','MST7MDT':'northamerica','PST8PDT':'northamerica','America':'northamerica','Pacific':'australasia','Atlantic':'europe','Africa':'africa','Indian':'africa','Antarctica':'antarctica','Asia':'asia','Australia':'australasia','Europe':'europe','WET':'europe','CET':'europe','MET':'europe','EET':'europe'}
416
+      , regionExceptions = {'Pacific/Honolulu':'northamerica','Atlantic/Bermuda':'northamerica','Atlantic/Cape_Verde':'africa','Atlantic/St_Helena':'africa','Indian/Kerguelen':'antarctica','Indian/Chagos':'asia','Indian/Maldives':'asia','Indian/Christmas':'australasia','Indian/Cocos':'australasia','America/Danmarkshavn':'europe','America/Scoresbysund':'europe','America/Godthab':'europe','America/Thule':'europe','Asia/Yekaterinburg':'europe','Asia/Omsk':'europe','Asia/Novosibirsk':'europe','Asia/Krasnoyarsk':'europe','Asia/Irkutsk':'europe','Asia/Yakutsk':'europe','Asia/Vladivostok':'europe','Asia/Sakhalin':'europe','Asia/Magadan':'europe','Asia/Kamchatka':'europe','Asia/Anadyr':'europe','Africa/Ceuta':'europe','America/Argentina/Buenos_Aires':'southamerica','America/Argentina/Cordoba':'southamerica','America/Argentina/Tucuman':'southamerica','America/Argentina/La_Rioja':'southamerica','America/Argentina/San_Juan':'southamerica','America/Argentina/Jujuy':'southamerica','America/Argentina/Catamarca':'southamerica','America/Argentina/Mendoza':'southamerica','America/Argentina/Rio_Gallegos':'southamerica','America/Argentina/Ushuaia':'southamerica','America/Aruba':'southamerica','America/La_Paz':'southamerica','America/Noronha':'southamerica','America/Belem':'southamerica','America/Fortaleza':'southamerica','America/Recife':'southamerica','America/Araguaina':'southamerica','America/Maceio':'southamerica','America/Bahia':'southamerica','America/Sao_Paulo':'southamerica','America/Campo_Grande':'southamerica','America/Cuiaba':'southamerica','America/Porto_Velho':'southamerica','America/Boa_Vista':'southamerica','America/Manaus':'southamerica','America/Eirunepe':'southamerica','America/Rio_Branco':'southamerica','America/Santiago':'southamerica','Pacific/Easter':'southamerica','America/Bogota':'southamerica','America/Curacao':'southamerica','America/Guayaquil':'southamerica','Pacific/Galapagos':'southamerica','Atlantic/Stanley':'southamerica','America/Cayenne':'southamerica','America/Guyana':'southamerica','America/Asuncion':'southamerica','America/Lima':'southamerica','Atlantic/South_Georgia':'southamerica','America/Paramaribo':'southamerica','America/Port_of_Spain':'southamerica','America/Montevideo':'southamerica','America/Caracas':'southamerica'};
417
+    function invalidTZError(t) { throw new Error('Timezone "' + t + '" is either incorrect, or not loaded in the timezone registry.'); }
418
+    function builtInLoadZoneFile(fileName, opts) {
419
+      var url = _this.zoneFileBasePath + '/' + fileName;
420
+      return !opts || !opts.async
421
+      ? _this.parseZones(_this.transport({ url : url, async : false }))
422
+      : _this.transport({
423
+        async: true,
424
+        url : url,
425
+        success : function (str) {
426
+          if (_this.parseZones(str) && typeof opts.callback === 'function') {
427
+            opts.callback();
428
+          }
429
+          return true;
430
+        },
431
+        error : function () {
432
+          throw new Error('Error retrieving "' + url + '" zoneinfo files');
433
+        }
434
+      });
435
+    }
436
+    function getRegionForTimezone(tz) {
437
+      var exc = regionExceptions[tz]
438
+        , reg
439
+        , ret;
440
+      if (exc) return exc;
441
+      reg = tz.split('/')[0];
442
+      ret = regionMap[reg];
443
+      // If there's nothing listed in the main regions for this TZ, check the 'backward' links
444
+      if (ret) return ret;
445
+      var link = _this.zones[tz];
446
+      if (typeof link === 'string') {
447
+        return getRegionForTimezone(link);
448
+      }
449
+      // Backward-compat file hasn't loaded yet, try looking in there
450
+      if (!_this.loadedZones.backward) {
451
+        // This is for obvious legacy zones (e.g., Iceland) that don't even have a prefix like "America/" that look like normal zones
452
+        _this.loadZoneFile('backward');
453
+        return getRegionForTimezone(tz);
454
+      }
455
+      invalidTZError(tz);
456
+    }
457
+    function parseTimeString(str) {
458
+      var pat = /(\d+)(?::0*(\d*))?(?::0*(\d*))?([wsugz])?$/;
459
+      var hms = str.match(pat);
460
+      hms[1] = parseInt(hms[1], 10);
461
+      hms[2] = hms[2] ? parseInt(hms[2], 10) : 0;
462
+      hms[3] = hms[3] ? parseInt(hms[3], 10) : 0;
463
+
464
+      return hms;
465
+    }
466
+    function processZone(z) {
467
+      if (!z[3]) { return; }
468
+      var yea = parseInt(z[3], 10);
469
+      var mon = 11;
470
+      var dat = 31;
471
+      if (z[4]) {
472
+        mon = SHORT_MONTHS[z[4].substr(0, 3)];
473
+        dat = parseInt(z[5], 10) || 1;
474
+      }
475
+      var string = z[6] ? z[6] : '00:00:00'
476
+        , t = parseTimeString(string);
477
+      return [yea, mon, dat, t[1], t[2], t[3]];
478
+    }
479
+    function getZone(dt, tz) {
480
+      var utcMillis = typeof dt === 'number' ? dt : new Date(dt).getTime();
481
+      var t = tz;
482
+      var zoneList = _this.zones[t];
483
+      // Follow links to get to an actual zone
484
+      while (typeof zoneList === "string") {
485
+        t = zoneList;
486
+        zoneList = _this.zones[t];
487
+      }
488
+      if (!zoneList) {
489
+        // Backward-compat file hasn't loaded yet, try looking in there
490
+        if (!_this.loadedZones.backward) {
491
+          //This is for backward entries like "America/Fort_Wayne" that
492
+          // getRegionForTimezone *thinks* it has a region file and zone
493
+          // for (e.g., America => 'northamerica'), but in reality it's a
494
+          // legacy zone we need the backward file for.
495
+          _this.loadZoneFile('backward');
496
+          return getZone(dt, tz);
497
+        }
498
+        invalidTZError(t);
499
+      }
500
+      if (zoneList.length === 0) {
501
+        throw new Error('No Zone found for "' + tz + '" on ' + dt);
502
+      }
503
+      //Do backwards lookup since most use cases deal with newer dates.
504
+      for (var i = zoneList.length - 1; i >= 0; i--) {
505
+        var z = zoneList[i];
506
+        if (z[3] && utcMillis > z[3]) break;
507
+      }
508
+      return zoneList[i+1];
509
+    }
510
+    function getBasicOffset(time) {
511
+      var off = parseTimeString(time)
512
+        , adj = time.indexOf('-') === 0 ? -1 : 1;
513
+      off = adj * (((off[1] * 60 + off[2]) * 60 + off[3]) * 1000);
514
+      return off/60/1000;
515
+    }
516
+
517
+    //if isUTC is true, date is given in UTC, otherwise it's given
518
+    // in local time (ie. date.getUTC*() returns local time components)
519
+    function getRule(dt, zone, isUTC) {
520
+      var date = typeof dt === 'number' ? new Date(dt) : dt;
521
+      var ruleset = zone[1];
522
+      var basicOffset = zone[0];
523
+
524
+      //Convert a date to UTC. Depending on the 'type' parameter, the date
525
+      // parameter may be:
526
+      //
527
+      // - `u`, `g`, `z`: already UTC (no adjustment).
528
+      //
529
+      // - `s`: standard time (adjust for time zone offset but not for DST)
530
+      //
531
+    // - `w`: wall clock time (adjust for both time zone and DST offset).
532
+      //
533
+      // DST adjustment is done using the rule given as third argument.
534
+      var convertDateToUTC = function (date, type, rule) {
535
+        var offset = 0;
536
+
537
+        if (type === 'u' || type === 'g' || type === 'z') { // UTC
538
+          offset = 0;
539
+        } else if (type === 's') { // Standard Time
540
+          offset = basicOffset;
541
+        } else if (type === 'w' || !type) { // Wall Clock Time
542
+          offset = getAdjustedOffset(basicOffset, rule);
543
+        } else {
544
+          throw("unknown type " + type);
545
+        }
546
+        offset *= 60 * 1000; // to millis
547
+
548
+        return new Date(date.getTime() + offset);
549
+      };
550
+
551
+      //Step 1:  Find applicable rules for this year.
552
+      //
553
+      //Step 2:  Sort the rules by effective date.
554
+      //
555
+      //Step 3:  Check requested date to see if a rule has yet taken effect this year.  If not,
556
+      //
557
+      //Step 4:  Get the rules for the previous year.  If there isn't an applicable rule for last year, then
558
+      // there probably is no current time offset since they seem to explicitly turn off the offset
559
+      // when someone stops observing DST.
560
+      //
561
+      // FIXME if this is not the case and we'll walk all the way back (ugh).
562
+      //
563
+      //Step 5:  Sort the rules by effective date.
564
+      //Step 6:  Apply the most recent rule before the current time.
565
+      var convertRuleToExactDateAndTime = function (yearAndRule, prevRule) {
566
+        var year = yearAndRule[0]
567
+          , rule = yearAndRule[1];
568
+          // Assume that the rule applies to the year of the given date.
569
+
570
+        var hms = rule[5];
571
+        var effectiveDate;
572
+
573
+        if (!EXACT_DATE_TIME[year])
574
+          EXACT_DATE_TIME[year] = {};
575
+
576
+        // Result for given parameters is already stored
577
+        if (EXACT_DATE_TIME[year][rule])
578
+          effectiveDate = EXACT_DATE_TIME[year][rule];
579
+        else {
580
+          //If we have a specific date, use that!
581
+          if (!isNaN(rule[4])) {
582
+            effectiveDate = new Date(Date.UTC(year, SHORT_MONTHS[rule[3]], rule[4], hms[1], hms[2], hms[3], 0));
583
+          }
584
+          //Let's hunt for the date.
585
+          else {
586
+            var targetDay
587
+              , operator;
588
+            //Example: `lastThu`
589
+            if (rule[4].substr(0, 4) === "last") {
590
+              // Start at the last day of the month and work backward.
591
+              effectiveDate = new Date(Date.UTC(year, SHORT_MONTHS[rule[3]] + 1, 1, hms[1] - 24, hms[2], hms[3], 0));
592
+              targetDay = SHORT_DAYS[rule[4].substr(4, 3)];
593
+              operator = "<=";
594
+            }
595
+            //Example: `Sun>=15`
596
+            else {
597
+              //Start at the specified date.
598
+              effectiveDate = new Date(Date.UTC(year, SHORT_MONTHS[rule[3]], rule[4].substr(5), hms[1], hms[2], hms[3], 0));
599
+              targetDay = SHORT_DAYS[rule[4].substr(0, 3)];
600
+              operator = rule[4].substr(3, 2);
601
+            }
602
+            var ourDay = effectiveDate.getUTCDay();
603
+            //Go forwards.
604
+            if (operator === ">=") {
605
+              effectiveDate.setUTCDate(effectiveDate.getUTCDate() + (targetDay - ourDay + ((targetDay < ourDay) ? 7 : 0)));
606
+            }
607
+            //Go backwards.  Looking for the last of a certain day, or operator is "<=" (less likely).
608
+            else {
609
+              effectiveDate.setUTCDate(effectiveDate.getUTCDate() + (targetDay - ourDay - ((targetDay > ourDay) ? 7 : 0)));
610
+            }
611
+          }
612
+          EXACT_DATE_TIME[year][rule] = effectiveDate;
613
+        }
614
+
615
+
616
+        //If previous rule is given, correct for the fact that the starting time of the current
617
+        // rule may be specified in local time.
618
+        if (prevRule) {
619
+          effectiveDate = convertDateToUTC(effectiveDate, hms[4], prevRule);
620
+        }
621
+        return effectiveDate;
622
+      };
623
+
624
+      var findApplicableRules = function (year, ruleset) {
625
+        var applicableRules = [];
626
+        for (var i = 0; ruleset && i < ruleset.length; i++) {
627
+          //Exclude future rules.
628
+          if (ruleset[i][0] <= year &&
629
+              (
630
+                // Date is in a set range.
631
+                ruleset[i][1] >= year ||
632
+                // Date is in an "only" year.
633
+                  (ruleset[i][0] === year && ruleset[i][1] === "only") ||
634
+                //We're in a range from the start year to infinity.
635
+                    ruleset[i][1] === "max"
636
+          )
637
+             ) {
638
+               //It's completely okay to have any number of matches here.
639
+               // Normally we should only see two, but that doesn't preclude other numbers of matches.
640
+               // These matches are applicable to this year.
641
+               applicableRules.push([year, ruleset[i]]);
642
+             }
643
+        }
644
+        return applicableRules;
645
+      };
646
+
647
+      var compareDates = function (a, b, prev) {
648
+        var year, rule;
649
+        if (a.constructor !== Date) {
650
+          year = a[0];
651
+          rule = a[1];
652
+          a = (!prev && EXACT_DATE_TIME[year] && EXACT_DATE_TIME[year][rule])
653
+            ? EXACT_DATE_TIME[year][rule]
654
+            : convertRuleToExactDateAndTime(a, prev);
655
+        } else if (prev) {
656
+          a = convertDateToUTC(a, isUTC ? 'u' : 'w', prev);
657
+        }
658
+        if (b.constructor !== Date) {
659
+          year = b[0];
660
+          rule = b[1];
661
+          b = (!prev && EXACT_DATE_TIME[year] && EXACT_DATE_TIME[year][rule]) ? EXACT_DATE_TIME[year][rule]
662
+            : convertRuleToExactDateAndTime(b, prev);
663
+        } else if (prev) {
664
+          b = convertDateToUTC(b, isUTC ? 'u' : 'w', prev);
665
+        }
666
+        a = Number(a);
667
+        b = Number(b);
668
+        return a - b;
669
+      };
670
+
671
+      var year = date.getUTCFullYear();
672
+      var applicableRules;
673
+
674
+      applicableRules = findApplicableRules(year, _this.rules[ruleset]);
675
+      applicableRules.push(date);
676
+      //While sorting, the time zone in which the rule starting time is specified
677
+      // is ignored. This is ok as long as the timespan between two DST changes is
678
+      // larger than the DST offset, which is probably always true.
679
+      // As the given date may indeed be close to a DST change, it may get sorted
680
+      // to a wrong position (off by one), which is corrected below.
681
+      applicableRules.sort(compareDates);
682
+
683
+      //If there are not enough past DST rules...
684
+      if (applicableRules.indexOf(date) < 2) {
685
+        applicableRules = applicableRules.concat(findApplicableRules(year-1, _this.rules[ruleset]));
686
+        applicableRules.sort(compareDates);
687
+      }
688
+      var pinpoint = applicableRules.indexOf(date);
689
+      if (pinpoint > 1 && compareDates(date, applicableRules[pinpoint-1], applicableRules[pinpoint-2][1]) < 0) {
690
+        //The previous rule does not really apply, take the one before that.
691
+        return applicableRules[pinpoint - 2][1];
692
+      } else if (pinpoint > 0 && pinpoint < applicableRules.length - 1 && compareDates(date, applicableRules[pinpoint+1], applicableRules[pinpoint-1][1]) > 0) {
693
+
694
+        //The next rule does already apply, take that one.
695
+        return applicableRules[pinpoint + 1][1];
696
+      } else if (pinpoint === 0) {
697
+        //No applicable rule found in this and in previous year.
698
+        return null;
699
+      }
700
+      return applicableRules[pinpoint - 1][1];
701
+    }
702
+    function getAdjustedOffset(off, rule) {
703
+      return -Math.ceil(rule[6] - off);
704
+    }
705
+    function getAbbreviation(zone, rule) {
706
+      var res;
707
+      var base = zone[2];
708
+      if (base.indexOf('%s') > -1) {
709
+        var repl;
710
+        if (rule) {
711
+          repl = rule[7] === '-' ? '' : rule[7];
712
+        }
713
+        //FIXME: Right now just falling back to Standard --
714
+        // apparently ought to use the last valid rule,
715
+        // although in practice that always ought to be Standard
716
+        else {
717
+          repl = 'S';
718
+        }
719
+        res = base.replace('%s', repl);
720
+      }
721
+      else if (base.indexOf('/') > -1) {
722
+        //Chose one of two alternative strings.
723
+        res = base.split("/", 2)[rule[6] ? 1 : 0];
724
+      } else {
725
+        res = base;
726
+      }
727
+      return res;
728
+    }
729
+
730
+    this.zoneFileBasePath;
731
+    this.zoneFiles = ['africa', 'antarctica', 'asia', 'australasia', 'backward', 'etcetera', 'europe', 'northamerica', 'pacificnew', 'southamerica'];
732
+    this.loadingSchemes = {
733
+      PRELOAD_ALL: 'preloadAll',
734
+      LAZY_LOAD: 'lazyLoad',
735
+      MANUAL_LOAD: 'manualLoad'
736
+    };
737
+    this.loadingScheme = this.loadingSchemes.LAZY_LOAD;
738
+    this.loadedZones = {};
739
+    this.zones = {};
740
+    this.rules = {};
741
+
742
+    this.init = function (o) {
743
+      var opts = { async: true }
744
+        , def = this.defaultZoneFile = this.loadingScheme === this.loadingSchemes.PRELOAD_ALL
745
+          ? this.zoneFiles
746
+          : 'northamerica'
747
+        , done = 0
748
+        , callbackFn;
749
+      //Override default with any passed-in opts
750
+      for (var p in o) {
751
+        opts[p] = o[p];
752
+      }
753
+      if (typeof def === 'string') {
754
+        return this.loadZoneFile(def, opts);
755
+      }
756
+      //Wraps callback function in another one that makes
757
+      // sure all files have been loaded.
758
+      callbackFn = opts.callback;
759
+      opts.callback = function () {
760
+        done++;
761
+        (done === def.length) && typeof callbackFn === 'function' && callbackFn();
762
+      };
763
+      for (var i = 0; i < def.length; i++) {
764
+        this.loadZoneFile(def[i], opts);
765
+      }
766
+    };
767
+
768
+    //Get the zone files via XHR -- if the sync flag
769
+    // is set to true, it's being called by the lazy-loading
770
+    // mechanism, so the result needs to be returned inline.
771
+    this.loadZoneFile = function (fileName, opts) {
772
+      if (typeof this.zoneFileBasePath === 'undefined') {
773
+        throw new Error('Please define a base path to your zone file directory -- timezoneJS.timezone.zoneFileBasePath.');
774
+      }
775
+      //Ignore already loaded zones.
776
+      if (this.loadedZones[fileName]) {
777
+        return;
778
+      }
779
+      this.loadedZones[fileName] = true;
780
+      return builtInLoadZoneFile(fileName, opts);
781
+    };
782
+    this.loadZoneJSONData = function (url, sync) {
783
+      var processData = function (data) {
784
+        data = eval('('+ data +')');
785
+        for (var z in data.zones) {
786
+          _this.zones[z] = data.zones[z];
787
+        }
788
+        for (var r in data.rules) {
789
+          _this.rules[r] = data.rules[r];
790
+        }
791
+      };
792
+      return sync
793
+      ? processData(_this.transport({ url : url, async : false }))
794
+      : _this.transport({ url : url, success : processData });
795
+    };
796
+    this.loadZoneDataFromObject = function (data) {
797
+      if (!data) { return; }
798
+      for (var z in data.zones) {
799
+        _this.zones[z] = data.zones[z];
800
+      }
801
+      for (var r in data.rules) {
802
+        _this.rules[r] = data.rules[r];
803
+      }
804
+    };
805
+    this.getAllZones = function () {
806
+      var arr = [];
807
+      for (var z in this.zones) { arr.push(z); }
808
+      return arr.sort();
809
+    };
810
+    this.parseZones = function (str) {
811
+      var lines = str.split('\n')
812
+        , arr = []
813
+        , chunk = ''
814
+        , l
815
+        , zone = null
816
+        , rule = null;
817
+      for (var i = 0; i < lines.length; i++) {
818
+        l = lines[i];
819
+        if (l.match(/^\s/)) {
820
+          l = "Zone " + zone + l;
821
+        }
822
+        l = l.split("#")[0];
823
+        if (l.length > 3) {
824
+          arr = l.split(/\s+/);
825
+          chunk = arr.shift();
826
+          //Ignore Leap.
827
+          switch (chunk) {
828
+            case 'Zone':
829
+              zone = arr.shift();
830
+              if (!_this.zones[zone]) {
831
+                _this.zones[zone] = [];
832
+              }
833
+              if (arr.length < 3) break;
834
+              //Process zone right here and replace 3rd element with the processed array.
835
+              arr.splice(3, arr.length, processZone(arr));
836
+              if (arr[3]) arr[3] = Date.UTC.apply(null, arr[3]);
837
+              arr[0] = -getBasicOffset(arr[0]);
838
+              _this.zones[zone].push(arr);
839
+              break;
840
+            case 'Rule':
841
+              rule = arr.shift();
842
+              if (!_this.rules[rule]) {
843
+                _this.rules[rule] = [];
844
+              }
845
+              //Parse int FROM year and TO year
846
+              arr[0] = parseInt(arr[0], 10);
847
+              arr[1] = parseInt(arr[1], 10) || arr[1];
848
+              //Parse time string AT
849
+              arr[5] = parseTimeString(arr[5]);
850
+              //Parse offset SAVE
851
+              arr[6] = getBasicOffset(arr[6]);
852
+              _this.rules[rule].push(arr);
853
+              break;
854
+            case 'Link':
855
+              //No zones for these should already exist.
856
+              if (_this.zones[arr[1]]) {
857
+                throw new Error('Error with Link ' + arr[1] + '. Cannot create link of a preexisted zone.');
858
+              }
859
+              //Create the link.
860
+              _this.zones[arr[1]] = arr[0];
861
+              break;
862
+          }
863
+        }
864
+      }
865
+      return true;
866
+    };
867
+    //Expose transport mechanism and allow overwrite.
868
+    this.transport = _transport;
869
+    this.getTzInfo = function (dt, tz, isUTC) {
870
+      //Lazy-load any zones not yet loaded.
871
+      if (this.loadingScheme === this.loadingSchemes.LAZY_LOAD) {
872
+        //Get the correct region for the zone.
873
+        var zoneFile = getRegionForTimezone(tz);
874
+        if (!zoneFile) {
875
+          throw new Error('Not a valid timezone ID.');
876
+        }
877
+        if (!this.loadedZones[zoneFile]) {
878
+          //Get the file and parse it -- use synchronous XHR.
879
+          this.loadZoneFile(zoneFile);
880
+        }
881
+      }
882
+      var z = getZone(dt, tz);
883
+      var off = z[0];
884
+      //See if the offset needs adjustment.
885
+      var rule = getRule(dt, z, isUTC);
886
+      if (rule) {
887
+        off = getAdjustedOffset(off, rule);
888
+      }
889
+      var abbr = getAbbreviation(z, rule);
890
+      return { tzOffset: off, tzAbbr: abbr };
891
+    };
892
+  };
893
+}).call(this);
... ...
@@ -0,0 +1,114 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Time zones</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.time.js"></script>
11
+	<script language="javascript" type="text/javascript" src="date.js"></script>
12
+	<script type="text/javascript">
13
+
14
+	$(function() {
15
+
16
+		timezoneJS.timezone.zoneFileBasePath = "tz";
17
+		timezoneJS.timezone.defaultZoneFile = [];
18
+		timezoneJS.timezone.init({async: false});
19
+
20
+		var d = [
21
+			[Date.UTC(2011, 2, 12, 14, 0, 0), 28],
22
+			[Date.UTC(2011, 2, 12, 15, 0, 0), 27],
23
+			[Date.UTC(2011, 2, 12, 16, 0, 0), 25],
24
+			[Date.UTC(2011, 2, 12, 17, 0, 0), 19],
25
+			[Date.UTC(2011, 2, 12, 18, 0, 0), 16],
26
+			[Date.UTC(2011, 2, 12, 19, 0, 0), 14],
27
+			[Date.UTC(2011, 2, 12, 20, 0, 0), 11],
28
+			[Date.UTC(2011, 2, 12, 21, 0, 0), 9],
29
+			[Date.UTC(2011, 2, 12, 22, 0, 0), 7.5],
30
+			[Date.UTC(2011, 2, 12, 23, 0, 0), 6],
31
+			[Date.UTC(2011, 2, 13, 0, 0, 0), 5],
32
+			[Date.UTC(2011, 2, 13, 1, 0, 0), 6],
33
+			[Date.UTC(2011, 2, 13, 2, 0, 0), 7.5],
34
+			[Date.UTC(2011, 2, 13, 3, 0, 0), 9],
35
+			[Date.UTC(2011, 2, 13, 4, 0, 0), 11],
36
+			[Date.UTC(2011, 2, 13, 5, 0, 0), 14],
37
+			[Date.UTC(2011, 2, 13, 6, 0, 0), 16],
38
+			[Date.UTC(2011, 2, 13, 7, 0, 0), 19],
39
+			[Date.UTC(2011, 2, 13, 8, 0, 0), 25],
40
+			[Date.UTC(2011, 2, 13, 9, 0, 0), 27],
41
+			[Date.UTC(2011, 2, 13, 10, 0, 0), 28],
42
+			[Date.UTC(2011, 2, 13, 11, 0, 0), 29],
43
+			[Date.UTC(2011, 2, 13, 12, 0, 0), 29.5],
44
+			[Date.UTC(2011, 2, 13, 13, 0, 0), 29],
45
+			[Date.UTC(2011, 2, 13, 14, 0, 0), 28],
46
+			[Date.UTC(2011, 2, 13, 15, 0, 0), 27],
47
+			[Date.UTC(2011, 2, 13, 16, 0, 0), 25],
48
+			[Date.UTC(2011, 2, 13, 17, 0, 0), 19],
49
+			[Date.UTC(2011, 2, 13, 18, 0, 0), 16],
50
+			[Date.UTC(2011, 2, 13, 19, 0, 0), 14],
51
+			[Date.UTC(2011, 2, 13, 20, 0, 0), 11],
52
+			[Date.UTC(2011, 2, 13, 21, 0, 0), 9],
53
+			[Date.UTC(2011, 2, 13, 22, 0, 0), 7.5],
54
+			[Date.UTC(2011, 2, 13, 23, 0, 0), 6]
55
+		];
56
+
57
+		var plot = $.plot("#placeholderUTC", [d], {
58
+			xaxis: {
59
+				mode: "time"
60
+			}
61
+		});
62
+
63
+		var plot = $.plot("#placeholderLocal", [d], {
64
+			xaxis: {
65
+				mode: "time",
66
+				timezone: "browser"
67
+			}
68
+		});
69
+
70
+		var plot = $.plot("#placeholderChicago", [d], {
71
+			xaxis: {
72
+				mode: "time",
73
+				timezone: "America/Chicago"
74
+			}
75
+		});
76
+
77
+		// Add the Flot version string to the footer
78
+
79
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
80
+	});
81
+
82
+	</script>
83
+</head>
84
+<body>
85
+
86
+	<div id="header">
87
+		<h2>Time zones</h2>
88
+	</div>
89
+
90
+	<div id="content">
91
+
92
+		<h3>UTC</h3>
93
+		<div class="demo-container" style="height: 300px;">
94
+			<div id="placeholderUTC" class="demo-placeholder"></div>
95
+		</div>
96
+
97
+		<h3>Browser</h3>
98
+		<div class="demo-container" style="height: 300px;">
99
+			<div id="placeholderLocal" class="demo-placeholder"></div>
100
+		</div>
101
+
102
+		<h3>Chicago</h3>
103
+		<div class="demo-container" style="height: 300px;">
104
+			<div id="placeholderChicago" class="demo-placeholder"></div>
105
+		</div>
106
+
107
+	</div>
108
+
109
+	<div id="footer">
110
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
111
+	</div>
112
+
113
+</body>
114
+</html>
... ...
@@ -0,0 +1,1181 @@
1
+# <pre>
2
+# This file is in the public domain, so clarified as of
3
+# 2009-05-17 by Arthur David Olson.
4
+
5
+# This data is by no means authoritative; if you think you know better,
6
+# go ahead and edit the file (and please send any changes to
7
+# tz@iana.org for general use in the future).
8
+
9
+# From Paul Eggert (2006-03-22):
10
+#
11
+# A good source for time zone historical data outside the U.S. is
12
+# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
13
+# San Diego: ACS Publications, Inc. (2003).
14
+#
15
+# Gwillim Law writes that a good source
16
+# for recent time zone data is the International Air Transport
17
+# Association's Standard Schedules Information Manual (IATA SSIM),
18
+# published semiannually.  Law sent in several helpful summaries
19
+# of the IATA's data after 1990.
20
+#
21
+# Except where otherwise noted, Shanks & Pottenger is the source for
22
+# entries through 1990, and IATA SSIM is the source for entries afterwards.
23
+#
24
+# Another source occasionally used is Edward W. Whitman, World Time Differences,
25
+# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
26
+# I found in the UCLA library.
27
+#
28
+# A reliable and entertaining source about time zones is
29
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
30
+#
31
+# Previous editions of this database used WAT, CAT, SAT, and EAT
32
+# for +0:00 through +3:00, respectively,
33
+# but Mark R V Murray reports that
34
+# `SAST' is the official abbreviation for +2:00 in the country of South Africa,
35
+# `CAT' is commonly used for +2:00 in countries north of South Africa, and
36
+# `WAT' is probably the best name for +1:00, as the common phrase for
37
+# the area that includes Nigeria is ``West Africa''.
38
+# He has heard of ``Western Sahara Time'' for +0:00 but can find no reference.
39
+#
40
+# To make things confusing, `WAT' seems to have been used for -1:00 long ago;
41
+# I'd guess that this was because people needed _some_ name for -1:00,
42
+# and at the time, far west Africa was the only major land area in -1:00.
43
+# This usage is now obsolete, as the last use of -1:00 on the African
44
+# mainland seems to have been 1976 in Western Sahara.
45
+#
46
+# To summarize, the following abbreviations seem to have some currency:
47
+#	-1:00	WAT	West Africa Time (no longer used)
48
+#	 0:00	GMT	Greenwich Mean Time
49
+#	 2:00	CAT	Central Africa Time
50
+#	 2:00	SAST	South Africa Standard Time
51
+# and Murray suggests the following abbreviation:
52
+#	 1:00	WAT	West Africa Time
53
+# I realize that this leads to `WAT' being used for both -1:00 and 1:00
54
+# for times before 1976, but this is the best I can think of
55
+# until we get more information.
56
+#
57
+# I invented the following abbreviations; corrections are welcome!
58
+#	 2:00	WAST	West Africa Summer Time
59
+#	 2:30	BEAT	British East Africa Time (no longer used)
60
+#	 2:45	BEAUT	British East Africa Unified Time (no longer used)
61
+#	 3:00	CAST	Central Africa Summer Time (no longer used)
62
+#	 3:00	SAST	South Africa Summer Time (no longer used)
63
+#	 3:00	EAT	East Africa Time
64
+#	 4:00	EAST	East Africa Summer Time (no longer used)
65
+
66
+# Algeria
67
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
68
+Rule	Algeria	1916	only	-	Jun	14	23:00s	1:00	S
69
+Rule	Algeria	1916	1919	-	Oct	Sun>=1	23:00s	0	-
70
+Rule	Algeria	1917	only	-	Mar	24	23:00s	1:00	S
71
+Rule	Algeria	1918	only	-	Mar	 9	23:00s	1:00	S
72
+Rule	Algeria	1919	only	-	Mar	 1	23:00s	1:00	S
73
+Rule	Algeria	1920	only	-	Feb	14	23:00s	1:00	S
74
+Rule	Algeria	1920	only	-	Oct	23	23:00s	0	-
75
+Rule	Algeria	1921	only	-	Mar	14	23:00s	1:00	S
76
+Rule	Algeria	1921	only	-	Jun	21	23:00s	0	-
77
+Rule	Algeria	1939	only	-	Sep	11	23:00s	1:00	S
78
+Rule	Algeria	1939	only	-	Nov	19	 1:00	0	-
79
+Rule	Algeria	1944	1945	-	Apr	Mon>=1	 2:00	1:00	S
80
+Rule	Algeria	1944	only	-	Oct	 8	 2:00	0	-
81
+Rule	Algeria	1945	only	-	Sep	16	 1:00	0	-
82
+Rule	Algeria	1971	only	-	Apr	25	23:00s	1:00	S
83
+Rule	Algeria	1971	only	-	Sep	26	23:00s	0	-
84
+Rule	Algeria	1977	only	-	May	 6	 0:00	1:00	S
85
+Rule	Algeria	1977	only	-	Oct	21	 0:00	0	-
86
+Rule	Algeria	1978	only	-	Mar	24	 1:00	1:00	S
87
+Rule	Algeria	1978	only	-	Sep	22	 3:00	0	-
88
+Rule	Algeria	1980	only	-	Apr	25	 0:00	1:00	S
89
+Rule	Algeria	1980	only	-	Oct	31	 2:00	0	-
90
+# Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
91
+# more precise 0:09:21.
92
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
93
+Zone	Africa/Algiers	0:12:12 -	LMT	1891 Mar 15 0:01
94
+			0:09:21	-	PMT	1911 Mar 11    # Paris Mean Time
95
+			0:00	Algeria	WE%sT	1940 Feb 25 2:00
96
+			1:00	Algeria	CE%sT	1946 Oct  7
97
+			0:00	-	WET	1956 Jan 29
98
+			1:00	-	CET	1963 Apr 14
99
+			0:00	Algeria	WE%sT	1977 Oct 21
100
+			1:00	Algeria	CE%sT	1979 Oct 26
101
+			0:00	Algeria	WE%sT	1981 May
102
+			1:00	-	CET
103
+
104
+# Angola
105
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
106
+Zone	Africa/Luanda	0:52:56	-	LMT	1892
107
+			0:52:04	-	AOT	1911 May 26 # Angola Time
108
+			1:00	-	WAT
109
+
110
+# Benin
111
+# Whitman says they switched to 1:00 in 1946, not 1934;
112
+# go with Shanks & Pottenger.
113
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
114
+Zone Africa/Porto-Novo	0:10:28	-	LMT	1912
115
+			0:00	-	GMT	1934 Feb 26
116
+			1:00	-	WAT
117
+
118
+# Botswana
119
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
120
+Zone	Africa/Gaborone	1:43:40 -	LMT	1885
121
+			2:00	-	CAT	1943 Sep 19 2:00
122
+			2:00	1:00	CAST	1944 Mar 19 2:00
123
+			2:00	-	CAT
124
+
125
+# Burkina Faso
126
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
127
+Zone Africa/Ouagadougou	-0:06:04 -	LMT	1912
128
+			 0:00	-	GMT
129
+
130
+# Burundi
131
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
132
+Zone Africa/Bujumbura	1:57:28	-	LMT	1890
133
+			2:00	-	CAT
134
+
135
+# Cameroon
136
+# Whitman says they switched to 1:00 in 1920; go with Shanks & Pottenger.
137
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
138
+Zone	Africa/Douala	0:38:48	-	LMT	1912
139
+			1:00	-	WAT
140
+
141
+# Cape Verde
142
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
143
+Zone Atlantic/Cape_Verde -1:34:04 -	LMT	1907			# Praia
144
+			-2:00	-	CVT	1942 Sep
145
+			-2:00	1:00	CVST	1945 Oct 15
146
+			-2:00	-	CVT	1975 Nov 25 2:00
147
+			-1:00	-	CVT
148
+
149
+# Central African Republic
150
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
151
+Zone	Africa/Bangui	1:14:20	-	LMT	1912
152
+			1:00	-	WAT
153
+
154
+# Chad
155
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
156
+Zone	Africa/Ndjamena	1:00:12 -	LMT	1912
157
+			1:00	-	WAT	1979 Oct 14
158
+			1:00	1:00	WAST	1980 Mar  8
159
+			1:00	-	WAT
160
+
161
+# Comoros
162
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
163
+Zone	Indian/Comoro	2:53:04 -	LMT	1911 Jul   # Moroni, Gran Comoro
164
+			3:00	-	EAT
165
+
166
+# Democratic Republic of Congo
167
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
168
+Zone Africa/Kinshasa	1:01:12 -	LMT	1897 Nov 9
169
+			1:00	-	WAT
170
+Zone Africa/Lubumbashi	1:49:52 -	LMT	1897 Nov 9
171
+			2:00	-	CAT
172
+
173
+# Republic of the Congo
174
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
175
+Zone Africa/Brazzaville	1:01:08 -	LMT	1912
176
+			1:00	-	WAT
177
+
178
+# Cote D'Ivoire
179
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
180
+Zone	Africa/Abidjan	-0:16:08 -	LMT	1912
181
+			 0:00	-	GMT
182
+
183
+# Djibouti
184
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
185
+Zone	Africa/Djibouti	2:52:36 -	LMT	1911 Jul
186
+			3:00	-	EAT
187
+
188
+###############################################################################
189
+
190
+# Egypt
191
+
192
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
193
+Rule	Egypt	1940	only	-	Jul	15	0:00	1:00	S
194
+Rule	Egypt	1940	only	-	Oct	 1	0:00	0	-
195
+Rule	Egypt	1941	only	-	Apr	15	0:00	1:00	S
196
+Rule	Egypt	1941	only	-	Sep	16	0:00	0	-
197
+Rule	Egypt	1942	1944	-	Apr	 1	0:00	1:00	S
198
+Rule	Egypt	1942	only	-	Oct	27	0:00	0	-
199
+Rule	Egypt	1943	1945	-	Nov	 1	0:00	0	-
200
+Rule	Egypt	1945	only	-	Apr	16	0:00	1:00	S
201
+Rule	Egypt	1957	only	-	May	10	0:00	1:00	S
202
+Rule	Egypt	1957	1958	-	Oct	 1	0:00	0	-
203
+Rule	Egypt	1958	only	-	May	 1	0:00	1:00	S
204
+Rule	Egypt	1959	1981	-	May	 1	1:00	1:00	S
205
+Rule	Egypt	1959	1965	-	Sep	30	3:00	0	-
206
+Rule	Egypt	1966	1994	-	Oct	 1	3:00	0	-
207
+Rule	Egypt	1982	only	-	Jul	25	1:00	1:00	S
208
+Rule	Egypt	1983	only	-	Jul	12	1:00	1:00	S
209
+Rule	Egypt	1984	1988	-	May	 1	1:00	1:00	S
210
+Rule	Egypt	1989	only	-	May	 6	1:00	1:00	S
211
+Rule	Egypt	1990	1994	-	May	 1	1:00	1:00	S
212
+# IATA (after 1990) says transitions are at 0:00.
213
+# Go with IATA starting in 1995, except correct 1995 entry from 09-30 to 09-29.
214
+
215
+# From Alexander Krivenyshev (2011-04-20):
216
+# "...Egypt's interim cabinet decided on Wednesday to cancel daylight
217
+# saving time after a poll posted on its website showed the majority of
218
+# Egyptians would approve the cancellation."
219
+#
220
+# Egypt to cancel daylight saving time
221
+# <a href="http://www.almasryalyoum.com/en/node/407168">
222
+# http://www.almasryalyoum.com/en/node/407168
223
+# </a>
224
+# or
225
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_egypt04.html">
226
+# http://www.worldtimezone.com/dst_news/dst_news_egypt04.html
227
+# </a>
228
+Rule	Egypt	1995	2010	-	Apr	lastFri	 0:00s	1:00	S
229
+Rule	Egypt	1995	2005	-	Sep	lastThu	23:00s	0	-
230
+# From Steffen Thorsen (2006-09-19):
231
+# The Egyptian Gazette, issue 41,090 (2006-09-18), page 1, reports:
232
+# Egypt will turn back clocks by one hour at the midnight of Thursday
233
+# after observing the daylight saving time since May.
234
+# http://news.gom.com.eg/gazette/pdf/2006/09/18/01.pdf
235
+Rule	Egypt	2006	only	-	Sep	21	23:00s	0	-
236
+# From Dirk Losch (2007-08-14):
237
+# I received a mail from an airline which says that the daylight
238
+# saving time in Egypt will end in the night of 2007-09-06 to 2007-09-07.
239
+# From Jesper Norgaard Welen (2007-08-15): [The following agree:]
240
+# http://www.nentjes.info/Bill/bill5.htm
241
+# http://www.timeanddate.com/worldclock/city.html?n=53
242
+# From Steffen Thorsen (2007-09-04): The official information...:
243
+# http://www.sis.gov.eg/En/EgyptOnline/Miscellaneous/000002/0207000000000000001580.htm
244
+Rule	Egypt	2007	only	-	Sep	Thu>=1	23:00s	0	-
245
+# From Abdelrahman Hassan (2007-09-06):
246
+# Due to the Hijri (lunar Islamic calendar) year being 11 days shorter
247
+# than the year of the Gregorian calendar, Ramadan shifts earlier each
248
+# year. This year it will be observed September 13 (September is quite
249
+# hot in Egypt), and the idea is to make fasting easier for workers by
250
+# shifting business hours one hour out of daytime heat. Consequently,
251
+# unless discontinued, next DST may end Thursday 28 August 2008.
252
+# From Paul Eggert (2007-08-17):
253
+# For lack of better info, assume the new rule is last Thursday in August.
254
+
255
+# From Petr Machata (2009-04-06):
256
+# The following appeared in Red Hat bugzilla[1] (edited):
257
+#
258
+# > $ zdump -v /usr/share/zoneinfo/Africa/Cairo | grep 2009
259
+# > /usr/share/zoneinfo/Africa/Cairo  Thu Apr 23 21:59:59 2009 UTC = Thu =
260
+# Apr 23
261
+# > 23:59:59 2009 EET isdst=0 gmtoff=7200
262
+# > /usr/share/zoneinfo/Africa/Cairo  Thu Apr 23 22:00:00 2009 UTC = Fri =
263
+# Apr 24
264
+# > 01:00:00 2009 EEST isdst=1 gmtoff=10800
265
+# > /usr/share/zoneinfo/Africa/Cairo  Thu Aug 27 20:59:59 2009 UTC = Thu =
266
+# Aug 27
267
+# > 23:59:59 2009 EEST isdst=1 gmtoff=10800
268
+# > /usr/share/zoneinfo/Africa/Cairo  Thu Aug 27 21:00:00 2009 UTC = Thu =
269
+# Aug 27
270
+# > 23:00:00 2009 EET isdst=0 gmtoff=7200
271
+#
272
+# > end date should be Thu Sep 24 2009 (Last Thursday in September at 23:59=
273
+# :59)
274
+# > http://support.microsoft.com/kb/958729/
275
+#
276
+# timeanddate[2] and another site I've found[3] also support that.
277
+#
278
+# [1] <a href="https://bugzilla.redhat.com/show_bug.cgi?id=492263">
279
+# https://bugzilla.redhat.com/show_bug.cgi?id=492263
280
+# </a>
281
+# [2] <a href="http://www.timeanddate.com/worldclock/clockchange.html?n=53">
282
+# http://www.timeanddate.com/worldclock/clockchange.html?n=53
283
+# </a>
284
+# [3] <a href="http://wwp.greenwichmeantime.com/time-zone/africa/egypt/">
285
+# http://wwp.greenwichmeantime.com/time-zone/africa/egypt/
286
+# </a>
287
+
288
+# From Arthur David Olson (2009-04-20):
289
+# In 2009 (and for the next several years), Ramadan ends before the fourth
290
+# Thursday in September; Egypt is expected to revert to the last Thursday
291
+# in September.
292
+
293
+# From Steffen Thorsen (2009-08-11):
294
+# We have been able to confirm the August change with the Egyptian Cabinet
295
+# Information and Decision Support Center:
296
+# <a href="http://www.timeanddate.com/news/time/egypt-dst-ends-2009.html">
297
+# http://www.timeanddate.com/news/time/egypt-dst-ends-2009.html
298
+# </a>
299
+#
300
+# The Middle East News Agency
301
+# <a href="http://www.mena.org.eg/index.aspx">
302
+# http://www.mena.org.eg/index.aspx
303
+# </a>
304
+# also reports "Egypt starts winter time on August 21"
305
+# today in article numbered "71, 11/08/2009 12:25 GMT."
306
+# Only the title above is available without a subscription to their service,
307
+# and can be found by searching for "winter" in their search engine
308
+# (at least today).
309
+
310
+# From Alexander Krivenyshev (2010-07-20):
311
+# According to News from Egypt -  Al-Masry Al-Youm Egypt's cabinet has
312
+# decided that Daylight Saving Time will not be used in Egypt during
313
+# Ramadan.
314
+#
315
+# Arabic translation:
316
+# "Clocks to go back during Ramadan--and then forward again"
317
+# <a href="http://www.almasryalyoum.com/en/news/clocks-go-back-during-ramadan-and-then-forward-again">
318
+# http://www.almasryalyoum.com/en/news/clocks-go-back-during-ramadan-and-then-forward-again
319
+# </a>
320
+# or
321
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_egypt02.html">
322
+# http://www.worldtimezone.com/dst_news/dst_news_egypt02.html
323
+# </a>
324
+
325
+Rule	Egypt	2008	only	-	Aug	lastThu	23:00s	0	-
326
+Rule	Egypt	2009	only	-	Aug	20	23:00s	0	-
327
+Rule	Egypt	2010	only	-	Aug	11	0:00	0	-
328
+Rule	Egypt	2010	only	-	Sep	10	0:00	1:00	S
329
+Rule	Egypt	2010	only	-	Sep	lastThu	23:00s	0	-
330
+
331
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
332
+Zone	Africa/Cairo	2:05:00 -	LMT	1900 Oct
333
+			2:00	Egypt	EE%sT
334
+
335
+# Equatorial Guinea
336
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
337
+Zone	Africa/Malabo	0:35:08 -	LMT	1912
338
+			0:00	-	GMT	1963 Dec 15
339
+			1:00	-	WAT
340
+
341
+# Eritrea
342
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
343
+Zone	Africa/Asmara	2:35:32 -	LMT	1870
344
+			2:35:32	-	AMT	1890	      # Asmara Mean Time
345
+			2:35:20	-	ADMT	1936 May 5    # Adis Dera MT
346
+			3:00	-	EAT
347
+
348
+# Ethiopia
349
+# From Paul Eggert (2006-03-22):
350
+# Shanks & Pottenger write that Ethiopia had six narrowly-spaced time zones
351
+# between 1870 and 1890, and that they merged to 38E50 (2:35:20) in 1890.
352
+# We'll guess that 38E50 is for Adis Dera.
353
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
354
+Zone Africa/Addis_Ababa	2:34:48 -	LMT	1870
355
+			2:35:20	-	ADMT	1936 May 5    # Adis Dera MT
356
+			3:00	-	EAT
357
+
358
+# Gabon
359
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
360
+Zone Africa/Libreville	0:37:48 -	LMT	1912
361
+			1:00	-	WAT
362
+
363
+# Gambia
364
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
365
+Zone	Africa/Banjul	-1:06:36 -	LMT	1912
366
+			-1:06:36 -	BMT	1935	# Banjul Mean Time
367
+			-1:00	-	WAT	1964
368
+			 0:00	-	GMT
369
+
370
+# Ghana
371
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
372
+# Whitman says DST was observed from 1931 to ``the present'';
373
+# go with Shanks & Pottenger.
374
+Rule	Ghana	1936	1942	-	Sep	 1	0:00	0:20	GHST
375
+Rule	Ghana	1936	1942	-	Dec	31	0:00	0	GMT
376
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
377
+Zone	Africa/Accra	-0:00:52 -	LMT	1918
378
+			 0:00	Ghana	%s
379
+
380
+# Guinea
381
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
382
+Zone	Africa/Conakry	-0:54:52 -	LMT	1912
383
+			 0:00	-	GMT	1934 Feb 26
384
+			-1:00	-	WAT	1960
385
+			 0:00	-	GMT
386
+
387
+# Guinea-Bissau
388
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
389
+Zone	Africa/Bissau	-1:02:20 -	LMT	1911 May 26
390
+			-1:00	-	WAT	1975
391
+			 0:00	-	GMT
392
+
393
+# Kenya
394
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
395
+Zone	Africa/Nairobi	2:27:16	-	LMT	1928 Jul
396
+			3:00	-	EAT	1930
397
+			2:30	-	BEAT	1940
398
+			2:45	-	BEAUT	1960
399
+			3:00	-	EAT
400
+
401
+# Lesotho
402
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
403
+Zone	Africa/Maseru	1:50:00 -	LMT	1903 Mar
404
+			2:00	-	SAST	1943 Sep 19 2:00
405
+			2:00	1:00	SAST	1944 Mar 19 2:00
406
+			2:00	-	SAST
407
+
408
+# Liberia
409
+# From Paul Eggert (2006-03-22):
410
+# In 1972 Liberia was the last country to switch
411
+# from a UTC offset that was not a multiple of 15 or 20 minutes.
412
+# Howse reports that it was in honor of their president's birthday.
413
+# Shank & Pottenger report the date as May 1, whereas Howse reports Jan;
414
+# go with Shanks & Pottenger.
415
+# For Liberia before 1972, Shanks & Pottenger report -0:44, whereas Howse and
416
+# Whitman each report -0:44:30; go with the more precise figure.
417
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
418
+Zone	Africa/Monrovia	-0:43:08 -	LMT	1882
419
+			-0:43:08 -	MMT	1919 Mar # Monrovia Mean Time
420
+			-0:44:30 -	LRT	1972 May # Liberia Time
421
+			 0:00	-	GMT
422
+
423
+###############################################################################
424
+
425
+# Libya
426
+
427
+# From Even Scharning (2012-11-10):
428
+# Libya set their time one hour back at 02:00 on Saturday November 10.
429
+# http://www.libyaherald.com/2012/11/04/clocks-to-go-back-an-hour-on-saturday/
430
+# Here is an official source [in Arabic]: http://ls.ly/fb6Yc
431
+#
432
+# Steffen Thorsen forwarded a translation (2012-11-10) in
433
+# http://mm.icann.org/pipermail/tz/2012-November/018451.html
434
+#
435
+# From Tim Parenti (2012-11-11):
436
+# Treat the 2012-11-10 change as a zone change from UTC+2 to UTC+1.
437
+# The DST rules planned for 2013 and onward roughly mirror those of Europe
438
+# (either two days before them or five days after them, so as to fall on
439
+# lastFri instead of lastSun).
440
+
441
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
442
+Rule	Libya	1951	only	-	Oct	14	2:00	1:00	S
443
+Rule	Libya	1952	only	-	Jan	 1	0:00	0	-
444
+Rule	Libya	1953	only	-	Oct	 9	2:00	1:00	S
445
+Rule	Libya	1954	only	-	Jan	 1	0:00	0	-
446
+Rule	Libya	1955	only	-	Sep	30	0:00	1:00	S
447
+Rule	Libya	1956	only	-	Jan	 1	0:00	0	-
448
+Rule	Libya	1982	1984	-	Apr	 1	0:00	1:00	S
449
+Rule	Libya	1982	1985	-	Oct	 1	0:00	0	-
450
+Rule	Libya	1985	only	-	Apr	 6	0:00	1:00	S
451
+Rule	Libya	1986	only	-	Apr	 4	0:00	1:00	S
452
+Rule	Libya	1986	only	-	Oct	 3	0:00	0	-
453
+Rule	Libya	1987	1989	-	Apr	 1	0:00	1:00	S
454
+Rule	Libya	1987	1989	-	Oct	 1	0:00	0	-
455
+Rule	Libya	1997	only	-	Apr	 4	0:00	1:00	S
456
+Rule	Libya	1997	only	-	Oct	 4	0:00	0	-
457
+Rule	Libya	2013	max	-	Mar	lastFri	1:00	1:00	S
458
+Rule	Libya	2013	max	-	Oct	lastFri	2:00	0	-
459
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
460
+Zone	Africa/Tripoli	0:52:44 -	LMT	1920
461
+			1:00	Libya	CE%sT	1959
462
+			2:00	-	EET	1982
463
+			1:00	Libya	CE%sT	1990 May  4
464
+# The 1996 and 1997 entries are from Shanks & Pottenger;
465
+# the IATA SSIM data contain some obvious errors.
466
+			2:00	-	EET	1996 Sep 30
467
+			1:00	Libya	CE%sT	1997 Oct  4
468
+			2:00	-	EET	2012 Nov 10 2:00
469
+			1:00	Libya	CE%sT
470
+
471
+# Madagascar
472
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
473
+Zone Indian/Antananarivo 3:10:04 -	LMT	1911 Jul
474
+			3:00	-	EAT	1954 Feb 27 23:00s
475
+			3:00	1:00	EAST	1954 May 29 23:00s
476
+			3:00	-	EAT
477
+
478
+# Malawi
479
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
480
+Zone	Africa/Blantyre	2:20:00 -	LMT	1903 Mar
481
+			2:00	-	CAT
482
+
483
+# Mali
484
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
485
+Zone	Africa/Bamako	-0:32:00 -	LMT	1912
486
+			 0:00	-	GMT	1934 Feb 26
487
+			-1:00	-	WAT	1960 Jun 20
488
+			 0:00	-	GMT
489
+
490
+# Mauritania
491
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
492
+Zone Africa/Nouakchott	-1:03:48 -	LMT	1912
493
+			 0:00	-	GMT	1934 Feb 26
494
+			-1:00	-	WAT	1960 Nov 28
495
+			 0:00	-	GMT
496
+
497
+# Mauritius
498
+
499
+# From Steffen Thorsen (2008-06-25):
500
+# Mauritius plans to observe DST from 2008-11-01 to 2009-03-31 on a trial
501
+# basis....
502
+# It seems that Mauritius observed daylight saving time from 1982-10-10 to
503
+# 1983-03-20 as well, but that was not successful....
504
+# http://www.timeanddate.com/news/time/mauritius-daylight-saving-time.html
505
+
506
+# From Alex Krivenyshev (2008-06-25):
507
+# http://economicdevelopment.gov.mu/portal/site/Mainhomepage/menuitem.a42b24128104d9845dabddd154508a0c/?content_id=0a7cee8b5d69a110VgnVCM1000000a04a8c0RCRD
508
+
509
+# From Arthur David Olson (2008-06-30):
510
+# The www.timeanddate.com article cited by Steffen Thorsen notes that "A
511
+# final decision has yet to be made on the times that daylight saving
512
+# would begin and end on these dates." As a place holder, use midnight.
513
+
514
+# From Paul Eggert (2008-06-30):
515
+# Follow Thorsen on DST in 1982/1983, instead of Shanks & Pottenger.
516
+
517
+# From Steffen Thorsen (2008-07-10):
518
+# According to
519
+# <a href="http://www.lexpress.mu/display_article.php?news_id=111216">
520
+# http://www.lexpress.mu/display_article.php?news_id=111216
521
+# </a>
522
+# (in French), Mauritius will start and end their DST a few days earlier
523
+# than previously announced (2008-11-01 to 2009-03-31).  The new start
524
+# date is 2008-10-26 at 02:00 and the new end date is 2009-03-27 (no time
525
+# given, but it is probably at either 2 or 3 wall clock time).
526
+#
527
+# A little strange though, since the article says that they moved the date
528
+# to align itself with Europe and USA which also change time on that date,
529
+# but that means they have not paid attention to what happened in
530
+# USA/Canada last year (DST ends first Sunday in November). I also wonder
531
+# why that they end on a Friday, instead of aligning with Europe which
532
+# changes two days later.
533
+
534
+# From Alex Krivenyshev (2008-07-11):
535
+# Seems that English language article "The revival of daylight saving
536
+# time:  Energy conservation?"-# No. 16578 (07/11/2008) was originally
537
+# published on Monday, June 30, 2008...
538
+#
539
+# I guess that article in French "Le gouvernement avance l'introduction
540
+# de l'heure d'ete" stating that DST in Mauritius starting on October 26
541
+# and ending on March 27, 2009 is the most recent one.
542
+# ...
543
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_mauritius02.html">
544
+# http://www.worldtimezone.com/dst_news/dst_news_mauritius02.html
545
+# </a>
546
+
547
+# From Riad M. Hossen Ally (2008-08-03):
548
+# The Government of Mauritius weblink
549
+# <a href="http://www.gov.mu/portal/site/pmosite/menuitem.4ca0efdee47462e7440a600248a521ca/?content_id=4728ca68b2a5b110VgnVCM1000000a04a8c0RCRD">
550
+# http://www.gov.mu/portal/site/pmosite/menuitem.4ca0efdee47462e7440a600248a521ca/?content_id=4728ca68b2a5b110VgnVCM1000000a04a8c0RCRD
551
+# </a>
552
+# Cabinet Decision of July 18th, 2008 states as follows:
553
+#
554
+# 4. ...Cabinet has agreed to the introduction into the National Assembly
555
+# of the Time Bill which provides for the introduction of summer time in
556
+# Mauritius. The summer time period which will be of one hour ahead of
557
+# the standard time, will be aligned with that in Europe and the United
558
+# States of America. It will start at two o'clock in the morning on the
559
+# last Sunday of October and will end at two o'clock in the morning on
560
+# the last Sunday of March the following year. The summer time for the
561
+# year 2008 - 2009 will, therefore, be effective as from 26 October 2008
562
+# and end on 29 March 2009.
563
+
564
+# From Ed Maste (2008-10-07):
565
+# THE TIME BILL (No. XXVII of 2008) Explanatory Memorandum states the
566
+# beginning / ending of summer time is 2 o'clock standard time in the
567
+# morning of the last Sunday of October / last Sunday of March.
568
+# <a href="http://www.gov.mu/portal/goc/assemblysite/file/bill2708.pdf">
569
+# http://www.gov.mu/portal/goc/assemblysite/file/bill2708.pdf
570
+# </a>
571
+
572
+# From Steffen Thorsen (2009-06-05):
573
+# According to several sources, Mauritius will not continue to observe
574
+# DST the coming summer...
575
+#
576
+# Some sources, in French:
577
+# <a href="http://www.defimedia.info/news/946/Rashid-Beebeejaun-:-%C2%AB-L%E2%80%99heure-d%E2%80%99%C3%A9t%C3%A9-ne-sera-pas-appliqu%C3%A9e-cette-ann%C3%A9e-%C2%BB">
578
+# http://www.defimedia.info/news/946/Rashid-Beebeejaun-:-%C2%AB-L%E2%80%99heure-d%E2%80%99%C3%A9t%C3%A9-ne-sera-pas-appliqu%C3%A9e-cette-ann%C3%A9e-%C2%BB
579
+# </a>
580
+# <a href="http://lexpress.mu/Story/3398~Beebeejaun---Les-objectifs-d-%C3%A9conomie-d-%C3%A9nergie-de-l-heure-d-%C3%A9t%C3%A9-ont-%C3%A9t%C3%A9-atteints-">
581
+# http://lexpress.mu/Story/3398~Beebeejaun---Les-objectifs-d-%C3%A9conomie-d-%C3%A9nergie-de-l-heure-d-%C3%A9t%C3%A9-ont-%C3%A9t%C3%A9-atteints-
582
+# </a>
583
+#
584
+# Our wrap-up:
585
+# <a href="http://www.timeanddate.com/news/time/mauritius-dst-will-not-repeat.html">
586
+# http://www.timeanddate.com/news/time/mauritius-dst-will-not-repeat.html
587
+# </a>
588
+
589
+# From Arthur David Olson (2009-07-11):
590
+# The "mauritius-dst-will-not-repeat" wrapup includes this:
591
+# "The trial ended on March 29, 2009, when the clocks moved back by one hour
592
+# at 2am (or 02:00) local time..."
593
+
594
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
595
+Rule Mauritius	1982	only	-	Oct	10	0:00	1:00	S
596
+Rule Mauritius	1983	only	-	Mar	21	0:00	0	-
597
+Rule Mauritius	2008	only	-	Oct	lastSun	2:00	1:00	S
598
+Rule Mauritius	2009	only	-	Mar	lastSun	2:00	0	-
599
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
600
+Zone Indian/Mauritius	3:50:00 -	LMT	1907		# Port Louis
601
+			4:00 Mauritius	MU%sT	# Mauritius Time
602
+# Agalega Is, Rodriguez
603
+# no information; probably like Indian/Mauritius
604
+
605
+# Mayotte
606
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
607
+Zone	Indian/Mayotte	3:00:56 -	LMT	1911 Jul	# Mamoutzou
608
+			3:00	-	EAT
609
+
610
+# Morocco
611
+# See the `europe' file for Spanish Morocco (Africa/Ceuta).
612
+
613
+# From Alex Krivenyshev (2008-05-09):
614
+# Here is an article that Morocco plan to introduce Daylight Saving Time between
615
+# 1 June, 2008 and 27 September, 2008.
616
+#
617
+# "... Morocco is to save energy by adjusting its clock during summer so it will
618
+# be one hour ahead of GMT between 1 June and 27 September, according to
619
+# Communication Minister and Gov ernment Spokesman, Khalid Naciri...."
620
+#
621
+# <a href="http://www.worldtimezone.net/dst_news/dst_news_morocco01.html">
622
+# http://www.worldtimezone.net/dst_news/dst_news_morocco01.html
623
+# </a>
624
+# OR
625
+# <a href="http://en.afrik.com/news11892.html">
626
+# http://en.afrik.com/news11892.html
627
+# </a>
628
+
629
+# From Alex Krivenyshev (2008-05-09):
630
+# The Morocco time change can be confirmed on Morocco web site Maghreb Arabe Presse:
631
+# <a href="http://www.map.ma/eng/sections/box3/morocco_shifts_to_da/view">
632
+# http://www.map.ma/eng/sections/box3/morocco_shifts_to_da/view
633
+# </a>
634
+#
635
+# Morocco shifts to daylight time on June 1st through September 27, Govt.
636
+# spokesman.
637
+
638
+# From Patrice Scattolin (2008-05-09):
639
+# According to this article:
640
+# <a href="http://www.avmaroc.com/actualite/heure-dete-comment-a127896.html">
641
+# http://www.avmaroc.com/actualite/heure-dete-comment-a127896.html
642
+# </a>
643
+# (and republished here:
644
+# <a href="http://www.actu.ma/heure-dete-comment_i127896_0.html">
645
+# http://www.actu.ma/heure-dete-comment_i127896_0.html
646
+# </a>
647
+# )
648
+# the changes occurs at midnight:
649
+#
650
+# saturday night may 31st at midnight (which in french is to be
651
+# intrepreted as the night between saturday and sunday)
652
+# sunday night the 28th  at midnight
653
+#
654
+# Seeing that the 28th is monday, I am guessing that she intends to say
655
+# the midnight of the 28th which is the midnight between sunday and
656
+# monday, which jives with other sources that say that it's inclusive
657
+# june1st to sept 27th.
658
+#
659
+# The decision was taken by decree *2-08-224 *but I can't find the decree
660
+# published on the web.
661
+#
662
+# It's also confirmed here:
663
+# <a href="http://www.maroc.ma/NR/exeres/FACF141F-D910-44B0-B7FA-6E03733425D1.htm">
664
+# http://www.maroc.ma/NR/exeres/FACF141F-D910-44B0-B7FA-6E03733425D1.htm
665
+# </a>
666
+# on a government portal as being  between june 1st and sept 27th (not yet
667
+# posted in english).
668
+#
669
+# The following google query will generate many relevant hits:
670
+# <a href="http://www.google.com/search?hl=en&q=Conseil+de+gouvernement+maroc+heure+avance&btnG=Search">
671
+# http://www.google.com/search?hl=en&q=Conseil+de+gouvernement+maroc+heure+avance&btnG=Search
672
+# </a>
673
+
674
+# From Alex Krivenyshev (2008-05-09):
675
+# Is Western Sahara (part which administrated by Morocco) going to follow
676
+# Morocco DST changes?  Any information?  What about other part of
677
+# Western Sahara - under administration of POLISARIO Front (also named
678
+# SADR Saharawi Arab Democratic Republic)?
679
+
680
+# From Arthur David Olson (2008-05-09):
681
+# XXX--guess that it is only Morocco for now; guess only 2008 for now.
682
+
683
+# From Steffen Thorsen (2008-08-27):
684
+# Morocco will change the clocks back on the midnight between August 31
685
+# and September 1. They originally planned to observe DST to near the end
686
+# of September:
687
+#
688
+# One article about it (in French):
689
+# <a href="http://www.menara.ma/fr/Actualites/Maroc/Societe/ci.retour_a_l_heure_gmt_a_partir_du_dimanche_31_aout_a_minuit_officiel_.default">
690
+# http://www.menara.ma/fr/Actualites/Maroc/Societe/ci.retour_a_l_heure_gmt_a_partir_du_dimanche_31_aout_a_minuit_officiel_.default
691
+# </a>
692
+#
693
+# We have some further details posted here:
694
+# <a href="http://www.timeanddate.com/news/time/morocco-ends-dst-early-2008.html">
695
+# http://www.timeanddate.com/news/time/morocco-ends-dst-early-2008.html
696
+# </a>
697
+
698
+# From Steffen Thorsen (2009-03-17):
699
+# Morocco will observe DST from 2009-06-01 00:00 to 2009-08-21 00:00 according
700
+# to many sources, such as
701
+# <a href="http://news.marweb.com/morocco/entertainment/morocco-daylight-saving.html">
702
+# http://news.marweb.com/morocco/entertainment/morocco-daylight-saving.html
703
+# </a>
704
+# <a href="http://www.medi1sat.ma/fr/depeche.aspx?idp=2312">
705
+# http://www.medi1sat.ma/fr/depeche.aspx?idp=2312
706
+# </a>
707
+# (French)
708
+#
709
+# Our summary:
710
+# <a href="http://www.timeanddate.com/news/time/morocco-starts-dst-2009.html">
711
+# http://www.timeanddate.com/news/time/morocco-starts-dst-2009.html
712
+# </a>
713
+
714
+# From Alexander Krivenyshev (2009-03-17):
715
+# Here is a link to official document from Royaume du Maroc Premier Ministre,
716
+# Ministere de la Modernisation des Secteurs Publics
717
+#
718
+# Under Article 1 of Royal Decree No. 455-67 of Act 23 safar 1387 (2 june 1967)
719
+# concerning the amendment of the legal time, the Ministry of Modernization of
720
+# Public Sectors announced that the official time in the Kingdom will be
721
+# advanced 60 minutes from Sunday 31 May 2009 at midnight.
722
+#
723
+# <a href="http://www.mmsp.gov.ma/francais/Actualites_fr/PDF_Actualites_Fr/HeureEte_FR.pdf">
724
+# http://www.mmsp.gov.ma/francais/Actualites_fr/PDF_Actualites_Fr/HeureEte_FR.pdf
725
+# </a>
726
+#
727
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_morocco03.html">
728
+# http://www.worldtimezone.com/dst_news/dst_news_morocco03.html
729
+# </a>
730
+
731
+# From Steffen Thorsen (2010-04-13):
732
+# Several news media in Morocco report that the Ministry of Modernization
733
+# of Public Sectors has announced that Morocco will have DST from
734
+# 2010-05-02 to 2010-08-08.
735
+#
736
+# Example:
737
+# <a href="http://www.lavieeco.com/actualites/4099-le-maroc-passera-a-l-heure-d-ete-gmt1-le-2-mai.html">
738
+# http://www.lavieeco.com/actualites/4099-le-maroc-passera-a-l-heure-d-ete-gmt1-le-2-mai.html
739
+# </a>
740
+# (French)
741
+# Our page:
742
+# <a href="http://www.timeanddate.com/news/time/morocco-starts-dst-2010.html">
743
+# http://www.timeanddate.com/news/time/morocco-starts-dst-2010.html
744
+# </a>
745
+
746
+# From Dan Abitol (2011-03-30):
747
+# ...Rules for Africa/Casablanca are the following (24h format)
748
+# The 3rd april 2011 at 00:00:00, [it] will be 3rd april 1:00:00
749
+# The 31th july 2011 at 00:59:59,  [it] will be 31th July 00:00:00
750
+# ...Official links of change in morocco
751
+# The change was broadcast on the FM Radio
752
+# I ve called ANRT (telecom regulations in Morocco) at
753
+# +212.537.71.84.00
754
+# <a href="http://www.anrt.net.ma/fr/">
755
+# http://www.anrt.net.ma/fr/
756
+# </a>
757
+# They said that
758
+# <a href="http://www.map.ma/fr/sections/accueil/l_heure_legale_au_ma/view">
759
+# http://www.map.ma/fr/sections/accueil/l_heure_legale_au_ma/view
760
+# </a>
761
+# is the official publication to look at.
762
+# They said that the decision was already taken.
763
+#
764
+# More articles in the press
765
+# <a href="http://www.yabiladi.com/articles/details/5058/secret-l-heure-d-ete-maroc-lev">
766
+# http://www.yabiladi.com/articles/details/5058/secret-l-heure-d-ete-maroc-lev
767
+# </a>
768
+# e.html
769
+# <a href="http://www.lematin.ma/Actualite/Express/Article.asp?id=148923">
770
+# http://www.lematin.ma/Actualite/Express/Article.asp?id=148923
771
+# </a>
772
+# <a href="http://www.lavieeco.com/actualite/Le-Maroc-passe-sur-GMT%2B1-a-partir-de-dim">
773
+# http://www.lavieeco.com/actualite/Le-Maroc-passe-sur-GMT%2B1-a-partir-de-dim
774
+# anche-prochain-5538.html
775
+# </a>
776
+
777
+# From Petr Machata (2011-03-30):
778
+# They have it written in English here:
779
+# <a href="http://www.map.ma/eng/sections/home/morocco_to_spring_fo/view">
780
+# http://www.map.ma/eng/sections/home/morocco_to_spring_fo/view
781
+# </a>
782
+#
783
+# It says there that "Morocco will resume its standard time on July 31,
784
+# 2011 at midnight." Now they don't say whether they mean midnight of
785
+# wall clock time (i.e. 11pm UTC), but that's what I would assume. It has
786
+# also been like that in the past.
787
+
788
+# From Alexander Krivenyshev (2012-03-09):
789
+# According to Infom&eacute;diaire web site from Morocco (infomediaire.ma),
790
+# on March 9, 2012, (in French) Heure l&eacute;gale:
791
+# Le Maroc adopte officiellement l'heure d'&eacute;t&eacute;
792
+# <a href="http://www.infomediaire.ma/news/maroc/heure-l%C3%A9gale-le-maroc-adopte-officiellement-lheure-d%C3%A9t%C3%A9">
793
+# http://www.infomediaire.ma/news/maroc/heure-l%C3%A9gale-le-maroc-adopte-officiellement-lheure-d%C3%A9t%C3%A9
794
+# </a>
795
+# Governing Council adopted draft decree, that Morocco DST starts on
796
+# the last Sunday of March (March 25, 2012) and ends on
797
+# last Sunday of September (September 30, 2012)
798
+# except the month of Ramadan.
799
+# or (brief)
800
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_morocco06.html">
801
+# http://www.worldtimezone.com/dst_news/dst_news_morocco06.html
802
+# </a>
803
+
804
+# From Arthur David Olson (2012-03-10):
805
+# The infomediaire.ma source indicates that the system is to be in
806
+# effect every year. It gives 03H00 as the "fall back" time of day;
807
+# it lacks a "spring forward" time of day; assume 2:00 XXX.
808
+# Wait on specifying the Ramadan exception for details about
809
+# start date, start time of day, end date, and end time of day XXX.
810
+
811
+# From Christophe Tropamer (2012-03-16):
812
+# Seen Morocco change again:
813
+# <a href="http://www.le2uminutes.com/actualite.php">
814
+# http://www.le2uminutes.com/actualite.php
815
+# </a>
816
+# "...&agrave; partir du dernier dimance d'avril et non fins mars,
817
+# comme annonc&eacute; pr&eacute;c&eacute;demment."
818
+
819
+# From Milamber Space Network (2012-07-17):
820
+# The official return to GMT is announced by the Moroccan government:
821
+# <a href="http://www.mmsp.gov.ma/fr/actualites.aspx?id=288">
822
+# http://www.mmsp.gov.ma/fr/actualites.aspx?id=288 [in French]
823
+# </a>
824
+#
825
+# Google translation, lightly edited:
826
+# Back to the standard time of the Kingdom (GMT)
827
+# Pursuant to Decree No. 2-12-126 issued on 26 Jumada (I) 1433 (April 18,
828
+# 2012) and in accordance with the order of Mr. President of the
829
+# Government No. 3-47-12 issued on 24 Sha'ban (11 July 2012), the Ministry
830
+# of Public Service and Administration Modernization announces the return
831
+# of the legal time of the Kingdom (GMT) from Friday, July 20, 2012 until
832
+# Monday, August 20, 2012.  So the time will be delayed by 60 minutes from
833
+# 3:00 am Friday, July 20, 2012 and will again be advanced by 60 minutes
834
+# August 20, 2012 from 2:00 am.
835
+
836
+# RULE	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
837
+
838
+Rule	Morocco	1939	only	-	Sep	12	 0:00	1:00	S
839
+Rule	Morocco	1939	only	-	Nov	19	 0:00	0	-
840
+Rule	Morocco	1940	only	-	Feb	25	 0:00	1:00	S
841
+Rule	Morocco	1945	only	-	Nov	18	 0:00	0	-
842
+Rule	Morocco	1950	only	-	Jun	11	 0:00	1:00	S
843
+Rule	Morocco	1950	only	-	Oct	29	 0:00	0	-
844
+Rule	Morocco	1967	only	-	Jun	 3	12:00	1:00	S
845
+Rule	Morocco	1967	only	-	Oct	 1	 0:00	0	-
846
+Rule	Morocco	1974	only	-	Jun	24	 0:00	1:00	S
847
+Rule	Morocco	1974	only	-	Sep	 1	 0:00	0	-
848
+Rule	Morocco	1976	1977	-	May	 1	 0:00	1:00	S
849
+Rule	Morocco	1976	only	-	Aug	 1	 0:00	0	-
850
+Rule	Morocco	1977	only	-	Sep	28	 0:00	0	-
851
+Rule	Morocco	1978	only	-	Jun	 1	 0:00	1:00	S
852
+Rule	Morocco	1978	only	-	Aug	 4	 0:00	0	-
853
+Rule	Morocco	2008	only	-	Jun	 1	 0:00	1:00	S
854
+Rule	Morocco	2008	only	-	Sep	 1	 0:00	0	-
855
+Rule	Morocco	2009	only	-	Jun	 1	 0:00	1:00	S
856
+Rule	Morocco	2009	only	-	Aug	 21	 0:00	0	-
857
+Rule	Morocco	2010	only	-	May	 2	 0:00	1:00	S
858
+Rule	Morocco	2010	only	-	Aug	 8	 0:00	0	-
859
+Rule	Morocco	2011	only	-	Apr	 3	 0:00	1:00	S
860
+Rule	Morocco	2011	only	-	Jul	 31	 0	0	-
861
+Rule	Morocco	2012	max	-	Apr	 lastSun 2:00	1:00	S
862
+Rule	Morocco	2012	max	-	Sep	 lastSun 3:00	0	-
863
+Rule	Morocco	2012	only	-	Jul	 20	 3:00	0	-
864
+Rule	Morocco	2012	only	-	Aug	 20	 2:00	1:00	S
865
+
866
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
867
+Zone Africa/Casablanca	-0:30:20 -	LMT	1913 Oct 26
868
+			 0:00	Morocco	WE%sT	1984 Mar 16
869
+			 1:00	-	CET	1986
870
+			 0:00	Morocco	WE%sT
871
+# Western Sahara
872
+Zone Africa/El_Aaiun	-0:52:48 -	LMT	1934 Jan
873
+			-1:00	-	WAT	1976 Apr 14
874
+			 0:00	-	WET
875
+
876
+# Mozambique
877
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
878
+Zone	Africa/Maputo	2:10:20 -	LMT	1903 Mar
879
+			2:00	-	CAT
880
+
881
+# Namibia
882
+# The 1994-04-03 transition is from Shanks & Pottenger.
883
+# Shanks & Pottenger report no DST after 1998-04; go with IATA.
884
+
885
+# From Petronella Sibeene (2007-03-30) in
886
+# <http://allafrica.com/stories/200703300178.html>:
887
+# While the entire country changes its time, Katima Mulilo and other
888
+# settlements in Caprivi unofficially will not because the sun there
889
+# rises and sets earlier compared to other regions.  Chief of
890
+# Forecasting Riaan van Zyl explained that the far eastern parts of
891
+# the country are close to 40 minutes earlier in sunrise than the rest
892
+# of the country.
893
+#
894
+# From Paul Eggert (2007-03-31):
895
+# Apparently the Caprivi Strip informally observes Botswana time, but
896
+# we have no details.  In the meantime people there can use Africa/Gaborone.
897
+
898
+# RULE	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
899
+Rule	Namibia	1994	max	-	Sep	Sun>=1	2:00	1:00	S
900
+Rule	Namibia	1995	max	-	Apr	Sun>=1	2:00	0	-
901
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
902
+Zone	Africa/Windhoek	1:08:24 -	LMT	1892 Feb 8
903
+			1:30	-	SWAT	1903 Mar	# SW Africa Time
904
+			2:00	-	SAST	1942 Sep 20 2:00
905
+			2:00	1:00	SAST	1943 Mar 21 2:00
906
+			2:00	-	SAST	1990 Mar 21 # independence
907
+			2:00	-	CAT	1994 Apr  3
908
+			1:00	Namibia	WA%sT
909
+
910
+# Niger
911
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
912
+Zone	Africa/Niamey	 0:08:28 -	LMT	1912
913
+			-1:00	-	WAT	1934 Feb 26
914
+			 0:00	-	GMT	1960
915
+			 1:00	-	WAT
916
+
917
+# Nigeria
918
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
919
+Zone	Africa/Lagos	0:13:36 -	LMT	1919 Sep
920
+			1:00	-	WAT
921
+
922
+# Reunion
923
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
924
+Zone	Indian/Reunion	3:41:52 -	LMT	1911 Jun	# Saint-Denis
925
+			4:00	-	RET	# Reunion Time
926
+#
927
+# Scattered Islands (Iles Eparses) administered from Reunion are as follows.
928
+# The following information about them is taken from
929
+# Iles Eparses (www.outre-mer.gouv.fr/domtom/ile.htm, 1997-07-22, in French;
930
+# no longer available as of 1999-08-17).
931
+# We have no info about their time zone histories.
932
+#
933
+# Bassas da India - uninhabited
934
+# Europa Island - inhabited from 1905 to 1910 by two families
935
+# Glorioso Is - inhabited until at least 1958
936
+# Juan de Nova - uninhabited
937
+# Tromelin - inhabited until at least 1958
938
+
939
+# Rwanda
940
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
941
+Zone	Africa/Kigali	2:00:16 -	LMT	1935 Jun
942
+			2:00	-	CAT
943
+
944
+# St Helena
945
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
946
+Zone Atlantic/St_Helena	-0:22:48 -	LMT	1890		# Jamestown
947
+			-0:22:48 -	JMT	1951	# Jamestown Mean Time
948
+			 0:00	-	GMT
949
+# The other parts of the St Helena territory are similar:
950
+#	Tristan da Cunha: on GMT, say Whitman and the CIA
951
+#	Ascension: on GMT, says usno1995 and the CIA
952
+#	Gough (scientific station since 1955; sealers wintered previously):
953
+#		on GMT, says the CIA
954
+#	Inaccessible, Nightingale: no information, but probably GMT
955
+
956
+# Sao Tome and Principe
957
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
958
+Zone	Africa/Sao_Tome	 0:26:56 -	LMT	1884
959
+			-0:36:32 -	LMT	1912	# Lisbon Mean Time
960
+			 0:00	-	GMT
961
+
962
+# Senegal
963
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
964
+Zone	Africa/Dakar	-1:09:44 -	LMT	1912
965
+			-1:00	-	WAT	1941 Jun
966
+			 0:00	-	GMT
967
+
968
+# Seychelles
969
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
970
+Zone	Indian/Mahe	3:41:48 -	LMT	1906 Jun	# Victoria
971
+			4:00	-	SCT	# Seychelles Time
972
+# From Paul Eggert (2001-05-30):
973
+# Aldabra, Farquhar, and Desroches, originally dependencies of the
974
+# Seychelles, were transferred to the British Indian Ocean Territory
975
+# in 1965 and returned to Seychelles control in 1976.  We don't know
976
+# whether this affected their time zone, so omit this for now.
977
+# Possibly the islands were uninhabited.
978
+
979
+# Sierra Leone
980
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
981
+# Whitman gives Mar 31 - Aug 31 for 1931 on; go with Shanks & Pottenger.
982
+Rule	SL	1935	1942	-	Jun	 1	0:00	0:40	SLST
983
+Rule	SL	1935	1942	-	Oct	 1	0:00	0	WAT
984
+Rule	SL	1957	1962	-	Jun	 1	0:00	1:00	SLST
985
+Rule	SL	1957	1962	-	Sep	 1	0:00	0	GMT
986
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
987
+Zone	Africa/Freetown	-0:53:00 -	LMT	1882
988
+			-0:53:00 -	FMT	1913 Jun # Freetown Mean Time
989
+			-1:00	SL	%s	1957
990
+			 0:00	SL	%s
991
+
992
+# Somalia
993
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
994
+Zone Africa/Mogadishu	3:01:28 -	LMT	1893 Nov
995
+			3:00	-	EAT	1931
996
+			2:30	-	BEAT	1957
997
+			3:00	-	EAT
998
+
999
+# South Africa
1000
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1001
+Rule	SA	1942	1943	-	Sep	Sun>=15	2:00	1:00	-
1002
+Rule	SA	1943	1944	-	Mar	Sun>=15	2:00	0	-
1003
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1004
+Zone Africa/Johannesburg 1:52:00 -	LMT	1892 Feb 8
1005
+			1:30	-	SAST	1903 Mar
1006
+			2:00	SA	SAST
1007
+# Marion and Prince Edward Is
1008
+# scientific station since 1947
1009
+# no information
1010
+
1011
+# Sudan
1012
+#
1013
+# From <a href="http://www.sunanews.net/sn13jane.html">
1014
+# Sudan News Agency (2000-01-13)
1015
+# </a>, also reported by Michael De Beukelaer-Dossche via Steffen Thorsen:
1016
+# Clocks will be moved ahead for 60 minutes all over the Sudan as of noon
1017
+# Saturday....  This was announced Thursday by Caretaker State Minister for
1018
+# Manpower Abdul-Rahman Nur-Eddin.
1019
+#
1020
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1021
+Rule	Sudan	1970	only	-	May	 1	0:00	1:00	S
1022
+Rule	Sudan	1970	1985	-	Oct	15	0:00	0	-
1023
+Rule	Sudan	1971	only	-	Apr	30	0:00	1:00	S
1024
+Rule	Sudan	1972	1985	-	Apr	lastSun	0:00	1:00	S
1025
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1026
+Zone	Africa/Khartoum	2:10:08 -	LMT	1931
1027
+			2:00	Sudan	CA%sT	2000 Jan 15 12:00
1028
+			3:00	-	EAT
1029
+
1030
+# South Sudan
1031
+Zone	Africa/Juba	2:06:24 -	LMT	1931
1032
+			2:00	Sudan	CA%sT	2000 Jan 15 12:00
1033
+			3:00	-	EAT
1034
+
1035
+# Swaziland
1036
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1037
+Zone	Africa/Mbabane	2:04:24 -	LMT	1903 Mar
1038
+			2:00	-	SAST
1039
+
1040
+# Tanzania
1041
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1042
+Zone Africa/Dar_es_Salaam 2:37:08 -	LMT	1931
1043
+			3:00	-	EAT	1948
1044
+			2:45	-	BEAUT	1961
1045
+			3:00	-	EAT
1046
+
1047
+# Togo
1048
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1049
+Zone	Africa/Lome	0:04:52 -	LMT	1893
1050
+			0:00	-	GMT
1051
+
1052
+# Tunisia
1053
+
1054
+# From Gwillim Law (2005-04-30):
1055
+# My correspondent, Risto Nykanen, has alerted me to another adoption of DST,
1056
+# this time in Tunisia.  According to Yahoo France News
1057
+# <http://fr.news.yahoo.com/050426/5/4dumk.html>, in a story attributed to AP
1058
+# and dated 2005-04-26, "Tunisia has decided to advance its official time by
1059
+# one hour, starting on Sunday, May 1.  Henceforth, Tunisian time will be
1060
+# UTC+2 instead of UTC+1.  The change will take place at 23:00 UTC next
1061
+# Saturday."  (My translation)
1062
+#
1063
+# From Oscar van Vlijmen (2005-05-02):
1064
+# LaPresse, the first national daily newspaper ...
1065
+# <http://www.lapresse.tn/archives/archives280405/actualites/lheure.html>
1066
+# ... DST for 2005: on: Sun May 1 0h standard time, off: Fri Sept. 30,
1067
+# 1h standard time.
1068
+#
1069
+# From Atef Loukil (2006-03-28):
1070
+# The daylight saving time will be the same each year:
1071
+# Beginning      : the last Sunday of March at 02:00
1072
+# Ending         : the last Sunday of October at 03:00 ...
1073
+# http://www.tap.info.tn/en/index.php?option=com_content&task=view&id=1188&Itemid=50
1074
+
1075
+# From Steffen Thorsen (2009-03-16):
1076
+# According to several news sources, Tunisia will not observe DST this year.
1077
+# (Arabic)
1078
+# <a href="http://www.elbashayer.com/?page=viewn&nid=42546">
1079
+# http://www.elbashayer.com/?page=viewn&nid=42546
1080
+# </a>
1081
+# <a href="http://www.babnet.net/kiwidetail-15295.asp">
1082
+# http://www.babnet.net/kiwidetail-15295.asp
1083
+# </a>
1084
+#
1085
+# We have also confirmed this with the US embassy in Tunisia.
1086
+# We have a wrap-up about this on the following page:
1087
+# <a href="http://www.timeanddate.com/news/time/tunisia-cancels-dst-2009.html">
1088
+# http://www.timeanddate.com/news/time/tunisia-cancels-dst-2009.html
1089
+# </a>
1090
+
1091
+# From Alexander Krivenyshev (2009-03-17):
1092
+# Here is a link to Tunis Afrique Presse News Agency
1093
+#
1094
+# Standard time to be kept the whole year long (tap.info.tn):
1095
+#
1096
+# (in English)
1097
+# <a href="http://www.tap.info.tn/en/index.php?option=com_content&task=view&id=26813&Itemid=157">
1098
+# http://www.tap.info.tn/en/index.php?option=com_content&task=view&id=26813&Itemid=157
1099
+# </a>
1100
+#
1101
+# (in Arabic)
1102
+# <a href="http://www.tap.info.tn/ar/index.php?option=com_content&task=view&id=61240&Itemid=1">
1103
+# http://www.tap.info.tn/ar/index.php?option=com_content&task=view&id=61240&Itemid=1
1104
+# </a>
1105
+
1106
+# From Arthur David Olson (2009--3-18):
1107
+# The Tunis Afrique Presse News Agency notice contains this: "This measure is due to the fact
1108
+# that the fasting month of ramadan coincides with the period concerned by summer time.
1109
+# Therefore, the standard time will be kept unchanged the whole year long."
1110
+# So foregoing DST seems to be an exception (albeit one that may be repeated in the  future).
1111
+
1112
+# From Alexander Krivenyshev (2010-03-27):
1113
+# According to some news reports Tunis confirmed not to use DST in 2010
1114
+#
1115
+# (translation):
1116
+# "The Tunisian government has decided to abandon DST, which was scheduled on
1117
+# Sunday...
1118
+# Tunisian authorities had suspended the DST for the first time last year also
1119
+# coincided with the month of Ramadan..."
1120
+#
1121
+# (in Arabic)
1122
+# <a href="http://www.moheet.com/show_news.aspx?nid=358861&pg=1">
1123
+# http://www.moheet.com/show_news.aspx?nid=358861&pg=1
1124
+# <a href="http://www.almadenahnews.com/newss/news.php?c=118&id=38036">
1125
+# http://www.almadenahnews.com/newss/news.php?c=118&id=38036
1126
+# or
1127
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_tunis02.html">
1128
+# http://www.worldtimezone.com/dst_news/dst_news_tunis02.html
1129
+
1130
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1131
+Rule	Tunisia	1939	only	-	Apr	15	23:00s	1:00	S
1132
+Rule	Tunisia	1939	only	-	Nov	18	23:00s	0	-
1133
+Rule	Tunisia	1940	only	-	Feb	25	23:00s	1:00	S
1134
+Rule	Tunisia	1941	only	-	Oct	 6	 0:00	0	-
1135
+Rule	Tunisia	1942	only	-	Mar	 9	 0:00	1:00	S
1136
+Rule	Tunisia	1942	only	-	Nov	 2	 3:00	0	-
1137
+Rule	Tunisia	1943	only	-	Mar	29	 2:00	1:00	S
1138
+Rule	Tunisia	1943	only	-	Apr	17	 2:00	0	-
1139
+Rule	Tunisia	1943	only	-	Apr	25	 2:00	1:00	S
1140
+Rule	Tunisia	1943	only	-	Oct	 4	 2:00	0	-
1141
+Rule	Tunisia	1944	1945	-	Apr	Mon>=1	 2:00	1:00	S
1142
+Rule	Tunisia	1944	only	-	Oct	 8	 0:00	0	-
1143
+Rule	Tunisia	1945	only	-	Sep	16	 0:00	0	-
1144
+Rule	Tunisia	1977	only	-	Apr	30	 0:00s	1:00	S
1145
+Rule	Tunisia	1977	only	-	Sep	24	 0:00s	0	-
1146
+Rule	Tunisia	1978	only	-	May	 1	 0:00s	1:00	S
1147
+Rule	Tunisia	1978	only	-	Oct	 1	 0:00s	0	-
1148
+Rule	Tunisia	1988	only	-	Jun	 1	 0:00s	1:00	S
1149
+Rule	Tunisia	1988	1990	-	Sep	lastSun	 0:00s	0	-
1150
+Rule	Tunisia	1989	only	-	Mar	26	 0:00s	1:00	S
1151
+Rule	Tunisia	1990	only	-	May	 1	 0:00s	1:00	S
1152
+Rule	Tunisia	2005	only	-	May	 1	 0:00s	1:00	S
1153
+Rule	Tunisia	2005	only	-	Sep	30	 1:00s	0	-
1154
+Rule	Tunisia	2006	2008	-	Mar	lastSun	 2:00s	1:00	S
1155
+Rule	Tunisia	2006	2008	-	Oct	lastSun	 2:00s	0	-
1156
+
1157
+# Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
1158
+# more precise 0:09:21.
1159
+# Shanks & Pottenger say the 1911 switch was on Mar 9; go with Howse's Mar 11.
1160
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1161
+Zone	Africa/Tunis	0:40:44 -	LMT	1881 May 12
1162
+			0:09:21	-	PMT	1911 Mar 11    # Paris Mean Time
1163
+			1:00	Tunisia	CE%sT
1164
+
1165
+# Uganda
1166
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1167
+Zone	Africa/Kampala	2:09:40 -	LMT	1928 Jul
1168
+			3:00	-	EAT	1930
1169
+			2:30	-	BEAT	1948
1170
+			2:45	-	BEAUT	1957
1171
+			3:00	-	EAT
1172
+
1173
+# Zambia
1174
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1175
+Zone	Africa/Lusaka	1:53:08 -	LMT	1903 Mar
1176
+			2:00	-	CAT
1177
+
1178
+# Zimbabwe
1179
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1180
+Zone	Africa/Harare	2:04:12 -	LMT	1903 Mar
1181
+			2:00	-	CAT
... ...
@@ -0,0 +1,413 @@
1
+# <pre>
2
+# This file is in the public domain, so clarified as of
3
+# 2009-05-17 by Arthur David Olson.
4
+
5
+# From Paul Eggert (1999-11-15):
6
+# To keep things manageable, we list only locations occupied year-round; see
7
+# <a href="http://www.comnap.aq/comnap/comnap.nsf/P/Stations/">
8
+# COMNAP - Stations and Bases
9
+# </a>
10
+# and
11
+# <a href="http://www.spri.cam.ac.uk/bob/periant.htm">
12
+# Summary of the Peri-Antarctic Islands (1998-07-23)
13
+# </a>
14
+# for information.
15
+# Unless otherwise specified, we have no time zone information.
16
+#
17
+# Except for the French entries,
18
+# I made up all time zone abbreviations mentioned here; corrections welcome!
19
+# FORMAT is `zzz' and GMTOFF is 0 for locations while uninhabited.
20
+
21
+# These rules are stolen from the `southamerica' file.
22
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
23
+Rule	ArgAQ	1964	1966	-	Mar	 1	0:00	0	-
24
+Rule	ArgAQ	1964	1966	-	Oct	15	0:00	1:00	S
25
+Rule	ArgAQ	1967	only	-	Apr	 2	0:00	0	-
26
+Rule	ArgAQ	1967	1968	-	Oct	Sun>=1	0:00	1:00	S
27
+Rule	ArgAQ	1968	1969	-	Apr	Sun>=1	0:00	0	-
28
+Rule	ArgAQ	1974	only	-	Jan	23	0:00	1:00	S
29
+Rule	ArgAQ	1974	only	-	May	 1	0:00	0	-
30
+Rule	ChileAQ	1972	1986	-	Mar	Sun>=9	3:00u	0	-
31
+Rule	ChileAQ	1974	1987	-	Oct	Sun>=9	4:00u	1:00	S
32
+Rule	ChileAQ	1987	only	-	Apr	12	3:00u	0	-
33
+Rule	ChileAQ	1988	1989	-	Mar	Sun>=9	3:00u	0	-
34
+Rule	ChileAQ	1988	only	-	Oct	Sun>=1	4:00u	1:00	S
35
+Rule	ChileAQ	1989	only	-	Oct	Sun>=9	4:00u	1:00	S
36
+Rule	ChileAQ	1990	only	-	Mar	18	3:00u	0	-
37
+Rule	ChileAQ	1990	only	-	Sep	16	4:00u	1:00	S
38
+Rule	ChileAQ	1991	1996	-	Mar	Sun>=9	3:00u	0	-
39
+Rule	ChileAQ	1991	1997	-	Oct	Sun>=9	4:00u	1:00	S
40
+Rule	ChileAQ	1997	only	-	Mar	30	3:00u	0	-
41
+Rule	ChileAQ	1998	only	-	Mar	Sun>=9	3:00u	0	-
42
+Rule	ChileAQ	1998	only	-	Sep	27	4:00u	1:00	S
43
+Rule	ChileAQ	1999	only	-	Apr	 4	3:00u	0	-
44
+Rule	ChileAQ	1999	2010	-	Oct	Sun>=9	4:00u	1:00	S
45
+Rule	ChileAQ	2000	2007	-	Mar	Sun>=9	3:00u	0	-
46
+# N.B.: the end of March 29 in Chile is March 30 in Universal time,
47
+# which is used below in specifying the transition.
48
+Rule	ChileAQ	2008	only	-	Mar	30	3:00u	0	-
49
+Rule	ChileAQ	2009	only	-	Mar	Sun>=9	3:00u	0	-
50
+Rule	ChileAQ	2010	only	-	Apr	Sun>=1	3:00u	0	-
51
+Rule	ChileAQ	2011	only	-	May	Sun>=2	3:00u	0	-
52
+Rule	ChileAQ	2011	only	-	Aug	Sun>=16	4:00u	1:00	S
53
+Rule	ChileAQ	2012	only	-	Apr	Sun>=23	3:00u	0	-
54
+Rule	ChileAQ	2012	only	-	Sep	Sun>=2	4:00u	1:00	S
55
+Rule	ChileAQ	2013	max	-	Mar	Sun>=9	3:00u	0	-
56
+Rule	ChileAQ	2013	max	-	Oct	Sun>=9	4:00u	1:00	S
57
+
58
+# These rules are stolen from the `australasia' file.
59
+Rule	AusAQ	1917	only	-	Jan	 1	0:01	1:00	-
60
+Rule	AusAQ	1917	only	-	Mar	25	2:00	0	-
61
+Rule	AusAQ	1942	only	-	Jan	 1	2:00	1:00	-
62
+Rule	AusAQ	1942	only	-	Mar	29	2:00	0	-
63
+Rule	AusAQ	1942	only	-	Sep	27	2:00	1:00	-
64
+Rule	AusAQ	1943	1944	-	Mar	lastSun	2:00	0	-
65
+Rule	AusAQ	1943	only	-	Oct	 3	2:00	1:00	-
66
+Rule	ATAQ	1967	only	-	Oct	Sun>=1	2:00s	1:00	-
67
+Rule	ATAQ	1968	only	-	Mar	lastSun	2:00s	0	-
68
+Rule	ATAQ	1968	1985	-	Oct	lastSun	2:00s	1:00	-
69
+Rule	ATAQ	1969	1971	-	Mar	Sun>=8	2:00s	0	-
70
+Rule	ATAQ	1972	only	-	Feb	lastSun	2:00s	0	-
71
+Rule	ATAQ	1973	1981	-	Mar	Sun>=1	2:00s	0	-
72
+Rule	ATAQ	1982	1983	-	Mar	lastSun	2:00s	0	-
73
+Rule	ATAQ	1984	1986	-	Mar	Sun>=1	2:00s	0	-
74
+Rule	ATAQ	1986	only	-	Oct	Sun>=15	2:00s	1:00	-
75
+Rule	ATAQ	1987	1990	-	Mar	Sun>=15	2:00s	0	-
76
+Rule	ATAQ	1987	only	-	Oct	Sun>=22	2:00s	1:00	-
77
+Rule	ATAQ	1988	1990	-	Oct	lastSun	2:00s	1:00	-
78
+Rule	ATAQ	1991	1999	-	Oct	Sun>=1	2:00s	1:00	-
79
+Rule	ATAQ	1991	2005	-	Mar	lastSun	2:00s	0	-
80
+Rule	ATAQ	2000	only	-	Aug	lastSun	2:00s	1:00	-
81
+Rule	ATAQ	2001	max	-	Oct	Sun>=1	2:00s	1:00	-
82
+Rule	ATAQ	2006	only	-	Apr	Sun>=1	2:00s	0	-
83
+Rule	ATAQ	2007	only	-	Mar	lastSun	2:00s	0	-
84
+Rule	ATAQ	2008	max	-	Apr	Sun>=1	2:00s	0	-
85
+
86
+# Argentina - year-round bases
87
+# Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05
88
+# Esperanza, San Martin Land, -6323-05659, since 1952-12-17
89
+# Jubany, Potter Peninsula, King George Island, -6414-0602320, since 1982-01
90
+# Marambio, Seymour I, -6414-05637, since 1969-10-29
91
+# Orcadas, Laurie I, -6016-04444, since 1904-02-22
92
+# San Martin, Debenham I, -6807-06708, since 1951-03-21
93
+#	(except 1960-03 / 1976-03-21)
94
+
95
+# Australia - territories
96
+# Heard Island, McDonald Islands (uninhabited)
97
+#	previously sealers and scientific personnel wintered
98
+#	<a href="http://web.archive.org/web/20021204222245/http://www.dstc.qut.edu.au/DST/marg/daylight.html">
99
+#	Margaret Turner reports
100
+#	</a> (1999-09-30) that they're UTC+5, with no DST;
101
+#	presumably this is when they have visitors.
102
+#
103
+# year-round bases
104
+# Casey, Bailey Peninsula, -6617+11032, since 1969
105
+# Davis, Vestfold Hills, -6835+07759, since 1957-01-13
106
+#	(except 1964-11 - 1969-02)
107
+# Mawson, Holme Bay, -6736+06253, since 1954-02-13
108
+
109
+# From Steffen Thorsen (2009-03-11):
110
+# Three Australian stations in Antarctica have changed their time zone:
111
+# Casey moved from UTC+8 to UTC+11
112
+# Davis moved from UTC+7 to UTC+5
113
+# Mawson moved from UTC+6 to UTC+5
114
+# The changes occurred on 2009-10-18 at 02:00 (local times).
115
+#
116
+# Government source: (Australian Antarctic Division)
117
+# <a href="http://www.aad.gov.au/default.asp?casid=37079">
118
+# http://www.aad.gov.au/default.asp?casid=37079
119
+# </a>
120
+#
121
+# We have more background information here:
122
+# <a href="http://www.timeanddate.com/news/time/antarctica-new-times.html">
123
+# http://www.timeanddate.com/news/time/antarctica-new-times.html
124
+# </a>
125
+
126
+# From Steffen Thorsen (2010-03-10):
127
+# We got these changes from the Australian Antarctic Division:
128
+# - Macquarie Island will stay on UTC+11 for winter and therefore not
129
+# switch back from daylight savings time when other parts of Australia do
130
+# on 4 April.
131
+#
132
+# - Casey station reverted to its normal time of UTC+8 on 5 March 2010.
133
+# The change to UTC+11 is being considered as a regular summer thing but
134
+# has not been decided yet.
135
+#
136
+# - Davis station will revert to its normal time of UTC+7 at 10 March 2010
137
+# 20:00 UTC.
138
+#
139
+# - Mawson station stays on UTC+5.
140
+#
141
+# In addition to the Rule changes for Casey/Davis, it means that Macquarie
142
+# will no longer be like Hobart and will have to have its own Zone created.
143
+#
144
+# Background:
145
+# <a href="http://www.timeanddate.com/news/time/antartica-time-changes-2010.html">
146
+# http://www.timeanddate.com/news/time/antartica-time-changes-2010.html
147
+# </a>
148
+
149
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
150
+Zone Antarctica/Casey	0	-	zzz	1969
151
+			8:00	-	WST	2009 Oct 18 2:00
152
+						# Western (Aus) Standard Time
153
+			11:00	-	CAST	2010 Mar 5 2:00
154
+						# Casey Time
155
+			8:00	-	WST	2011 Oct 28 2:00
156
+			11:00	-	CAST	2012 Feb 21 17:00u
157
+			8:00	-	WST
158
+Zone Antarctica/Davis	0	-	zzz	1957 Jan 13
159
+			7:00	-	DAVT	1964 Nov # Davis Time
160
+			0	-	zzz	1969 Feb
161
+			7:00	-	DAVT	2009 Oct 18 2:00
162
+			5:00	-	DAVT	2010 Mar 10 20:00u
163
+			7:00	-	DAVT	2011 Oct 28 2:00
164
+			5:00	-	DAVT	2012 Feb 21 20:00u
165
+			7:00	-	DAVT
166
+Zone Antarctica/Mawson	0	-	zzz	1954 Feb 13
167
+			6:00	-	MAWT	2009 Oct 18 2:00
168
+						# Mawson Time
169
+			5:00	-	MAWT
170
+Zone Antarctica/Macquarie 0	-	zzz	1911
171
+			10:00	-	EST	1916 Oct 1 2:00
172
+			10:00	1:00	EST	1917 Feb
173
+			10:00	AusAQ	EST	1967
174
+			10:00	ATAQ	EST	2010 Apr 4 3:00
175
+			11:00	-	MIST	# Macquarie Island Time
176
+# References:
177
+# <a href="http://www.antdiv.gov.au/aad/exop/sfo/casey/casey_aws.html">
178
+# Casey Weather (1998-02-26)
179
+# </a>
180
+# <a href="http://www.antdiv.gov.au/aad/exop/sfo/davis/video.html">
181
+# Davis Station, Antarctica (1998-02-26)
182
+# </a>
183
+# <a href="http://www.antdiv.gov.au/aad/exop/sfo/mawson/video.html">
184
+# Mawson Station, Antarctica (1998-02-25)
185
+# </a>
186
+
187
+# Brazil - year-round base
188
+# Comandante Ferraz, King George Island, -6205+05824, since 1983/4
189
+
190
+# Chile - year-round bases and towns
191
+# Escudero, South Shetland Is, -621157-0585735, since 1994
192
+# Presidente Eduadro Frei, King George Island, -6214-05848, since 1969-03-07
193
+# General Bernardo O'Higgins, Antarctic Peninsula, -6319-05704, since 1948-02
194
+# Capitan Arturo Prat, -6230-05941
195
+# Villa Las Estrellas (a town), around the Frei base, since 1984-04-09
196
+# These locations have always used Santiago time; use TZ='America/Santiago'.
197
+
198
+# China - year-round bases
199
+# Great Wall, King George Island, -6213-05858, since 1985-02-20
200
+# Zhongshan, Larsemann Hills, Prydz Bay, -6922+07623, since 1989-02-26
201
+
202
+# France - year-round bases
203
+#
204
+# From Antoine Leca (1997-01-20):
205
+# Time data are from Nicole Pailleau at the IFRTP
206
+# (French Institute for Polar Research and Technology).
207
+# She confirms that French Southern Territories and Terre Adelie bases
208
+# don't observe daylight saving time, even if Terre Adelie supplies came
209
+# from Tasmania.
210
+#
211
+# French Southern Territories with year-round inhabitants
212
+#
213
+# Martin-de-Vivies Base, Amsterdam Island, -374105+0773155, since 1950
214
+# Alfred-Faure Base, Crozet Islands, -462551+0515152, since 1964
215
+# Port-aux-Francais, Kerguelen Islands, -492110+0701303, since 1951;
216
+#	whaling & sealing station operated 1908/1914, 1920/1929, and 1951/1956
217
+#
218
+# St Paul Island - near Amsterdam, uninhabited
219
+#	fishing stations operated variously 1819/1931
220
+#
221
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
222
+Zone Indian/Kerguelen	0	-	zzz	1950	# Port-aux-Francais
223
+			5:00	-	TFT	# ISO code TF Time
224
+#
225
+# year-round base in the main continent
226
+# Dumont-d'Urville, Ile des Petrels, -6640+14001, since 1956-11
227
+#
228
+# Another base at Port-Martin, 50km east, began operation in 1947.
229
+# It was destroyed by fire on 1952-01-14.
230
+#
231
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
232
+Zone Antarctica/DumontDUrville 0 -	zzz	1947
233
+			10:00	-	PMT	1952 Jan 14 # Port-Martin Time
234
+			0	-	zzz	1956 Nov
235
+			10:00	-	DDUT	# Dumont-d'Urville Time
236
+# Reference:
237
+# <a href="http://en.wikipedia.org/wiki/Dumont_d'Urville_Station">
238
+# Dumont d'Urville Station (2005-12-05)
239
+# </a>
240
+
241
+# Germany - year-round base
242
+# Georg von Neumayer, -7039-00815
243
+
244
+# India - year-round base
245
+# Dakshin Gangotri, -7005+01200
246
+
247
+# Japan - year-round bases
248
+# Dome Fuji, -7719+03942
249
+# Syowa, -690022+0393524
250
+#
251
+# From Hideyuki Suzuki (1999-02-06):
252
+# In all Japanese stations, +0300 is used as the standard time.
253
+#
254
+# Syowa station, which is the first antarctic station of Japan,
255
+# was established on 1957-01-29.  Since Syowa station is still the main
256
+# station of Japan, it's appropriate for the principal location.
257
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
258
+Zone Antarctica/Syowa	0	-	zzz	1957 Jan 29
259
+			3:00	-	SYOT	# Syowa Time
260
+# See:
261
+# <a href="http://www.nipr.ac.jp/english/ara01.html">
262
+# NIPR Antarctic Research Activities (1999-08-17)
263
+# </a>
264
+
265
+# S Korea - year-round base
266
+# King Sejong, King George Island, -6213-05847, since 1988
267
+
268
+# New Zealand - claims
269
+# Balleny Islands (never inhabited)
270
+# Scott Island (never inhabited)
271
+#
272
+# year-round base
273
+# Scott, Ross Island, since 1957-01, is like Antarctica/McMurdo.
274
+#
275
+# These rules for New Zealand are stolen from the `australasia' file.
276
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
277
+Rule	NZAQ	1974	only	-	Nov	 3	2:00s	1:00	D
278
+Rule	NZAQ	1975	1988	-	Oct	lastSun	2:00s	1:00	D
279
+Rule	NZAQ	1989	only	-	Oct	 8	2:00s	1:00	D
280
+Rule	NZAQ	1990	2006	-	Oct	Sun>=1	2:00s	1:00	D
281
+Rule	NZAQ	1975	only	-	Feb	23	2:00s	0	S
282
+Rule	NZAQ	1976	1989	-	Mar	Sun>=1	2:00s	0	S
283
+Rule	NZAQ	1990	2007	-	Mar	Sun>=15	2:00s	0	S
284
+Rule	NZAQ	2007	max	-	Sep	lastSun	2:00s	1:00	D
285
+Rule	NZAQ	2008	max	-	Apr	Sun>=1	2:00s	0	S
286
+
287
+# Norway - territories
288
+# Bouvet (never inhabited)
289
+#
290
+# claims
291
+# Peter I Island (never inhabited)
292
+
293
+# Poland - year-round base
294
+# Arctowski, King George Island, -620945-0582745, since 1977
295
+
296
+# Russia - year-round bases
297
+# Bellingshausen, King George Island, -621159-0585337, since 1968-02-22
298
+# Mirny, Davis coast, -6633+09301, since 1956-02
299
+# Molodezhnaya, Alasheyev Bay, -6740+04551,
300
+#	year-round from 1962-02 to 1999-07-01
301
+# Novolazarevskaya, Queen Maud Land, -7046+01150,
302
+#	year-round from 1960/61 to 1992
303
+
304
+# Vostok, since 1957-12-16, temporarily closed 1994-02/1994-11
305
+# <a href="http://quest.arc.nasa.gov/antarctica/QA/computers/Directions,Time,ZIP">
306
+# From Craig Mundell (1994-12-15)</a>:
307
+# Vostok, which is one of the Russian stations, is set on the same
308
+# time as Moscow, Russia.
309
+#
310
+# From Lee Hotz (2001-03-08):
311
+# I queried the folks at Columbia who spent the summer at Vostok and this is
312
+# what they had to say about time there:
313
+# ``in the US Camp (East Camp) we have been on New Zealand (McMurdo)
314
+# time, which is 12 hours ahead of GMT. The Russian Station Vostok was
315
+# 6 hours behind that (although only 2 miles away, i.e. 6 hours ahead
316
+# of GMT). This is a time zone I think two hours east of Moscow. The
317
+# natural time zone is in between the two: 8 hours ahead of GMT.''
318
+#
319
+# From Paul Eggert (2001-05-04):
320
+# This seems to be hopelessly confusing, so I asked Lee Hotz about it
321
+# in person.  He said that some Antartic locations set their local
322
+# time so that noon is the warmest part of the day, and that this
323
+# changes during the year and does not necessarily correspond to mean
324
+# solar noon.  So the Vostok time might have been whatever the clocks
325
+# happened to be during their visit.  So we still don't really know what time
326
+# it is at Vostok.  But we'll guess UTC+6.
327
+#
328
+Zone Antarctica/Vostok	0	-	zzz	1957 Dec 16
329
+			6:00	-	VOST	# Vostok time
330
+
331
+# S Africa - year-round bases
332
+# Marion Island, -4653+03752
333
+# Sanae, -7141-00250
334
+
335
+# UK
336
+#
337
+# British Antarctic Territories (BAT) claims
338
+# South Orkney Islands
339
+#	scientific station from 1903
340
+#	whaling station at Signy I 1920/1926
341
+# South Shetland Islands
342
+#
343
+# year-round bases
344
+# Bird Island, South Georgia, -5400-03803, since 1983
345
+# Deception Island, -6259-06034, whaling station 1912/1931,
346
+#	scientific station 1943/1967,
347
+#	previously sealers and a scientific expedition wintered by accident,
348
+#	and a garrison was deployed briefly
349
+# Halley, Coates Land, -7535-02604, since 1956-01-06
350
+#	Halley is on a moving ice shelf and is periodically relocated
351
+#	so that it is never more than 10km from its nominal location.
352
+# Rothera, Adelaide Island, -6734-6808, since 1976-12-01
353
+#
354
+# From Paul Eggert (2002-10-22)
355
+# <http://webexhibits.org/daylightsaving/g.html> says Rothera is -03 all year.
356
+#
357
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
358
+Zone Antarctica/Rothera	0	-	zzz	1976 Dec  1
359
+			-3:00	-	ROTT	# Rothera time
360
+
361
+# Uruguay - year round base
362
+# Artigas, King George Island, -621104-0585107
363
+
364
+# USA - year-round bases
365
+#
366
+# Palmer, Anvers Island, since 1965 (moved 2 miles in 1968)
367
+#
368
+# From Ethan Dicks (1996-10-06):
369
+# It keeps the same time as Punta Arenas, Chile, because, just like us
370
+# and the South Pole, that's the other end of their supply line....
371
+# I verified with someone who was there that since 1980,
372
+# Palmer has followed Chile.  Prior to that, before the Falklands War,
373
+# Palmer used to be supplied from Argentina.
374
+#
375
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
376
+Zone Antarctica/Palmer	0	-	zzz	1965
377
+			-4:00	ArgAQ	AR%sT	1969 Oct 5
378
+			-3:00	ArgAQ	AR%sT	1982 May
379
+			-4:00	ChileAQ	CL%sT
380
+#
381
+#
382
+# McMurdo, Ross Island, since 1955-12
383
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
384
+Zone Antarctica/McMurdo	0	-	zzz	1956
385
+			12:00	NZAQ	NZ%sT
386
+#
387
+# Amundsen-Scott, South Pole, continuously occupied since 1956-11-20
388
+#
389
+# From Paul Eggert (1996-09-03):
390
+# Normally it wouldn't have a separate entry, since it's like the
391
+# larger Antarctica/McMurdo since 1970, but it's too famous to omit.
392
+#
393
+# From Chris Carrier (1996-06-27):
394
+# Siple, the first commander of the South Pole station,
395
+# stated that he would have liked to have kept GMT at the station,
396
+# but that he found it more convenient to keep GMT+12
397
+# as supplies for the station were coming from McMurdo Sound,
398
+# which was on GMT+12 because New Zealand was on GMT+12 all year
399
+# at that time (1957).  (Source: Siple's book 90 degrees SOUTH.)
400
+#
401
+# From Susan Smith
402
+# http://www.cybertours.com/whs/pole10.html
403
+# (1995-11-13 16:24:56 +1300, no longer available):
404
+# We use the same time as McMurdo does.
405
+# And they use the same time as Christchurch, NZ does....
406
+# One last quirk about South Pole time.
407
+# All the electric clocks are usually wrong.
408
+# Something about the generators running at 60.1hertz or something
409
+# makes all of the clocks run fast.  So every couple of days,
410
+# we have to go around and set them back 5 minutes or so.
411
+# Maybe if we let them run fast all of the time, we'd get to leave here sooner!!
412
+#
413
+Link	Antarctica/McMurdo	Antarctica/South_Pole
... ...
@@ -0,0 +1,2717 @@
1
+# <pre>
2
+# This file is in the public domain, so clarified as of
3
+# 2009-05-17 by Arthur David Olson.
4
+
5
+# This data is by no means authoritative; if you think you know better,
6
+# go ahead and edit the file (and please send any changes to
7
+# tz@iana.org for general use in the future).
8
+
9
+# From Paul Eggert (2006-03-22):
10
+#
11
+# A good source for time zone historical data outside the U.S. is
12
+# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
13
+# San Diego: ACS Publications, Inc. (2003).
14
+#
15
+# Gwillim Law writes that a good source
16
+# for recent time zone data is the International Air Transport
17
+# Association's Standard Schedules Information Manual (IATA SSIM),
18
+# published semiannually.  Law sent in several helpful summaries
19
+# of the IATA's data after 1990.
20
+#
21
+# Except where otherwise noted, Shanks & Pottenger is the source for
22
+# entries through 1990, and IATA SSIM is the source for entries afterwards.
23
+#
24
+# Another source occasionally used is Edward W. Whitman, World Time Differences,
25
+# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
26
+# I found in the UCLA library.
27
+#
28
+# A reliable and entertaining source about time zones is
29
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
30
+#
31
+# I invented the abbreviations marked `*' in the following table;
32
+# the rest are from earlier versions of this file, or from other sources.
33
+# Corrections are welcome!
34
+#	     std  dst
35
+#	     LMT	Local Mean Time
36
+#	2:00 EET  EEST	Eastern European Time
37
+#	2:00 IST  IDT	Israel
38
+#	3:00 AST  ADT	Arabia*
39
+#	3:30 IRST IRDT	Iran
40
+#	4:00 GST	Gulf*
41
+#	5:30 IST	India
42
+#	7:00 ICT	Indochina*
43
+#	7:00 WIT	west Indonesia
44
+#	8:00 CIT	central Indonesia
45
+#	8:00 CST	China
46
+#	9:00 CJT	Central Japanese Time (1896/1937)*
47
+#	9:00 EIT	east Indonesia
48
+#	9:00 JST  JDT	Japan
49
+#	9:00 KST  KDT	Korea
50
+#	9:30 CST	(Australian) Central Standard Time
51
+#
52
+# See the `europe' file for Russia and Turkey in Asia.
53
+
54
+# From Guy Harris:
55
+# Incorporates data for Singapore from Robert Elz' asia 1.1, as well as
56
+# additional information from Tom Yap, Sun Microsystems Intercontinental
57
+# Technical Support (including a page from the Official Airline Guide -
58
+# Worldwide Edition).  The names for time zones are guesses.
59
+
60
+###############################################################################
61
+
62
+# These rules are stolen from the `europe' file.
63
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
64
+Rule	EUAsia	1981	max	-	Mar	lastSun	 1:00u	1:00	S
65
+Rule	EUAsia	1979	1995	-	Sep	lastSun	 1:00u	0	-
66
+Rule	EUAsia	1996	max	-	Oct	lastSun	 1:00u	0	-
67
+Rule E-EurAsia	1981	max	-	Mar	lastSun	 0:00	1:00	S
68
+Rule E-EurAsia	1979	1995	-	Sep	lastSun	 0:00	0	-
69
+Rule E-EurAsia	1996	max	-	Oct	lastSun	 0:00	0	-
70
+Rule RussiaAsia	1981	1984	-	Apr	1	 0:00	1:00	S
71
+Rule RussiaAsia	1981	1983	-	Oct	1	 0:00	0	-
72
+Rule RussiaAsia	1984	1991	-	Sep	lastSun	 2:00s	0	-
73
+Rule RussiaAsia	1985	1991	-	Mar	lastSun	 2:00s	1:00	S
74
+Rule RussiaAsia	1992	only	-	Mar	lastSat	23:00	1:00	S
75
+Rule RussiaAsia	1992	only	-	Sep	lastSat	23:00	0	-
76
+Rule RussiaAsia	1993	max	-	Mar	lastSun	 2:00s	1:00	S
77
+Rule RussiaAsia	1993	1995	-	Sep	lastSun	 2:00s	0	-
78
+Rule RussiaAsia	1996	max	-	Oct	lastSun	 2:00s	0	-
79
+
80
+# Afghanistan
81
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
82
+Zone	Asia/Kabul	4:36:48 -	LMT	1890
83
+			4:00	-	AFT	1945
84
+			4:30	-	AFT
85
+
86
+# Armenia
87
+# From Paul Eggert (2006-03-22):
88
+# Shanks & Pottenger have Yerevan switching to 3:00 (with Russian DST)
89
+# in spring 1991, then to 4:00 with no DST in fall 1995, then
90
+# readopting Russian DST in 1997.  Go with Shanks & Pottenger, even
91
+# when they disagree with others.  Edgar Der-Danieliantz
92
+# reported (1996-05-04) that Yerevan probably wouldn't use DST
93
+# in 1996, though it did use DST in 1995.  IATA SSIM (1991/1998) reports that
94
+# Armenia switched from 3:00 to 4:00 in 1998 and observed DST after 1991,
95
+# but started switching at 3:00s in 1998.
96
+
97
+# From Arthur David Olson (2011-06-15):
98
+# While Russia abandoned DST in 2011, Armenia may choose to
99
+# follow Russia's "old" rules.
100
+
101
+# From Alexander Krivenyshev (2012-02-10):
102
+# According to News Armenia, on Feb 9, 2012,
103
+# http://newsarmenia.ru/society/20120209/42609695.html
104
+#
105
+# The Armenia National Assembly adopted final reading of Amendments to the
106
+# Law "On procedure of calculation time on the territory of the Republic of
107
+# Armenia" according to which Armenia [is] abolishing Daylight Saving Time.
108
+# or
109
+# (brief)
110
+# http://www.worldtimezone.com/dst_news/dst_news_armenia03.html
111
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
112
+Zone	Asia/Yerevan	2:58:00 -	LMT	1924 May  2
113
+			3:00	-	YERT	1957 Mar    # Yerevan Time
114
+			4:00 RussiaAsia YER%sT	1991 Mar 31 2:00s
115
+			3:00	1:00	YERST	1991 Sep 23 # independence
116
+			3:00 RussiaAsia	AM%sT	1995 Sep 24 2:00s
117
+			4:00	-	AMT	1997
118
+			4:00 RussiaAsia	AM%sT	2012 Mar 25 2:00s
119
+			4:00	-	AMT
120
+
121
+# Azerbaijan
122
+# From Rustam Aliyev of the Azerbaijan Internet Forum (2005-10-23):
123
+# According to the resolution of Cabinet of Ministers, 1997
124
+# Resolution available at: http://aif.az/docs/daylight_res.pdf
125
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
126
+Rule	Azer	1997	max	-	Mar	lastSun	 4:00	1:00	S
127
+Rule	Azer	1997	max	-	Oct	lastSun	 5:00	0	-
128
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
129
+Zone	Asia/Baku	3:19:24 -	LMT	1924 May  2
130
+			3:00	-	BAKT	1957 Mar    # Baku Time
131
+			4:00 RussiaAsia BAK%sT	1991 Mar 31 2:00s
132
+			3:00	1:00	BAKST	1991 Aug 30 # independence
133
+			3:00 RussiaAsia	AZ%sT	1992 Sep lastSat 23:00
134
+			4:00	-	AZT	1996 # Azerbaijan time
135
+			4:00	EUAsia	AZ%sT	1997
136
+			4:00	Azer	AZ%sT
137
+
138
+# Bahrain
139
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
140
+Zone	Asia/Bahrain	3:22:20 -	LMT	1920		# Al Manamah
141
+			4:00	-	GST	1972 Jun
142
+			3:00	-	AST
143
+
144
+# Bangladesh
145
+# From Alexander Krivenyshev (2009-05-13):
146
+# According to newspaper Asian Tribune (May 6, 2009) Bangladesh may introduce
147
+# Daylight Saving Time from June 16 to Sept 30
148
+#
149
+# Bangladesh to introduce daylight saving time likely from June 16
150
+# <a href="http://www.asiantribune.com/?q=node/17288">
151
+# http://www.asiantribune.com/?q=node/17288
152
+# </a>
153
+# or
154
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_bangladesh02.html">
155
+# http://www.worldtimezone.com/dst_news/dst_news_bangladesh02.html
156
+# </a>
157
+#
158
+# "... Bangladesh government has decided to switch daylight saving time from
159
+# June
160
+# 16 till September 30 in a bid to ensure maximum use of daylight to cope with
161
+# crippling power crisis. "
162
+#
163
+# The switch will remain in effect from June 16 to Sept 30 (2009) but if
164
+# implemented the next year, it will come in force from April 1, 2010
165
+
166
+# From Steffen Thorsen (2009-06-02):
167
+# They have finally decided now, but changed the start date to midnight between
168
+# the 19th and 20th, and they have not set the end date yet.
169
+#
170
+# Some sources:
171
+# <a href="http://in.reuters.com/article/southAsiaNews/idINIndia-40017620090601">
172
+# http://in.reuters.com/article/southAsiaNews/idINIndia-40017620090601
173
+# </a>
174
+# <a href="http://bdnews24.com/details.php?id=85889&cid=2">
175
+# http://bdnews24.com/details.php?id=85889&cid=2
176
+# </a>
177
+#
178
+# Our wrap-up:
179
+# <a href="http://www.timeanddate.com/news/time/bangladesh-daylight-saving-2009.html">
180
+# http://www.timeanddate.com/news/time/bangladesh-daylight-saving-2009.html
181
+# </a>
182
+
183
+# From A. N. M. Kamrus Saadat (2009-06-15):
184
+# Finally we've got the official mail regarding DST start time where DST start
185
+# time is mentioned as Jun 19 2009, 23:00 from BTRC (Bangladesh
186
+# Telecommunication Regulatory Commission).
187
+#
188
+# No DST end date has been announced yet.
189
+
190
+# From Alexander Krivenyshev (2009-09-25):
191
+# Bangladesh won't go back to Standard Time from October 1, 2009,
192
+# instead it will continue DST measure till the cabinet makes a fresh decision.
193
+#
194
+# Following report by same newspaper-"The Daily Star Friday":
195
+# "DST change awaits cabinet decision-Clock won't go back by 1-hr from Oct 1"
196
+# <a href="http://www.thedailystar.net/newDesign/news-details.php?nid=107021">
197
+# http://www.thedailystar.net/newDesign/news-details.php?nid=107021
198
+# </a>
199
+# or
200
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_bangladesh04.html">
201
+# http://www.worldtimezone.com/dst_news/dst_news_bangladesh04.html
202
+# </a>
203
+
204
+# From Steffen Thorsen (2009-10-13):
205
+# IANS (Indo-Asian News Service) now reports:
206
+# Bangladesh has decided that the clock advanced by an hour to make
207
+# maximum use of daylight hours as an energy saving measure would
208
+# "continue for an indefinite period."
209
+#
210
+# One of many places where it is published:
211
+# <a href="http://www.thaindian.com/newsportal/business/bangladesh-to-continue-indefinitely-with-advanced-time_100259987.html">
212
+# http://www.thaindian.com/newsportal/business/bangladesh-to-continue-indefinitely-with-advanced-time_100259987.html
213
+# </a>
214
+
215
+# From Alexander Krivenyshev (2009-12-24):
216
+# According to Bangladesh newspaper "The Daily Star,"
217
+# Bangladesh will change its clock back to Standard Time on Dec 31, 2009.
218
+#
219
+# Clock goes back 1-hr on Dec 31 night.
220
+# <a href="http://www.thedailystar.net/newDesign/news-details.php?nid=119228">
221
+# http://www.thedailystar.net/newDesign/news-details.php?nid=119228
222
+# </a>
223
+# and
224
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_bangladesh05.html">
225
+# http://www.worldtimezone.com/dst_news/dst_news_bangladesh05.html
226
+# </a>
227
+#
228
+# "...The government yesterday decided to put the clock back by one hour
229
+# on December 31 midnight and the new time will continue until March 31,
230
+# 2010 midnight. The decision came at a cabinet meeting at the Prime
231
+# Minister's Office last night..."
232
+
233
+# From Alexander Krivenyshev (2010-03-22):
234
+# According to Bangladesh newspaper "The Daily Star,"
235
+# Cabinet cancels Daylight Saving Time
236
+# <a href="http://www.thedailystar.net/newDesign/latest_news.php?nid=22817">
237
+# http://www.thedailystar.net/newDesign/latest_news.php?nid=22817
238
+# </a>
239
+# or
240
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_bangladesh06.html">
241
+# http://www.worldtimezone.com/dst_news/dst_news_bangladesh06.html
242
+# </a>
243
+
244
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
245
+Rule	Dhaka	2009	only	-	Jun	19	23:00	1:00	S
246
+Rule	Dhaka	2009	only	-	Dec	31	23:59	0	-
247
+
248
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
249
+Zone	Asia/Dhaka	6:01:40 -	LMT	1890
250
+			5:53:20	-	HMT	1941 Oct    # Howrah Mean Time?
251
+			6:30	-	BURT	1942 May 15 # Burma Time
252
+			5:30	-	IST	1942 Sep
253
+			6:30	-	BURT	1951 Sep 30
254
+			6:00	-	DACT	1971 Mar 26 # Dacca Time
255
+			6:00	-	BDT	2009
256
+			6:00	Dhaka	BD%sT
257
+
258
+# Bhutan
259
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
260
+Zone	Asia/Thimphu	5:58:36 -	LMT	1947 Aug 15 # or Thimbu
261
+			5:30	-	IST	1987 Oct
262
+			6:00	-	BTT	# Bhutan Time
263
+
264
+# British Indian Ocean Territory
265
+# Whitman and the 1995 CIA time zone map say 5:00, but the
266
+# 1997 and later maps say 6:00.  Assume the switch occurred in 1996.
267
+# We have no information as to when standard time was introduced;
268
+# assume it occurred in 1907, the same year as Mauritius (which
269
+# then contained the Chagos Archipelago).
270
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
271
+Zone	Indian/Chagos	4:49:40	-	LMT	1907
272
+			5:00	-	IOT	1996 # BIOT Time
273
+			6:00	-	IOT
274
+
275
+# Brunei
276
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
277
+Zone	Asia/Brunei	7:39:40 -	LMT	1926 Mar   # Bandar Seri Begawan
278
+			7:30	-	BNT	1933
279
+			8:00	-	BNT
280
+
281
+# Burma / Myanmar
282
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
283
+Zone	Asia/Rangoon	6:24:40 -	LMT	1880		# or Yangon
284
+			6:24:36	-	RMT	1920	   # Rangoon Mean Time?
285
+			6:30	-	BURT	1942 May   # Burma Time
286
+			9:00	-	JST	1945 May 3
287
+			6:30	-	MMT		   # Myanmar Time
288
+
289
+# Cambodia
290
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
291
+Zone	Asia/Phnom_Penh	6:59:40 -	LMT	1906 Jun  9
292
+			7:06:20	-	SMT	1911 Mar 11 0:01 # Saigon MT?
293
+			7:00	-	ICT	1912 May
294
+			8:00	-	ICT	1931 May
295
+			7:00	-	ICT
296
+
297
+# China
298
+
299
+# From Guy Harris:
300
+# People's Republic of China.  Yes, they really have only one time zone.
301
+
302
+# From Bob Devine (1988-01-28):
303
+# No they don't.  See TIME mag, 1986-02-17 p.52.  Even though
304
+# China is across 4 physical time zones, before Feb 1, 1986 only the
305
+# Peking (Bejing) time zone was recognized.  Since that date, China
306
+# has two of 'em -- Peking's and Urumqi (named after the capital of
307
+# the Xinjiang Uyghur Autonomous Region).  I don't know about DST for it.
308
+#
309
+# . . .I just deleted the DST table and this editor makes it too
310
+# painful to suck in another copy..  So, here is what I have for
311
+# DST start/end dates for Peking's time zone (info from AP):
312
+#
313
+#     1986 May 4 - Sept 14
314
+#     1987 mid-April - ??
315
+
316
+# From U. S. Naval Observatory (1989-01-19):
317
+# CHINA               8 H  AHEAD OF UTC  ALL OF CHINA, INCL TAIWAN
318
+# CHINA               9 H  AHEAD OF UTC  APR 17 - SEP 10
319
+
320
+# From Paul Eggert (2006-03-22):
321
+# Shanks & Pottenger write that China (except for Hong Kong and Macau)
322
+# has had a single time zone since 1980 May 1, observing summer DST
323
+# from 1986 through 1991; this contradicts Devine's
324
+# note about Time magazine, though apparently _something_ happened in 1986.
325
+# Go with Shanks & Pottenger for now.  I made up names for the other
326
+# pre-1980 time zones.
327
+
328
+# From Shanks & Pottenger:
329
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
330
+Rule	Shang	1940	only	-	Jun	 3	0:00	1:00	D
331
+Rule	Shang	1940	1941	-	Oct	 1	0:00	0	S
332
+Rule	Shang	1941	only	-	Mar	16	0:00	1:00	D
333
+Rule	PRC	1986	only	-	May	 4	0:00	1:00	D
334
+Rule	PRC	1986	1991	-	Sep	Sun>=11	0:00	0	S
335
+Rule	PRC	1987	1991	-	Apr	Sun>=10	0:00	1:00	D
336
+
337
+# From Anthony Fok (2001-12-20):
338
+# BTW, I did some research on-line and found some info regarding these five
339
+# historic timezones from some Taiwan websites.  And yes, there are official
340
+# Chinese names for these locales (before 1949).
341
+#
342
+# From Jesper Norgaard Welen (2006-07-14):
343
+# I have investigated the timezones around 1970 on the
344
+# http://www.astro.com/atlas site [with provinces and county
345
+# boundaries summarized below]....  A few other exceptions were two
346
+# counties on the Sichuan side of the Xizang-Sichuan border,
347
+# counties Dege and Baiyu which lies on the Sichuan side and are
348
+# therefore supposed to be GMT+7, Xizang region being GMT+6, but Dege
349
+# county is GMT+8 according to astro.com while Baiyu county is GMT+6
350
+# (could be true), for the moment I am assuming that those two
351
+# counties are mistakes in the astro.com data.
352
+
353
+# From Paul Eggert (2008-02-11):
354
+# I just now checked Google News for western news sources that talk
355
+# about China's single time zone, and couldn't find anything before 1986
356
+# talking about China being in one time zone.  (That article was: Jim
357
+# Mann, "A clumsy embrace for another western custom: China on daylight
358
+# time--sort of", Los Angeles Times, 1986-05-05.  By the way, this
359
+# article confirms the tz database's data claiming that China began
360
+# observing daylight saving time in 1986.
361
+#
362
+# From Thomas S. Mullaney (2008-02-11):
363
+# I think you're combining two subjects that need to treated
364
+# separately: daylight savings (which, you're correct, wasn't
365
+# implemented until the 1980s) and the unified time zone centered near
366
+# Beijing (which was implemented in 1949). Briefly, there was also a
367
+# "Lhasa Time" in Tibet and "Urumqi Time" in Xinjiang. The first was
368
+# ceased, and the second eventually recognized (again, in the 1980s).
369
+#
370
+# From Paul Eggert (2008-06-30):
371
+# There seems to be a good chance China switched to a single time zone in 1949
372
+# rather than in 1980 as Shanks & Pottenger have it, but we don't have a
373
+# reliable documentary source saying so yet, so for now we still go with
374
+# Shanks & Pottenger.
375
+
376
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
377
+# Changbai Time ("Long-white Time", Long-white = Heilongjiang area)
378
+# Heilongjiang (except Mohe county), Jilin
379
+Zone	Asia/Harbin	8:26:44	-	LMT	1928 # or Haerbin
380
+			8:30	-	CHAT	1932 Mar # Changbai Time
381
+			8:00	-	CST	1940
382
+			9:00	-	CHAT	1966 May
383
+			8:30	-	CHAT	1980 May
384
+			8:00	PRC	C%sT
385
+# Zhongyuan Time ("Central plain Time")
386
+# most of China
387
+Zone	Asia/Shanghai	8:05:52	-	LMT	1928
388
+			8:00	Shang	C%sT	1949
389
+			8:00	PRC	C%sT
390
+# Long-shu Time (probably due to Long and Shu being two names of that area)
391
+# Guangxi, Guizhou, Hainan, Ningxia, Sichuan, Shaanxi, and Yunnan;
392
+# most of Gansu; west Inner Mongolia; west Qinghai; and the Guangdong
393
+# counties Deqing, Enping, Kaiping, Luoding, Taishan, Xinxing,
394
+# Yangchun, Yangjiang, Yu'nan, and Yunfu.
395
+Zone	Asia/Chongqing	7:06:20	-	LMT	1928 # or Chungking
396
+			7:00	-	LONT	1980 May # Long-shu Time
397
+			8:00	PRC	C%sT
398
+# Xin-zang Time ("Xinjiang-Tibet Time")
399
+# The Gansu counties Aksay, Anxi, Dunhuang, Subei; west Qinghai;
400
+# the Guangdong counties  Xuwen, Haikang, Suixi, Lianjiang,
401
+# Zhanjiang, Wuchuan, Huazhou, Gaozhou, Maoming, Dianbai, and Xinyi;
402
+# east Tibet, including Lhasa, Chamdo, Shigaise, Jimsar, Shawan and Hutubi;
403
+# east Xinjiang, including Urumqi, Turpan, Karamay, Korla, Minfeng, Jinghe,
404
+# Wusu, Qiemo, Xinyan, Wulanwusu, Jinghe, Yumin, Tacheng, Tuoli, Emin,
405
+# Shihezi, Changji, Yanqi, Heshuo, Tuokexun, Tulufan, Shanshan, Hami,
406
+# Fukang, Kuitun, Kumukuli, Miquan, Qitai, and Turfan.
407
+Zone	Asia/Urumqi	5:50:20	-	LMT	1928 # or Urumchi
408
+			6:00	-	URUT	1980 May # Urumqi Time
409
+			8:00	PRC	C%sT
410
+# Kunlun Time
411
+# West Tibet, including Pulan, Aheqi, Shufu, Shule;
412
+# West Xinjiang, including Aksu, Atushi, Yining, Hetian, Cele, Luopu, Nileke,
413
+# Zhaosu, Tekesi, Gongliu, Chabuchaer, Huocheng, Bole, Pishan, Suiding,
414
+# and Yarkand.
415
+
416
+# From Luther Ma (2009-10-17):
417
+# Almost all (>99.9%) ethnic Chinese (properly ethnic Han) living in
418
+# Xinjiang use Chinese Standard Time. Some are aware of Xinjiang time,
419
+# but have no need of it. All planes, trains, and schools function on
420
+# what is called "Beijing time." When Han make an appointment in Chinese
421
+# they implicitly use Beijing time.
422
+#
423
+# On the other hand, ethnic Uyghurs, who make up about half the
424
+# population of Xinjiang, typically use "Xinjiang time" which is two
425
+# hours behind Beijing time, or UTC +0600. The government of the Xinjiang
426
+# Uyghur Autonomous Region, (XAUR, or just Xinjiang for short) as well as
427
+# local governments such as the Urumqi city government use both times in
428
+# publications, referring to what is popularly called Xinjiang time as
429
+# "Urumqi time." When Uyghurs make an appointment in the Uyghur language
430
+# they almost invariably use Xinjiang time.
431
+#
432
+# (Their ethnic Han compatriots would typically have no clue of its
433
+# widespread use, however, because so extremely few of them are fluent in
434
+# Uyghur, comparable to the number of Anglo-Americans fluent in Navajo.)
435
+#
436
+# (...As with the rest of China there was a brief interval ending in 1990
437
+# or 1991 when summer time was in use.  The confusion was severe, with
438
+# the province not having dual times but four times in use at the same
439
+# time. Some areas remained on standard Xinjiang time or Beijing time and
440
+# others moving their clocks ahead.)
441
+#
442
+# ...an example of an official website using of Urumqi time.
443
+#
444
+# The first few lines of the Google translation of
445
+# <a href="http://www.fjysgl.gov.cn/show.aspx?id=2379&cid=39">
446
+# http://www.fjysgl.gov.cn/show.aspx?id=2379&cid=39
447
+# </a>
448
+# (retrieved 2009-10-13)
449
+# > Urumqi fire seven people are missing the alleged losses of at least
450
+# > 500 million yuan
451
+# >
452
+# > (Reporter Dong Liu) the day before 20:20 or so (Urumqi Time 18:20),
453
+# > Urumqi City Department of International Plaza Luther Qiantang River
454
+# > burst fire. As of yesterday, 18:30, Urumqi City Fire officers and men
455
+# > have worked continuously for 22 hours...
456
+
457
+# From Luther Ma (2009-11-19):
458
+# With the risk of being redundant to previous answers these are the most common
459
+# English "transliterations" (w/o using non-English symbols):
460
+#
461
+# 1. Wulumuqi...
462
+# 2. Kashi...
463
+# 3. Urumqi...
464
+# 4. Kashgar...
465
+# ...
466
+# 5. It seems that Uyghurs in Urumqi has been using Xinjiang since at least the
467
+# 1960's. I know of one Han, now over 50, who grew up in the surrounding
468
+# countryside and used Xinjiang time as a child.
469
+#
470
+# 6. Likewise for Kashgar and the rest of south Xinjiang I don't know of any
471
+# start date for Xinjiang time.
472
+#
473
+# Without having access to local historical records, nor the ability to legally
474
+# publish them, I would go with October 1, 1949, when Xinjiang became the Uyghur
475
+# Autonomous Region under the PRC. (Before that Uyghurs, of course, would also
476
+# not be using Beijing time, but some local time.)
477
+
478
+Zone	Asia/Kashgar	5:03:56	-	LMT	1928 # or Kashi or Kaxgar
479
+			5:30	-	KAST	1940	 # Kashgar Time
480
+			5:00	-	KAST	1980 May
481
+			8:00	PRC	C%sT
482
+
483
+
484
+# From Lee Yiu Chung (2009-10-24):
485
+# I found there are some mistakes for the...DST rule for Hong
486
+# Kong. [According] to the DST record from Hong Kong Observatory (actually,
487
+# it is not [an] observatory, but the official meteorological agency of HK,
488
+# and also serves as the official timing agency), there are some missing
489
+# and incorrect rules. Although the exact switch over time is missing, I
490
+# think 3:30 is correct. The official DST record for Hong Kong can be
491
+# obtained from
492
+# <a href="http://www.hko.gov.hk/gts/time/Summertime.htm">
493
+# http://www.hko.gov.hk/gts/time/Summertime.htm
494
+# </a>.
495
+
496
+# From Arthur David Olson (2009-10-28):
497
+# Here are the dates given at
498
+# <a href="http://www.hko.gov.hk/gts/time/Summertime.htm">
499
+# http://www.hko.gov.hk/gts/time/Summertime.htm
500
+# </a>
501
+# as of 2009-10-28:
502
+# Year        Period
503
+# 1941        1 Apr to 30 Sep
504
+# 1942        Whole year
505
+# 1943        Whole year
506
+# 1944        Whole year
507
+# 1945        Whole year
508
+# 1946        20 Apr to 1 Dec
509
+# 1947        13 Apr to 30 Dec
510
+# 1948        2 May to 31 Oct
511
+# 1949        3 Apr to 30 Oct
512
+# 1950        2 Apr to 29 Oct
513
+# 1951        1 Apr to 28 Oct
514
+# 1952        6 Apr to 25 Oct
515
+# 1953        5 Apr to 1 Nov
516
+# 1954        21 Mar to 31 Oct
517
+# 1955        20 Mar to 6 Nov
518
+# 1956        18 Mar to 4 Nov
519
+# 1957        24 Mar to 3 Nov
520
+# 1958        23 Mar to 2 Nov
521
+# 1959        22 Mar to 1 Nov
522
+# 1960        20 Mar to 6 Nov
523
+# 1961        19 Mar to 5 Nov
524
+# 1962        18 Mar to 4 Nov
525
+# 1963        24 Mar to 3 Nov
526
+# 1964        22 Mar to 1 Nov
527
+# 1965        18 Apr to 17 Oct
528
+# 1966        17 Apr to 16 Oct
529
+# 1967        16 Apr to 22 Oct
530
+# 1968        21 Apr to 20 Oct
531
+# 1969        20 Apr to 19 Oct
532
+# 1970        19 Apr to 18 Oct
533
+# 1971        18 Apr to 17 Oct
534
+# 1972        16 Apr to 22 Oct
535
+# 1973        22 Apr to 21 Oct
536
+# 1973/74     30 Dec 73 to 20 Oct 74
537
+# 1975        20 Apr to 19 Oct
538
+# 1976        18 Apr to 17 Oct
539
+# 1977        Nil
540
+# 1978        Nil
541
+# 1979        13 May to 21 Oct
542
+# 1980 to Now Nil
543
+# The page does not give start or end times of day.
544
+# The page does not give a start date for 1942.
545
+# The page does not givw an end date for 1945.
546
+# The Japanese occupation of Hong Kong began on 1941-12-25.
547
+# The Japanese surrender of Hong Kong was signed 1945-09-15.
548
+# For lack of anything better, use start of those days as the transition times.
549
+
550
+# Hong Kong (Xianggang)
551
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
552
+Rule	HK	1941	only	-	Apr	1	3:30	1:00	S
553
+Rule	HK	1941	only	-	Sep	30	3:30	0	-
554
+Rule	HK	1946	only	-	Apr	20	3:30	1:00	S
555
+Rule	HK	1946	only	-	Dec	1	3:30	0	-
556
+Rule	HK	1947	only	-	Apr	13	3:30	1:00	S
557
+Rule	HK	1947	only	-	Dec	30	3:30	0	-
558
+Rule	HK	1948	only	-	May	2	3:30	1:00	S
559
+Rule	HK	1948	1951	-	Oct	lastSun	3:30	0	-
560
+Rule	HK	1952	only	-	Oct	25	3:30	0	-
561
+Rule	HK	1949	1953	-	Apr	Sun>=1	3:30	1:00	S
562
+Rule	HK	1953	only	-	Nov	1	3:30	0	-
563
+Rule	HK	1954	1964	-	Mar	Sun>=18	3:30	1:00	S
564
+Rule	HK	1954	only	-	Oct	31	3:30	0	-
565
+Rule	HK	1955	1964	-	Nov	Sun>=1	3:30	0	-
566
+Rule	HK	1965	1976	-	Apr	Sun>=16	3:30	1:00	S
567
+Rule	HK	1965	1976	-	Oct	Sun>=16	3:30	0	-
568
+Rule	HK	1973	only	-	Dec	30	3:30	1:00	S
569
+Rule	HK	1979	only	-	May	Sun>=8	3:30	1:00	S
570
+Rule	HK	1979	only	-	Oct	Sun>=16	3:30	0	-
571
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
572
+Zone	Asia/Hong_Kong	7:36:36 -	LMT	1904 Oct 30
573
+			8:00	HK	HK%sT	1941 Dec 25
574
+			9:00	-	JST	1945 Sep 15
575
+			8:00	HK	HK%sT
576
+
577
+###############################################################################
578
+
579
+# Taiwan
580
+
581
+# Shanks & Pottenger write that Taiwan observed DST during 1945, when it
582
+# was still controlled by Japan.  This is hard to believe, but we don't
583
+# have any other information.
584
+
585
+# From smallufo (2010-04-03):
586
+# According to Taiwan's CWB,
587
+# <a href="http://www.cwb.gov.tw/V6/astronomy/cdata/summert.htm">
588
+# http://www.cwb.gov.tw/V6/astronomy/cdata/summert.htm
589
+# </a>
590
+# Taipei has DST in 1979 between July 1st and Sep 30.
591
+
592
+# From Arthur David Olson (2010-04-07):
593
+# Here's Google's translation of the table at the bottom of the "summert.htm" page:
594
+# Decade 	                                                    Name                      Start and end date
595
+# Republic of China 34 years to 40 years (AD 1945-1951 years) Summer Time               May 1 to September 30
596
+# 41 years of the Republic of China (AD 1952)                 Daylight Saving Time      March 1 to October 31
597
+# Republic of China 42 years to 43 years (AD 1953-1954 years) Daylight Saving Time      April 1 to October 31
598
+# In the 44 years to 45 years (AD 1955-1956 years)            Daylight Saving Time      April 1 to September 30
599
+# Republic of China 46 years to 48 years (AD 1957-1959)       Summer Time               April 1 to September 30
600
+# Republic of China 49 years to 50 years (AD 1960-1961)       Summer Time               June 1 to September 30
601
+# Republic of China 51 years to 62 years (AD 1962-1973 years) Stop Summer Time
602
+# Republic of China 63 years to 64 years (1974-1975 AD)       Daylight Saving Time      April 1 to September 30
603
+# Republic of China 65 years to 67 years (1976-1978 AD)       Stop Daylight Saving Time
604
+# Republic of China 68 years (AD 1979)                        Daylight Saving Time      July 1 to September 30
605
+# Republic of China since 69 years (AD 1980)                  Stop Daylight Saving Time
606
+
607
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
608
+Rule	Taiwan	1945	1951	-	May	1	0:00	1:00	D
609
+Rule	Taiwan	1945	1951	-	Oct	1	0:00	0	S
610
+Rule	Taiwan	1952	only	-	Mar	1	0:00	1:00	D
611
+Rule	Taiwan	1952	1954	-	Nov	1	0:00	0	S
612
+Rule	Taiwan	1953	1959	-	Apr	1	0:00	1:00	D
613
+Rule	Taiwan	1955	1961	-	Oct	1	0:00	0	S
614
+Rule	Taiwan	1960	1961	-	Jun	1	0:00	1:00	D
615
+Rule	Taiwan	1974	1975	-	Apr	1	0:00	1:00	D
616
+Rule	Taiwan	1974	1975	-	Oct	1	0:00	0	S
617
+Rule	Taiwan	1979	only	-	Jun	30	0:00	1:00	D
618
+Rule	Taiwan	1979	only	-	Sep	30	0:00	0	S
619
+
620
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
621
+Zone	Asia/Taipei	8:06:00 -	LMT	1896 # or Taibei or T'ai-pei
622
+			8:00	Taiwan	C%sT
623
+
624
+# Macau (Macao, Aomen)
625
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
626
+Rule	Macau	1961	1962	-	Mar	Sun>=16	3:30	1:00	S
627
+Rule	Macau	1961	1964	-	Nov	Sun>=1	3:30	0	-
628
+Rule	Macau	1963	only	-	Mar	Sun>=16	0:00	1:00	S
629
+Rule	Macau	1964	only	-	Mar	Sun>=16	3:30	1:00	S
630
+Rule	Macau	1965	only	-	Mar	Sun>=16	0:00	1:00	S
631
+Rule	Macau	1965	only	-	Oct	31	0:00	0	-
632
+Rule	Macau	1966	1971	-	Apr	Sun>=16	3:30	1:00	S
633
+Rule	Macau	1966	1971	-	Oct	Sun>=16	3:30	0	-
634
+Rule	Macau	1972	1974	-	Apr	Sun>=15	0:00	1:00	S
635
+Rule	Macau	1972	1973	-	Oct	Sun>=15	0:00	0	-
636
+Rule	Macau	1974	1977	-	Oct	Sun>=15	3:30	0	-
637
+Rule	Macau	1975	1977	-	Apr	Sun>=15	3:30	1:00	S
638
+Rule	Macau	1978	1980	-	Apr	Sun>=15	0:00	1:00	S
639
+Rule	Macau	1978	1980	-	Oct	Sun>=15	0:00	0	-
640
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
641
+Zone	Asia/Macau	7:34:20 -	LMT	1912
642
+			8:00	Macau	MO%sT	1999 Dec 20 # return to China
643
+			8:00	PRC	C%sT
644
+
645
+
646
+###############################################################################
647
+
648
+# Cyprus
649
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
650
+Rule	Cyprus	1975	only	-	Apr	13	0:00	1:00	S
651
+Rule	Cyprus	1975	only	-	Oct	12	0:00	0	-
652
+Rule	Cyprus	1976	only	-	May	15	0:00	1:00	S
653
+Rule	Cyprus	1976	only	-	Oct	11	0:00	0	-
654
+Rule	Cyprus	1977	1980	-	Apr	Sun>=1	0:00	1:00	S
655
+Rule	Cyprus	1977	only	-	Sep	25	0:00	0	-
656
+Rule	Cyprus	1978	only	-	Oct	2	0:00	0	-
657
+Rule	Cyprus	1979	1997	-	Sep	lastSun	0:00	0	-
658
+Rule	Cyprus	1981	1998	-	Mar	lastSun	0:00	1:00	S
659
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
660
+Zone	Asia/Nicosia	2:13:28 -	LMT	1921 Nov 14
661
+			2:00	Cyprus	EE%sT	1998 Sep
662
+			2:00	EUAsia	EE%sT
663
+# IATA SSIM (1998-09) has Cyprus using EU rules for the first time.
664
+
665
+# Classically, Cyprus belongs to Asia; e.g. see Herodotus, Histories, I.72.
666
+# However, for various reasons many users expect to find it under Europe.
667
+Link	Asia/Nicosia	Europe/Nicosia
668
+
669
+# Georgia
670
+# From Paul Eggert (1994-11-19):
671
+# Today's _Economist_ (p 60) reports that Georgia moved its clocks forward
672
+# an hour recently, due to a law proposed by Zurab Murvanidze,
673
+# an MP who went on a hunger strike for 11 days to force discussion about it!
674
+# We have no details, but we'll guess they didn't move the clocks back in fall.
675
+#
676
+# From Mathew Englander, quoting AP (1996-10-23 13:05-04):
677
+# Instead of putting back clocks at the end of October, Georgia
678
+# will stay on daylight savings time this winter to save energy,
679
+# President Eduard Shevardnadze decreed Wednesday.
680
+#
681
+# From the BBC via Joseph S. Myers (2004-06-27):
682
+#
683
+# Georgia moved closer to Western Europe on Sunday...  The former Soviet
684
+# republic has changed its time zone back to that of Moscow.  As a result it
685
+# is now just four hours ahead of Greenwich Mean Time, rather than five hours
686
+# ahead.  The switch was decreed by the pro-Western president of Georgia,
687
+# Mikhail Saakashvili, who said the change was partly prompted by the process
688
+# of integration into Europe.
689
+
690
+# From Teimuraz Abashidze (2005-11-07):
691
+# Government of Georgia ... decided to NOT CHANGE daylight savings time on
692
+# [Oct.] 30, as it was done before during last more than 10 years.
693
+# Currently, we are in fact GMT +4:00, as before 30 October it was GMT
694
+# +3:00.... The problem is, there is NO FORMAL LAW or governmental document
695
+# about it.  As far as I can find, I was told, that there is no document,
696
+# because we just DIDN'T ISSUE document about switching to winter time....
697
+# I don't know what can be done, especially knowing that some years ago our
698
+# DST rules where changed THREE TIMES during one month.
699
+
700
+
701
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
702
+Zone	Asia/Tbilisi	2:59:16 -	LMT	1880
703
+			2:59:16	-	TBMT	1924 May  2 # Tbilisi Mean Time
704
+			3:00	-	TBIT	1957 Mar    # Tbilisi Time
705
+			4:00 RussiaAsia TBI%sT	1991 Mar 31 2:00s
706
+			3:00	1:00	TBIST	1991 Apr  9 # independence
707
+			3:00 RussiaAsia GE%sT	1992 # Georgia Time
708
+			3:00 E-EurAsia	GE%sT	1994 Sep lastSun
709
+			4:00 E-EurAsia	GE%sT	1996 Oct lastSun
710
+			4:00	1:00	GEST	1997 Mar lastSun
711
+			4:00 E-EurAsia	GE%sT	2004 Jun 27
712
+			3:00 RussiaAsia	GE%sT	2005 Mar lastSun 2:00
713
+			4:00	-	GET
714
+
715
+# East Timor
716
+
717
+# See Indonesia for the 1945 transition.
718
+
719
+# From Joao Carrascalao, brother of the former governor of East Timor, in
720
+# <a href="http://etan.org/et99c/december/26-31/30ETMAY.htm">
721
+# East Timor may be late for its millennium
722
+# </a> (1999-12-26/31):
723
+# Portugal tried to change the time forward in 1974 because the sun
724
+# rises too early but the suggestion raised a lot of problems with the
725
+# Timorese and I still don't think it would work today because it
726
+# conflicts with their way of life.
727
+
728
+# From Paul Eggert (2000-12-04):
729
+# We don't have any record of the above attempt.
730
+# Most likely our records are incomplete, but we have no better data.
731
+
732
+# <a href="http://www.hri.org/news/world/undh/last/00-08-16.undh.html">
733
+# From Manoel de Almeida e Silva, Deputy Spokesman for the UN Secretary-General
734
+# (2000-08-16)</a>:
735
+# The Cabinet of the East Timor Transition Administration decided
736
+# today to advance East Timor's time by one hour.  The time change,
737
+# which will be permanent, with no seasonal adjustment, will happen at
738
+# midnight on Saturday, September 16.
739
+
740
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
741
+Zone	Asia/Dili	8:22:20 -	LMT	1912
742
+			8:00	-	TLT	1942 Feb 21 23:00 # E Timor Time
743
+			9:00	-	JST	1945 Sep 23
744
+			9:00	-	TLT	1976 May  3
745
+			8:00	-	CIT	2000 Sep 17 00:00
746
+			9:00	-	TLT
747
+
748
+# India
749
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
750
+Zone	Asia/Kolkata	5:53:28 -	LMT	1880	# Kolkata
751
+			5:53:20	-	HMT	1941 Oct    # Howrah Mean Time?
752
+			6:30	-	BURT	1942 May 15 # Burma Time
753
+			5:30	-	IST	1942 Sep
754
+			5:30	1:00	IST	1945 Oct 15
755
+			5:30	-	IST
756
+# The following are like Asia/Kolkata:
757
+#	Andaman Is
758
+#	Lakshadweep (Laccadive, Minicoy and Amindivi Is)
759
+#	Nicobar Is
760
+
761
+# Indonesia
762
+#
763
+# From Gwillim Law (2001-05-28), overriding Shanks & Pottenger:
764
+# <http://www.sumatera-inc.com/go_to_invest/about_indonesia.asp#standtime>
765
+# says that Indonesia's time zones changed on 1988-01-01.  Looking at some
766
+# time zone maps, I think that must refer to Western Borneo (Kalimantan Barat
767
+# and Kalimantan Tengah) switching from UTC+8 to UTC+7.
768
+#
769
+# From Paul Eggert (2007-03-10):
770
+# Here is another correction to Shanks & Pottenger.
771
+# JohnTWB writes that Japanese forces did not surrender control in
772
+# Indonesia until 1945-09-01 00:00 at the earliest (in Jakarta) and
773
+# other formal surrender ceremonies were September 9, 11, and 13, plus
774
+# September 12 for the regional surrender to Mountbatten in Singapore.
775
+# These would be the earliest possible times for a change.
776
+# Regimes horaires pour le monde entier, by Henri Le Corre, (Editions
777
+# Traditionnelles, 1987, Paris) says that Java and Madura switched
778
+# from JST to UTC+07:30 on 1945-09-23, and gives 1944-09-01 for Jayapura
779
+# (Hollandia).  For now, assume all Indonesian locations other than Jayapura
780
+# switched on 1945-09-23.
781
+#
782
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
783
+Zone Asia/Jakarta	7:07:12 -	LMT	1867 Aug 10
784
+# Shanks & Pottenger say the next transition was at 1924 Jan 1 0:13,
785
+# but this must be a typo.
786
+			7:07:12	-	JMT	1923 Dec 31 23:47:12 # Jakarta
787
+			7:20	-	JAVT	1932 Nov	 # Java Time
788
+			7:30	-	WIT	1942 Mar 23
789
+			9:00	-	JST	1945 Sep 23
790
+			7:30	-	WIT	1948 May
791
+			8:00	-	WIT	1950 May
792
+			7:30	-	WIT	1964
793
+			7:00	-	WIT
794
+Zone Asia/Pontianak	7:17:20	-	LMT	1908 May
795
+			7:17:20	-	PMT	1932 Nov    # Pontianak MT
796
+			7:30	-	WIT	1942 Jan 29
797
+			9:00	-	JST	1945 Sep 23
798
+			7:30	-	WIT	1948 May
799
+			8:00	-	WIT	1950 May
800
+			7:30	-	WIT	1964
801
+			8:00	-	CIT	1988 Jan  1
802
+			7:00	-	WIT
803
+Zone Asia/Makassar	7:57:36 -	LMT	1920
804
+			7:57:36	-	MMT	1932 Nov    # Macassar MT
805
+			8:00	-	CIT	1942 Feb  9
806
+			9:00	-	JST	1945 Sep 23
807
+			8:00	-	CIT
808
+Zone Asia/Jayapura	9:22:48 -	LMT	1932 Nov
809
+			9:00	-	EIT	1944 Sep  1
810
+			9:30	-	CST	1964
811
+			9:00	-	EIT
812
+
813
+# Iran
814
+
815
+# From Roozbeh Pournader (2003-03-15):
816
+# This is an English translation of what I just found (originally in Persian).
817
+# The Gregorian dates in brackets are mine:
818
+#
819
+#	Official Newspaper No. 13548-1370/6/25 [1991-09-16]
820
+#	No. 16760/T233 H				1370/6/10 [1991-09-01]
821
+#
822
+#	The Rule About Change of the Official Time of the Country
823
+#
824
+#	The Board of Ministers, in the meeting dated 1370/5/23 [1991-08-14],
825
+#	based on the suggestion number 2221/D dated 1370/4/22 [1991-07-13]
826
+#	of the Country's Organization for Official and Employment Affairs,
827
+#	and referring to the law for equating the working hours of workers
828
+#	and officers in the whole country dated 1359/4/23 [1980-07-14], and
829
+#	for synchronizing the official times of the country, agreed that:
830
+#
831
+#	The official time of the country will should move forward one hour
832
+#	at the 24[:00] hours of the first day of Farvardin and should return
833
+#	to its previous state at the 24[:00] hours of the 30th day of
834
+#	Shahrivar.
835
+#
836
+#	First Deputy to the President - Hassan Habibi
837
+#
838
+# From personal experience, that agrees with what has been followed
839
+# for at least the last 5 years.  Before that, for a few years, the
840
+# date used was the first Thursday night of Farvardin and the last
841
+# Thursday night of Shahrivar, but I can't give exact dates....
842
+# I have also changed the abbreviations to what is considered correct
843
+# here in Iran, IRST for regular time and IRDT for daylight saving time.
844
+#
845
+# From Roozbeh Pournader (2005-04-05):
846
+# The text of the Iranian law, in effect since 1925, clearly mentions
847
+# that the true solar year is the measure, and there is no arithmetic
848
+# leap year calculation involved.  There has never been any serious
849
+# plan to change that law....
850
+#
851
+# From Paul Eggert (2006-03-22):
852
+# Go with Shanks & Pottenger before Sept. 1991, and with Pournader thereafter.
853
+# I used Ed Reingold's cal-persia in GNU Emacs 21.2 to check Persian dates,
854
+# stopping after 2037 when 32-bit time_t's overflow.
855
+# That cal-persia used Birashk's approximation, which disagrees with the solar
856
+# calendar predictions for the year 2025, so I corrected those dates by hand.
857
+#
858
+# From Oscar van Vlijmen (2005-03-30), writing about future
859
+# discrepancies between cal-persia and the Iranian calendar:
860
+# For 2091 solar-longitude-after yields 2091-03-20 08:40:07.7 UT for
861
+# the vernal equinox and that gets so close to 12:00 some local
862
+# Iranian time that the definition of the correct location needs to be
863
+# known exactly, amongst other factors.  2157 is even closer:
864
+# 2157-03-20 08:37:15.5 UT.  But the Gregorian year 2025 should give
865
+# no interpretation problem whatsoever.  By the way, another instant
866
+# in the near future where there will be a discrepancy between
867
+# arithmetical and astronomical Iranian calendars will be in 2058:
868
+# vernal equinox on 2058-03-20 09:03:05.9 UT.  The Java version of
869
+# Reingold's/Dershowitz' calculator gives correctly the Gregorian date
870
+# 2058-03-21 for 1 Farvardin 1437 (astronomical).
871
+#
872
+# From Steffen Thorsen (2006-03-22):
873
+# Several of my users have reported that Iran will not observe DST anymore:
874
+# http://www.irna.ir/en/news/view/line-17/0603193812164948.htm
875
+#
876
+# From Reuters (2007-09-16), with a heads-up from Jesper Norgaard Welen:
877
+# ... the Guardian Council ... approved a law on Sunday to re-introduce
878
+# daylight saving time ...
879
+# http://uk.reuters.com/article/oilRpt/idUKBLA65048420070916
880
+#
881
+# From Roozbeh Pournader (2007-11-05):
882
+# This is quoted from Official Gazette of the Islamic Republic of
883
+# Iran, Volume 63, Number 18242, dated Tuesday 1386/6/24
884
+# [2007-10-16]. I am doing the best translation I can:...
885
+# The official time of the country will be moved forward for one hour
886
+# on the 24 hours of the first day of the month of Farvardin and will
887
+# be changed back to its previous state on the 24 hours of the
888
+# thirtieth day of Shahrivar.
889
+#
890
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
891
+Rule	Iran	1978	1980	-	Mar	21	0:00	1:00	D
892
+Rule	Iran	1978	only	-	Oct	21	0:00	0	S
893
+Rule	Iran	1979	only	-	Sep	19	0:00	0	S
894
+Rule	Iran	1980	only	-	Sep	23	0:00	0	S
895
+Rule	Iran	1991	only	-	May	 3	0:00	1:00	D
896
+Rule	Iran	1992	1995	-	Mar	22	0:00	1:00	D
897
+Rule	Iran	1991	1995	-	Sep	22	0:00	0	S
898
+Rule	Iran	1996	only	-	Mar	21	0:00	1:00	D
899
+Rule	Iran	1996	only	-	Sep	21	0:00	0	S
900
+Rule	Iran	1997	1999	-	Mar	22	0:00	1:00	D
901
+Rule	Iran	1997	1999	-	Sep	22	0:00	0	S
902
+Rule	Iran	2000	only	-	Mar	21	0:00	1:00	D
903
+Rule	Iran	2000	only	-	Sep	21	0:00	0	S
904
+Rule	Iran	2001	2003	-	Mar	22	0:00	1:00	D
905
+Rule	Iran	2001	2003	-	Sep	22	0:00	0	S
906
+Rule	Iran	2004	only	-	Mar	21	0:00	1:00	D
907
+Rule	Iran	2004	only	-	Sep	21	0:00	0	S
908
+Rule	Iran	2005	only	-	Mar	22	0:00	1:00	D
909
+Rule	Iran	2005	only	-	Sep	22	0:00	0	S
910
+Rule	Iran	2008	only	-	Mar	21	0:00	1:00	D
911
+Rule	Iran	2008	only	-	Sep	21	0:00	0	S
912
+Rule	Iran	2009	2011	-	Mar	22	0:00	1:00	D
913
+Rule	Iran	2009	2011	-	Sep	22	0:00	0	S
914
+Rule	Iran	2012	only	-	Mar	21	0:00	1:00	D
915
+Rule	Iran	2012	only	-	Sep	21	0:00	0	S
916
+Rule	Iran	2013	2015	-	Mar	22	0:00	1:00	D
917
+Rule	Iran	2013	2015	-	Sep	22	0:00	0	S
918
+Rule	Iran	2016	only	-	Mar	21	0:00	1:00	D
919
+Rule	Iran	2016	only	-	Sep	21	0:00	0	S
920
+Rule	Iran	2017	2019	-	Mar	22	0:00	1:00	D
921
+Rule	Iran	2017	2019	-	Sep	22	0:00	0	S
922
+Rule	Iran	2020	only	-	Mar	21	0:00	1:00	D
923
+Rule	Iran	2020	only	-	Sep	21	0:00	0	S
924
+Rule	Iran	2021	2023	-	Mar	22	0:00	1:00	D
925
+Rule	Iran	2021	2023	-	Sep	22	0:00	0	S
926
+Rule	Iran	2024	only	-	Mar	21	0:00	1:00	D
927
+Rule	Iran	2024	only	-	Sep	21	0:00	0	S
928
+Rule	Iran	2025	2027	-	Mar	22	0:00	1:00	D
929
+Rule	Iran	2025	2027	-	Sep	22	0:00	0	S
930
+Rule	Iran	2028	2029	-	Mar	21	0:00	1:00	D
931
+Rule	Iran	2028	2029	-	Sep	21	0:00	0	S
932
+Rule	Iran	2030	2031	-	Mar	22	0:00	1:00	D
933
+Rule	Iran	2030	2031	-	Sep	22	0:00	0	S
934
+Rule	Iran	2032	2033	-	Mar	21	0:00	1:00	D
935
+Rule	Iran	2032	2033	-	Sep	21	0:00	0	S
936
+Rule	Iran	2034	2035	-	Mar	22	0:00	1:00	D
937
+Rule	Iran	2034	2035	-	Sep	22	0:00	0	S
938
+Rule	Iran	2036	2037	-	Mar	21	0:00	1:00	D
939
+Rule	Iran	2036	2037	-	Sep	21	0:00	0	S
940
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
941
+Zone	Asia/Tehran	3:25:44	-	LMT	1916
942
+			3:25:44	-	TMT	1946	# Tehran Mean Time
943
+			3:30	-	IRST	1977 Nov
944
+			4:00	Iran	IR%sT	1979
945
+			3:30	Iran	IR%sT
946
+
947
+
948
+# Iraq
949
+#
950
+# From Jonathan Lennox (2000-06-12):
951
+# An article in this week's Economist ("Inside the Saddam-free zone", p. 50 in
952
+# the U.S. edition) on the Iraqi Kurds contains a paragraph:
953
+# "The three northern provinces ... switched their clocks this spring and
954
+# are an hour ahead of Baghdad."
955
+#
956
+# But Rives McDow (2000-06-18) quotes a contact in Iraqi-Kurdistan as follows:
957
+# In the past, some Kurdish nationalists, as a protest to the Iraqi
958
+# Government, did not adhere to daylight saving time.  They referred
959
+# to daylight saving as Saddam time.  But, as of today, the time zone
960
+# in Iraqi-Kurdistan is on standard time with Baghdad, Iraq.
961
+#
962
+# So we'll ignore the Economist's claim.
963
+
964
+# From Steffen Thorsen (2008-03-10):
965
+# The cabinet in Iraq abolished DST last week, according to the following
966
+# news sources (in Arabic):
967
+# <a href="http://www.aljeeran.net/wesima_articles/news-20080305-98602.html">
968
+# http://www.aljeeran.net/wesima_articles/news-20080305-98602.html
969
+# </a>
970
+# <a href="http://www.aswataliraq.info/look/article.tpl?id=2047&IdLanguage=17&IdPublication=4&NrArticle=71743&NrIssue=1&NrSection=10">
971
+# http://www.aswataliraq.info/look/article.tpl?id=2047&IdLanguage=17&IdPublication=4&NrArticle=71743&NrIssue=1&NrSection=10
972
+# </a>
973
+#
974
+# We have published a short article in English about the change:
975
+# <a href="http://www.timeanddate.com/news/time/iraq-dumps-daylight-saving.html">
976
+# http://www.timeanddate.com/news/time/iraq-dumps-daylight-saving.html
977
+# </a>
978
+
979
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
980
+Rule	Iraq	1982	only	-	May	1	0:00	1:00	D
981
+Rule	Iraq	1982	1984	-	Oct	1	0:00	0	S
982
+Rule	Iraq	1983	only	-	Mar	31	0:00	1:00	D
983
+Rule	Iraq	1984	1985	-	Apr	1	0:00	1:00	D
984
+Rule	Iraq	1985	1990	-	Sep	lastSun	1:00s	0	S
985
+Rule	Iraq	1986	1990	-	Mar	lastSun	1:00s	1:00	D
986
+# IATA SSIM (1991/1996) says Apr 1 12:01am UTC; guess the `:01' is a typo.
987
+# Shanks & Pottenger say Iraq did not observe DST 1992/1997; ignore this.
988
+#
989
+Rule	Iraq	1991	2007	-	Apr	 1	3:00s	1:00	D
990
+Rule	Iraq	1991	2007	-	Oct	 1	3:00s	0	S
991
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
992
+Zone	Asia/Baghdad	2:57:40	-	LMT	1890
993
+			2:57:36	-	BMT	1918	    # Baghdad Mean Time?
994
+			3:00	-	AST	1982 May
995
+			3:00	Iraq	A%sT
996
+
997
+
998
+###############################################################################
999
+
1000
+# Israel
1001
+
1002
+# From Ephraim Silverberg (2001-01-11):
1003
+#
1004
+# I coined "IST/IDT" circa 1988.  Until then there were three
1005
+# different abbreviations in use:
1006
+#
1007
+# JST  Jerusalem Standard Time [Danny Braniss, Hebrew University]
1008
+# IZT  Israel Zonal (sic) Time [Prof. Haim Papo, Technion]
1009
+# EEST Eastern Europe Standard Time [used by almost everyone else]
1010
+#
1011
+# Since timezones should be called by country and not capital cities,
1012
+# I ruled out JST.  As Israel is in Asia Minor and not Eastern Europe,
1013
+# EEST was equally unacceptable.  Since "zonal" was not compatible with
1014
+# any other timezone abbreviation, I felt that 'IST' was the way to go
1015
+# and, indeed, it has received almost universal acceptance in timezone
1016
+# settings in Israeli computers.
1017
+#
1018
+# In any case, I am happy to share timezone abbreviations with India,
1019
+# high on my favorite-country list (and not only because my wife's
1020
+# family is from India).
1021
+
1022
+# From Shanks & Pottenger:
1023
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1024
+Rule	Zion	1940	only	-	Jun	 1	0:00	1:00	D
1025
+Rule	Zion	1942	1944	-	Nov	 1	0:00	0	S
1026
+Rule	Zion	1943	only	-	Apr	 1	2:00	1:00	D
1027
+Rule	Zion	1944	only	-	Apr	 1	0:00	1:00	D
1028
+Rule	Zion	1945	only	-	Apr	16	0:00	1:00	D
1029
+Rule	Zion	1945	only	-	Nov	 1	2:00	0	S
1030
+Rule	Zion	1946	only	-	Apr	16	2:00	1:00	D
1031
+Rule	Zion	1946	only	-	Nov	 1	0:00	0	S
1032
+Rule	Zion	1948	only	-	May	23	0:00	2:00	DD
1033
+Rule	Zion	1948	only	-	Sep	 1	0:00	1:00	D
1034
+Rule	Zion	1948	1949	-	Nov	 1	2:00	0	S
1035
+Rule	Zion	1949	only	-	May	 1	0:00	1:00	D
1036
+Rule	Zion	1950	only	-	Apr	16	0:00	1:00	D
1037
+Rule	Zion	1950	only	-	Sep	15	3:00	0	S
1038
+Rule	Zion	1951	only	-	Apr	 1	0:00	1:00	D
1039
+Rule	Zion	1951	only	-	Nov	11	3:00	0	S
1040
+Rule	Zion	1952	only	-	Apr	20	2:00	1:00	D
1041
+Rule	Zion	1952	only	-	Oct	19	3:00	0	S
1042
+Rule	Zion	1953	only	-	Apr	12	2:00	1:00	D
1043
+Rule	Zion	1953	only	-	Sep	13	3:00	0	S
1044
+Rule	Zion	1954	only	-	Jun	13	0:00	1:00	D
1045
+Rule	Zion	1954	only	-	Sep	12	0:00	0	S
1046
+Rule	Zion	1955	only	-	Jun	11	2:00	1:00	D
1047
+Rule	Zion	1955	only	-	Sep	11	0:00	0	S
1048
+Rule	Zion	1956	only	-	Jun	 3	0:00	1:00	D
1049
+Rule	Zion	1956	only	-	Sep	30	3:00	0	S
1050
+Rule	Zion	1957	only	-	Apr	29	2:00	1:00	D
1051
+Rule	Zion	1957	only	-	Sep	22	0:00	0	S
1052
+Rule	Zion	1974	only	-	Jul	 7	0:00	1:00	D
1053
+Rule	Zion	1974	only	-	Oct	13	0:00	0	S
1054
+Rule	Zion	1975	only	-	Apr	20	0:00	1:00	D
1055
+Rule	Zion	1975	only	-	Aug	31	0:00	0	S
1056
+Rule	Zion	1985	only	-	Apr	14	0:00	1:00	D
1057
+Rule	Zion	1985	only	-	Sep	15	0:00	0	S
1058
+Rule	Zion	1986	only	-	May	18	0:00	1:00	D
1059
+Rule	Zion	1986	only	-	Sep	 7	0:00	0	S
1060
+Rule	Zion	1987	only	-	Apr	15	0:00	1:00	D
1061
+Rule	Zion	1987	only	-	Sep	13	0:00	0	S
1062
+Rule	Zion	1988	only	-	Apr	 9	0:00	1:00	D
1063
+Rule	Zion	1988	only	-	Sep	 3	0:00	0	S
1064
+
1065
+# From Ephraim Silverberg
1066
+# (1997-03-04, 1998-03-16, 1998-12-28, 2000-01-17, 2000-07-25, 2004-12-22,
1067
+# and 2005-02-17):
1068
+
1069
+# According to the Office of the Secretary General of the Ministry of
1070
+# Interior, there is NO set rule for Daylight-Savings/Standard time changes.
1071
+# One thing is entrenched in law, however: that there must be at least 150
1072
+# days of daylight savings time annually.  From 1993-1998, the change to
1073
+# daylight savings time was on a Friday morning from midnight IST to
1074
+# 1 a.m IDT; up until 1998, the change back to standard time was on a
1075
+# Saturday night from midnight daylight savings time to 11 p.m. standard
1076
+# time.  1996 is an exception to this rule where the change back to standard
1077
+# time took place on Sunday night instead of Saturday night to avoid
1078
+# conflicts with the Jewish New Year.  In 1999, the change to
1079
+# daylight savings time was still on a Friday morning but from
1080
+# 2 a.m. IST to 3 a.m. IDT; furthermore, the change back to standard time
1081
+# was also on a Friday morning from 2 a.m. IDT to 1 a.m. IST for
1082
+# 1999 only.  In the year 2000, the change to daylight savings time was
1083
+# similar to 1999, but although the change back will be on a Friday, it
1084
+# will take place from 1 a.m. IDT to midnight IST.  Starting in 2001, all
1085
+# changes to/from will take place at 1 a.m. old time, but now there is no
1086
+# rule as to what day of the week it will take place in as the start date
1087
+# (except in 2003) is the night after the Passover Seder (i.e. the eve
1088
+# of the 16th of Nisan in the lunar Hebrew calendar) and the end date
1089
+# (except in 2002) is three nights before Yom Kippur [Day of Atonement]
1090
+# (the eve of the 7th of Tishrei in the lunar Hebrew calendar).
1091
+
1092
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1093
+Rule	Zion	1989	only	-	Apr	30	0:00	1:00	D
1094
+Rule	Zion	1989	only	-	Sep	 3	0:00	0	S
1095
+Rule	Zion	1990	only	-	Mar	25	0:00	1:00	D
1096
+Rule	Zion	1990	only	-	Aug	26	0:00	0	S
1097
+Rule	Zion	1991	only	-	Mar	24	0:00	1:00	D
1098
+Rule	Zion	1991	only	-	Sep	 1	0:00	0	S
1099
+Rule	Zion	1992	only	-	Mar	29	0:00	1:00	D
1100
+Rule	Zion	1992	only	-	Sep	 6	0:00	0	S
1101
+Rule	Zion	1993	only	-	Apr	 2	0:00	1:00	D
1102
+Rule	Zion	1993	only	-	Sep	 5	0:00	0	S
1103
+
1104
+# The dates for 1994-1995 were obtained from Office of the Spokeswoman for the
1105
+# Ministry of Interior, Jerusalem, Israel.  The spokeswoman can be reached by
1106
+# calling the office directly at 972-2-6701447 or 972-2-6701448.
1107
+
1108
+# Rule	NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
1109
+Rule	Zion	1994	only	-	Apr	 1	0:00	1:00	D
1110
+Rule	Zion	1994	only	-	Aug	28	0:00	0	S
1111
+Rule	Zion	1995	only	-	Mar	31	0:00	1:00	D
1112
+Rule	Zion	1995	only	-	Sep	 3	0:00	0	S
1113
+
1114
+# The dates for 1996 were determined by the Minister of Interior of the
1115
+# time, Haim Ramon.  The official announcement regarding 1996-1998
1116
+# (with the dates for 1997-1998 no longer being relevant) can be viewed at:
1117
+#
1118
+#   ftp://ftp.cs.huji.ac.il/pub/tz/announcements/1996-1998.ramon.ps.gz
1119
+#
1120
+# The dates for 1997-1998 were altered by his successor, Rabbi Eli Suissa.
1121
+#
1122
+# The official announcements for the years 1997-1999 can be viewed at:
1123
+#
1124
+#   ftp://ftp.cs.huji.ac.il/pub/tz/announcements/YYYY.ps.gz
1125
+#
1126
+#       where YYYY is the relevant year.
1127
+
1128
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1129
+Rule	Zion	1996	only	-	Mar	15	0:00	1:00	D
1130
+Rule	Zion	1996	only	-	Sep	16	0:00	0	S
1131
+Rule	Zion	1997	only	-	Mar	21	0:00	1:00	D
1132
+Rule	Zion	1997	only	-	Sep	14	0:00	0	S
1133
+Rule	Zion	1998	only	-	Mar	20	0:00	1:00	D
1134
+Rule	Zion	1998	only	-	Sep	 6	0:00	0	S
1135
+Rule	Zion	1999	only	-	Apr	 2	2:00	1:00	D
1136
+Rule	Zion	1999	only	-	Sep	 3	2:00	0	S
1137
+
1138
+# The Knesset Interior Committee has changed the dates for 2000 for
1139
+# the third time in just over a year and have set new dates for the
1140
+# years 2001-2004 as well.
1141
+#
1142
+# The official announcement for the start date of 2000 can be viewed at:
1143
+#
1144
+#	ftp://ftp.cs.huji.ac.il/pub/tz/announcements/2000-start.ps.gz
1145
+#
1146
+# The official announcement for the end date of 2000 and the dates
1147
+# for the years 2001-2004 can be viewed at:
1148
+#
1149
+#	ftp://ftp.cs.huji.ac.il/pub/tz/announcements/2000-2004.ps.gz
1150
+
1151
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1152
+Rule	Zion	2000	only	-	Apr	14	2:00	1:00	D
1153
+Rule	Zion	2000	only	-	Oct	 6	1:00	0	S
1154
+Rule	Zion	2001	only	-	Apr	 9	1:00	1:00	D
1155
+Rule	Zion	2001	only	-	Sep	24	1:00	0	S
1156
+Rule	Zion	2002	only	-	Mar	29	1:00	1:00	D
1157
+Rule	Zion	2002	only	-	Oct	 7	1:00	0	S
1158
+Rule	Zion	2003	only	-	Mar	28	1:00	1:00	D
1159
+Rule	Zion	2003	only	-	Oct	 3	1:00	0	S
1160
+Rule	Zion	2004	only	-	Apr	 7	1:00	1:00	D
1161
+Rule	Zion	2004	only	-	Sep	22	1:00	0	S
1162
+
1163
+# The proposed law agreed upon by the Knesset Interior Committee on
1164
+# 2005-02-14 is that, for 2005 and beyond, DST starts at 02:00 the
1165
+# last Friday before April 2nd (i.e. the last Friday in March or April
1166
+# 1st itself if it falls on a Friday) and ends at 02:00 on the Saturday
1167
+# night _before_ the fast of Yom Kippur.
1168
+#
1169
+# Those who can read Hebrew can view the announcement at:
1170
+#
1171
+#	ftp://ftp.cs.huji.ac.il/pub/tz/announcements/2005+beyond.ps
1172
+
1173
+# From Paul Eggert (2012-10-26):
1174
+# I used Ephraim Silverberg's dst-israel.el program
1175
+# <ftp://ftp.cs.huji.ac.il/pub/tz/software/dst-israel.el> (2005-02-20)
1176
+# along with Ed Reingold's cal-hebrew in GNU Emacs 21.4,
1177
+# to generate the transitions from 2005 through 2012.
1178
+# (I replaced "lastFri" with "Fri>=26" by hand.)
1179
+# The spring transitions all correspond to the following Rule:
1180
+#
1181
+# Rule	Zion	2005	2012	-	Mar	Fri>=26	2:00	1:00	D
1182
+#
1183
+# but older zic implementations (e.g., Solaris 8) do not support
1184
+# "Fri>=26" to mean April 1 in years like 2005, so for now we list the
1185
+# springtime transitions explicitly.
1186
+
1187
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1188
+Rule	Zion	2005	only	-	Apr	 1	2:00	1:00	D
1189
+Rule	Zion	2005	only	-	Oct	 9	2:00	0	S
1190
+Rule	Zion	2006	2010	-	Mar	Fri>=26	2:00	1:00	D
1191
+Rule	Zion	2006	only	-	Oct	 1	2:00	0	S
1192
+Rule	Zion	2007	only	-	Sep	16	2:00	0	S
1193
+Rule	Zion	2008	only	-	Oct	 5	2:00	0	S
1194
+Rule	Zion	2009	only	-	Sep	27	2:00	0	S
1195
+Rule	Zion	2010	only	-	Sep	12	2:00	0	S
1196
+Rule	Zion	2011	only	-	Apr	 1	2:00	1:00	D
1197
+Rule	Zion	2011	only	-	Oct	 2	2:00	0	S
1198
+Rule	Zion	2012	only	-	Mar	Fri>=26	2:00	1:00	D
1199
+Rule	Zion	2012	only	-	Sep	23	2:00	0	S
1200
+
1201
+# From Ephraim Silverberg (2012-10-18):
1202
+# Yesterday, the Interior Ministry Committee, after more than a year
1203
+# past, approved sending the proposed June 2011 changes to the Time
1204
+# Decree Law back to the Knesset for second and third (final) votes
1205
+# before the upcoming elections on Jan. 22, 2013.  Hence, although the
1206
+# changes are not yet law, they are expected to be so before February 2013.
1207
+#
1208
+# As of 2013, DST starts at 02:00 on the Friday before the last Sunday in March.
1209
+# DST ends at 02:00 on the first Sunday after October 1, unless it occurs on the
1210
+# second day of the Jewish Rosh Hashana holiday, in which case DST ends a day
1211
+# later (i.e. at 02:00 the first Monday after October 2).
1212
+# [Rosh Hashana holidays are factored in until 2100.]
1213
+
1214
+# From Ephraim Silverberg (2012-11-05):
1215
+# The Knesset passed today (in second and final readings) the amendment to the
1216
+# Time Decree Law making the changes ... law.
1217
+
1218
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1219
+Rule	Zion	2013	max	-	Mar	Fri>=23	2:00	1:00	D
1220
+Rule	Zion	2013	2026	-	Oct	Sun>=2	2:00	0	S
1221
+Rule	Zion	2027	only	-	Oct	Mon>=3	2:00	0	S
1222
+Rule	Zion	2028	max	-	Oct	Sun>=2	2:00	0	S
1223
+# The following rules are commented out for now, as they break older
1224
+# versions of zic that support only signed 32-bit timestamps, i.e.,
1225
+# through 2038-01-19 03:14:07 UTC.
1226
+#Rule	Zion	2028	2053	-	Oct	Sun>=2	2:00	0	S
1227
+#Rule	Zion	2054	only	-	Oct	Mon>=3	2:00	0	S
1228
+#Rule	Zion	2055	2080	-	Oct	Sun>=2	2:00	0	S
1229
+#Rule	Zion	2081	only	-	Oct	Mon>=3	2:00	0	S
1230
+#Rule	Zion	2082	max	-	Oct	Sun>=2	2:00	0	S
1231
+
1232
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1233
+Zone	Asia/Jerusalem	2:20:56 -	LMT	1880
1234
+			2:20:40	-	JMT	1918	# Jerusalem Mean Time?
1235
+			2:00	Zion	I%sT
1236
+
1237
+
1238
+
1239
+###############################################################################
1240
+
1241
+# Japan
1242
+
1243
+# `9:00' and `JST' is from Guy Harris.
1244
+
1245
+# From Paul Eggert (1995-03-06):
1246
+# Today's _Asahi Evening News_ (page 4) reports that Japan had
1247
+# daylight saving between 1948 and 1951, but ``the system was discontinued
1248
+# because the public believed it would lead to longer working hours.''
1249
+
1250
+# From Mayumi Negishi in the 2005-08-10 Japan Times
1251
+# <http://www.japantimes.co.jp/cgi-bin/getarticle.pl5?nn20050810f2.htm>:
1252
+# Occupation authorities imposed daylight-saving time on Japan on
1253
+# [1948-05-01]....  But lack of prior debate and the execution of
1254
+# daylight-saving time just three days after the bill was passed generated
1255
+# deep hatred of the concept....  The Diet unceremoniously passed a bill to
1256
+# dump the unpopular system in October 1951, less than a month after the San
1257
+# Francisco Peace Treaty was signed.  (A government poll in 1951 showed 53%
1258
+# of the Japanese wanted to scrap daylight-saving time, as opposed to 30% who
1259
+# wanted to keep it.)
1260
+
1261
+# From Paul Eggert (2006-03-22):
1262
+# Shanks & Pottenger write that DST in Japan during those years was as follows:
1263
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1264
+Rule	Japan	1948	only	-	May	Sun>=1	2:00	1:00	D
1265
+Rule	Japan	1948	1951	-	Sep	Sat>=8	2:00	0	S
1266
+Rule	Japan	1949	only	-	Apr	Sun>=1	2:00	1:00	D
1267
+Rule	Japan	1950	1951	-	May	Sun>=1	2:00	1:00	D
1268
+# but the only locations using it (for birth certificates, presumably, since
1269
+# their audience is astrologers) were US military bases.  For now, assume
1270
+# that for most purposes daylight-saving time was observed; otherwise, what
1271
+# would have been the point of the 1951 poll?
1272
+
1273
+# From Hideyuki Suzuki (1998-11-09):
1274
+# 'Tokyo' usually stands for the former location of Tokyo Astronomical
1275
+# Observatory: E 139 44' 40".90 (9h 18m 58s.727), N 35 39' 16".0.
1276
+# This data is from 'Rika Nenpyou (Chronological Scientific Tables) 1996'
1277
+# edited by National Astronomical Observatory of Japan....
1278
+# JST (Japan Standard Time) has been used since 1888-01-01 00:00 (JST).
1279
+# The law is enacted on 1886-07-07.
1280
+
1281
+# From Hideyuki Suzuki (1998-11-16):
1282
+# The ordinance No. 51 (1886) established "standard time" in Japan,
1283
+# which stands for the time on E 135 degree.
1284
+# In the ordinance No. 167 (1895), "standard time" was renamed to "central
1285
+# standard time".  And the same ordinance also established "western standard
1286
+# time", which stands for the time on E 120 degree....  But "western standard
1287
+# time" was abolished in the ordinance No. 529 (1937).  In the ordinance No.
1288
+# 167, there is no mention regarding for what place western standard time is
1289
+# standard....
1290
+#
1291
+# I wrote "ordinance" above, but I don't know how to translate.
1292
+# In Japanese it's "chokurei", which means ordinance from emperor.
1293
+
1294
+# Shanks & Pottenger claim JST in use since 1896, and that a few
1295
+# places (e.g. Ishigaki) use +0800; go with Suzuki.  Guess that all
1296
+# ordinances took effect on Jan 1.
1297
+
1298
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1299
+Zone	Asia/Tokyo	9:18:59	-	LMT	1887 Dec 31 15:00u
1300
+			9:00	-	JST	1896
1301
+			9:00	-	CJT	1938
1302
+			9:00	Japan	J%sT
1303
+# Since 1938, all Japanese possessions have been like Asia/Tokyo.
1304
+
1305
+# Jordan
1306
+#
1307
+# From <a href="http://star.arabia.com/990701/JO9.html">
1308
+# Jordan Week (1999-07-01) </a> via Steffen Thorsen (1999-09-09):
1309
+# Clocks in Jordan were forwarded one hour on Wednesday at midnight,
1310
+# in accordance with the government's decision to implement summer time
1311
+# all year round.
1312
+#
1313
+# From <a href="http://star.arabia.com/990930/JO9.html">
1314
+# Jordan Week (1999-09-30) </a> via Steffen Thorsen (1999-11-09):
1315
+# Winter time starts today Thursday, 30 September. Clocks will be turned back
1316
+# by one hour.  This is the latest government decision and it's final!
1317
+# The decision was taken because of the increase in working hours in
1318
+# government's departments from six to seven hours.
1319
+#
1320
+# From Paul Eggert (2005-11-22):
1321
+# Starting 2003 transitions are from Steffen Thorsen's web site timeanddate.com.
1322
+#
1323
+# From Steffen Thorsen (2005-11-23):
1324
+# For Jordan I have received multiple independent user reports every year
1325
+# about DST end dates, as the end-rule is different every year.
1326
+#
1327
+# From Steffen Thorsen (2006-10-01), after a heads-up from Hilal Malawi:
1328
+# http://www.petranews.gov.jo/nepras/2006/Sep/05/4000.htm
1329
+# "Jordan will switch to winter time on Friday, October 27".
1330
+#
1331
+
1332
+# From Phil Pizzey (2009-04-02):
1333
+# ...I think I may have spotted an error in the timezone data for
1334
+# Jordan.
1335
+# The current (2009d) asia file shows Jordan going to daylight
1336
+# saving
1337
+# time on the last Thursday in March.
1338
+#
1339
+# Rule  Jordan      2000  max	-  Mar   lastThu     0:00s 1:00  S
1340
+#
1341
+# However timeanddate.com, which I usually find reliable, shows Jordan
1342
+# going to daylight saving time on the last Friday in March since 2002.
1343
+# Please see
1344
+# <a href="http://www.timeanddate.com/worldclock/timezone.html?n=11">
1345
+# http://www.timeanddate.com/worldclock/timezone.html?n=11
1346
+# </a>
1347
+
1348
+# From Steffen Thorsen (2009-04-02):
1349
+# This single one might be good enough, (2009-03-24, Arabic):
1350
+# <a href="http://petra.gov.jo/Artical.aspx?Lng=2&Section=8&Artical=95279">
1351
+# http://petra.gov.jo/Artical.aspx?Lng=2&Section=8&Artical=95279
1352
+# </a>
1353
+#
1354
+# Google's translation:
1355
+#
1356
+# > The Council of Ministers decided in 2002 to adopt the principle of timely
1357
+# > submission of the summer at 60 minutes as of midnight on the last Thursday
1358
+# > of the month of March of each year.
1359
+#
1360
+# So - this means the midnight between Thursday and Friday since 2002.
1361
+
1362
+# From Arthur David Olson (2009-04-06):
1363
+# We still have Jordan switching to DST on Thursdays in 2000 and 2001.
1364
+
1365
+# From Steffen Thorsen (2012-10-25):
1366
+# Yesterday the government in Jordan announced that they will not
1367
+# switch back to standard time this winter, so the will stay on DST
1368
+# until about the same time next year (at least).
1369
+# http://www.petra.gov.jo/Public_News/Nws_NewsDetails.aspx?NewsID=88950
1370
+#
1371
+# From Paul Eggert (2012-10-25):
1372
+# For now, assume this is just a one-year measure.  If it becomes
1373
+# permanent, we should move Jordan from EET to AST effective tomorrow.
1374
+
1375
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1376
+Rule	Jordan	1973	only	-	Jun	6	0:00	1:00	S
1377
+Rule	Jordan	1973	1975	-	Oct	1	0:00	0	-
1378
+Rule	Jordan	1974	1977	-	May	1	0:00	1:00	S
1379
+Rule	Jordan	1976	only	-	Nov	1	0:00	0	-
1380
+Rule	Jordan	1977	only	-	Oct	1	0:00	0	-
1381
+Rule	Jordan	1978	only	-	Apr	30	0:00	1:00	S
1382
+Rule	Jordan	1978	only	-	Sep	30	0:00	0	-
1383
+Rule	Jordan	1985	only	-	Apr	1	0:00	1:00	S
1384
+Rule	Jordan	1985	only	-	Oct	1	0:00	0	-
1385
+Rule	Jordan	1986	1988	-	Apr	Fri>=1	0:00	1:00	S
1386
+Rule	Jordan	1986	1990	-	Oct	Fri>=1	0:00	0	-
1387
+Rule	Jordan	1989	only	-	May	8	0:00	1:00	S
1388
+Rule	Jordan	1990	only	-	Apr	27	0:00	1:00	S
1389
+Rule	Jordan	1991	only	-	Apr	17	0:00	1:00	S
1390
+Rule	Jordan	1991	only	-	Sep	27	0:00	0	-
1391
+Rule	Jordan	1992	only	-	Apr	10	0:00	1:00	S
1392
+Rule	Jordan	1992	1993	-	Oct	Fri>=1	0:00	0	-
1393
+Rule	Jordan	1993	1998	-	Apr	Fri>=1	0:00	1:00	S
1394
+Rule	Jordan	1994	only	-	Sep	Fri>=15	0:00	0	-
1395
+Rule	Jordan	1995	1998	-	Sep	Fri>=15	0:00s	0	-
1396
+Rule	Jordan	1999	only	-	Jul	 1	0:00s	1:00	S
1397
+Rule	Jordan	1999	2002	-	Sep	lastFri	0:00s	0	-
1398
+Rule	Jordan	2000	2001	-	Mar	lastThu	0:00s	1:00	S
1399
+Rule	Jordan	2002	max	-	Mar	lastThu	24:00	1:00	S
1400
+Rule	Jordan	2003	only	-	Oct	24	0:00s	0	-
1401
+Rule	Jordan	2004	only	-	Oct	15	0:00s	0	-
1402
+Rule	Jordan	2005	only	-	Sep	lastFri	0:00s	0	-
1403
+Rule	Jordan	2006	2011	-	Oct	lastFri	0:00s	0	-
1404
+Rule	Jordan	2013	max	-	Oct	lastFri	0:00s	0	-
1405
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1406
+Zone	Asia/Amman	2:23:44 -	LMT	1931
1407
+			2:00	Jordan	EE%sT
1408
+
1409
+
1410
+# Kazakhstan
1411
+
1412
+# From Paul Eggert (1996-11-22):
1413
+# Andrew Evtichov (1996-04-13) writes that Kazakhstan
1414
+# stayed in sync with Moscow after 1990, and that Aqtobe (formerly Aktyubinsk)
1415
+# and Aqtau (formerly Shevchenko) are the largest cities in their zones.
1416
+# Guess that Aqtau and Aqtobe diverged in 1995, since that's the first time
1417
+# IATA SSIM mentions a third time zone in Kazakhstan.
1418
+
1419
+# From Paul Eggert (2006-03-22):
1420
+# German Iofis, ELSI, Almaty (2001-10-09) reports that Kazakhstan uses
1421
+# RussiaAsia rules, instead of switching at 00:00 as the IATA has it.
1422
+# Go with Shanks & Pottenger, who have them always using RussiaAsia rules.
1423
+# Also go with the following claims of Shanks & Pottenger:
1424
+#
1425
+# - Kazakhstan did not observe DST in 1991.
1426
+# - Qyzylorda switched from +5:00 to +6:00 on 1992-01-19 02:00.
1427
+# - Oral switched from +5:00 to +4:00 in spring 1989.
1428
+
1429
+# <a href="http://www.kazsociety.org.uk/news/2005/03/30.htm">
1430
+# From Kazakhstan Embassy's News Bulletin #11 (2005-03-21):
1431
+# </a>
1432
+# The Government of Kazakhstan passed a resolution March 15 abolishing
1433
+# daylight saving time citing lack of economic benefits and health
1434
+# complications coupled with a decrease in productivity.
1435
+#
1436
+# From Branislav Kojic (in Astana) via Gwillim Law (2005-06-28):
1437
+# ... what happened was that the former Kazakhstan Eastern time zone
1438
+# was "blended" with the Central zone.  Therefore, Kazakhstan now has
1439
+# two time zones, and difference between them is one hour.  The zone
1440
+# closer to UTC is the former Western zone (probably still called the
1441
+# same), encompassing four provinces in the west: Aqtobe, Atyrau,
1442
+# Mangghystau, and West Kazakhstan.  The other zone encompasses
1443
+# everything else....  I guess that would make Kazakhstan time zones
1444
+# de jure UTC+5 and UTC+6 respectively.
1445
+
1446
+#
1447
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1448
+#
1449
+# Almaty (formerly Alma-Ata), representing most locations in Kazakhstan
1450
+Zone	Asia/Almaty	5:07:48 -	LMT	1924 May  2 # or Alma-Ata
1451
+			5:00	-	ALMT	1930 Jun 21 # Alma-Ata Time
1452
+			6:00 RussiaAsia ALM%sT	1991
1453
+			6:00	-	ALMT	1992
1454
+			6:00 RussiaAsia	ALM%sT	2005 Mar 15
1455
+			6:00	-	ALMT
1456
+# Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.)
1457
+Zone	Asia/Qyzylorda	4:21:52 -	LMT	1924 May  2
1458
+			4:00	-	KIZT	1930 Jun 21 # Kizilorda Time
1459
+			5:00	-	KIZT	1981 Apr  1
1460
+			5:00	1:00	KIZST	1981 Oct  1
1461
+			6:00	-	KIZT	1982 Apr  1
1462
+			5:00 RussiaAsia	KIZ%sT	1991
1463
+			5:00	-	KIZT	1991 Dec 16 # independence
1464
+			5:00	-	QYZT	1992 Jan 19 2:00
1465
+			6:00 RussiaAsia	QYZ%sT	2005 Mar 15
1466
+			6:00	-	QYZT
1467
+# Aqtobe (aka Aktobe, formerly Akt'ubinsk)
1468
+Zone	Asia/Aqtobe	3:48:40	-	LMT	1924 May  2
1469
+			4:00	-	AKTT	1930 Jun 21 # Aktyubinsk Time
1470
+			5:00	-	AKTT	1981 Apr  1
1471
+			5:00	1:00	AKTST	1981 Oct  1
1472
+			6:00	-	AKTT	1982 Apr  1
1473
+			5:00 RussiaAsia	AKT%sT	1991
1474
+			5:00	-	AKTT	1991 Dec 16 # independence
1475
+			5:00 RussiaAsia	AQT%sT	2005 Mar 15 # Aqtobe Time
1476
+			5:00	-	AQTT
1477
+# Mangghystau
1478
+# Aqtau was not founded until 1963, but it represents an inhabited region,
1479
+# so include time stamps before 1963.
1480
+Zone	Asia/Aqtau	3:21:04	-	LMT	1924 May  2
1481
+			4:00	-	FORT	1930 Jun 21 # Fort Shevchenko T
1482
+			5:00	-	FORT	1963
1483
+			5:00	-	SHET	1981 Oct  1 # Shevchenko Time
1484
+			6:00	-	SHET	1982 Apr  1
1485
+			5:00 RussiaAsia	SHE%sT	1991
1486
+			5:00	-	SHET	1991 Dec 16 # independence
1487
+			5:00 RussiaAsia	AQT%sT	1995 Mar lastSun 2:00 # Aqtau Time
1488
+			4:00 RussiaAsia	AQT%sT	2005 Mar 15
1489
+			5:00	-	AQTT
1490
+# West Kazakhstan
1491
+Zone	Asia/Oral	3:25:24	-	LMT	1924 May  2 # or Ural'sk
1492
+			4:00	-	URAT	1930 Jun 21 # Ural'sk time
1493
+			5:00	-	URAT	1981 Apr  1
1494
+			5:00	1:00	URAST	1981 Oct  1
1495
+			6:00	-	URAT	1982 Apr  1
1496
+			5:00 RussiaAsia	URA%sT	1989 Mar 26 2:00
1497
+			4:00 RussiaAsia	URA%sT	1991
1498
+			4:00	-	URAT	1991 Dec 16 # independence
1499
+			4:00 RussiaAsia	ORA%sT	2005 Mar 15 # Oral Time
1500
+			5:00	-	ORAT
1501
+
1502
+# Kyrgyzstan (Kirgizstan)
1503
+# Transitions through 1991 are from Shanks & Pottenger.
1504
+
1505
+# From Paul Eggert (2005-08-15):
1506
+# According to an article dated today in the Kyrgyzstan Development Gateway
1507
+# <http://eng.gateway.kg/cgi-bin/page.pl?id=1&story_name=doc9979.shtml>
1508
+# Kyrgyzstan is canceling the daylight saving time system.  I take the article
1509
+# to mean that they will leave their clocks at 6 hours ahead of UTC.
1510
+# From Malik Abdugaliev (2005-09-21):
1511
+# Our government cancels daylight saving time 6th of August 2005.
1512
+# From 2005-08-12 our GMT-offset is +6, w/o any daylight saving.
1513
+
1514
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1515
+Rule	Kyrgyz	1992	1996	-	Apr	Sun>=7	0:00s	1:00	S
1516
+Rule	Kyrgyz	1992	1996	-	Sep	lastSun	0:00	0	-
1517
+Rule	Kyrgyz	1997	2005	-	Mar	lastSun	2:30	1:00	S
1518
+Rule	Kyrgyz	1997	2004	-	Oct	lastSun	2:30	0	-
1519
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1520
+Zone	Asia/Bishkek	4:58:24 -	LMT	1924 May  2
1521
+			5:00	-	FRUT	1930 Jun 21 # Frunze Time
1522
+			6:00 RussiaAsia FRU%sT	1991 Mar 31 2:00s
1523
+			5:00	1:00	FRUST	1991 Aug 31 2:00 # independence
1524
+			5:00	Kyrgyz	KG%sT	2005 Aug 12    # Kyrgyzstan Time
1525
+			6:00	-	KGT
1526
+
1527
+###############################################################################
1528
+
1529
+# Korea (North and South)
1530
+
1531
+# From Annie I. Bang (2006-07-10) in
1532
+# <http://www.koreaherald.co.kr/SITE/data/html_dir/2006/07/10/200607100012.asp>:
1533
+# The Ministry of Commerce, Industry and Energy has already
1534
+# commissioned a research project [to reintroduce DST] and has said
1535
+# the system may begin as early as 2008....  Korea ran a daylight
1536
+# saving program from 1949-61 but stopped it during the 1950-53 Korean War.
1537
+
1538
+# From Shanks & Pottenger:
1539
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1540
+Rule	ROK	1960	only	-	May	15	0:00	1:00	D
1541
+Rule	ROK	1960	only	-	Sep	13	0:00	0	S
1542
+Rule	ROK	1987	1988	-	May	Sun>=8	0:00	1:00	D
1543
+Rule	ROK	1987	1988	-	Oct	Sun>=8	0:00	0	S
1544
+
1545
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1546
+Zone	Asia/Seoul	8:27:52	-	LMT	1890
1547
+			8:30	-	KST	1904 Dec
1548
+			9:00	-	KST	1928
1549
+			8:30	-	KST	1932
1550
+			9:00	-	KST	1954 Mar 21
1551
+			8:00	ROK	K%sT	1961 Aug 10
1552
+			8:30	-	KST	1968 Oct
1553
+			9:00	ROK	K%sT
1554
+Zone	Asia/Pyongyang	8:23:00 -	LMT	1890
1555
+			8:30	-	KST	1904 Dec
1556
+			9:00	-	KST	1928
1557
+			8:30	-	KST	1932
1558
+			9:00	-	KST	1954 Mar 21
1559
+			8:00	-	KST	1961 Aug 10
1560
+			9:00	-	KST
1561
+
1562
+###############################################################################
1563
+
1564
+# Kuwait
1565
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1566
+# From the Arab Times (2007-03-14):
1567
+# The Civil Service Commission (CSC) has approved a proposal forwarded
1568
+# by MP Ahmad Baqer on implementing the daylight saving time (DST) in
1569
+# Kuwait starting from April until the end of Sept this year, reports Al-Anba.
1570
+# <http://www.arabtimesonline.com/arabtimes/kuwait/Viewdet.asp?ID=9950>.
1571
+# From Paul Eggert (2007-03-29):
1572
+# We don't know the details, or whether the approval means it'll happen,
1573
+# so for now we assume no DST.
1574
+Zone	Asia/Kuwait	3:11:56 -	LMT	1950
1575
+			3:00	-	AST
1576
+
1577
+# Laos
1578
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1579
+Zone	Asia/Vientiane	6:50:24 -	LMT	1906 Jun  9 # or Viangchan
1580
+			7:06:20	-	SMT	1911 Mar 11 0:01 # Saigon MT?
1581
+			7:00	-	ICT	1912 May
1582
+			8:00	-	ICT	1931 May
1583
+			7:00	-	ICT
1584
+
1585
+# Lebanon
1586
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1587
+Rule	Lebanon	1920	only	-	Mar	28	0:00	1:00	S
1588
+Rule	Lebanon	1920	only	-	Oct	25	0:00	0	-
1589
+Rule	Lebanon	1921	only	-	Apr	3	0:00	1:00	S
1590
+Rule	Lebanon	1921	only	-	Oct	3	0:00	0	-
1591
+Rule	Lebanon	1922	only	-	Mar	26	0:00	1:00	S
1592
+Rule	Lebanon	1922	only	-	Oct	8	0:00	0	-
1593
+Rule	Lebanon	1923	only	-	Apr	22	0:00	1:00	S
1594
+Rule	Lebanon	1923	only	-	Sep	16	0:00	0	-
1595
+Rule	Lebanon	1957	1961	-	May	1	0:00	1:00	S
1596
+Rule	Lebanon	1957	1961	-	Oct	1	0:00	0	-
1597
+Rule	Lebanon	1972	only	-	Jun	22	0:00	1:00	S
1598
+Rule	Lebanon	1972	1977	-	Oct	1	0:00	0	-
1599
+Rule	Lebanon	1973	1977	-	May	1	0:00	1:00	S
1600
+Rule	Lebanon	1978	only	-	Apr	30	0:00	1:00	S
1601
+Rule	Lebanon	1978	only	-	Sep	30	0:00	0	-
1602
+Rule	Lebanon	1984	1987	-	May	1	0:00	1:00	S
1603
+Rule	Lebanon	1984	1991	-	Oct	16	0:00	0	-
1604
+Rule	Lebanon	1988	only	-	Jun	1	0:00	1:00	S
1605
+Rule	Lebanon	1989	only	-	May	10	0:00	1:00	S
1606
+Rule	Lebanon	1990	1992	-	May	1	0:00	1:00	S
1607
+Rule	Lebanon	1992	only	-	Oct	4	0:00	0	-
1608
+Rule	Lebanon	1993	max	-	Mar	lastSun	0:00	1:00	S
1609
+Rule	Lebanon	1993	1998	-	Sep	lastSun	0:00	0	-
1610
+Rule	Lebanon	1999	max	-	Oct	lastSun	0:00	0	-
1611
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1612
+Zone	Asia/Beirut	2:22:00 -	LMT	1880
1613
+			2:00	Lebanon	EE%sT
1614
+
1615
+# Malaysia
1616
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1617
+Rule	NBorneo	1935	1941	-	Sep	14	0:00	0:20	TS # one-Third Summer
1618
+Rule	NBorneo	1935	1941	-	Dec	14	0:00	0	-
1619
+#
1620
+# peninsular Malaysia
1621
+# The data here are taken from Mok Ly Yng (2003-10-30)
1622
+# <http://www.math.nus.edu.sg/aslaksen/teaching/timezone.html>.
1623
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1624
+Zone Asia/Kuala_Lumpur	6:46:46 -	LMT	1901 Jan  1
1625
+			6:55:25	-	SMT	1905 Jun  1 # Singapore M.T.
1626
+			7:00	-	MALT	1933 Jan  1 # Malaya Time
1627
+			7:00	0:20	MALST	1936 Jan  1
1628
+			7:20	-	MALT	1941 Sep  1
1629
+			7:30	-	MALT	1942 Feb 16
1630
+			9:00	-	JST	1945 Sep 12
1631
+			7:30	-	MALT	1982 Jan  1
1632
+			8:00	-	MYT	# Malaysia Time
1633
+# Sabah & Sarawak
1634
+# From Paul Eggert (2006-03-22):
1635
+# The data here are mostly from Shanks & Pottenger, but the 1942, 1945 and 1982
1636
+# transition dates are from Mok Ly Yng.
1637
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1638
+Zone Asia/Kuching	7:21:20	-	LMT	1926 Mar
1639
+			7:30	-	BORT	1933	# Borneo Time
1640
+			8:00	NBorneo	BOR%sT	1942 Feb 16
1641
+			9:00	-	JST	1945 Sep 12
1642
+			8:00	-	BORT	1982 Jan  1
1643
+			8:00	-	MYT
1644
+
1645
+# Maldives
1646
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1647
+Zone	Indian/Maldives	4:54:00 -	LMT	1880	# Male
1648
+			4:54:00	-	MMT	1960	# Male Mean Time
1649
+			5:00	-	MVT		# Maldives Time
1650
+
1651
+# Mongolia
1652
+
1653
+# Shanks & Pottenger say that Mongolia has three time zones, but
1654
+# usno1995 and the CIA map Standard Time Zones of the World (2005-03)
1655
+# both say that it has just one.
1656
+
1657
+# From Oscar van Vlijmen (1999-12-11):
1658
+# <a href="http://www.mongoliatourism.gov.mn/general.htm">
1659
+# General Information Mongolia
1660
+# </a> (1999-09)
1661
+# "Time: Mongolia has two time zones. Three westernmost provinces of
1662
+# Bayan-Ulgii, Uvs, and Hovd are one hour earlier than the capital city, and
1663
+# the rest of the country follows the Ulaanbaatar time, which is UTC/GMT plus
1664
+# eight hours."
1665
+
1666
+# From Rives McDow (1999-12-13):
1667
+# Mongolia discontinued the use of daylight savings time in 1999; 1998
1668
+# being the last year it was implemented.  The dates of implementation I am
1669
+# unsure of, but most probably it was similar to Russia, except for the time
1670
+# of implementation may have been different....
1671
+# Some maps in the past have indicated that there was an additional time
1672
+# zone in the eastern part of Mongolia, including the provinces of Dornod,
1673
+# Suhbaatar, and possibly Khentij.
1674
+
1675
+# From Paul Eggert (1999-12-15):
1676
+# Naming and spelling is tricky in Mongolia.
1677
+# We'll use Hovd (also spelled Chovd and Khovd) to represent the west zone;
1678
+# the capital of the Hovd province is sometimes called Hovd, sometimes Dund-Us,
1679
+# and sometimes Jirgalanta (with variant spellings), but the name Hovd
1680
+# is good enough for our purposes.
1681
+
1682
+# From Rives McDow (2001-05-13):
1683
+# In addition to Mongolia starting daylight savings as reported earlier
1684
+# (adopted DST on 2001-04-27 02:00 local time, ending 2001-09-28),
1685
+# there are three time zones.
1686
+#
1687
+# Provinces [at 7:00]: Bayan-ulgii, Uvs, Khovd, Zavkhan, Govi-Altai
1688
+# Provinces [at 8:00]: Khovsgol, Bulgan, Arkhangai, Khentii, Tov,
1689
+#	Bayankhongor, Ovorkhangai, Dundgovi, Dornogovi, Omnogovi
1690
+# Provinces [at 9:00]: Dornod, Sukhbaatar
1691
+#
1692
+# [The province of Selenge is omitted from the above lists.]
1693
+
1694
+# From Ganbold Ts., Ulaanbaatar (2004-04-17):
1695
+# Daylight saving occurs at 02:00 local time last Saturday of March.
1696
+# It will change back to normal at 02:00 local time last Saturday of
1697
+# September.... As I remember this rule was changed in 2001.
1698
+#
1699
+# From Paul Eggert (2004-04-17):
1700
+# For now, assume Rives McDow's informant got confused about Friday vs
1701
+# Saturday, and that his 2001 dates should have 1 added to them.
1702
+
1703
+# From Paul Eggert (2005-07-26):
1704
+# We have wildly conflicting information about Mongolia's time zones.
1705
+# Bill Bonnet (2005-05-19) reports that the US Embassy in Ulaanbaatar says
1706
+# there is only one time zone and that DST is observed, citing Microsoft
1707
+# Windows XP as the source.  Risto Nykanen (2005-05-16) reports that
1708
+# travelmongolia.org says there are two time zones (UTC+7, UTC+8) with no DST.
1709
+# Oscar van Vlijmen (2005-05-20) reports that the Mongolian Embassy in
1710
+# Washington, DC says there are two time zones, with DST observed.
1711
+# He also found
1712
+# <http://ubpost.mongolnews.mn/index.php?subaction=showcomments&id=1111634894&archive=&start_from=&ucat=1&>
1713
+# which also says that there is DST, and which has a comment by "Toddius"
1714
+# (2005-03-31 06:05 +0700) saying "Mongolia actually has 3.5 time zones.
1715
+# The West (OLGII) is +7 GMT, most of the country is ULAT is +8 GMT
1716
+# and some Eastern provinces are +9 GMT but Sukhbaatar Aimag is SUHK +8.5 GMT.
1717
+# The SUKH timezone is new this year, it is one of the few things the
1718
+# parliament passed during the tumultuous winter session."
1719
+# For now, let's ignore this information, until we have more confirmation.
1720
+
1721
+# From Ganbold Ts. (2007-02-26):
1722
+# Parliament of Mongolia has just changed the daylight-saving rule in February.
1723
+# They decided not to adopt daylight-saving time....
1724
+# http://www.mongolnews.mn/index.php?module=unuudur&sec=view&id=15742
1725
+
1726
+# From Deborah Goldsmith (2008-03-30):
1727
+# We received a bug report claiming that the tz database UTC offset for
1728
+# Asia/Choibalsan (GMT+09:00) is incorrect, and that it should be GMT
1729
+# +08:00 instead. Different sources appear to disagree with the tz
1730
+# database on this, e.g.:
1731
+#
1732
+# <a href="http://www.timeanddate.com/worldclock/city.html?n=1026">
1733
+# http://www.timeanddate.com/worldclock/city.html?n=1026
1734
+# </a>
1735
+# <a href="http://www.worldtimeserver.com/current_time_in_MN.aspx">
1736
+# http://www.worldtimeserver.com/current_time_in_MN.aspx
1737
+# </a>
1738
+#
1739
+# both say GMT+08:00.
1740
+
1741
+# From Steffen Thorsen (2008-03-31):
1742
+# eznis airways, which operates several domestic flights, has a flight
1743
+# schedule here:
1744
+# <a href="http://www.eznis.com/Container.jsp?id=112">
1745
+# http://www.eznis.com/Container.jsp?id=112
1746
+# </a>
1747
+# (click the English flag for English)
1748
+#
1749
+# There it appears that flights between Choibalsan and Ulaanbatar arrive
1750
+# about 1:35 - 1:50 hours later in local clock time, no matter the
1751
+# direction, while Ulaanbaatar-Khvod takes 2 hours in the Eastern
1752
+# direction and 3:35 back, which indicates that Ulaanbatar and Khvod are
1753
+# in different time zones (like we know about), while Choibalsan and
1754
+# Ulaanbatar are in the same time zone (correction needed).
1755
+
1756
+# From Arthur David Olson (2008-05-19):
1757
+# Assume that Choibalsan is indeed offset by 8:00.
1758
+# XXX--in the absence of better information, assume that transition
1759
+# was at the start of 2008-03-31 (the day of Steffen Thorsen's report);
1760
+# this is almost surely wrong.
1761
+
1762
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1763
+Rule	Mongol	1983	1984	-	Apr	1	0:00	1:00	S
1764
+Rule	Mongol	1983	only	-	Oct	1	0:00	0	-
1765
+# Shanks & Pottenger and IATA SSIM say 1990s switches occurred at 00:00,
1766
+# but McDow says the 2001 switches occurred at 02:00.  Also, IATA SSIM
1767
+# (1996-09) says 1996-10-25.  Go with Shanks & Pottenger through 1998.
1768
+#
1769
+# Shanks & Pottenger say that the Sept. 1984 through Sept. 1990 switches
1770
+# in Choibalsan (more precisely, in Dornod and Sukhbaatar) took place
1771
+# at 02:00 standard time, not at 00:00 local time as in the rest of
1772
+# the country.  That would be odd, and possibly is a result of their
1773
+# correction of 02:00 (in the previous edition) not being done correctly
1774
+# in the latest edition; so ignore it for now.
1775
+
1776
+Rule	Mongol	1985	1998	-	Mar	lastSun	0:00	1:00	S
1777
+Rule	Mongol	1984	1998	-	Sep	lastSun	0:00	0	-
1778
+# IATA SSIM (1999-09) says Mongolia no longer observes DST.
1779
+Rule	Mongol	2001	only	-	Apr	lastSat	2:00	1:00	S
1780
+Rule	Mongol	2001	2006	-	Sep	lastSat	2:00	0	-
1781
+Rule	Mongol	2002	2006	-	Mar	lastSat	2:00	1:00	S
1782
+
1783
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1784
+# Hovd, a.k.a. Chovd, Dund-Us, Dzhargalant, Khovd, Jirgalanta
1785
+Zone	Asia/Hovd	6:06:36 -	LMT	1905 Aug
1786
+			6:00	-	HOVT	1978	# Hovd Time
1787
+			7:00	Mongol	HOV%sT
1788
+# Ulaanbaatar, a.k.a. Ulan Bataar, Ulan Bator, Urga
1789
+Zone	Asia/Ulaanbaatar 7:07:32 -	LMT	1905 Aug
1790
+			7:00	-	ULAT	1978	# Ulaanbaatar Time
1791
+			8:00	Mongol	ULA%sT
1792
+# Choibalsan, a.k.a. Bajan Tuemen, Bajan Tumen, Chojbalsan,
1793
+# Choybalsan, Sanbejse, Tchoibalsan
1794
+Zone	Asia/Choibalsan	7:38:00 -	LMT	1905 Aug
1795
+			7:00	-	ULAT	1978
1796
+			8:00	-	ULAT	1983 Apr
1797
+			9:00	Mongol	CHO%sT	2008 Mar 31 # Choibalsan Time
1798
+			8:00	Mongol	CHO%sT
1799
+
1800
+# Nepal
1801
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1802
+Zone	Asia/Kathmandu	5:41:16 -	LMT	1920
1803
+			5:30	-	IST	1986
1804
+			5:45	-	NPT	# Nepal Time
1805
+
1806
+# Oman
1807
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1808
+Zone	Asia/Muscat	3:54:20 -	LMT	1920
1809
+			4:00	-	GST
1810
+
1811
+# Pakistan
1812
+
1813
+# From Rives McDow (2002-03-13):
1814
+# I have been advised that Pakistan has decided to adopt dst on a
1815
+# TRIAL basis for one year, starting 00:01 local time on April 7, 2002
1816
+# and ending at 00:01 local time October 6, 2002.  This is what I was
1817
+# told, but I believe that the actual time of change may be 00:00; the
1818
+# 00:01 was to make it clear which day it was on.
1819
+
1820
+# From Paul Eggert (2002-03-15):
1821
+# Jesper Norgaard found this URL:
1822
+# http://www.pak.gov.pk/public/news/app/app06_dec.htm
1823
+# (dated 2001-12-06) which says that the Cabinet adopted a scheme "to
1824
+# advance the clocks by one hour on the night between the first
1825
+# Saturday and Sunday of April and revert to the original position on
1826
+# 15th October each year".  This agrees with McDow's 04-07 at 00:00,
1827
+# but disagrees about the October transition, and makes it sound like
1828
+# it's not on a trial basis.  Also, the "between the first Saturday
1829
+# and Sunday of April" phrase, if taken literally, means that the
1830
+# transition takes place at 00:00 on the first Sunday on or after 04-02.
1831
+
1832
+# From Paul Eggert (2003-02-09):
1833
+# DAWN <http://www.dawn.com/2002/10/06/top13.htm> reported on 2002-10-05
1834
+# that 2002 DST ended that day at midnight.  Go with McDow for now.
1835
+
1836
+# From Steffen Thorsen (2003-03-14):
1837
+# According to http://www.dawn.com/2003/03/07/top15.htm
1838
+# there will be no DST in Pakistan this year:
1839
+#
1840
+# ISLAMABAD, March 6: Information and Media Development Minister Sheikh
1841
+# Rashid Ahmed on Thursday said the cabinet had reversed a previous
1842
+# decision to advance clocks by one hour in summer and put them back by
1843
+# one hour in winter with the aim of saving light hours and energy.
1844
+#
1845
+# The minister told a news conference that the experiment had rather
1846
+# shown 8 per cent higher consumption of electricity.
1847
+
1848
+# From Alex Krivenyshev (2008-05-15):
1849
+#
1850
+# Here is an article that Pakistan plan to introduce Daylight Saving Time
1851
+# on June 1, 2008 for 3 months.
1852
+#
1853
+# "... The federal cabinet on Wednesday announced a new conservation plan to help
1854
+# reduce load shedding by approving the closure of commercial centres at 9pm and
1855
+# moving clocks forward by one hour for the next three months.
1856
+# ...."
1857
+#
1858
+# <a href="http://www.worldtimezone.net/dst_news/dst_news_pakistan01.html">
1859
+# http://www.worldtimezone.net/dst_news/dst_news_pakistan01.html
1860
+# </a>
1861
+# OR
1862
+# <a href="http://www.dailytimes.com.pk/default.asp?page=2008%5C05%5C15%5Cstory_15-5-2008_pg1_4">
1863
+# http://www.dailytimes.com.pk/default.asp?page=2008%5C05%5C15%5Cstory_15-5-2008_pg1_4
1864
+# </a>
1865
+
1866
+# From Arthur David Olson (2008-05-19):
1867
+# XXX--midnight transitions is a guess; 2008 only is a guess.
1868
+
1869
+# From Alexander Krivenyshev (2008-08-28):
1870
+# Pakistan government has decided to keep the watches one-hour advanced
1871
+# for another 2 months--plan to return to Standard Time on October 31
1872
+# instead of August 31.
1873
+#
1874
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_pakistan02.html">
1875
+# http://www.worldtimezone.com/dst_news/dst_news_pakistan02.html
1876
+# </a>
1877
+# OR
1878
+# <a href="http://dailymailnews.com/200808/28/news/dmbrn03.html">
1879
+# http://dailymailnews.com/200808/28/news/dmbrn03.html
1880
+# </a>
1881
+
1882
+# From Alexander Krivenyshev (2009-04-08):
1883
+# Based on previous media reports that "... proposed plan to
1884
+# advance clocks by one hour from May 1 will cause disturbance
1885
+# to the working schedules rather than bringing discipline in
1886
+# official working."
1887
+# <a href="http://www.thenews.com.pk/daily_detail.asp?id=171280">
1888
+# http://www.thenews.com.pk/daily_detail.asp?id=171280
1889
+# </a>
1890
+#
1891
+# recent news that instead of May 2009 - Pakistan plan to
1892
+# introduce DST from April 15, 2009
1893
+#
1894
+# FYI: Associated Press Of Pakistan
1895
+# April 08, 2009
1896
+# Cabinet okays proposal to advance clocks by one hour from April 15
1897
+# <a href="http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=73043&Itemid=1">
1898
+# http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=73043&Itemid=1
1899
+# </a>
1900
+#
1901
+# or
1902
+#
1903
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_pakistan05.html">
1904
+# http://www.worldtimezone.com/dst_news/dst_news_pakistan05.html
1905
+# </a>
1906
+#
1907
+# ....
1908
+# The Federal Cabinet on Wednesday approved the proposal to
1909
+# advance clocks in the country by one hour from April 15 to
1910
+# conserve energy"
1911
+
1912
+# From Steffen Thorsen (2009-09-17):
1913
+# "The News International," Pakistan reports that: "The Federal
1914
+# Government has decided to restore the previous time by moving the
1915
+# clocks backward by one hour from October 1. A formal announcement to
1916
+# this effect will be made after the Prime Minister grants approval in
1917
+# this regard."
1918
+# <a href="http://www.thenews.com.pk/updates.asp?id=87168">
1919
+# http://www.thenews.com.pk/updates.asp?id=87168
1920
+# </a>
1921
+
1922
+# From Alexander Krivenyshev (2009-09-28):
1923
+# According to Associated Press Of Pakistan, it is confirmed that
1924
+# Pakistan clocks across the country would be turned back by an hour from October
1925
+# 1, 2009.
1926
+#
1927
+# "Clocks to go back one hour from 1 Oct"
1928
+# <a href="http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=86715&Itemid=2">
1929
+# http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=86715&Itemid=2
1930
+# </a>
1931
+# or
1932
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_pakistan07.htm">
1933
+# http://www.worldtimezone.com/dst_news/dst_news_pakistan07.htm
1934
+# </a>
1935
+
1936
+# From Steffen Thorsen (2009-09-29):
1937
+# Alexander Krivenyshev wrote:
1938
+# > According to Associated Press Of Pakistan, it is confirmed that
1939
+# > Pakistan clocks across the country would be turned back by an hour from October
1940
+# > 1, 2009.
1941
+#
1942
+# Now they seem to have changed their mind, November 1 is the new date:
1943
+# <a href="http://www.thenews.com.pk/top_story_detail.asp?Id=24742">
1944
+# http://www.thenews.com.pk/top_story_detail.asp?Id=24742
1945
+# </a>
1946
+# "The country's clocks will be reversed by one hour on November 1.
1947
+# Officials of Federal Ministry for Interior told this to Geo News on
1948
+# Monday."
1949
+#
1950
+# And more importantly, it seems that these dates will be kept every year:
1951
+# "It has now been decided that clocks will be wound forward by one hour
1952
+# on April 15 and reversed by an hour on November 1 every year without
1953
+# obtaining prior approval, the officials added."
1954
+#
1955
+# We have confirmed this year's end date with both with the Ministry of
1956
+# Water and Power and the Pakistan Electric Power Company:
1957
+# <a href="http://www.timeanddate.com/news/time/pakistan-ends-dst09.html">
1958
+# http://www.timeanddate.com/news/time/pakistan-ends-dst09.html
1959
+# </a>
1960
+
1961
+# From Christoph Goehre (2009-10-01):
1962
+# [T]he German Consulate General in Karachi reported me today that Pakistan
1963
+# will go back to standard time on 1st of November.
1964
+
1965
+# From Steffen Thorsen (2010-03-26):
1966
+# Steffen Thorsen wrote:
1967
+# > On Thursday (2010-03-25) it was announced that DST would start in
1968
+# > Pakistan on 2010-04-01.
1969
+# >
1970
+# > Then today, the president said that they might have to revert the
1971
+# > decision if it is not supported by the parliament. So at the time
1972
+# > being, it seems unclear if DST will be actually observed or not - but
1973
+# > April 1 could be a more likely date than April 15.
1974
+# Now, it seems that the decision to not observe DST in final:
1975
+#
1976
+# "Govt Withdraws Plan To Advance Clocks"
1977
+# <a href="http://www.apakistannews.com/govt-withdraws-plan-to-advance-clocks-172041">
1978
+# http://www.apakistannews.com/govt-withdraws-plan-to-advance-clocks-172041
1979
+# </a>
1980
+#
1981
+# "People laud PM's announcement to end DST"
1982
+# <a href="http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=99374&Itemid=2">
1983
+# http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=99374&Itemid=2
1984
+# </a>
1985
+
1986
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1987
+Rule Pakistan	2002	only	-	Apr	Sun>=2	0:01	1:00	S
1988
+Rule Pakistan	2002	only	-	Oct	Sun>=2	0:01	0	-
1989
+Rule Pakistan	2008	only	-	Jun	1	0:00	1:00	S
1990
+Rule Pakistan	2008	only	-	Nov	1	0:00	0	-
1991
+Rule Pakistan	2009	only	-	Apr	15	0:00	1:00	S
1992
+Rule Pakistan	2009	only	-	Nov	1	0:00	0	-
1993
+
1994
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1995
+Zone	Asia/Karachi	4:28:12 -	LMT	1907
1996
+			5:30	-	IST	1942 Sep
1997
+			5:30	1:00	IST	1945 Oct 15
1998
+			5:30	-	IST	1951 Sep 30
1999
+			5:00	-	KART	1971 Mar 26 # Karachi Time
2000
+			5:00 Pakistan	PK%sT	# Pakistan Time
2001
+
2002
+# Palestine
2003
+
2004
+# From Amos Shapir (1998-02-15):
2005
+#
2006
+# From 1917 until 1948-05-15, all of Palestine, including the parts now
2007
+# known as the Gaza Strip and the West Bank, was under British rule.
2008
+# Therefore the rules given for Israel for that period, apply there too...
2009
+#
2010
+# The Gaza Strip was under Egyptian rule between 1948-05-15 until 1967-06-05
2011
+# (except a short occupation by Israel from 1956-11 till 1957-03, but no
2012
+# time zone was affected then).  It was never formally annexed to Egypt,
2013
+# though.
2014
+#
2015
+# The rest of Palestine was under Jordanian rule at that time, formally
2016
+# annexed in 1950 as the West Bank (and the word "Trans" was dropped from
2017
+# the country's previous name of "the Hashemite Kingdom of the
2018
+# Trans-Jordan").  So the rules for Jordan for that time apply.  Major
2019
+# towns in that area are Nablus (Shchem), El-Halil (Hebron), Ramallah, and
2020
+# East Jerusalem.
2021
+#
2022
+# Both areas were occupied by Israel in June 1967, but not annexed (except
2023
+# for East Jerusalem).  They were on Israel time since then; there might
2024
+# have been a Military Governor's order about time zones, but I'm not aware
2025
+# of any (such orders may have been issued semi-annually whenever summer
2026
+# time was in effect, but maybe the legal aspect of time was just neglected).
2027
+#
2028
+# The Palestinian Authority was established in 1993, and got hold of most
2029
+# towns in the West Bank and Gaza by 1995.  I know that in order to
2030
+# demonstrate...independence, they have been switching to
2031
+# summer time and back on a different schedule than Israel's, but I don't
2032
+# know when this was started, or what algorithm is used (most likely the
2033
+# Jordanian one).
2034
+#
2035
+# To summarize, the table should probably look something like that:
2036
+#
2037
+# Area \ when | 1918-1947 | 1948-1967 | 1967-1995 | 1996-
2038
+# ------------+-----------+-----------+-----------+-----------
2039
+# Israel      | Zion      | Zion      | Zion      | Zion
2040
+# West bank   | Zion      | Jordan    | Zion      | Jordan
2041
+# Gaza        | Zion      | Egypt     | Zion      | Jordan
2042
+#
2043
+# I guess more info may be available from the PA's web page (if/when they
2044
+# have one).
2045
+
2046
+# From Paul Eggert (2006-03-22):
2047
+# Shanks & Pottenger write that Gaza did not observe DST until 1957, but go
2048
+# with Shapir and assume that it observed DST from 1940 through 1947,
2049
+# and that it used Jordanian rules starting in 1996.
2050
+# We don't yet need a separate entry for the West Bank, since
2051
+# the only differences between it and Gaza that we know about
2052
+# occurred before our cutoff date of 1970.
2053
+# However, as we get more information, we may need to add entries
2054
+# for parts of the West Bank as they transitioned from Israel's rules
2055
+# to Palestine's rules.
2056
+
2057
+# From IINS News Service - Israel - 1998-03-23 10:38:07 Israel time,
2058
+# forwarded by Ephraim Silverberg:
2059
+#
2060
+# Despite the fact that Israel changed over to daylight savings time
2061
+# last week, the PLO Authority (PA) has decided not to turn its clocks
2062
+# one-hour forward at this time.  As a sign of independence from Israeli rule,
2063
+# the PA has decided to implement DST in April.
2064
+
2065
+# From Paul Eggert (1999-09-20):
2066
+# Daoud Kuttab writes in
2067
+# <a href="http://www.jpost.com/com/Archive/22.Apr.1999/Opinion/Article-2.html">
2068
+# Holiday havoc
2069
+# </a> (Jerusalem Post, 1999-04-22) that
2070
+# the Palestinian National Authority changed to DST on 1999-04-15.
2071
+# I vaguely recall that they switch back in October (sorry, forgot the source).
2072
+# For now, let's assume that the spring switch was at 24:00,
2073
+# and that they switch at 0:00 on the 3rd Fridays of April and October.
2074
+
2075
+# From Paul Eggert (2005-11-22):
2076
+# Starting 2004 transitions are from Steffen Thorsen's web site timeanddate.com.
2077
+
2078
+# From Steffen Thorsen (2005-11-23):
2079
+# A user from Gaza reported that Gaza made the change early because of
2080
+# the Ramadan.  Next year Ramadan will be even earlier, so I think
2081
+# there is a good chance next year's end date will be around two weeks
2082
+# earlier--the same goes for Jordan.
2083
+
2084
+# From Steffen Thorsen (2006-08-17):
2085
+# I was informed by a user in Bethlehem that in Bethlehem it started the
2086
+# same day as Israel, and after checking with other users in the area, I
2087
+# was informed that they started DST one day after Israel.  I was not
2088
+# able to find any authoritative sources at the time, nor details if
2089
+# Gaza changed as well, but presumed Gaza to follow the same rules as
2090
+# the West Bank.
2091
+
2092
+# From Steffen Thorsen (2006-09-26):
2093
+# according to the Palestine News Network (2006-09-19):
2094
+# http://english.pnn.ps/index.php?option=com_content&task=view&id=596&Itemid=5
2095
+# > The Council of Ministers announced that this year its winter schedule
2096
+# > will begin early, as of midnight Thursday.  It is also time to turn
2097
+# > back the clocks for winter.  Friday will begin an hour late this week.
2098
+# I guess it is likely that next year's date will be moved as well,
2099
+# because of the Ramadan.
2100
+
2101
+# From Jesper Norgaard Welen (2007-09-18):
2102
+# According to Steffen Thorsen's web site the Gaza Strip and the rest of the
2103
+# Palestinian territories left DST early on 13.th. of September at 2:00.
2104
+
2105
+# From Paul Eggert (2007-09-20):
2106
+# My understanding is that Gaza and the West Bank disagree even over when
2107
+# the weekend is (Thursday+Friday versus Friday+Saturday), so I'd be a bit
2108
+# surprised if they agreed about DST.  But for now, assume they agree.
2109
+# For lack of better information, predict that future changes will be
2110
+# the 2nd Thursday of September at 02:00.
2111
+
2112
+# From Alexander Krivenyshev (2008-08-28):
2113
+# Here is an article, that Mideast running on different clocks at Ramadan.
2114
+#
2115
+# Gaza Strip (as Egypt) ended DST at midnight Thursday (Aug 28, 2008), while
2116
+# the West Bank will end Daylight Saving Time at midnight Sunday (Aug 31, 2008).
2117
+#
2118
+# <a href="http://www.guardian.co.uk/world/feedarticle/7759001">
2119
+# http://www.guardian.co.uk/world/feedarticle/7759001
2120
+# </a>
2121
+# <a href="http://www.abcnews.go.com/International/wireStory?id=5676087">
2122
+# http://www.abcnews.go.com/International/wireStory?id=5676087
2123
+# </a>
2124
+# or
2125
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_gazastrip01.html">
2126
+# http://www.worldtimezone.com/dst_news/dst_news_gazastrip01.html
2127
+# </a>
2128
+
2129
+# From Alexander Krivenyshev (2009-03-26):
2130
+# According to the Palestine News Network (arabic.pnn.ps), Palestinian
2131
+# government decided to start Daylight Time on Thursday night March
2132
+# 26 and continue until the night of 27 September 2009.
2133
+#
2134
+# (in Arabic)
2135
+# <a href="http://arabic.pnn.ps/index.php?option=com_content&task=view&id=50850">
2136
+# http://arabic.pnn.ps/index.php?option=com_content&task=view&id=50850
2137
+# </a>
2138
+#
2139
+# or
2140
+# (English translation)
2141
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_westbank01.html">
2142
+# http://www.worldtimezone.com/dst_news/dst_news_westbank01.html
2143
+# </a>
2144
+
2145
+# From Steffen Thorsen (2009-08-31):
2146
+# Palestine's Council of Ministers announced that they will revert back to
2147
+# winter time on Friday, 2009-09-04.
2148
+#
2149
+# One news source:
2150
+# <a href="http://www.safa.ps/ara/?action=showdetail&seid=4158">
2151
+# http://www.safa.ps/ara/?action=showdetail&seid=4158
2152
+# </a>
2153
+# (Palestinian press agency, Arabic),
2154
+# Google translate: "Decided that the Palestinian government in Ramallah
2155
+# headed by Salam Fayyad, the start of work in time for the winter of
2156
+# 2009, starting on Friday approved the fourth delay Sept. clock sixty
2157
+# minutes per hour as of Friday morning."
2158
+#
2159
+# We are not sure if Gaza will do the same, last year they had a different
2160
+# end date, we will keep this page updated:
2161
+# <a href="http://www.timeanddate.com/news/time/westbank-gaza-dst-2009.html">
2162
+# http://www.timeanddate.com/news/time/westbank-gaza-dst-2009.html
2163
+# </a>
2164
+
2165
+# From Alexander Krivenyshev (2009-09-02):
2166
+# Seems that Gaza Strip will go back to Winter Time same date as West Bank.
2167
+#
2168
+# According to Palestinian Ministry Of Interior, West Bank and Gaza Strip plan
2169
+# to change time back to Standard time on September 4, 2009.
2170
+#
2171
+# "Winter time unite the West Bank and Gaza"
2172
+# (from Palestinian National Authority):
2173
+# <a href="http://www.moi.gov.ps/en/?page=633167343250594025&nid=11505
2174
+# http://www.moi.gov.ps/en/?page=633167343250594025&nid=11505
2175
+# </a>
2176
+# or
2177
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_gazastrip02.html>
2178
+# http://www.worldtimezone.com/dst_news/dst_news_gazastrip02.html
2179
+# </a>
2180
+
2181
+# From Alexander Krivenyshev (2010-03-19):
2182
+# According to Voice of Palestine DST will last for 191 days, from March
2183
+# 26, 2010 till "the last Sunday before the tenth day of Tishri
2184
+# (October), each year" (October 03, 2010?)
2185
+#
2186
+# <a href="http://palvoice.org/forums/showthread.php?t=245697">
2187
+# http://palvoice.org/forums/showthread.php?t=245697
2188
+# </a>
2189
+# (in Arabic)
2190
+# or
2191
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_westbank03.html">
2192
+# http://www.worldtimezone.com/dst_news/dst_news_westbank03.html
2193
+# </a>
2194
+
2195
+# From Steffen Thorsen (2010-03-24):
2196
+# ...Ma'an News Agency reports that Hamas cabinet has decided it will
2197
+# start one day later, at 12:01am. Not sure if they really mean 12:01am or
2198
+# noon though:
2199
+#
2200
+# <a href="http://www.maannews.net/eng/ViewDetails.aspx?ID=271178">
2201
+# http://www.maannews.net/eng/ViewDetails.aspx?ID=271178
2202
+# </a>
2203
+# (Ma'an News Agency)
2204
+# "At 12:01am Friday, clocks in Israel and the West Bank will change to
2205
+# 1:01am, while Gaza clocks will change at 12:01am Saturday morning."
2206
+
2207
+# From Steffen Thorsen (2010-08-11):
2208
+# According to several sources, including
2209
+# <a href="http://www.maannews.net/eng/ViewDetails.aspx?ID=306795">
2210
+# http://www.maannews.net/eng/ViewDetails.aspx?ID=306795
2211
+# </a>
2212
+# the clocks were set back one hour at 2010-08-11 00:00:00 local time in
2213
+# Gaza and the West Bank.
2214
+# Some more background info:
2215
+# <a href="http://www.timeanddate.com/news/time/westbank-gaza-end-dst-2010.html">
2216
+# http://www.timeanddate.com/news/time/westbank-gaza-end-dst-2010.html
2217
+# </a>
2218
+
2219
+# From Steffen Thorsen (2011-08-26):
2220
+# Gaza and the West Bank did go back to standard time in the beginning of
2221
+# August, and will now enter daylight saving time again on 2011-08-30
2222
+# 00:00 (so two periods of DST in 2011). The pause was because of
2223
+# Ramadan.
2224
+#
2225
+# <a href="http://www.maannews.net/eng/ViewDetails.aspx?ID=416217">
2226
+# http://www.maannews.net/eng/ViewDetails.aspx?ID=416217
2227
+# </a>
2228
+# Additional info:
2229
+# <a href="http://www.timeanddate.com/news/time/palestine-dst-2011.html">
2230
+# http://www.timeanddate.com/news/time/palestine-dst-2011.html
2231
+# </a>
2232
+
2233
+# From Alexander Krivenyshev (2011-08-27):
2234
+# According to the article in The Jerusalem Post:
2235
+# "...Earlier this month, the Palestinian government in the West Bank decided to
2236
+# move to standard time for 30 days, during Ramadan. The Palestinians in the
2237
+# Gaza Strip accepted the change and also moved their clocks one hour back.
2238
+# The Hamas government said on Saturday that it won't observe summertime after
2239
+# the Muslim feast of Id al-Fitr, which begins on Tuesday..."
2240
+# ...
2241
+# <a href="http://www.jpost.com/MiddleEast/Article.aspx?id=235650">
2242
+# http://www.jpost.com/MiddleEast/Article.aspx?id=235650
2243
+# </a>
2244
+# or
2245
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_gazastrip05.html">
2246
+# http://www.worldtimezone.com/dst_news/dst_news_gazastrip05.html
2247
+# </a>
2248
+# The rules for Egypt are stolen from the `africa' file.
2249
+
2250
+# From Steffen Thorsen (2011-09-30):
2251
+# West Bank did end Daylight Saving Time this morning/midnight (2011-09-30
2252
+# 00:00).
2253
+# So West Bank and Gaza now have the same time again.
2254
+#
2255
+# Many sources, including:
2256
+# <a href="http://www.maannews.net/eng/ViewDetails.aspx?ID=424808">
2257
+# http://www.maannews.net/eng/ViewDetails.aspx?ID=424808
2258
+# </a>
2259
+
2260
+# From Steffen Thorsen (2012-03-26):
2261
+# Palestinian news sources tell that both Gaza and West Bank will start DST
2262
+# on Friday (Thursday midnight, 2012-03-29 24:00).
2263
+# Some of many sources in Arabic:
2264
+# <a href="http://www.samanews.com/index.php?act=Show&id=122638">
2265
+# http://www.samanews.com/index.php?act=Show&id=122638
2266
+# </a>
2267
+#
2268
+# <a href="http://safa.ps/details/news/74352/%D8%A8%D8%AF%D8%A1-%D8%A7%D9%84%D8%AA%D9%88%D9%82%D9%8A%D8%AA-%D8%A7%D9%84%D8%B5%D9%8A%D9%81%D9%8A-%D8%A8%D8%A7%D9%84%D8%B6%D9%81%D8%A9-%D9%88%D8%BA%D8%B2%D8%A9-%D9%84%D9%8A%D9%84%D8%A9-%D8%A7%D9%84%D8%AC%D9%85%D8%B9%D8%A9.html">
2269
+# http://safa.ps/details/news/74352/%D8%A8%D8%AF%D8%A1-%D8%A7%D9%84%D8%AA%D9%88%D9%82%D9%8A%D8%AA-%D8%A7%D9%84%D8%B5%D9%8A%D9%81%D9%8A-%D8%A8%D8%A7%D9%84%D8%B6%D9%81%D8%A9-%D9%88%D8%BA%D8%B2%D8%A9-%D9%84%D9%8A%D9%84%D8%A9-%D8%A7%D9%84%D8%AC%D9%85%D8%B9%D8%A9.html
2270
+# </a>
2271
+#
2272
+# Our brief summary:
2273
+# <a href="http://www.timeanddate.com/news/time/gaza-west-bank-dst-2012.html">
2274
+# http://www.timeanddate.com/news/time/gaza-west-bank-dst-2012.html
2275
+# </a>
2276
+
2277
+# From Arthur David Olson (2012-03-27):
2278
+# The timeanddate article for 2012 says that "the end date has not yet been
2279
+# announced" and that "Last year, both...paused daylight saving time during...
2280
+# Ramadan. It is not yet known [for] 2012."
2281
+# For now, assume both switch back on the last Friday in September. XXX
2282
+
2283
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
2284
+Rule EgyptAsia	1957	only	-	May	10	0:00	1:00	S
2285
+Rule EgyptAsia	1957	1958	-	Oct	 1	0:00	0	-
2286
+Rule EgyptAsia	1958	only	-	May	 1	0:00	1:00	S
2287
+Rule EgyptAsia	1959	1967	-	May	 1	1:00	1:00	S
2288
+Rule EgyptAsia	1959	1965	-	Sep	30	3:00	0	-
2289
+Rule EgyptAsia	1966	only	-	Oct	 1	3:00	0	-
2290
+
2291
+Rule Palestine	1999	2005	-	Apr	Fri>=15	0:00	1:00	S
2292
+Rule Palestine	1999	2003	-	Oct	Fri>=15	0:00	0	-
2293
+Rule Palestine	2004	only	-	Oct	 1	1:00	0	-
2294
+Rule Palestine	2005	only	-	Oct	 4	2:00	0	-
2295
+Rule Palestine	2006	2008	-	Apr	 1	0:00	1:00	S
2296
+Rule Palestine	2006	only	-	Sep	22	0:00	0	-
2297
+Rule Palestine	2007	only	-	Sep	Thu>=8	2:00	0	-
2298
+Rule Palestine	2008	only	-	Aug	lastFri	0:00	0	-
2299
+Rule Palestine	2009	only	-	Mar	lastFri	0:00	1:00	S
2300
+Rule Palestine	2009	only	-	Sep	Fri>=1	2:00	0	-
2301
+Rule Palestine	2010	only	-	Mar	lastSat	0:01	1:00	S
2302
+Rule Palestine	2010	only	-	Aug	11	0:00	0	-
2303
+
2304
+# From Arthur David Olson (2011-09-20):
2305
+# 2011 transitions per http://www.timeanddate.com as of 2011-09-20.
2306
+# From Paul Eggert (2012-10-12):
2307
+# 2012 transitions per http://www.timeanddate.com as of 2012-10-12.
2308
+
2309
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2310
+Zone	Asia/Gaza	2:17:52	-	LMT	1900 Oct
2311
+			2:00	Zion	EET	1948 May 15
2312
+			2:00 EgyptAsia	EE%sT	1967 Jun  5
2313
+			2:00	Zion	I%sT	1996
2314
+			2:00	Jordan	EE%sT	1999
2315
+			2:00 Palestine	EE%sT	2011 Apr  2 12:01
2316
+			2:00	1:00	EEST	2011 Aug  1
2317
+			2:00	-	EET	2012 Mar 30
2318
+			2:00	1:00	EEST	2012 Sep 21 1:00
2319
+			2:00	-	EET
2320
+
2321
+Zone	Asia/Hebron	2:20:23	-	LMT	1900 Oct
2322
+			2:00	Zion	EET	1948 May 15
2323
+			2:00 EgyptAsia	EE%sT	1967 Jun  5
2324
+			2:00	Zion	I%sT	1996
2325
+			2:00	Jordan	EE%sT	1999
2326
+			2:00 Palestine	EE%sT	2008 Aug
2327
+			2:00 	1:00	EEST	2008 Sep
2328
+			2:00 Palestine	EE%sT	2011 Apr  1 12:01
2329
+			2:00	1:00	EEST	2011 Aug  1
2330
+			2:00	-	EET	2011 Aug 30
2331
+			2:00	1:00	EEST	2011 Sep 30 3:00
2332
+			2:00	-	EET	2012 Mar 30
2333
+			2:00	1:00	EEST	2012 Sep 21 1:00
2334
+			2:00	-	EET
2335
+
2336
+# Paracel Is
2337
+# no information
2338
+
2339
+# Philippines
2340
+# On 1844-08-16, Narciso Claveria, governor-general of the
2341
+# Philippines, issued a proclamation announcing that 1844-12-30 was to
2342
+# be immediately followed by 1845-01-01.  Robert H. van Gent has a
2343
+# transcript of the decree in <http://www.phys.uu.nl/~vgent/idl/idl.htm>.
2344
+# The rest of the data are from Shanks & Pottenger.
2345
+
2346
+# From Paul Eggert (2006-04-25):
2347
+# Tomorrow's Manila Standard reports that the Philippines Department of
2348
+# Trade and Industry is considering adopting DST this June when the
2349
+# rainy season begins.  See
2350
+# <http://www.manilastandardtoday.com/?page=politics02_april26_2006>.
2351
+# For now, we'll ignore this, since it's not definite and we lack details.
2352
+#
2353
+# From Jesper Norgaard Welen (2006-04-26):
2354
+# ... claims that Philippines had DST last time in 1990:
2355
+# http://story.philippinetimes.com/p.x/ct/9/id/145be20cc6b121c0/cid/3e5bbccc730d258c/
2356
+# [a story dated 2006-04-25 by Cris Larano of Dow Jones Newswires,
2357
+# but no details]
2358
+
2359
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
2360
+Rule	Phil	1936	only	-	Nov	1	0:00	1:00	S
2361
+Rule	Phil	1937	only	-	Feb	1	0:00	0	-
2362
+Rule	Phil	1954	only	-	Apr	12	0:00	1:00	S
2363
+Rule	Phil	1954	only	-	Jul	1	0:00	0	-
2364
+Rule	Phil	1978	only	-	Mar	22	0:00	1:00	S
2365
+Rule	Phil	1978	only	-	Sep	21	0:00	0	-
2366
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2367
+Zone	Asia/Manila	-15:56:00 -	LMT	1844 Dec 31
2368
+			8:04:00 -	LMT	1899 May 11
2369
+			8:00	Phil	PH%sT	1942 May
2370
+			9:00	-	JST	1944 Nov
2371
+			8:00	Phil	PH%sT
2372
+
2373
+# Qatar
2374
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2375
+Zone	Asia/Qatar	3:26:08 -	LMT	1920	# Al Dawhah / Doha
2376
+			4:00	-	GST	1972 Jun
2377
+			3:00	-	AST
2378
+
2379
+# Saudi Arabia
2380
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2381
+Zone	Asia/Riyadh	3:06:52 -	LMT	1950
2382
+			3:00	-	AST
2383
+
2384
+# Singapore
2385
+# The data here are taken from Mok Ly Yng (2003-10-30)
2386
+# <http://www.math.nus.edu.sg/aslaksen/teaching/timezone.html>.
2387
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2388
+Zone	Asia/Singapore	6:55:25 -	LMT	1901 Jan  1
2389
+			6:55:25	-	SMT	1905 Jun  1 # Singapore M.T.
2390
+			7:00	-	MALT	1933 Jan  1 # Malaya Time
2391
+			7:00	0:20	MALST	1936 Jan  1
2392
+			7:20	-	MALT	1941 Sep  1
2393
+			7:30	-	MALT	1942 Feb 16
2394
+			9:00	-	JST	1945 Sep 12
2395
+			7:30	-	MALT	1965 Aug  9 # independence
2396
+			7:30	-	SGT	1982 Jan  1 # Singapore Time
2397
+			8:00	-	SGT
2398
+
2399
+# Spratly Is
2400
+# no information
2401
+
2402
+# Sri Lanka
2403
+# From Paul Eggert (1996-09-03):
2404
+# "Sri Lanka advances clock by an hour to avoid blackout"
2405
+# (www.virtual-pc.com/lankaweb/news/items/240596-2.html, 1996-05-24,
2406
+# no longer available as of 1999-08-17)
2407
+# reported ``the country's standard time will be put forward by one hour at
2408
+# midnight Friday (1830 GMT) `in the light of the present power crisis'.''
2409
+#
2410
+# From Dharmasiri Senanayake, Sri Lanka Media Minister (1996-10-24), as quoted
2411
+# by Shamindra in
2412
+# <a href="news:54rka5$m5h@mtinsc01-mgt.ops.worldnet.att.net">
2413
+# Daily News - Hot News Section (1996-10-26)
2414
+# </a>:
2415
+# With effect from 12.30 a.m. on 26th October 1996
2416
+# Sri Lanka will be six (06) hours ahead of GMT.
2417
+
2418
+# From Jesper Norgaard Welen (2006-04-14), quoting Sri Lanka News Online
2419
+# <http://news.sinhalaya.com/wmview.php?ArtID=11002> (2006-04-13):
2420
+# 0030 hrs on April 15, 2006 (midnight of April 14, 2006 +30 minutes)
2421
+# at present, become 2400 hours of April 14, 2006 (midnight of April 14, 2006).
2422
+
2423
+# From Peter Apps and Ranga Sirila of Reuters (2006-04-12) in:
2424
+# <http://today.reuters.co.uk/news/newsArticle.aspx?type=scienceNews&storyID=2006-04-12T172228Z_01_COL295762_RTRIDST_0_SCIENCE-SRILANKA-TIME-DC.XML>
2425
+# [The Tamil Tigers] never accepted the original 1996 time change and simply
2426
+# kept their clocks set five and a half hours ahead of Greenwich Mean
2427
+# Time (GMT), in line with neighbor India.
2428
+# From Paul Eggert (2006-04-18):
2429
+# People who live in regions under Tamil control can use [TZ='Asia/Kolkata'],
2430
+# as that zone has agreed with the Tamil areas since our cutoff date of 1970.
2431
+
2432
+# From K Sethu (2006-04-25):
2433
+# I think the abbreviation LKT originated from the world of computers at
2434
+# the time of or subsequent to the time zone changes by SL Government
2435
+# twice in 1996 and probably SL Government or its standardization
2436
+# agencies never declared an abbreviation as a national standard.
2437
+#
2438
+# I recollect before the recent change the government annoucemments
2439
+# mentioning it as simply changing Sri Lanka Standard Time or Sri Lanka
2440
+# Time and no mention was made about the abbreviation.
2441
+#
2442
+# If we look at Sri Lanka Department of Government's "Official News
2443
+# Website of Sri Lanka" ... http://www.news.lk/ we can see that they
2444
+# use SLT as abbreviation in time stamp at the beginning of each news
2445
+# item....
2446
+#
2447
+# Within Sri Lanka I think LKT is well known among computer users and
2448
+# adminsitrators.  In my opinion SLT may not be a good choice because the
2449
+# nation's largest telcom / internet operator Sri Lanka Telcom is well
2450
+# known by that abbreviation - simply as SLT (there IP domains are
2451
+# slt.lk and sltnet.lk).
2452
+#
2453
+# But if indeed our government has adopted SLT as standard abbreviation
2454
+# (that we have not known so far) then  it is better that it be used for
2455
+# all computers.
2456
+
2457
+# From Paul Eggert (2006-04-25):
2458
+# One possibility is that we wait for a bit for the dust to settle down
2459
+# and then see what people actually say in practice.
2460
+
2461
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2462
+Zone	Asia/Colombo	5:19:24 -	LMT	1880
2463
+			5:19:32	-	MMT	1906	# Moratuwa Mean Time
2464
+			5:30	-	IST	1942 Jan  5
2465
+			5:30	0:30	IHST	1942 Sep
2466
+			5:30	1:00	IST	1945 Oct 16 2:00
2467
+			5:30	-	IST	1996 May 25 0:00
2468
+			6:30	-	LKT	1996 Oct 26 0:30
2469
+			6:00	-	LKT	2006 Apr 15 0:30
2470
+			5:30	-	IST
2471
+
2472
+# Syria
2473
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
2474
+Rule	Syria	1920	1923	-	Apr	Sun>=15	2:00	1:00	S
2475
+Rule	Syria	1920	1923	-	Oct	Sun>=1	2:00	0	-
2476
+Rule	Syria	1962	only	-	Apr	29	2:00	1:00	S
2477
+Rule	Syria	1962	only	-	Oct	1	2:00	0	-
2478
+Rule	Syria	1963	1965	-	May	1	2:00	1:00	S
2479
+Rule	Syria	1963	only	-	Sep	30	2:00	0	-
2480
+Rule	Syria	1964	only	-	Oct	1	2:00	0	-
2481
+Rule	Syria	1965	only	-	Sep	30	2:00	0	-
2482
+Rule	Syria	1966	only	-	Apr	24	2:00	1:00	S
2483
+Rule	Syria	1966	1976	-	Oct	1	2:00	0	-
2484
+Rule	Syria	1967	1978	-	May	1	2:00	1:00	S
2485
+Rule	Syria	1977	1978	-	Sep	1	2:00	0	-
2486
+Rule	Syria	1983	1984	-	Apr	9	2:00	1:00	S
2487
+Rule	Syria	1983	1984	-	Oct	1	2:00	0	-
2488
+Rule	Syria	1986	only	-	Feb	16	2:00	1:00	S
2489
+Rule	Syria	1986	only	-	Oct	9	2:00	0	-
2490
+Rule	Syria	1987	only	-	Mar	1	2:00	1:00	S
2491
+Rule	Syria	1987	1988	-	Oct	31	2:00	0	-
2492
+Rule	Syria	1988	only	-	Mar	15	2:00	1:00	S
2493
+Rule	Syria	1989	only	-	Mar	31	2:00	1:00	S
2494
+Rule	Syria	1989	only	-	Oct	1	2:00	0	-
2495
+Rule	Syria	1990	only	-	Apr	1	2:00	1:00	S
2496
+Rule	Syria	1990	only	-	Sep	30	2:00	0	-
2497
+Rule	Syria	1991	only	-	Apr	 1	0:00	1:00	S
2498
+Rule	Syria	1991	1992	-	Oct	 1	0:00	0	-
2499
+Rule	Syria	1992	only	-	Apr	 8	0:00	1:00	S
2500
+Rule	Syria	1993	only	-	Mar	26	0:00	1:00	S
2501
+Rule	Syria	1993	only	-	Sep	25	0:00	0	-
2502
+# IATA SSIM (1998-02) says 1998-04-02;
2503
+# (1998-09) says 1999-03-29 and 1999-09-29; (1999-02) says 1999-04-02,
2504
+# 2000-04-02, and 2001-04-02; (1999-09) says 2000-03-31 and 2001-03-31;
2505
+# (2006) says 2006-03-31 and 2006-09-22;
2506
+# for now ignore all these claims and go with Shanks & Pottenger,
2507
+# except for the 2006-09-22 claim (which seems right for Ramadan).
2508
+Rule	Syria	1994	1996	-	Apr	 1	0:00	1:00	S
2509
+Rule	Syria	1994	2005	-	Oct	 1	0:00	0	-
2510
+Rule	Syria	1997	1998	-	Mar	lastMon	0:00	1:00	S
2511
+Rule	Syria	1999	2006	-	Apr	 1	0:00	1:00	S
2512
+# From Stephen Colebourne (2006-09-18):
2513
+# According to IATA data, Syria will change DST on 21st September [21:00 UTC]
2514
+# this year [only]....  This is probably related to Ramadan, like Egypt.
2515
+Rule	Syria	2006	only	-	Sep	22	0:00	0	-
2516
+# From Paul Eggert (2007-03-29):
2517
+# Today the AP reported "Syria will switch to summertime at midnight Thursday."
2518
+# http://www.iht.com/articles/ap/2007/03/29/africa/ME-GEN-Syria-Time-Change.php
2519
+Rule	Syria	2007	only	-	Mar	lastFri	0:00	1:00	S
2520
+# From Jesper Norgard (2007-10-27):
2521
+# The sister center ICARDA of my work CIMMYT is confirming that Syria DST will
2522
+# not take place 1.st November at 0:00 o'clock but 1.st November at 24:00 or
2523
+# rather Midnight between Thursday and Friday. This does make more sence than
2524
+# having it between Wednesday and Thursday (two workdays in Syria) since the
2525
+# weekend in Syria is not Saturday and Sunday, but Friday and Saturday. So now
2526
+# it is implemented at midnight of the last workday before weekend...
2527
+#
2528
+# From Steffen Thorsen (2007-10-27):
2529
+# Jesper Norgaard Welen wrote:
2530
+#
2531
+# > "Winter local time in Syria will be observed at midnight of Thursday 1
2532
+# > November 2007, and the clock will be put back 1 hour."
2533
+#
2534
+# I found confirmation on this in this gov.sy-article (Arabic):
2535
+# http://wehda.alwehda.gov.sy/_print_veiw.asp?FileName=12521710520070926111247
2536
+#
2537
+# which using Google's translate tools says:
2538
+# Council of Ministers also approved the commencement of work on
2539
+# identifying the winter time as of Friday, 2/11/2007 where the 60th
2540
+# minute delay at midnight Thursday 1/11/2007.
2541
+Rule	Syria	2007	only	-	Nov	 Fri>=1	0:00	0	-
2542
+
2543
+# From Stephen Colebourne (2008-03-17):
2544
+# For everyone's info, I saw an IATA time zone change for [Syria] for
2545
+# this month (March 2008) in the last day or so...This is the data IATA
2546
+# are now using:
2547
+# Country     Time Standard   --- DST Start ---   --- DST End ---  DST
2548
+# Name        Zone Variation   Time    Date        Time    Date
2549
+# Variation
2550
+# Syrian Arab
2551
+# Republic    SY    +0200      2200  03APR08       2100  30SEP08   +0300
2552
+#                              2200  02APR09       2100  30SEP09   +0300
2553
+#                              2200  01APR10       2100  30SEP10   +0300
2554
+
2555
+# From Arthur David Olson (2008-03-17):
2556
+# Here's a link to English-language coverage by the Syrian Arab News
2557
+# Agency (SANA)...
2558
+# <a href="http://www.sana.sy/eng/21/2008/03/11/165173.htm">
2559
+# http://www.sana.sy/eng/21/2008/03/11/165173.htm
2560
+# </a>...which reads (in part) "The Cabinet approved the suggestion of the
2561
+# Ministry of Electricity to begin daylight savings time on Friday April
2562
+# 4th, advancing clocks one hour ahead on midnight of Thursday April 3rd."
2563
+# Since Syria is two hours east of UTC, the 2200 and 2100 transition times
2564
+# shown above match up with midnight in Syria.
2565
+
2566
+# From Arthur David Olson (2008-03-18):
2567
+# My buest guess at a Syrian rule is "the Friday nearest April 1";
2568
+# coding that involves either using a "Mar Fri>=29" construct that old time zone
2569
+# compilers can't handle  or having multiple Rules (a la Israel).
2570
+# For now, use "Apr Fri>=1", and go with IATA on a uniform Sep 30 end.
2571
+
2572
+# From Steffen Thorsen (2008-10-07):
2573
+# Syria has now officially decided to end DST on 2008-11-01 this year,
2574
+# according to the following article in the Syrian Arab News Agency (SANA).
2575
+#
2576
+# The article is in Arabic, and seems to tell that they will go back to
2577
+# winter time on 2008-11-01 at 00:00 local daylight time (delaying/setting
2578
+# clocks back 60 minutes).
2579
+#
2580
+# <a href="http://sana.sy/ara/2/2008/10/07/195459.htm">
2581
+# http://sana.sy/ara/2/2008/10/07/195459.htm
2582
+# </a>
2583
+
2584
+# From Steffen Thorsen (2009-03-19):
2585
+# Syria will start DST on 2009-03-27 00:00 this year according to many sources,
2586
+# two examples:
2587
+#
2588
+# <a href="http://www.sana.sy/eng/21/2009/03/17/217563.htm">
2589
+# http://www.sana.sy/eng/21/2009/03/17/217563.htm
2590
+# </a>
2591
+# (English, Syrian Arab News # Agency)
2592
+# <a href="http://thawra.alwehda.gov.sy/_View_news2.asp?FileName=94459258720090318012209">
2593
+# http://thawra.alwehda.gov.sy/_View_news2.asp?FileName=94459258720090318012209
2594
+# </a>
2595
+# (Arabic, gov-site)
2596
+#
2597
+# We have not found any sources saying anything about when DST ends this year.
2598
+#
2599
+# Our summary
2600
+# <a href="http://www.timeanddate.com/news/time/syria-dst-starts-march-27-2009.html">
2601
+# http://www.timeanddate.com/news/time/syria-dst-starts-march-27-2009.html
2602
+# </a>
2603
+
2604
+# From Steffen Thorsen (2009-10-27):
2605
+# The Syrian Arab News Network on 2009-09-29 reported that Syria will
2606
+# revert back to winter (standard) time on midnight between Thursday
2607
+# 2009-10-29 and Friday 2009-10-30:
2608
+# <a href="http://www.sana.sy/ara/2/2009/09/29/247012.htm">
2609
+# http://www.sana.sy/ara/2/2009/09/29/247012.htm (Arabic)
2610
+# </a>
2611
+
2612
+# From Arthur David Olson (2009-10-28):
2613
+# We'll see if future DST switching times turn out to be end of the last
2614
+# Thursday of the month or the start of the last Friday of the month or
2615
+# something else. For now, use the start of the last Friday.
2616
+
2617
+# From Steffen Thorsen (2010-03-17):
2618
+# The "Syrian News Station" reported on 2010-03-16 that the Council of
2619
+# Ministers has decided that Syria will start DST on midnight Thursday
2620
+# 2010-04-01: (midnight between Thursday and Friday):
2621
+# <a href="http://sns.sy/sns/?path=news/read/11421">
2622
+# http://sns.sy/sns/?path=news/read/11421 (Arabic)
2623
+# </a>
2624
+
2625
+# From Steffen Thorsen (2012-03-26):
2626
+# Today, Syria's government announced that they will start DST early on Friday
2627
+# (00:00). This is a bit earlier than the past two years.
2628
+#
2629
+# From Syrian Arab News Agency, in Arabic:
2630
+# <a href="http://www.sana.sy/ara/2/2012/03/26/408215.htm">
2631
+# http://www.sana.sy/ara/2/2012/03/26/408215.htm
2632
+# </a>
2633
+#
2634
+# Our brief summary:
2635
+# <a href="http://www.timeanddate.com/news/time/syria-dst-2012.html">
2636
+# http://www.timeanddate.com/news/time/syria-dst-2012.html
2637
+# </a>
2638
+
2639
+# From Arthur David Olson (2012-03-27):
2640
+# Assume last Friday in March going forward XXX.
2641
+
2642
+Rule	Syria	2008	only	-	Apr	Fri>=1	0:00	1:00	S
2643
+Rule	Syria	2008	only	-	Nov	1	0:00	0	-
2644
+Rule	Syria	2009	only	-	Mar	lastFri	0:00	1:00	S
2645
+Rule	Syria	2010	2011	-	Apr	Fri>=1	0:00	1:00	S
2646
+Rule	Syria	2012	max	-	Mar	lastFri	0:00	1:00	S
2647
+Rule	Syria	2009	max	-	Oct	lastFri	0:00	0	-
2648
+
2649
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2650
+Zone	Asia/Damascus	2:25:12 -	LMT	1920	# Dimashq
2651
+			2:00	Syria	EE%sT
2652
+
2653
+# Tajikistan
2654
+# From Shanks & Pottenger.
2655
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2656
+Zone	Asia/Dushanbe	4:35:12 -	LMT	1924 May  2
2657
+			5:00	-	DUST	1930 Jun 21 # Dushanbe Time
2658
+			6:00 RussiaAsia DUS%sT	1991 Mar 31 2:00s
2659
+			5:00	1:00	DUSST	1991 Sep  9 2:00s
2660
+			5:00	-	TJT		    # Tajikistan Time
2661
+
2662
+# Thailand
2663
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2664
+Zone	Asia/Bangkok	6:42:04	-	LMT	1880
2665
+			6:42:04	-	BMT	1920 Apr # Bangkok Mean Time
2666
+			7:00	-	ICT
2667
+
2668
+# Turkmenistan
2669
+# From Shanks & Pottenger.
2670
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2671
+Zone	Asia/Ashgabat	3:53:32 -	LMT	1924 May  2 # or Ashkhabad
2672
+			4:00	-	ASHT	1930 Jun 21 # Ashkhabad Time
2673
+			5:00 RussiaAsia	ASH%sT	1991 Mar 31 2:00
2674
+			4:00 RussiaAsia	ASH%sT	1991 Oct 27 # independence
2675
+			4:00 RussiaAsia	TM%sT	1992 Jan 19 2:00
2676
+			5:00	-	TMT
2677
+
2678
+# United Arab Emirates
2679
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2680
+Zone	Asia/Dubai	3:41:12 -	LMT	1920
2681
+			4:00	-	GST
2682
+
2683
+# Uzbekistan
2684
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2685
+Zone	Asia/Samarkand	4:27:12 -	LMT	1924 May  2
2686
+			4:00	-	SAMT	1930 Jun 21 # Samarkand Time
2687
+			5:00	-	SAMT	1981 Apr  1
2688
+			5:00	1:00	SAMST	1981 Oct  1
2689
+			6:00	-	TAST	1982 Apr  1 # Tashkent Time
2690
+			5:00 RussiaAsia	SAM%sT	1991 Sep  1 # independence
2691
+			5:00 RussiaAsia	UZ%sT	1992
2692
+			5:00	-	UZT
2693
+Zone	Asia/Tashkent	4:37:12 -	LMT	1924 May  2
2694
+			5:00	-	TAST	1930 Jun 21 # Tashkent Time
2695
+			6:00 RussiaAsia	TAS%sT	1991 Mar 31 2:00
2696
+			5:00 RussiaAsia	TAS%sT	1991 Sep  1 # independence
2697
+			5:00 RussiaAsia	UZ%sT	1992
2698
+			5:00	-	UZT
2699
+
2700
+# Vietnam
2701
+
2702
+# From Arthur David Olson (2008-03-18):
2703
+# The English-language name of Vietnam's most populous city is "Ho Chi Min City";
2704
+# we use Ho_Chi_Minh below to avoid a name of more than 14 characters.
2705
+
2706
+# From Shanks & Pottenger:
2707
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2708
+Zone	Asia/Ho_Chi_Minh	7:06:40 -	LMT	1906 Jun  9
2709
+			7:06:20	-	SMT	1911 Mar 11 0:01 # Saigon MT?
2710
+			7:00	-	ICT	1912 May
2711
+			8:00	-	ICT	1931 May
2712
+			7:00	-	ICT
2713
+
2714
+# Yemen
2715
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2716
+Zone	Asia/Aden	3:00:48	-	LMT	1950
2717
+			3:00	-	AST
... ...
@@ -0,0 +1,1719 @@
1
+# <pre>
2
+# This file is in the public domain, so clarified as of
3
+# 2009-05-17 by Arthur David Olson.
4
+
5
+# This file also includes Pacific islands.
6
+
7
+# Notes are at the end of this file
8
+
9
+###############################################################################
10
+
11
+# Australia
12
+
13
+# Please see the notes below for the controversy about "EST" versus "AEST" etc.
14
+
15
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
16
+Rule	Aus	1917	only	-	Jan	 1	0:01	1:00	-
17
+Rule	Aus	1917	only	-	Mar	25	2:00	0	-
18
+Rule	Aus	1942	only	-	Jan	 1	2:00	1:00	-
19
+Rule	Aus	1942	only	-	Mar	29	2:00	0	-
20
+Rule	Aus	1942	only	-	Sep	27	2:00	1:00	-
21
+Rule	Aus	1943	1944	-	Mar	lastSun	2:00	0	-
22
+Rule	Aus	1943	only	-	Oct	 3	2:00	1:00	-
23
+# Go with Whitman and the Australian National Standards Commission, which
24
+# says W Australia didn't use DST in 1943/1944.  Ignore Whitman's claim that
25
+# 1944/1945 was just like 1943/1944.
26
+
27
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
28
+# Northern Territory
29
+Zone Australia/Darwin	 8:43:20 -	LMT	1895 Feb
30
+			 9:00	-	CST	1899 May
31
+			 9:30	Aus	CST
32
+# Western Australia
33
+#
34
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
35
+Rule	AW	1974	only	-	Oct	lastSun	2:00s	1:00	-
36
+Rule	AW	1975	only	-	Mar	Sun>=1	2:00s	0	-
37
+Rule	AW	1983	only	-	Oct	lastSun	2:00s	1:00	-
38
+Rule	AW	1984	only	-	Mar	Sun>=1	2:00s	0	-
39
+Rule	AW	1991	only	-	Nov	17	2:00s	1:00	-
40
+Rule	AW	1992	only	-	Mar	Sun>=1	2:00s	0	-
41
+Rule	AW	2006	only	-	Dec	 3	2:00s	1:00	-
42
+Rule	AW	2007	2009	-	Mar	lastSun	2:00s	0	-
43
+Rule	AW	2007	2008	-	Oct	lastSun	2:00s	1:00	-
44
+Zone Australia/Perth	 7:43:24 -	LMT	1895 Dec
45
+			 8:00	Aus	WST	1943 Jul
46
+			 8:00	AW	WST
47
+Zone Australia/Eucla	 8:35:28 -	LMT	1895 Dec
48
+			 8:45	Aus	CWST	1943 Jul
49
+			 8:45	AW	CWST
50
+
51
+# Queensland
52
+#
53
+# From Alex Livingston (1996-11-01):
54
+# I have heard or read more than once that some resort islands off the coast
55
+# of Queensland chose to keep observing daylight-saving time even after
56
+# Queensland ceased to.
57
+#
58
+# From Paul Eggert (1996-11-22):
59
+# IATA SSIM (1993-02/1994-09) say that the Holiday Islands (Hayman, Lindeman,
60
+# Hamilton) observed DST for two years after the rest of Queensland stopped.
61
+# Hamilton is the largest, but there is also a Hamilton in Victoria,
62
+# so use Lindeman.
63
+#
64
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
65
+Rule	AQ	1971	only	-	Oct	lastSun	2:00s	1:00	-
66
+Rule	AQ	1972	only	-	Feb	lastSun	2:00s	0	-
67
+Rule	AQ	1989	1991	-	Oct	lastSun	2:00s	1:00	-
68
+Rule	AQ	1990	1992	-	Mar	Sun>=1	2:00s	0	-
69
+Rule	Holiday	1992	1993	-	Oct	lastSun	2:00s	1:00	-
70
+Rule	Holiday	1993	1994	-	Mar	Sun>=1	2:00s	0	-
71
+Zone Australia/Brisbane	10:12:08 -	LMT	1895
72
+			10:00	Aus	EST	1971
73
+			10:00	AQ	EST
74
+Zone Australia/Lindeman  9:55:56 -	LMT	1895
75
+			10:00	Aus	EST	1971
76
+			10:00	AQ	EST	1992 Jul
77
+			10:00	Holiday	EST
78
+
79
+# South Australia
80
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
81
+Rule	AS	1971	1985	-	Oct	lastSun	2:00s	1:00	-
82
+Rule	AS	1986	only	-	Oct	19	2:00s	1:00	-
83
+Rule	AS	1987	2007	-	Oct	lastSun	2:00s	1:00	-
84
+Rule	AS	1972	only	-	Feb	27	2:00s	0	-
85
+Rule	AS	1973	1985	-	Mar	Sun>=1	2:00s	0	-
86
+Rule	AS	1986	1990	-	Mar	Sun>=15	2:00s	0	-
87
+Rule	AS	1991	only	-	Mar	3	2:00s	0	-
88
+Rule	AS	1992	only	-	Mar	22	2:00s	0	-
89
+Rule	AS	1993	only	-	Mar	7	2:00s	0	-
90
+Rule	AS	1994	only	-	Mar	20	2:00s	0	-
91
+Rule	AS	1995	2005	-	Mar	lastSun	2:00s	0	-
92
+Rule	AS	2006	only	-	Apr	2	2:00s	0	-
93
+Rule	AS	2007	only	-	Mar	lastSun	2:00s	0	-
94
+Rule	AS	2008	max	-	Apr	Sun>=1	2:00s	0	-
95
+Rule	AS	2008	max	-	Oct	Sun>=1	2:00s	1:00	-
96
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
97
+Zone Australia/Adelaide	9:14:20 -	LMT	1895 Feb
98
+			9:00	-	CST	1899 May
99
+			9:30	Aus	CST	1971
100
+			9:30	AS	CST
101
+
102
+# Tasmania
103
+#
104
+# From Paul Eggert (2005-08-16):
105
+# <http://www.bom.gov.au/climate/averages/tables/dst_times.shtml>
106
+# says King Island didn't observe DST from WWII until late 1971.
107
+#
108
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
109
+Rule	AT	1967	only	-	Oct	Sun>=1	2:00s	1:00	-
110
+Rule	AT	1968	only	-	Mar	lastSun	2:00s	0	-
111
+Rule	AT	1968	1985	-	Oct	lastSun	2:00s	1:00	-
112
+Rule	AT	1969	1971	-	Mar	Sun>=8	2:00s	0	-
113
+Rule	AT	1972	only	-	Feb	lastSun	2:00s	0	-
114
+Rule	AT	1973	1981	-	Mar	Sun>=1	2:00s	0	-
115
+Rule	AT	1982	1983	-	Mar	lastSun	2:00s	0	-
116
+Rule	AT	1984	1986	-	Mar	Sun>=1	2:00s	0	-
117
+Rule	AT	1986	only	-	Oct	Sun>=15	2:00s	1:00	-
118
+Rule	AT	1987	1990	-	Mar	Sun>=15	2:00s	0	-
119
+Rule	AT	1987	only	-	Oct	Sun>=22	2:00s	1:00	-
120
+Rule	AT	1988	1990	-	Oct	lastSun	2:00s	1:00	-
121
+Rule	AT	1991	1999	-	Oct	Sun>=1	2:00s	1:00	-
122
+Rule	AT	1991	2005	-	Mar	lastSun	2:00s	0	-
123
+Rule	AT	2000	only	-	Aug	lastSun	2:00s	1:00	-
124
+Rule	AT	2001	max	-	Oct	Sun>=1	2:00s	1:00	-
125
+Rule	AT	2006	only	-	Apr	Sun>=1	2:00s	0	-
126
+Rule	AT	2007	only	-	Mar	lastSun	2:00s	0	-
127
+Rule	AT	2008	max	-	Apr	Sun>=1	2:00s	0	-
128
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
129
+Zone Australia/Hobart	9:49:16	-	LMT	1895 Sep
130
+			10:00	-	EST	1916 Oct 1 2:00
131
+			10:00	1:00	EST	1917 Feb
132
+			10:00	Aus	EST	1967
133
+			10:00	AT	EST
134
+Zone Australia/Currie	9:35:28	-	LMT	1895 Sep
135
+			10:00	-	EST	1916 Oct 1 2:00
136
+			10:00	1:00	EST	1917 Feb
137
+			10:00	Aus	EST	1971 Jul
138
+			10:00	AT	EST
139
+
140
+# Victoria
141
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
142
+Rule	AV	1971	1985	-	Oct	lastSun	2:00s	1:00	-
143
+Rule	AV	1972	only	-	Feb	lastSun	2:00s	0	-
144
+Rule	AV	1973	1985	-	Mar	Sun>=1	2:00s	0	-
145
+Rule	AV	1986	1990	-	Mar	Sun>=15	2:00s	0	-
146
+Rule	AV	1986	1987	-	Oct	Sun>=15	2:00s	1:00	-
147
+Rule	AV	1988	1999	-	Oct	lastSun	2:00s	1:00	-
148
+Rule	AV	1991	1994	-	Mar	Sun>=1	2:00s	0	-
149
+Rule	AV	1995	2005	-	Mar	lastSun	2:00s	0	-
150
+Rule	AV	2000	only	-	Aug	lastSun	2:00s	1:00	-
151
+Rule	AV	2001	2007	-	Oct	lastSun	2:00s	1:00	-
152
+Rule	AV	2006	only	-	Apr	Sun>=1	2:00s	0	-
153
+Rule	AV	2007	only	-	Mar	lastSun	2:00s	0	-
154
+Rule	AV	2008	max	-	Apr	Sun>=1	2:00s	0	-
155
+Rule	AV	2008	max	-	Oct	Sun>=1	2:00s	1:00	-
156
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
157
+Zone Australia/Melbourne 9:39:52 -	LMT	1895 Feb
158
+			10:00	Aus	EST	1971
159
+			10:00	AV	EST
160
+
161
+# New South Wales
162
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
163
+Rule	AN	1971	1985	-	Oct	lastSun	2:00s	1:00	-
164
+Rule	AN	1972	only	-	Feb	27	2:00s	0	-
165
+Rule	AN	1973	1981	-	Mar	Sun>=1	2:00s	0	-
166
+Rule	AN	1982	only	-	Apr	Sun>=1	2:00s	0	-
167
+Rule	AN	1983	1985	-	Mar	Sun>=1	2:00s	0	-
168
+Rule	AN	1986	1989	-	Mar	Sun>=15	2:00s	0	-
169
+Rule	AN	1986	only	-	Oct	19	2:00s	1:00	-
170
+Rule	AN	1987	1999	-	Oct	lastSun	2:00s	1:00	-
171
+Rule	AN	1990	1995	-	Mar	Sun>=1	2:00s	0	-
172
+Rule	AN	1996	2005	-	Mar	lastSun	2:00s	0	-
173
+Rule	AN	2000	only	-	Aug	lastSun	2:00s	1:00	-
174
+Rule	AN	2001	2007	-	Oct	lastSun	2:00s	1:00	-
175
+Rule	AN	2006	only	-	Apr	Sun>=1	2:00s	0	-
176
+Rule	AN	2007	only	-	Mar	lastSun	2:00s	0	-
177
+Rule	AN	2008	max	-	Apr	Sun>=1	2:00s	0	-
178
+Rule	AN	2008	max	-	Oct	Sun>=1	2:00s	1:00	-
179
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
180
+Zone Australia/Sydney	10:04:52 -	LMT	1895 Feb
181
+			10:00	Aus	EST	1971
182
+			10:00	AN	EST
183
+Zone Australia/Broken_Hill 9:25:48 -	LMT	1895 Feb
184
+			10:00	-	EST	1896 Aug 23
185
+			9:00	-	CST	1899 May
186
+			9:30	Aus	CST	1971
187
+			9:30	AN	CST	2000
188
+			9:30	AS	CST
189
+
190
+# Lord Howe Island
191
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
192
+Rule	LH	1981	1984	-	Oct	lastSun	2:00	1:00	-
193
+Rule	LH	1982	1985	-	Mar	Sun>=1	2:00	0	-
194
+Rule	LH	1985	only	-	Oct	lastSun	2:00	0:30	-
195
+Rule	LH	1986	1989	-	Mar	Sun>=15	2:00	0	-
196
+Rule	LH	1986	only	-	Oct	19	2:00	0:30	-
197
+Rule	LH	1987	1999	-	Oct	lastSun	2:00	0:30	-
198
+Rule	LH	1990	1995	-	Mar	Sun>=1	2:00	0	-
199
+Rule	LH	1996	2005	-	Mar	lastSun	2:00	0	-
200
+Rule	LH	2000	only	-	Aug	lastSun	2:00	0:30	-
201
+Rule	LH	2001	2007	-	Oct	lastSun	2:00	0:30	-
202
+Rule	LH	2006	only	-	Apr	Sun>=1	2:00	0	-
203
+Rule	LH	2007	only	-	Mar	lastSun	2:00	0	-
204
+Rule	LH	2008	max	-	Apr	Sun>=1	2:00	0	-
205
+Rule	LH	2008	max	-	Oct	Sun>=1	2:00	0:30	-
206
+Zone Australia/Lord_Howe 10:36:20 -	LMT	1895 Feb
207
+			10:00	-	EST	1981 Mar
208
+			10:30	LH	LHST
209
+
210
+# Australian miscellany
211
+#
212
+# Ashmore Is, Cartier
213
+# no indigenous inhabitants; only seasonal caretakers
214
+# no times are set
215
+#
216
+# Coral Sea Is
217
+# no indigenous inhabitants; only meteorologists
218
+# no times are set
219
+#
220
+# Macquarie
221
+# permanent occupation (scientific station) since 1948;
222
+# sealing and penguin oil station operated 1888/1917
223
+# like Australia/Hobart
224
+
225
+# Christmas
226
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
227
+Zone Indian/Christmas	7:02:52 -	LMT	1895 Feb
228
+			7:00	-	CXT	# Christmas Island Time
229
+
230
+# Cook Is
231
+# From Shanks & Pottenger:
232
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
233
+Rule	Cook	1978	only	-	Nov	12	0:00	0:30	HS
234
+Rule	Cook	1979	1991	-	Mar	Sun>=1	0:00	0	-
235
+Rule	Cook	1979	1990	-	Oct	lastSun	0:00	0:30	HS
236
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
237
+Zone Pacific/Rarotonga	-10:39:04 -	LMT	1901		# Avarua
238
+			-10:30	-	CKT	1978 Nov 12	# Cook Is Time
239
+			-10:00	Cook	CK%sT
240
+
241
+# Cocos
242
+# These islands were ruled by the Ross family from about 1830 to 1978.
243
+# We don't know when standard time was introduced; for now, we guess 1900.
244
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
245
+Zone	Indian/Cocos	6:27:40	-	LMT	1900
246
+			6:30	-	CCT	# Cocos Islands Time
247
+
248
+# Fiji
249
+# From Alexander Krivenyshev (2009-11-10):
250
+# According to Fiji Broadcasting Corporation,  Fiji plans to re-introduce DST
251
+# from November 29th 2009  to April 25th 2010.
252
+#
253
+# "Daylight savings to commence this month"
254
+# <a href="http://www.radiofiji.com.fj/fullstory.php?id=23719">
255
+# http://www.radiofiji.com.fj/fullstory.php?id=23719
256
+# </a>
257
+# or
258
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_fiji01.html">
259
+# http://www.worldtimezone.com/dst_news/dst_news_fiji01.html
260
+# </a>
261
+
262
+# From Steffen Thorsen (2009-11-10):
263
+# The Fiji Government has posted some more details about the approved
264
+# amendments:
265
+# <a href="http://www.fiji.gov.fj/publish/page_16198.shtml">
266
+# http://www.fiji.gov.fj/publish/page_16198.shtml
267
+# </a>
268
+
269
+# From Steffen Thorsen (2010-03-03):
270
+# The Cabinet in Fiji has decided to end DST about a month early, on
271
+# 2010-03-28 at 03:00.
272
+# The plan is to observe DST again, from 2010-10-24 to sometime in March
273
+# 2011 (last Sunday a good guess?).
274
+#
275
+# Official source:
276
+# <a href="http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=1096:3310-cabinet-approves-change-in-daylight-savings-dates&catid=49:cabinet-releases&Itemid=166">
277
+# http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=1096:3310-cabinet-approves-change-in-daylight-savings-dates&catid=49:cabinet-releases&Itemid=166
278
+# </a>
279
+#
280
+# A bit more background info here:
281
+# <a href="http://www.timeanddate.com/news/time/fiji-dst-ends-march-2010.html">
282
+# http://www.timeanddate.com/news/time/fiji-dst-ends-march-2010.html
283
+# </a>
284
+
285
+# From Alexander Krivenyshev (2010-10-24):
286
+# According to Radio Fiji and Fiji Times online, Fiji will end DST 3
287
+# weeks earlier than expected - on March 6, 2011, not March 27, 2011...
288
+# Here is confirmation from Government of the Republic of the Fiji Islands,
289
+# Ministry of Information (fiji.gov.fj) web site:
290
+# <a href="http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=2608:daylight-savings&catid=71:press-releases&Itemid=155">
291
+# http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=2608:daylight-savings&catid=71:press-releases&Itemid=155
292
+# </a>
293
+# or
294
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_fiji04.html">
295
+# http://www.worldtimezone.com/dst_news/dst_news_fiji04.html
296
+# </a>
297
+
298
+# From Steffen Thorsen (2011-10-03):
299
+# Now the dates have been confirmed, and at least our start date
300
+# assumption was correct (end date was one week wrong).
301
+#
302
+# <a href="http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=4966:daylight-saving-starts-in-fiji&catid=71:press-releases&Itemid=155">
303
+# www.fiji.gov.fj/index.php?option=com_content&view=article&id=4966:daylight-saving-starts-in-fiji&catid=71:press-releases&Itemid=155
304
+# </a>
305
+# which says
306
+# Members of the public are reminded to change their time to one hour in
307
+# advance at 2am to 3am on October 23, 2011 and one hour back at 3am to
308
+# 2am on February 26 next year.
309
+
310
+# From Ken Rylander (2011-10-24)
311
+# Another change to the Fiji DST end date. In the TZ database the end date for
312
+# Fiji DST 2012, is currently Feb 26. This has been changed to Jan 22.
313
+#
314
+# <a href="http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=5017:amendments-to-daylight-savings&catid=71:press-releases&Itemid=155">
315
+# http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=5017:amendments-to-daylight-savings&catid=71:press-releases&Itemid=155
316
+# </a>
317
+# states:
318
+#
319
+# The end of daylight saving scheduled initially for the 26th of February 2012
320
+# has been brought forward to the 22nd of January 2012.
321
+# The commencement of daylight saving will remain unchanged and start
322
+# on the  23rd of October, 2011.
323
+
324
+# From the Fiji Government Online Portal (2012-08-21) via Steffen Thorsen:
325
+# The Minister for Labour, Industrial Relations and Employment Mr Jone Usamate
326
+# today confirmed that Fiji will start daylight savings at 2 am on Sunday 21st
327
+# October 2012 and end at 3 am on Sunday 20th January 2013.
328
+# http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=6702&catid=71&Itemid=155
329
+#
330
+# From Paul Eggert (2012-08-31):
331
+# For now, guess a pattern of the penultimate Sundays in October and January.
332
+
333
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
334
+Rule	Fiji	1998	1999	-	Nov	Sun>=1	2:00	1:00	S
335
+Rule	Fiji	1999	2000	-	Feb	lastSun	3:00	0	-
336
+Rule	Fiji	2009	only	-	Nov	29	2:00	1:00	S
337
+Rule	Fiji	2010	only	-	Mar	lastSun	3:00	0	-
338
+Rule	Fiji	2010	max	-	Oct	Sun>=18	2:00	1:00	S
339
+Rule	Fiji	2011	only	-	Mar	Sun>=1	3:00	0	-
340
+Rule	Fiji	2012	max	-	Jan	Sun>=18	3:00	0	-
341
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
342
+Zone	Pacific/Fiji	11:53:40 -	LMT	1915 Oct 26	# Suva
343
+			12:00	Fiji	FJ%sT	# Fiji Time
344
+
345
+# French Polynesia
346
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
347
+Zone	Pacific/Gambier	 -8:59:48 -	LMT	1912 Oct	# Rikitea
348
+			 -9:00	-	GAMT	# Gambier Time
349
+Zone	Pacific/Marquesas -9:18:00 -	LMT	1912 Oct
350
+			 -9:30	-	MART	# Marquesas Time
351
+Zone	Pacific/Tahiti	 -9:58:16 -	LMT	1912 Oct	# Papeete
352
+			-10:00	-	TAHT	# Tahiti Time
353
+# Clipperton (near North America) is administered from French Polynesia;
354
+# it is uninhabited.
355
+
356
+# Guam
357
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
358
+Zone	Pacific/Guam	-14:21:00 -	LMT	1844 Dec 31
359
+			 9:39:00 -	LMT	1901		# Agana
360
+			10:00	-	GST	2000 Dec 23	# Guam
361
+			10:00	-	ChST	# Chamorro Standard Time
362
+
363
+# Kiribati
364
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
365
+Zone Pacific/Tarawa	 11:32:04 -	LMT	1901		# Bairiki
366
+			 12:00	-	GILT		 # Gilbert Is Time
367
+Zone Pacific/Enderbury	-11:24:20 -	LMT	1901
368
+			-12:00	-	PHOT	1979 Oct # Phoenix Is Time
369
+			-11:00	-	PHOT	1995
370
+			 13:00	-	PHOT
371
+Zone Pacific/Kiritimati	-10:29:20 -	LMT	1901
372
+			-10:40	-	LINT	1979 Oct # Line Is Time
373
+			-10:00	-	LINT	1995
374
+			 14:00	-	LINT
375
+
376
+# N Mariana Is
377
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
378
+Zone Pacific/Saipan	-14:17:00 -	LMT	1844 Dec 31
379
+			 9:43:00 -	LMT	1901
380
+			 9:00	-	MPT	1969 Oct # N Mariana Is Time
381
+			10:00	-	MPT	2000 Dec 23
382
+			10:00	-	ChST	# Chamorro Standard Time
383
+
384
+# Marshall Is
385
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
386
+Zone Pacific/Majuro	11:24:48 -	LMT	1901
387
+			11:00	-	MHT	1969 Oct # Marshall Islands Time
388
+			12:00	-	MHT
389
+Zone Pacific/Kwajalein	11:09:20 -	LMT	1901
390
+			11:00	-	MHT	1969 Oct
391
+			-12:00	-	KWAT	1993 Aug 20	# Kwajalein Time
392
+			12:00	-	MHT
393
+
394
+# Micronesia
395
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
396
+Zone Pacific/Chuuk	10:07:08 -	LMT	1901
397
+			10:00	-	CHUT			# Chuuk Time
398
+Zone Pacific/Pohnpei	10:32:52 -	LMT	1901		# Kolonia
399
+			11:00	-	PONT			# Pohnpei Time
400
+Zone Pacific/Kosrae	10:51:56 -	LMT	1901
401
+			11:00	-	KOST	1969 Oct	# Kosrae Time
402
+			12:00	-	KOST	1999
403
+			11:00	-	KOST
404
+
405
+# Nauru
406
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
407
+Zone	Pacific/Nauru	11:07:40 -	LMT	1921 Jan 15	# Uaobe
408
+			11:30	-	NRT	1942 Mar 15	# Nauru Time
409
+			9:00	-	JST	1944 Aug 15
410
+			11:30	-	NRT	1979 May
411
+			12:00	-	NRT
412
+
413
+# New Caledonia
414
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
415
+Rule	NC	1977	1978	-	Dec	Sun>=1	0:00	1:00	S
416
+Rule	NC	1978	1979	-	Feb	27	0:00	0	-
417
+Rule	NC	1996	only	-	Dec	 1	2:00s	1:00	S
418
+# Shanks & Pottenger say the following was at 2:00; go with IATA.
419
+Rule	NC	1997	only	-	Mar	 2	2:00s	0	-
420
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
421
+Zone	Pacific/Noumea	11:05:48 -	LMT	1912 Jan 13
422
+			11:00	NC	NC%sT
423
+
424
+
425
+###############################################################################
426
+
427
+# New Zealand
428
+
429
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
430
+Rule	NZ	1927	only	-	Nov	 6	2:00	1:00	S
431
+Rule	NZ	1928	only	-	Mar	 4	2:00	0	M
432
+Rule	NZ	1928	1933	-	Oct	Sun>=8	2:00	0:30	S
433
+Rule	NZ	1929	1933	-	Mar	Sun>=15	2:00	0	M
434
+Rule	NZ	1934	1940	-	Apr	lastSun	2:00	0	M
435
+Rule	NZ	1934	1940	-	Sep	lastSun	2:00	0:30	S
436
+Rule	NZ	1946	only	-	Jan	 1	0:00	0	S
437
+# Since 1957 Chatham has been 45 minutes ahead of NZ, but there's no
438
+# convenient notation for this so we must duplicate the Rule lines.
439
+Rule	NZ	1974	only	-	Nov	Sun>=1	2:00s	1:00	D
440
+Rule	Chatham	1974	only	-	Nov	Sun>=1	2:45s	1:00	D
441
+Rule	NZ	1975	only	-	Feb	lastSun	2:00s	0	S
442
+Rule	Chatham	1975	only	-	Feb	lastSun	2:45s	0	S
443
+Rule	NZ	1975	1988	-	Oct	lastSun	2:00s	1:00	D
444
+Rule	Chatham	1975	1988	-	Oct	lastSun	2:45s	1:00	D
445
+Rule	NZ	1976	1989	-	Mar	Sun>=1	2:00s	0	S
446
+Rule	Chatham	1976	1989	-	Mar	Sun>=1	2:45s	0	S
447
+Rule	NZ	1989	only	-	Oct	Sun>=8	2:00s	1:00	D
448
+Rule	Chatham	1989	only	-	Oct	Sun>=8	2:45s	1:00	D
449
+Rule	NZ	1990	2006	-	Oct	Sun>=1	2:00s	1:00	D
450
+Rule	Chatham	1990	2006	-	Oct	Sun>=1	2:45s	1:00	D
451
+Rule	NZ	1990	2007	-	Mar	Sun>=15	2:00s	0	S
452
+Rule	Chatham	1990	2007	-	Mar	Sun>=15	2:45s	0	S
453
+Rule	NZ	2007	max	-	Sep	lastSun	2:00s	1:00	D
454
+Rule	Chatham	2007	max	-	Sep	lastSun	2:45s	1:00	D
455
+Rule	NZ	2008	max	-	Apr	Sun>=1	2:00s	0	S
456
+Rule	Chatham	2008	max	-	Apr	Sun>=1	2:45s	0	S
457
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
458
+Zone Pacific/Auckland	11:39:04 -	LMT	1868 Nov  2
459
+			11:30	NZ	NZ%sT	1946 Jan  1
460
+			12:00	NZ	NZ%sT
461
+Zone Pacific/Chatham	12:13:48 -	LMT	1957 Jan  1
462
+			12:45	Chatham	CHA%sT
463
+
464
+
465
+# Auckland Is
466
+# uninhabited; Maori and Moriori, colonial settlers, pastoralists, sealers,
467
+# and scientific personnel have wintered
468
+
469
+# Campbell I
470
+# minor whaling stations operated 1909/1914
471
+# scientific station operated 1941/1995;
472
+# previously whalers, sealers, pastoralists, and scientific personnel wintered
473
+# was probably like Pacific/Auckland
474
+
475
+###############################################################################
476
+
477
+
478
+# Niue
479
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
480
+Zone	Pacific/Niue	-11:19:40 -	LMT	1901		# Alofi
481
+			-11:20	-	NUT	1951	# Niue Time
482
+			-11:30	-	NUT	1978 Oct 1
483
+			-11:00	-	NUT
484
+
485
+# Norfolk
486
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
487
+Zone	Pacific/Norfolk	11:11:52 -	LMT	1901		# Kingston
488
+			11:12	-	NMT	1951	# Norfolk Mean Time
489
+			11:30	-	NFT		# Norfolk Time
490
+
491
+# Palau (Belau)
492
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
493
+Zone Pacific/Palau	8:57:56 -	LMT	1901		# Koror
494
+			9:00	-	PWT	# Palau Time
495
+
496
+# Papua New Guinea
497
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
498
+Zone Pacific/Port_Moresby 9:48:40 -	LMT	1880
499
+			9:48:32	-	PMMT	1895	# Port Moresby Mean Time
500
+			10:00	-	PGT		# Papua New Guinea Time
501
+
502
+# Pitcairn
503
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
504
+Zone Pacific/Pitcairn	-8:40:20 -	LMT	1901		# Adamstown
505
+			-8:30	-	PNT	1998 Apr 27 00:00
506
+			-8:00	-	PST	# Pitcairn Standard Time
507
+
508
+# American Samoa
509
+Zone Pacific/Pago_Pago	 12:37:12 -	LMT	1879 Jul  5
510
+			-11:22:48 -	LMT	1911
511
+			-11:30	-	SAMT	1950		# Samoa Time
512
+			-11:00	-	NST	1967 Apr	# N=Nome
513
+			-11:00	-	BST	1983 Nov 30	# B=Bering
514
+			-11:00	-	SST			# S=Samoa
515
+
516
+# Samoa
517
+
518
+# From Steffen Thorsen (2009-10-16):
519
+# We have been in contact with the government of Samoa again, and received
520
+# the following info:
521
+#
522
+# "Cabinet has now approved Daylight Saving to be effected next year
523
+# commencing from the last Sunday of September 2010 and conclude first
524
+# Sunday of April 2011."
525
+#
526
+# Background info:
527
+# <a href="http://www.timeanddate.com/news/time/samoa-dst-plan-2009.html">
528
+# http://www.timeanddate.com/news/time/samoa-dst-plan-2009.html
529
+# </a>
530
+#
531
+# Samoa's Daylight Saving Time Act 2009 is available here, but does not
532
+# contain any dates:
533
+# <a href="http://www.parliament.gov.ws/documents/acts/Daylight%20Saving%20Act%20%202009%20%28English%29%20-%20Final%207-7-091.pdf">
534
+# http://www.parliament.gov.ws/documents/acts/Daylight%20Saving%20Act%20%202009%20%28English%29%20-%20Final%207-7-091.pdf
535
+# </a>
536
+
537
+# From Laupue Raymond Hughes (2010-10-07):
538
+# Please see
539
+# <a href="http://www.mcil.gov.ws">
540
+# http://www.mcil.gov.ws
541
+# </a>,
542
+# the Ministry of Commerce, Industry and Labour (sideframe) "Last Sunday
543
+# September 2010 (26/09/10) - adjust clocks forward from 12:00 midnight
544
+# to 01:00am and First Sunday April 2011 (03/04/11) - adjust clocks
545
+# backwards from 1:00am to 12:00am"
546
+
547
+# From Laupue Raymond Hughes (2011-03-07):
548
+# I believe this will be posted shortly on the website
549
+# <a href="http://www.mcil.gov.ws">
550
+# www.mcil.gov.ws
551
+# </a>
552
+#
553
+# PUBLIC NOTICE ON DAYLIGHT SAVING TIME
554
+#
555
+# Pursuant to the Daylight Saving Act 2009 and Cabinets decision,
556
+# businesses and the general public are hereby advised that daylight
557
+# saving time is on the first Saturday of April 2011 (02/04/11).
558
+#
559
+# The public is therefore advised that when the standard time strikes
560
+# the hour of four oclock (4.00am or 0400 Hours) on the 2nd April 2011,
561
+# then all instruments used to measure standard time are to be
562
+# adjusted/changed to three oclock (3:00am or 0300Hrs).
563
+#
564
+# Margaret Fruean ACTING CHIEF EXECUTIVE OFFICER MINISTRY OF COMMERCE,
565
+# INDUSTRY AND LABOUR 28th February 2011
566
+
567
+# From David Zuelke (2011-05-09):
568
+# Subject: Samoa to move timezone from east to west of international date line
569
+#
570
+# <a href="http://www.morningstar.co.uk/uk/markets/newsfeeditem.aspx?id=138501958347963">
571
+# http://www.morningstar.co.uk/uk/markets/newsfeeditem.aspx?id=138501958347963
572
+# </a>
573
+
574
+# From Mark Sim-Smith (2011-08-17):
575
+# I have been in contact with Leilani Tuala Warren from the Samoa Law
576
+# Reform Commission, and she has sent me a copy of the Bill that she
577
+# confirmed has been passed...Most of the sections are about maps rather
578
+# than the time zone change, but I'll paste the relevant bits below. But
579
+# the essence is that at midnight 29 Dec (UTC-11 I suppose), Samoa
580
+# changes from UTC-11 to UTC+13:
581
+#
582
+# International Date Line Bill 2011
583
+#
584
+# AN ACT to provide for the change to standard time in Samoa and to make
585
+# consequential amendments to the position of the International Date
586
+# Line, and for related purposes.
587
+#
588
+# BE IT ENACTED by the Legislative Assembly of Samoa in Parliament
589
+# assembled as follows:
590
+#
591
+# 1. Short title and commencement-(1) This Act may be cited as the
592
+# International Date Line Act 2011. (2) Except for section 5(3) this Act
593
+# commences at 12 o'clock midnight, on Thursday 29th December 2011. (3)
594
+# Section 5(3) commences on the date of assent by the Head of State.
595
+#
596
+# [snip]
597
+#
598
+# 3. Interpretation - [snip] "Samoa standard time" in this Act and any
599
+# other statute of Samoa which refers to 'Samoa standard time' means the
600
+# time 13 hours in advance of Co-ordinated Universal Time.
601
+#
602
+# 4. Samoa standard time - (1) Upon the commencement of this Act, Samoa
603
+# standard time shall be set at 13 hours in advance of Co-ordinated
604
+# Universal Time for the whole of Samoa. (2) All references to Samoa's
605
+# time zone and to Samoa standard time in Samoa in all legislation and
606
+# instruments after the commencement of this Act shall be references to
607
+# Samoa standard time as provided for in this Act. (3) Nothing in this
608
+# Act affects the provisions of the Daylight Saving Act 2009, except that
609
+# it defines Samoa standard time....
610
+
611
+# From Laupue Raymond Hughes (2011-09-02):
612
+# <a href="http://www.mcil.gov.ws/mcil_publications.html">
613
+# http://www.mcil.gov.ws/mcil_publications.html
614
+# </a>
615
+#
616
+# here is the official website publication for Samoa DST and dateline change
617
+#
618
+# DST
619
+# Year	End	Time	Start	Time
620
+# 2011	- - -	- - -	24 September	3:00am to 4:00am
621
+# 2012	01 April	4:00am to 3:00am	- - -	- - -
622
+#
623
+# Dateline Change skip Friday 30th Dec 2011
624
+# Thursday 29th December 2011	23:59:59 Hours
625
+# Saturday 31st December 2011	00:00:00 Hours
626
+#
627
+# Clarification by Tim Parenti (2012-01-03):
628
+# Although Samoa has used Daylight Saving Time in the 2010-2011 and 2011-2012
629
+# seasons, there is not yet any indication that this trend will continue on
630
+# a regular basis. For now, we have explicitly listed the transitions below.
631
+#
632
+# From Nicky (2012-09-10):
633
+# Daylight Saving Time commences on Sunday 30th September 2012 and
634
+# ends on Sunday 7th of April 2013.
635
+#
636
+# Please find link below for more information.
637
+# http://www.mcil.gov.ws/mcil_publications.html
638
+#
639
+# That publication also includes dates for Summer of 2013/4 as well
640
+# which give the impression of a pattern in selecting dates for the
641
+# future, so for now, we will guess this will continue.
642
+
643
+# Western Samoa
644
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
645
+Rule	WS	2012	max	-	Sep	lastSun	3:00	1	D
646
+Rule	WS	2012	max	-	Apr	Sun>=1	4:00	0	-
647
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
648
+Zone Pacific/Apia	 12:33:04 -	LMT	1879 Jul  5
649
+			-11:26:56 -	LMT	1911
650
+			-11:30	-	SAMT	1950		# Samoa Time
651
+			-11:00	-	WST	2010 Sep 26
652
+			-11:00	1:00	WSDT	2011 Apr 2 4:00
653
+			-11:00	-	WST	2011 Sep 24 3:00
654
+			-11:00	1:00	WSDT	2011 Dec 30
655
+			 13:00	1:00	WSDT	2012 Apr Sun>=1 4:00
656
+			 13:00	WS	WS%sT
657
+
658
+# Solomon Is
659
+# excludes Bougainville, for which see Papua New Guinea
660
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
661
+Zone Pacific/Guadalcanal 10:39:48 -	LMT	1912 Oct	# Honiara
662
+			11:00	-	SBT	# Solomon Is Time
663
+
664
+# Tokelau Is
665
+#
666
+# From Gwillim Law (2011-12-29)
667
+# A correspondent informed me that Tokelau, like Samoa, will be skipping
668
+# December 31 this year ...
669
+#
670
+# From Steffen Thorsen (2012-07-25)
671
+# ... we double checked by calling hotels and offices based in Tokelau asking
672
+# about the time there, and they all told a time that agrees with UTC+13....
673
+# Shanks says UTC-10 from 1901 [but] ... there is a good chance the change
674
+# actually was to UTC-11 back then.
675
+#
676
+# From Paul Eggert (2012-07-25)
677
+# A Google Books snippet of Appendix to the Journals of the House of
678
+# Representatives of New Zealand, Session 1948,
679
+# <http://books.google.com/books?id=ZaVCAQAAIAAJ>, page 65, says Tokelau
680
+# was "11 hours slow on G.M.T."  Go with Thorsen and assume Shanks & Pottenger
681
+# are off by an hour starting in 1901.
682
+
683
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
684
+Zone	Pacific/Fakaofo	-11:24:56 -	LMT	1901
685
+			-11:00	-	TKT 2011 Dec 30	# Tokelau Time
686
+			13:00	-	TKT
687
+
688
+# Tonga
689
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
690
+Rule	Tonga	1999	only	-	Oct	 7	2:00s	1:00	S
691
+Rule	Tonga	2000	only	-	Mar	19	2:00s	0	-
692
+Rule	Tonga	2000	2001	-	Nov	Sun>=1	2:00	1:00	S
693
+Rule	Tonga	2001	2002	-	Jan	lastSun	2:00	0	-
694
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
695
+Zone Pacific/Tongatapu	12:19:20 -	LMT	1901
696
+			12:20	-	TOT	1941 # Tonga Time
697
+			13:00	-	TOT	1999
698
+			13:00	Tonga	TO%sT
699
+
700
+# Tuvalu
701
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
702
+Zone Pacific/Funafuti	11:56:52 -	LMT	1901
703
+			12:00	-	TVT	# Tuvalu Time
704
+
705
+
706
+# US minor outlying islands
707
+
708
+# Howland, Baker
709
+# Howland was mined for guano by American companies 1857-1878 and British
710
+# 1886-1891; Baker was similar but exact dates are not known.
711
+# Inhabited by civilians 1935-1942; U.S. military bases 1943-1944;
712
+# uninhabited thereafter.
713
+# Howland observed Hawaii Standard Time (UTC-10:30) in 1937;
714
+# see page 206 of Elgen M. Long and Marie K. Long,
715
+# Amelia Earhart: the Mystery Solved, Simon & Schuster (2000).
716
+# So most likely Howland and Baker observed Hawaii Time from 1935
717
+# until they were abandoned after the war.
718
+
719
+# Jarvis
720
+# Mined for guano by American companies 1857-1879 and British 1883?-1891?.
721
+# Inhabited by civilians 1935-1942; IGY scientific base 1957-1958;
722
+# uninhabited thereafter.
723
+# no information; was probably like Pacific/Kiritimati
724
+
725
+# Johnston
726
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
727
+Zone Pacific/Johnston	-10:00	-	HST
728
+
729
+# Kingman
730
+# uninhabited
731
+
732
+# Midway
733
+#
734
+# From Mark Brader (2005-01-23):
735
+# [Fallacies and Fantasies of Air Transport History, by R.E.G. Davies,
736
+# published 1994 by Paladwr Press, McLean, VA, USA; ISBN 0-9626483-5-3]
737
+# reproduced a Pan American Airways timeables from 1936, for their weekly
738
+# "Orient Express" flights between San Francisco and Manila, and connecting
739
+# flights to Chicago and the US East Coast.  As it uses some time zone
740
+# designations that I've never seen before:....
741
+# Fri. 6:30A Lv. HONOLOLU (Pearl Harbor), H.I.   H.L.T. Ar. 5:30P Sun.
742
+#  "   3:00P Ar. MIDWAY ISLAND . . . . . . . . . M.L.T. Lv. 6:00A  "
743
+#
744
+Zone Pacific/Midway	-11:49:28 -	LMT	1901
745
+			-11:00	-	NST	1956 Jun  3
746
+			-11:00	1:00	NDT	1956 Sep  2
747
+			-11:00	-	NST	1967 Apr	# N=Nome
748
+			-11:00	-	BST	1983 Nov 30	# B=Bering
749
+			-11:00	-	SST			# S=Samoa
750
+
751
+# Palmyra
752
+# uninhabited since World War II; was probably like Pacific/Kiritimati
753
+
754
+# Wake
755
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
756
+Zone	Pacific/Wake	11:06:28 -	LMT	1901
757
+			12:00	-	WAKT	# Wake Time
758
+
759
+
760
+# Vanuatu
761
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
762
+Rule	Vanuatu	1983	only	-	Sep	25	0:00	1:00	S
763
+Rule	Vanuatu	1984	1991	-	Mar	Sun>=23	0:00	0	-
764
+Rule	Vanuatu	1984	only	-	Oct	23	0:00	1:00	S
765
+Rule	Vanuatu	1985	1991	-	Sep	Sun>=23	0:00	1:00	S
766
+Rule	Vanuatu	1992	1993	-	Jan	Sun>=23	0:00	0	-
767
+Rule	Vanuatu	1992	only	-	Oct	Sun>=23	0:00	1:00	S
768
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
769
+Zone	Pacific/Efate	11:13:16 -	LMT	1912 Jan 13		# Vila
770
+			11:00	Vanuatu	VU%sT	# Vanuatu Time
771
+
772
+# Wallis and Futuna
773
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
774
+Zone	Pacific/Wallis	12:15:20 -	LMT	1901
775
+			12:00	-	WFT	# Wallis & Futuna Time
776
+
777
+###############################################################################
778
+
779
+# NOTES
780
+
781
+# This data is by no means authoritative; if you think you know better,
782
+# go ahead and edit the file (and please send any changes to
783
+# tz@iana.org for general use in the future).
784
+
785
+# From Paul Eggert (2006-03-22):
786
+# A good source for time zone historical data outside the U.S. is
787
+# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
788
+# San Diego: ACS Publications, Inc. (2003).
789
+#
790
+# Gwillim Law writes that a good source
791
+# for recent time zone data is the International Air Transport
792
+# Association's Standard Schedules Information Manual (IATA SSIM),
793
+# published semiannually.  Law sent in several helpful summaries
794
+# of the IATA's data after 1990.
795
+#
796
+# Except where otherwise noted, Shanks & Pottenger is the source for
797
+# entries through 1990, and IATA SSIM is the source for entries afterwards.
798
+#
799
+# Another source occasionally used is Edward W. Whitman, World Time Differences,
800
+# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
801
+# I found in the UCLA library.
802
+#
803
+# A reliable and entertaining source about time zones is
804
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
805
+#
806
+# I invented the abbreviations marked `*' in the following table;
807
+# the rest are from earlier versions of this file, or from other sources.
808
+# Corrections are welcome!
809
+#		std dst
810
+#		LMT	Local Mean Time
811
+#	  8:00	WST WST	Western Australia
812
+#	  8:45	CWST CWST Central Western Australia*
813
+#	  9:00	JST	Japan
814
+#	  9:30	CST CST	Central Australia
815
+#	 10:00	EST EST	Eastern Australia
816
+#	 10:00	ChST	Chamorro
817
+#	 10:30	LHST LHST Lord Howe*
818
+#	 11:30	NZMT NZST New Zealand through 1945
819
+#	 12:00	NZST NZDT New Zealand 1946-present
820
+#	 12:45	CHAST CHADT Chatham*
821
+#	-11:00	SST	Samoa
822
+#	-10:00	HST	Hawaii
823
+#	- 8:00	PST	Pitcairn*
824
+#
825
+# See the `northamerica' file for Hawaii.
826
+# See the `southamerica' file for Easter I and the Galapagos Is.
827
+
828
+###############################################################################
829
+
830
+# Australia
831
+
832
+# From Paul Eggert (2005-12-08):
833
+# <a href="http://www.bom.gov.au/climate/averages/tables/dst_times.shtml">
834
+# Implementation Dates of Daylight Saving Time within Australia
835
+# </a> summarizes daylight saving issues in Australia.
836
+
837
+# From Arthur David Olson (2005-12-12):
838
+# <a href="http://www.lawlink.nsw.gov.au/lawlink/Corporate/ll_agdinfo.nsf/pages/community_relations_daylight_saving">
839
+# Lawlink NSW:Daylight Saving in New South Wales
840
+# </a> covers New South Wales in particular.
841
+
842
+# From John Mackin (1991-03-06):
843
+# We in Australia have _never_ referred to DST as `daylight' time.
844
+# It is called `summer' time.  Now by a happy coincidence, `summer'
845
+# and `standard' happen to start with the same letter; hence, the
846
+# abbreviation does _not_ change...
847
+# The legislation does not actually define abbreviations, at least
848
+# in this State, but the abbreviation is just commonly taken to be the
849
+# initials of the phrase, and the legislation here uniformly uses
850
+# the phrase `summer time' and does not use the phrase `daylight
851
+# time'.
852
+# Announcers on the Commonwealth radio network, the ABC (for Australian
853
+# Broadcasting Commission), use the phrases `Eastern Standard Time'
854
+# or `Eastern Summer Time'.  (Note, though, that as I say in the
855
+# current australasia file, there is really no such thing.)  Announcers
856
+# on its overseas service, Radio Australia, use the same phrases
857
+# prefixed by the word `Australian' when referring to local times;
858
+# time announcements on that service, naturally enough, are made in UTC.
859
+
860
+# From Arthur David Olson (1992-03-08):
861
+# Given the above, what's chosen for year-round use is:
862
+#	CST	for any place operating at a GMTOFF of 9:30
863
+#	WST	for any place operating at a GMTOFF of 8:00
864
+#	EST	for any place operating at a GMTOFF of 10:00
865
+
866
+# From Chuck Soper (2006-06-01):
867
+# I recently found this Australian government web page on time zones:
868
+# <http://www.australia.gov.au/about-australia-13time>
869
+# And this government web page lists time zone names and abbreviations:
870
+# <http://www.bom.gov.au/climate/averages/tables/daysavtm.shtml>
871
+
872
+# From Paul Eggert (2001-04-05), summarizing a long discussion about "EST"
873
+# versus "AEST" etc.:
874
+#
875
+# I see the following points of dispute:
876
+#
877
+# * How important are unique time zone abbreviations?
878
+#
879
+#   Here I tend to agree with the point (most recently made by Chris
880
+#   Newman) that unique abbreviations should not be essential for proper
881
+#   operation of software.  We have other instances of ambiguity
882
+#   (e.g. "IST" denoting both "Israel Standard Time" and "Indian
883
+#   Standard Time"), and they are not likely to go away any time soon.
884
+#   In the old days, some software mistakenly relied on unique
885
+#   abbreviations, but this is becoming less true with time, and I don't
886
+#   think it's that important to cater to such software these days.
887
+#
888
+#   On the other hand, there is another motivation for unambiguous
889
+#   abbreviations: it cuts down on human confusion.  This is
890
+#   particularly true for Australia, where "EST" can mean one thing for
891
+#   time T and a different thing for time T plus 1 second.
892
+#
893
+# * Does the relevant legislation indicate which abbreviations should be used?
894
+#
895
+#   Here I tend to think that things are a mess, just as they are in
896
+#   many other countries.  We Americans are currently disagreeing about
897
+#   which abbreviation to use for the newly legislated Chamorro Standard
898
+#   Time, for example.
899
+#
900
+#   Personally, I would prefer to use common practice; I would like to
901
+#   refer to legislation only for examples of common practice, or as a
902
+#   tiebreaker.
903
+#
904
+# * Do Australians more often use "Eastern Daylight Time" or "Eastern
905
+#   Summer Time"?  Do they typically prefix the time zone names with
906
+#   the word "Australian"?
907
+#
908
+#   My own impression is that both "Daylight Time" and "Summer Time" are
909
+#   common and are widely understood, but that "Summer Time" is more
910
+#   popular; and that the leading "A" is also common but is omitted more
911
+#   often than not.  I just used AltaVista advanced search and got the
912
+#   following count of page hits:
913
+#
914
+#     1,103 "Eastern Summer Time" AND domain:au
915
+#       971 "Australian Eastern Summer Time" AND domain:au
916
+#       613 "Eastern Daylight Time" AND domain:au
917
+#       127 "Australian Eastern Daylight Time" AND domain:au
918
+#
919
+#   Here "Summer" seems quite a bit more popular than "Daylight",
920
+#   particularly when we know the time zone is Australian and not US,
921
+#   say.  The "Australian" prefix seems to be popular for Eastern Summer
922
+#   Time, but unpopular for Eastern Daylight Time.
923
+#
924
+#   For abbreviations, tools like AltaVista are less useful because of
925
+#   ambiguity.  Many hits are not really time zones, unfortunately, and
926
+#   many hits denote US time zones and not Australian ones.  But here
927
+#   are the hit counts anyway:
928
+#
929
+#     161,304 "EST" and domain:au
930
+#      25,156 "EDT" and domain:au
931
+#      18,263 "AEST" and domain:au
932
+#      10,416 "AEDT" and domain:au
933
+#
934
+#      14,538 "CST" and domain:au
935
+#       5,728 "CDT" and domain:au
936
+#         176 "ACST" and domain:au
937
+#          29 "ACDT" and domain:au
938
+#
939
+#       7,539 "WST" and domain:au
940
+#          68 "AWST" and domain:au
941
+#
942
+#   This data suggest that Australians tend to omit the "A" prefix in
943
+#   practice.  The situation for "ST" versus "DT" is less clear, given
944
+#   the ambiguities involved.
945
+#
946
+# * How do Australians feel about the abbreviations in the tz database?
947
+#
948
+#   If you just count Australians on this list, I count 2 in favor and 3
949
+#   against.  One of the "against" votes (David Keegel) counseled delay,
950
+#   saying that both AEST/AEDT and EST/EST are widely used and
951
+#   understood in Australia.
952
+
953
+# From Paul Eggert (1995-12-19):
954
+# Shanks & Pottenger report 2:00 for all autumn changes in Australia and NZ.
955
+# Mark Prior writes that his newspaper
956
+# reports that NSW's fall 1995 change will occur at 2:00,
957
+# but Robert Elz says it's been 3:00 in Victoria since 1970
958
+# and perhaps the newspaper's `2:00' is referring to standard time.
959
+# For now we'll continue to assume 2:00s for changes since 1960.
960
+
961
+# From Eric Ulevik (1998-01-05):
962
+#
963
+# Here are some URLs to Australian time legislation. These URLs are stable,
964
+# and should probably be included in the data file. There are probably more
965
+# relevant entries in this database.
966
+#
967
+# NSW (including LHI and Broken Hill):
968
+# <a href="http://www.austlii.edu.au/au/legis/nsw/consol_act/sta1987137/index.html">
969
+# Standard Time Act 1987 (updated 1995-04-04)
970
+# </a>
971
+# ACT
972
+# <a href="http://www.austlii.edu.au/au/legis/act/consol_act/stasta1972279/index.html">
973
+# Standard Time and Summer Time Act 1972
974
+# </a>
975
+# SA
976
+# <a href="http://www.austlii.edu.au/au/legis/sa/consol_act/sta1898137/index.html">
977
+# Standard Time Act, 1898
978
+# </a>
979
+
980
+# From David Grosz (2005-06-13):
981
+# It was announced last week that Daylight Saving would be extended by
982
+# one week next year to allow for the 2006 Commonwealth Games.
983
+# Daylight Saving is now to end for next year only on the first Sunday
984
+# in April instead of the last Sunday in March.
985
+#
986
+# From Gwillim Law (2005-06-14):
987
+# I did some Googling and found that all of those states (and territory) plan
988
+# to extend DST together in 2006.
989
+# ACT: http://www.cmd.act.gov.au/mediareleases/fileread.cfm?file=86.txt
990
+# New South Wales: http://www.thecouriermail.news.com.au/common/story_page/0,5936,15538869%255E1702,00.html
991
+# South Australia: http://www.news.com.au/story/0,10117,15555031-1246,00.html
992
+# Tasmania: http://www.media.tas.gov.au/release.php?id=14772
993
+# Victoria: I wasn't able to find anything separate, but the other articles
994
+# allude to it.
995
+# But not Queensland
996
+# http://www.news.com.au/story/0,10117,15564030-1248,00.html.
997
+
998
+# Northern Territory
999
+
1000
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
1001
+# # The NORTHERN TERRITORY..  [ Courtesy N.T. Dept of the Chief Minister ]
1002
+# #					[ Nov 1990 ]
1003
+# #	N.T. have never utilised any DST due to sub-tropical/tropical location.
1004
+# ...
1005
+# Zone        Australia/North         9:30    -       CST
1006
+
1007
+# From Bradley White (1991-03-04):
1008
+# A recent excerpt from an Australian newspaper...
1009
+# the Northern Territory do[es] not have daylight saving.
1010
+
1011
+# Western Australia
1012
+
1013
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
1014
+# #  The state of WESTERN AUSTRALIA..  [ Courtesy W.A. dept Premier+Cabinet ]
1015
+# #						[ Nov 1990 ]
1016
+# #	W.A. suffers from a great deal of public and political opposition to
1017
+# #	DST in principle. A bill is brought before parliament in most years, but
1018
+# #	usually defeated either in the upper house, or in party caucus
1019
+# #	before reaching parliament.
1020
+# ...
1021
+# Zone	Australia/West		8:00	AW	%sST
1022
+# ...
1023
+# Rule	AW	1974	only	-	Oct	lastSun	2:00	1:00	D
1024
+# Rule	AW	1975	only	-	Mar	Sun>=1	3:00	0	W
1025
+# Rule	AW	1983	only	-	Oct	lastSun	2:00	1:00	D
1026
+# Rule	AW	1984	only	-	Mar	Sun>=1	3:00	0	W
1027
+
1028
+# From Bradley White (1991-03-04):
1029
+# A recent excerpt from an Australian newspaper...
1030
+# Western Australia...do[es] not have daylight saving.
1031
+
1032
+# From John D. Newman via Bradley White (1991-11-02):
1033
+# Western Australia is still on "winter time". Some DH in Sydney
1034
+# rang me at home a few days ago at 6.00am. (He had just arrived at
1035
+# work at 9.00am.)
1036
+# W.A. is switching to Summer Time on Nov 17th just to confuse
1037
+# everybody again.
1038
+
1039
+# From Arthur David Olson (1992-03-08):
1040
+# The 1992 ending date used in the rules is a best guess;
1041
+# it matches what was used in the past.
1042
+
1043
+# <a href="http://www.bom.gov.au/faq/faqgen.htm">
1044
+# The Australian Bureau of Meteorology FAQ
1045
+# </a> (1999-09-27) writes that Giles Meteorological Station uses
1046
+# South Australian time even though it's located in Western Australia.
1047
+
1048
+# Queensland
1049
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
1050
+# #   The state of QUEENSLAND.. [ Courtesy Qld. Dept Premier Econ&Trade Devel ]
1051
+# #						[ Dec 1990 ]
1052
+# ...
1053
+# Zone	Australia/Queensland	10:00	AQ	%sST
1054
+# ...
1055
+# Rule	AQ	1971	only	-	Oct	lastSun	2:00	1:00	D
1056
+# Rule	AQ	1972	only	-	Feb	lastSun	3:00	0	E
1057
+# Rule	AQ	1989	max	-	Oct	lastSun	2:00	1:00	D
1058
+# Rule	AQ	1990	max	-	Mar	Sun>=1	3:00	0	E
1059
+
1060
+# From Bradley White (1989-12-24):
1061
+# "Australia/Queensland" now observes daylight time (i.e. from
1062
+# October 1989).
1063
+
1064
+# From Bradley White (1991-03-04):
1065
+# A recent excerpt from an Australian newspaper...
1066
+# ...Queensland...[has] agreed to end daylight saving
1067
+# at 3am tomorrow (March 3)...
1068
+
1069
+# From John Mackin (1991-03-06):
1070
+# I can certainly confirm for my part that Daylight Saving in NSW did in fact
1071
+# end on Sunday, 3 March.  I don't know at what hour, though.  (It surprised
1072
+# me.)
1073
+
1074
+# From Bradley White (1992-03-08):
1075
+# ...there was recently a referendum in Queensland which resulted
1076
+# in the experimental daylight saving system being abandoned. So, ...
1077
+# ...
1078
+# Rule	QLD	1989	1991	-	Oct	lastSun	2:00	1:00	D
1079
+# Rule	QLD	1990	1992	-	Mar	Sun>=1	3:00	0	S
1080
+# ...
1081
+
1082
+# From Arthur David Olson (1992-03-08):
1083
+# The chosen rules the union of the 1971/1972 change and the 1989-1992 changes.
1084
+
1085
+# From Christopher Hunt (2006-11-21), after an advance warning
1086
+# from Jesper Norgaard Welen (2006-11-01):
1087
+# WA are trialing DST for three years.
1088
+# <http://www.parliament.wa.gov.au/parliament/bills.nsf/9A1B183144403DA54825721200088DF1/$File/Bill175-1B.pdf>
1089
+
1090
+# From Rives McDow (2002-04-09):
1091
+# The most interesting region I have found consists of three towns on the
1092
+# southern coast....  South Australia observes daylight saving time; Western
1093
+# Australia does not.  The two states are one and a half hours apart.  The
1094
+# residents decided to forget about this nonsense of changing the clock so
1095
+# much and set the local time 20 hours and 45 minutes from the
1096
+# international date line, or right in the middle of the time of South
1097
+# Australia and Western Australia....
1098
+#
1099
+# From Paul Eggert (2002-04-09):
1100
+# This is confirmed by the section entitled
1101
+# "What's the deal with time zones???" in
1102
+# <http://www.earthsci.unimelb.edu.au/~awatkins/null.html>.
1103
+#
1104
+# From Alex Livingston (2006-12-07):
1105
+# ... it was just on four years ago that I drove along the Eyre Highway,
1106
+# which passes through eastern Western Australia close to the southern
1107
+# coast of the continent.
1108
+#
1109
+# I paid particular attention to the time kept there. There can be no
1110
+# dispute that UTC+08:45 was considered "the time" from the border
1111
+# village just inside the border with South Australia to as far west
1112
+# as just east of Caiguna. There can also be no dispute that Eucla is
1113
+# the largest population centre in this zone....
1114
+#
1115
+# Now that Western Australia is observing daylight saving, the
1116
+# question arose whether this part of the state would follow suit. I
1117
+# just called the border village and confirmed that indeed they have,
1118
+# meaning that they are now observing UTC+09:45.
1119
+#
1120
+# (2006-12-09):
1121
+# I personally doubt that either experimentation with daylight saving
1122
+# in WA or its introduction in SA had anything to do with the genesis
1123
+# of this time zone.  My hunch is that it's been around since well
1124
+# before 1975.  I remember seeing it noted on road maps decades ago.
1125
+
1126
+# From Paul Eggert (2006-12-15):
1127
+# For lack of better info, assume the tradition dates back to the
1128
+# introduction of standard time in 1895.
1129
+
1130
+
1131
+# southeast Australia
1132
+#
1133
+# From Paul Eggert (2007-07-23):
1134
+# Starting autumn 2008 Victoria, NSW, South Australia, Tasmania and the ACT
1135
+# end DST the first Sunday in April and start DST the first Sunday in October.
1136
+# http://www.theage.com.au/news/national/daylight-savings-to-span-six-months/2007/06/27/1182623966703.html
1137
+
1138
+
1139
+# South Australia
1140
+
1141
+# From Bradley White (1991-03-04):
1142
+# A recent excerpt from an Australian newspaper...
1143
+# ...South Australia...[has] agreed to end daylight saving
1144
+# at 3am tomorrow (March 3)...
1145
+
1146
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
1147
+# #   The state of SOUTH AUSTRALIA....[ Courtesy of S.A. Dept of Labour ]
1148
+# #						[ Nov 1990 ]
1149
+# ...
1150
+# Zone	Australia/South		9:30	AS	%sST
1151
+# ...
1152
+# Rule	 AS	1971	max	-	Oct	lastSun	2:00	1:00	D
1153
+# Rule	 AS	1972	1985	-	Mar	Sun>=1	3:00	0	C
1154
+# Rule	 AS	1986	1990	-	Mar	Sun>=15	3:00	0	C
1155
+# Rule	 AS	1991	max	-	Mar	Sun>=1	3:00	0	C
1156
+
1157
+# From Bradley White (1992-03-11):
1158
+# Recent correspondence with a friend in Adelaide
1159
+# contained the following exchange:  "Due to the Adelaide Festival,
1160
+# South Australia delays setting back our clocks for a few weeks."
1161
+
1162
+# From Robert Elz (1992-03-13):
1163
+# I heard that apparently (or at least, it appears that)
1164
+# South Aus will have an extra 3 weeks daylight saving every even
1165
+# numbered year (from 1990).  That's when the Adelaide Festival
1166
+# is on...
1167
+
1168
+# From Robert Elz (1992-03-16, 00:57:07 +1000):
1169
+# DST didn't end in Adelaide today (yesterday)....
1170
+# But whether it's "4th Sunday" or "2nd last Sunday" I have no idea whatever...
1171
+# (it's just as likely to be "the Sunday we pick for this year"...).
1172
+
1173
+# From Bradley White (1994-04-11):
1174
+# If Sun, 15 March, 1992 was at +1030 as kre asserts, but yet Sun, 20 March,
1175
+# 1994 was at +0930 as John Connolly's customer seems to assert, then I can
1176
+# only conclude that the actual rule is more complicated....
1177
+
1178
+# From John Warburton (1994-10-07):
1179
+# The new Daylight Savings dates for South Australia ...
1180
+# was gazetted in the Government Hansard on Sep 26 1994....
1181
+# start on last Sunday in October and end in last sunday in March.
1182
+
1183
+# From Paul Eggert (2007-07-23):
1184
+# See "southeast Australia" above for 2008 and later.
1185
+
1186
+# Tasmania
1187
+
1188
+# The rules for 1967 through 1991 were reported by George Shepherd
1189
+# via Simon Woodhead via Robert Elz (1991-03-06):
1190
+# #  The state of TASMANIA.. [Courtesy Tasmanian Dept of Premier + Cabinet ]
1191
+# #					[ Nov 1990 ]
1192
+
1193
+# From Bill Hart via Guy Harris (1991-10-10):
1194
+# Oh yes, the new daylight savings rules are uniquely tasmanian, we have
1195
+# 6 weeks a year now when we are out of sync with the rest of Australia
1196
+# (but nothing new about that).
1197
+
1198
+# From Alex Livingston (1999-10-04):
1199
+# I heard on the ABC (Australian Broadcasting Corporation) radio news on the
1200
+# (long) weekend that Tasmania, which usually goes its own way in this regard,
1201
+# has decided to join with most of NSW, the ACT, and most of Victoria
1202
+# (Australia) and start daylight saving on the last Sunday in August in 2000
1203
+# instead of the first Sunday in October.
1204
+
1205
+# Sim Alam (2000-07-03) reported a legal citation for the 2000/2001 rules:
1206
+# http://www.thelaw.tas.gov.au/fragview/42++1968+GS3A@EN+2000070300
1207
+
1208
+# From Paul Eggert (2007-07-23):
1209
+# See "southeast Australia" above for 2008 and later.
1210
+
1211
+# Victoria
1212
+
1213
+# The rules for 1971 through 1991 were reported by George Shepherd
1214
+# via Simon Woodhead via Robert Elz (1991-03-06):
1215
+# #   The state of VICTORIA.. [ Courtesy of Vic. Dept of Premier + Cabinet ]
1216
+# #						[ Nov 1990 ]
1217
+
1218
+# From Scott Harrington (2001-08-29):
1219
+# On KQED's "City Arts and Lectures" program last night I heard an
1220
+# interesting story about daylight savings time.  Dr. John Heilbron was
1221
+# discussing his book "The Sun in the Church: Cathedrals as Solar
1222
+# Observatories"[1], and in particular the Shrine of Remembrance[2] located
1223
+# in Melbourne, Australia.
1224
+#
1225
+# Apparently the shrine's main purpose is a beam of sunlight which
1226
+# illuminates a special spot on the floor at the 11th hour of the 11th day
1227
+# of the 11th month (Remembrance Day) every year in memory of Australia's
1228
+# fallen WWI soldiers.  And if you go there on Nov. 11, at 11am local time,
1229
+# you will indeed see the sunbeam illuminate the special spot at the
1230
+# expected time.
1231
+#
1232
+# However, that is only because of some special mirror contraption that had
1233
+# to be employed, since due to daylight savings time, the true solar time of
1234
+# the remembrance moment occurs one hour later (or earlier?).  Perhaps
1235
+# someone with more information on this jury-rig can tell us more.
1236
+#
1237
+# [1] http://www.hup.harvard.edu/catalog/HEISUN.html
1238
+# [2] http://www.shrine.org.au
1239
+
1240
+# From Paul Eggert (2007-07-23):
1241
+# See "southeast Australia" above for 2008 and later.
1242
+
1243
+# New South Wales
1244
+
1245
+# From Arthur David Olson:
1246
+# New South Wales and subjurisdictions have their own ideas of a fun time.
1247
+# Based on law library research by John Mackin,
1248
+# who notes:
1249
+#	In Australia, time is not legislated federally, but rather by the
1250
+#	individual states.  Thus, while such terms as ``Eastern Standard Time''
1251
+#	[I mean, of course, Australian EST, not any other kind] are in common
1252
+#	use, _they have NO REAL MEANING_, as they are not defined in the
1253
+#	legislation.  This is very important to understand.
1254
+#	I have researched New South Wales time only...
1255
+
1256
+# From Eric Ulevik (1999-05-26):
1257
+# DST will start in NSW on the last Sunday of August, rather than the usual
1258
+# October in 2000.  [See: Matthew Moore,
1259
+# <a href="http://www.smh.com.au/news/9905/26/pageone/pageone4.html">
1260
+# Two months more daylight saving
1261
+# </a>
1262
+# Sydney Morning Herald (1999-05-26).]
1263
+
1264
+# From Paul Eggert (1999-09-27):
1265
+# See the following official NSW source:
1266
+# <a href="http://dir.gis.nsw.gov.au/cgi-bin/genobject/document/other/daylightsaving/tigGmZ">
1267
+# Daylight Saving in New South Wales.
1268
+# </a>
1269
+#
1270
+# Narrabri Shire (NSW) council has announced it will ignore the extension of
1271
+# daylight saving next year.  See:
1272
+# <a href="http://abc.net.au/news/regionals/neweng/monthly/regeng-22jul1999-1.htm">
1273
+# Narrabri Council to ignore daylight saving
1274
+# </a> (1999-07-22).  For now, we'll wait to see if this really happens.
1275
+#
1276
+# Victoria will following NSW.  See:
1277
+# <a href="http://abc.net.au/local/news/olympics/1999/07/item19990728112314_1.htm">
1278
+# Vic to extend daylight saving
1279
+# </a> (1999-07-28).
1280
+#
1281
+# However, South Australia rejected the DST request.  See:
1282
+# <a href="http://abc.net.au/news/olympics/1999/07/item19990719151754_1.htm">
1283
+# South Australia rejects Olympics daylight savings request
1284
+# </a> (1999-07-19).
1285
+#
1286
+# Queensland also will not observe DST for the Olympics.  See:
1287
+# <a href="http://abc.net.au/news/olympics/1999/06/item19990601114608_1.htm">
1288
+# Qld says no to daylight savings for Olympics
1289
+# </a> (1999-06-01), which quotes Queensland Premier Peter Beattie as saying
1290
+# ``Look you've got to remember in my family when this came up last time
1291
+# I voted for it, my wife voted against it and she said to me it's all very
1292
+# well for you, you don't have to worry about getting the children out of
1293
+# bed, getting them to school, getting them to sleep at night.
1294
+# I've been through all this argument domestically...my wife rules.''
1295
+#
1296
+# Broken Hill will stick with South Australian time in 2000.  See:
1297
+# <a href="http://abc.net.au/news/regionals/brokenh/monthly/regbrok-21jul1999-6.htm">
1298
+# Broken Hill to be behind the times
1299
+# </a> (1999-07-21).
1300
+
1301
+# IATA SSIM (1998-09) says that the spring 2000 change for Australian
1302
+# Capital Territory, New South Wales except Lord Howe Island and Broken
1303
+# Hill, and Victoria will be August 27, presumably due to the Sydney Olympics.
1304
+
1305
+# From Eric Ulevik, referring to Sydney's Sun Herald (2000-08-13), page 29:
1306
+# The Queensland Premier Peter Beattie is encouraging northern NSW
1307
+# towns to use Queensland time.
1308
+
1309
+# From Paul Eggert (2007-07-23):
1310
+# See "southeast Australia" above for 2008 and later.
1311
+
1312
+# Yancowinna
1313
+
1314
+# From John Mackin (1989-01-04):
1315
+# `Broken Hill' means the County of Yancowinna.
1316
+
1317
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
1318
+# # YANCOWINNA..  [ Confirmation courtesy of Broken Hill Postmaster ]
1319
+# #					[ Dec 1990 ]
1320
+# ...
1321
+# # Yancowinna uses Central Standard Time, despite [its] location on the
1322
+# # New South Wales side of the S.A. border. Most business and social dealings
1323
+# # are with CST zones, therefore CST is legislated by local government
1324
+# # although the switch to Summer Time occurs in line with N.S.W. There have
1325
+# # been years when this did not apply, but the historical data is not
1326
+# # presently available.
1327
+# Zone	Australia/Yancowinna	9:30	 AY	%sST
1328
+# ...
1329
+# Rule	 AY	1971	1985	-	Oct	lastSun	2:00	1:00	D
1330
+# Rule	 AY	1972	only	-	Feb	lastSun	3:00	0	C
1331
+# [followed by other Rules]
1332
+
1333
+# Lord Howe Island
1334
+
1335
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
1336
+# LHI...		[ Courtesy of Pauline Van Winsen ]
1337
+#					[ Dec 1990 ]
1338
+# Lord Howe Island is located off the New South Wales coast, and is half an
1339
+# hour ahead of NSW time.
1340
+
1341
+# From James Lonergan, Secretary, Lord Howe Island Board (2000-01-27):
1342
+# Lord Howe Island summer time in 2000/2001 will commence on the same
1343
+# date as the rest of NSW (i.e. 2000-08-27).  For your information the
1344
+# Lord Howe Island Board (controlling authority for the Island) is
1345
+# seeking the community's views on various options for summer time
1346
+# arrangements on the Island, e.g. advance clocks by 1 full hour
1347
+# instead of only 30 minutes.  [Dependent] on the wishes of residents
1348
+# the Board may approach the NSW government to change the existing
1349
+# arrangements.  The starting date for summer time on the Island will
1350
+# however always coincide with the rest of NSW.
1351
+
1352
+# From James Lonergan, Secretary, Lord Howe Island Board (2000-10-25):
1353
+# Lord Howe Island advances clocks by 30 minutes during DST in NSW and retards
1354
+# clocks by 30 minutes when DST finishes. Since DST was most recently
1355
+# introduced in NSW, the "changeover" time on the Island has been 02:00 as
1356
+# shown on clocks on LHI. I guess this means that for 30 minutes at the start
1357
+# of DST, LHI is actually 1 hour ahead of the rest of NSW.
1358
+
1359
+# From Paul Eggert (2006-03-22):
1360
+# For Lord Howe dates we use Shanks & Pottenger through 1989, and
1361
+# Lonergan thereafter.  For times we use Lonergan.
1362
+
1363
+# From Paul Eggert (2007-07-23):
1364
+# See "southeast Australia" above for 2008 and later.
1365
+
1366
+# From Steffen Thorsen (2009-04-28):
1367
+# According to the official press release, South Australia's extended daylight
1368
+# saving period will continue with the same rules as used during the 2008-2009
1369
+# summer (southern hemisphere).
1370
+#
1371
+# From
1372
+# <a href="http://www.safework.sa.gov.au/uploaded_files/DaylightDatesSet.pdf">
1373
+# http://www.safework.sa.gov.au/uploaded_files/DaylightDatesSet.pdf
1374
+# </a>
1375
+# The extended daylight saving period that South Australia has been trialling
1376
+# for over the last year is now set to be ongoing.
1377
+# Daylight saving will continue to start on the first Sunday in October each
1378
+# year and finish on the first Sunday in April the following year.
1379
+# Industrial Relations Minister, Paul Caica, says this provides South Australia
1380
+# with a consistent half hour time difference with NSW, Victoria, Tasmania and
1381
+# the ACT for all 52 weeks of the year...
1382
+#
1383
+# We have a wrap-up here:
1384
+# <a href="http://www.timeanddate.com/news/time/south-australia-extends-dst.html">
1385
+# http://www.timeanddate.com/news/time/south-australia-extends-dst.html
1386
+# </a>
1387
+###############################################################################
1388
+
1389
+# New Zealand
1390
+
1391
+# From Mark Davies (1990-10-03):
1392
+# the 1989/90 year was a trial of an extended "daylight saving" period.
1393
+# This trial was deemed successful and the extended period adopted for
1394
+# subsequent years (with the addition of a further week at the start).
1395
+# source -- phone call to Ministry of Internal Affairs Head Office.
1396
+
1397
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
1398
+# # The Country of New Zealand   (Australia's east island -) Gee they hate that!
1399
+# #				   or is Australia the west island of N.Z.
1400
+# #	[ courtesy of Geoff Tribble.. Auckland N.Z. ]
1401
+# #				[ Nov 1990 ]
1402
+# ...
1403
+# Rule	NZ      1974    1988	-	Oct	lastSun	2:00	1:00	D
1404
+# Rule	NZ	1989	max	-	Oct	Sun>=1	2:00	1:00	D
1405
+# Rule	NZ      1975    1989	-	Mar	Sun>=1	3:00	0	S
1406
+# Rule	NZ	1990	max	-	Mar	lastSun	3:00	0	S
1407
+# ...
1408
+# Zone	NZ			12:00	NZ		NZ%sT	# New Zealand
1409
+# Zone	NZ-CHAT			12:45	-		NZ-CHAT # Chatham Island
1410
+
1411
+# From Arthur David Olson (1992-03-08):
1412
+# The chosen rules use the Davies October 8 values for the start of DST in 1989
1413
+# rather than the October 1 value.
1414
+
1415
+# From Paul Eggert (1995-12-19);
1416
+# Shank & Pottenger report 2:00 for all autumn changes in Australia and NZ.
1417
+# Robert Uzgalis writes that the New Zealand Daylight
1418
+# Savings Time Order in Council dated 1990-06-18 specifies 2:00 standard
1419
+# time on both the first Sunday in October and the third Sunday in March.
1420
+# As with Australia, we'll assume the tradition is 2:00s, not 2:00.
1421
+#
1422
+# From Paul Eggert (2006-03-22):
1423
+# The Department of Internal Affairs (DIA) maintains a brief history,
1424
+# as does Carol Squires; see tz-link.htm for the full references.
1425
+# Use these sources in preference to Shanks & Pottenger.
1426
+#
1427
+# For Chatham, IATA SSIM (1991/1999) gives the NZ rules but with
1428
+# transitions at 2:45 local standard time; this confirms that Chatham
1429
+# is always exactly 45 minutes ahead of Auckland.
1430
+
1431
+# From Colin Sharples (2007-04-30):
1432
+# DST will now start on the last Sunday in September, and end on the
1433
+# first Sunday in April.  The changes take effect this year, meaning
1434
+# that DST will begin on 2007-09-30 2008-04-06.
1435
+# http://www.dia.govt.nz/diawebsite.nsf/wpg_URL/Services-Daylight-Saving-Daylight-saving-to-be-extended
1436
+
1437
+###############################################################################
1438
+
1439
+
1440
+# Fiji
1441
+
1442
+# Howse writes (p 153) that in 1879 the British governor of Fiji
1443
+# enacted an ordinance standardizing the islands on Antipodean Time
1444
+# instead of the American system (which was one day behind).
1445
+
1446
+# From Rives McDow (1998-10-08):
1447
+# Fiji will introduce DST effective 0200 local time, 1998-11-01
1448
+# until 0300 local time 1999-02-28.  Each year the DST period will
1449
+# be from the first Sunday in November until the last Sunday in February.
1450
+
1451
+# From Paul Eggert (2000-01-08):
1452
+# IATA SSIM (1999-09) says DST ends 0100 local time.  Go with McDow.
1453
+
1454
+# From the BBC World Service (1998-10-31 11:32 UTC):
1455
+# The Fijiian government says the main reasons for the time change is to
1456
+# improve productivity and reduce road accidents.  But correspondents say it
1457
+# also hopes the move will boost Fiji's ability to compete with other pacific
1458
+# islands in the effort to attract tourists to witness the dawning of the new
1459
+# millenium.
1460
+
1461
+# http://www.fiji.gov.fj/press/2000_09/2000_09_13-05.shtml (2000-09-13)
1462
+# reports that Fiji has discontinued DST.
1463
+
1464
+# Johnston
1465
+
1466
+# Johnston data is from usno1995.
1467
+
1468
+
1469
+# Kiribati
1470
+
1471
+# From Paul Eggert (1996-01-22):
1472
+# Today's _Wall Street Journal_ (page 1) reports that Kiribati
1473
+# ``declared it the same day [throughout] the country as of Jan. 1, 1995''
1474
+# as part of the competition to be first into the 21st century.
1475
+
1476
+
1477
+# Kwajalein
1478
+
1479
+# In comp.risks 14.87 (26 August 1993), Peter Neumann writes:
1480
+# I wonder what happened in Kwajalein, where there was NO Friday,
1481
+# 1993-08-20.  Thursday night at midnight Kwajalein switched sides with
1482
+# respect to the International Date Line, to rejoin its fellow islands,
1483
+# going from 11:59 p.m. Thursday to 12:00 m. Saturday in a blink.
1484
+
1485
+
1486
+# N Mariana Is, Guam
1487
+
1488
+# Howse writes (p 153) ``The Spaniards, on the other hand, reached the
1489
+# Philippines and the Ladrones from America,'' and implies that the Ladrones
1490
+# (now called the Marianas) kept American date for quite some time.
1491
+# For now, we assume the Ladrones switched at the same time as the Philippines;
1492
+# see Asia/Manila.
1493
+
1494
+# US Public Law 106-564 (2000-12-23) made UTC+10 the official standard time,
1495
+# under the name "Chamorro Standard Time".  There is no official abbreviation,
1496
+# but Congressman Robert A. Underwood, author of the bill that became law,
1497
+# wrote in a press release (2000-12-27) that he will seek the use of "ChST".
1498
+
1499
+
1500
+# Micronesia
1501
+
1502
+# Alan Eugene Davis writes (1996-03-16),
1503
+# ``I am certain, having lived there for the past decade, that "Truk"
1504
+# (now properly known as Chuuk) ... is in the time zone GMT+10.''
1505
+#
1506
+# Shanks & Pottenger write that Truk switched from UTC+10 to UTC+11
1507
+# on 1978-10-01; ignore this for now.
1508
+
1509
+# From Paul Eggert (1999-10-29):
1510
+# The Federated States of Micronesia Visitors Board writes in
1511
+# <a href="http://www.fsmgov.org/info/clocks.html">
1512
+# The Federated States of Micronesia - Visitor Information
1513
+# </a> (1999-01-26)
1514
+# that Truk and Yap are UTC+10, and Ponape and Kosrae are UTC+11.
1515
+# We don't know when Kosrae switched from UTC+12; assume January 1 for now.
1516
+
1517
+
1518
+# Midway
1519
+
1520
+# From Charles T O'Connor, KMTH DJ (1956),
1521
+# quoted in the KTMH section of the Radio Heritage Collection
1522
+# <http://radiodx.com/spdxr/KMTH.htm> (2002-12-31):
1523
+# For the past two months we've been on what is known as Daylight
1524
+# Saving Time.  This time has put us on air at 5am in the morning,
1525
+# your time down there in New Zealand.  Starting September 2, 1956
1526
+# we'll again go back to Standard Time.  This'll mean that we'll go to
1527
+# air at 6am your time.
1528
+#
1529
+# From Paul Eggert (2003-03-23):
1530
+# We don't know the date of that quote, but we'll guess they
1531
+# started DST on June 3.  Possibly DST was observed other years
1532
+# in Midway, but we have no record of it.
1533
+
1534
+
1535
+# Pitcairn
1536
+
1537
+# From Rives McDow (1999-11-08):
1538
+# A Proclamation was signed by the Governor of Pitcairn on the 27th March 1998
1539
+# with regard to Pitcairn Standard Time.  The Proclamation is as follows.
1540
+#
1541
+#	The local time for general purposes in the Islands shall be
1542
+#	Co-ordinated Universal time minus 8 hours and shall be known
1543
+#	as Pitcairn Standard Time.
1544
+#
1545
+# ... I have also seen Pitcairn listed as UTC minus 9 hours in several
1546
+# references, and can only assume that this was an error in interpretation
1547
+# somehow in light of this proclamation.
1548
+
1549
+# From Rives McDow (1999-11-09):
1550
+# The Proclamation regarding Pitcairn time came into effect on 27 April 1998
1551
+# ... at midnight.
1552
+
1553
+# From Howie Phelps (1999-11-10), who talked to a Pitcairner via shortwave:
1554
+# Betty Christian told me yesterday that their local time is the same as
1555
+# Pacific Standard Time. They used to be 1/2 hour different from us here in
1556
+# Sacramento but it was changed a couple of years ago.
1557
+
1558
+
1559
+# Samoa
1560
+
1561
+# Howse writes (p 153, citing p 10 of the 1883-11-18 New York Herald)
1562
+# that in 1879 the King of Samoa decided to change
1563
+# ``the date in his kingdom from the Antipodean to the American system,
1564
+# ordaining -- by a masterpiece of diplomatic flattery -- that
1565
+# the Fourth of July should be celebrated twice in that year.''
1566
+
1567
+
1568
+# Tonga
1569
+
1570
+# From Paul Eggert (1996-01-22):
1571
+# Today's _Wall Street Journal_ (p 1) reports that ``Tonga has been plotting
1572
+# to sneak ahead of [New Zealanders] by introducing daylight-saving time.''
1573
+# Since Kiribati has moved the Date Line it's not clear what Tonga will do.
1574
+
1575
+# Don Mundell writes in the 1997-02-20 Tonga Chronicle
1576
+# <a href="http://www.tongatapu.net.to/tonga/homeland/timebegins.htm">
1577
+# How Tonga became `The Land where Time Begins'
1578
+# </a>:
1579
+
1580
+# Until 1941 Tonga maintained a standard time 50 minutes ahead of NZST
1581
+# 12 hours and 20 minutes ahead of GMT.  When New Zealand adjusted its
1582
+# standard time in 1940s, Tonga had the choice of subtracting from its
1583
+# local time to come on the same standard time as New Zealand or of
1584
+# advancing its time to maintain the differential of 13 degrees
1585
+# (approximately 50 minutes ahead of New Zealand time).
1586
+#
1587
+# Because His Majesty King Taufa'ahau Tupou IV, then Crown Prince
1588
+# Tungi, preferred to ensure Tonga's title as the land where time
1589
+# begins, the Legislative Assembly approved the latter change.
1590
+#
1591
+# But some of the older, more conservative members from the outer
1592
+# islands objected. "If at midnight on Dec. 31, we move ahead 40
1593
+# minutes, as your Royal Highness wishes, what becomes of the 40
1594
+# minutes we have lost?"
1595
+#
1596
+# The Crown Prince, presented an unanswerable argument: "Remember that
1597
+# on the World Day of Prayer, you would be the first people on Earth
1598
+# to say your prayers in the morning."
1599
+
1600
+# From Paul Eggert (2006-03-22):
1601
+# Shanks & Pottenger say the transition was on 1968-10-01; go with Mundell.
1602
+
1603
+# From Eric Ulevik (1999-05-03):
1604
+# Tonga's director of tourism, who is also secretary of the National Millenium
1605
+# Committee, has a plan to get Tonga back in front.
1606
+# He has proposed a one-off move to tropical daylight saving for Tonga from
1607
+# October to March, which has won approval in principle from the Tongan
1608
+# Government.
1609
+
1610
+# From Steffen Thorsen (1999-09-09):
1611
+# * Tonga will introduce DST in November
1612
+#
1613
+# I was given this link by John Letts:
1614
+# <a href="http://news.bbc.co.uk/hi/english/world/asia-pacific/newsid_424000/424764.stm">
1615
+# http://news.bbc.co.uk/hi/english/world/asia-pacific/newsid_424000/424764.stm
1616
+# </a>
1617
+#
1618
+# I have not been able to find exact dates for the transition in November
1619
+# yet. By reading this article it seems like Fiji will be 14 hours ahead
1620
+# of UTC as well, but as far as I know Fiji will only be 13 hours ahead
1621
+# (12 + 1 hour DST).
1622
+
1623
+# From Arthur David Olson (1999-09-20):
1624
+# According to <a href="http://www.tongaonline.com/news/sept1799.html">
1625
+# http://www.tongaonline.com/news/sept1799.html
1626
+# </a>:
1627
+# "Daylight Savings Time will take effect on Oct. 2 through April 15, 2000
1628
+# and annually thereafter from the first Saturday in October through the
1629
+# third Saturday of April.  Under the system approved by Privy Council on
1630
+# Sept. 10, clocks must be turned ahead one hour on the opening day and
1631
+# set back an hour on the closing date."
1632
+# Alas, no indication of the time of day.
1633
+
1634
+# From Rives McDow (1999-10-06):
1635
+# Tonga started its Daylight Saving on Saturday morning October 2nd at 0200am.
1636
+# Daylight Saving ends on April 16 at 0300am which is Sunday morning.
1637
+
1638
+# From Steffen Thorsen (2000-10-31):
1639
+# Back in March I found a notice on the website http://www.tongaonline.com
1640
+# that Tonga changed back to standard time one month early, on March 19
1641
+# instead of the original reported date April 16. Unfortunately, the article
1642
+# is no longer available on the site, and I did not make a copy of the
1643
+# text, and I have forgotten to report it here.
1644
+# (Original URL was: http://www.tongaonline.com/news/march162000.htm )
1645
+
1646
+# From Rives McDow (2000-12-01):
1647
+# Tonga is observing DST as of 2000-11-04 and will stop on 2001-01-27.
1648
+
1649
+# From Sione Moala-Mafi (2001-09-20) via Rives McDow:
1650
+# At 2:00am on the first Sunday of November, the standard time in the Kingdom
1651
+# shall be moved forward by one hour to 3:00am.  At 2:00am on the last Sunday
1652
+# of January the standard time in the Kingdom shall be moved backward by one
1653
+# hour to 1:00am.
1654
+
1655
+# From Pulu 'Anau (2002-11-05):
1656
+# The law was for 3 years, supposedly to get renewed.  It wasn't.
1657
+
1658
+
1659
+# Wake
1660
+
1661
+# From Vernice Anderson, Personal Secretary to Philip Jessup,
1662
+# US Ambassador At Large (oral history interview, 1971-02-02):
1663
+#
1664
+# Saturday, the 14th [of October, 1950] -- ...  The time was all the
1665
+# more confusing at that point, because we had crossed the
1666
+# International Date Line, thus getting two Sundays.  Furthermore, we
1667
+# discovered that Wake Island had two hours of daylight saving time
1668
+# making calculation of time in Washington difficult if not almost
1669
+# impossible.
1670
+#
1671
+# http://www.trumanlibrary.org/wake/meeting.htm
1672
+
1673
+# From Paul Eggert (2003-03-23):
1674
+# We have no other report of DST in Wake Island, so omit this info for now.
1675
+
1676
+###############################################################################
1677
+
1678
+# The International Date Line
1679
+
1680
+# From Gwillim Law (2000-01-03):
1681
+#
1682
+# The International Date Line is not defined by any international standard,
1683
+# convention, or treaty.  Mapmakers are free to draw it as they please.
1684
+# Reputable mapmakers will simply ensure that every point of land appears on
1685
+# the correct side of the IDL, according to the date legally observed there.
1686
+#
1687
+# When Kiribati adopted a uniform date in 1995, thereby moving the Phoenix and
1688
+# Line Islands to the west side of the IDL (or, if you prefer, moving the IDL
1689
+# to the east side of the Phoenix and Line Islands), I suppose that most
1690
+# mapmakers redrew the IDL following the boundary of Kiribati.  Even that line
1691
+# has a rather arbitrary nature.  The straight-line boundaries between Pacific
1692
+# island nations that are shown on many maps are based on an international
1693
+# convention, but are not legally binding national borders.... The date is
1694
+# governed by the IDL; therefore, even on the high seas, there may be some
1695
+# places as late as fourteen hours later than UTC.  And, since the IDL is not
1696
+# an international standard, there are some places on the high seas where the
1697
+# correct date is ambiguous.
1698
+
1699
+# From Wikipedia <http://en.wikipedia.org/wiki/Time_zone> (2005-08-31):
1700
+# Before 1920, all ships kept local apparent time on the high seas by setting
1701
+# their clocks at night or at the morning sight so that, given the ship's
1702
+# speed and direction, it would be 12 o'clock when the Sun crossed the ship's
1703
+# meridian (12 o'clock = local apparent noon).  During 1917, at the
1704
+# Anglo-French Conference on Time-keeping at Sea, it was recommended that all
1705
+# ships, both military and civilian, should adopt hourly standard time zones
1706
+# on the high seas.  Whenever a ship was within the territorial waters of any
1707
+# nation it would use that nation's standard time.  The captain was permitted
1708
+# to change his ship's clocks at a time of his choice following his ship's
1709
+# entry into another zone time--he often chose midnight.  These zones were
1710
+# adopted by all major fleets between 1920 and 1925 but not by many
1711
+# independent merchant ships until World War II.
1712
+
1713
+# From Paul Eggert, using references suggested by Oscar van Vlijmen
1714
+# (2005-03-20):
1715
+#
1716
+# The American Practical Navigator (2002)
1717
+# <http://pollux.nss.nima.mil/pubs/pubs_j_apn_sections.html?rid=187>
1718
+# talks only about the 180-degree meridian with respect to ships in
1719
+# international waters; it ignores the international date line.
... ...
@@ -0,0 +1,117 @@
1
+# <pre>
2
+# This file is in the public domain, so clarified as of
3
+# 2009-05-17 by Arthur David Olson.
4
+
5
+# This file provides links between current names for time zones
6
+# and their old names.  Many names changed in late 1993.
7
+
8
+Link	Africa/Asmara		Africa/Asmera
9
+Link	Africa/Bamako		Africa/Timbuktu
10
+Link	America/Argentina/Catamarca	America/Argentina/ComodRivadavia
11
+Link	America/Adak		America/Atka
12
+Link	America/Argentina/Buenos_Aires	America/Buenos_Aires
13
+Link	America/Argentina/Catamarca	America/Catamarca
14
+Link	America/Atikokan	America/Coral_Harbour
15
+Link	America/Argentina/Cordoba	America/Cordoba
16
+Link	America/Tijuana		America/Ensenada
17
+Link	America/Indiana/Indianapolis	America/Fort_Wayne
18
+Link	America/Indiana/Indianapolis	America/Indianapolis
19
+Link	America/Argentina/Jujuy	America/Jujuy
20
+Link	America/Indiana/Knox	America/Knox_IN
21
+Link	America/Kentucky/Louisville	America/Louisville
22
+Link	America/Argentina/Mendoza	America/Mendoza
23
+Link	America/Rio_Branco	America/Porto_Acre
24
+Link	America/Argentina/Cordoba	America/Rosario
25
+Link	America/St_Thomas	America/Virgin
26
+Link	Asia/Ashgabat		Asia/Ashkhabad
27
+Link	Asia/Chongqing		Asia/Chungking
28
+Link	Asia/Dhaka		Asia/Dacca
29
+Link	Asia/Kathmandu		Asia/Katmandu
30
+Link	Asia/Kolkata		Asia/Calcutta
31
+Link	Asia/Macau		Asia/Macao
32
+Link	Asia/Jerusalem		Asia/Tel_Aviv
33
+Link	Asia/Ho_Chi_Minh	Asia/Saigon
34
+Link	Asia/Thimphu		Asia/Thimbu
35
+Link	Asia/Makassar		Asia/Ujung_Pandang
36
+Link	Asia/Ulaanbaatar	Asia/Ulan_Bator
37
+Link	Atlantic/Faroe		Atlantic/Faeroe
38
+Link	Europe/Oslo		Atlantic/Jan_Mayen
39
+Link	Australia/Sydney	Australia/ACT
40
+Link	Australia/Sydney	Australia/Canberra
41
+Link	Australia/Lord_Howe	Australia/LHI
42
+Link	Australia/Sydney	Australia/NSW
43
+Link	Australia/Darwin	Australia/North
44
+Link	Australia/Brisbane	Australia/Queensland
45
+Link	Australia/Adelaide	Australia/South
46
+Link	Australia/Hobart	Australia/Tasmania
47
+Link	Australia/Melbourne	Australia/Victoria
48
+Link	Australia/Perth		Australia/West
49
+Link	Australia/Broken_Hill	Australia/Yancowinna
50
+Link	America/Rio_Branco	Brazil/Acre
51
+Link	America/Noronha		Brazil/DeNoronha
52
+Link	America/Sao_Paulo	Brazil/East
53
+Link	America/Manaus		Brazil/West
54
+Link	America/Halifax		Canada/Atlantic
55
+Link	America/Winnipeg	Canada/Central
56
+Link	America/Regina		Canada/East-Saskatchewan
57
+Link	America/Toronto		Canada/Eastern
58
+Link	America/Edmonton	Canada/Mountain
59
+Link	America/St_Johns	Canada/Newfoundland
60
+Link	America/Vancouver	Canada/Pacific
61
+Link	America/Regina		Canada/Saskatchewan
62
+Link	America/Whitehorse	Canada/Yukon
63
+Link	America/Santiago	Chile/Continental
64
+Link	Pacific/Easter		Chile/EasterIsland
65
+Link	America/Havana		Cuba
66
+Link	Africa/Cairo		Egypt
67
+Link	Europe/Dublin		Eire
68
+Link	Europe/London		Europe/Belfast
69
+Link	Europe/Chisinau		Europe/Tiraspol
70
+Link	Europe/London		GB
71
+Link	Europe/London		GB-Eire
72
+Link	Etc/GMT			GMT+0
73
+Link	Etc/GMT			GMT-0
74
+Link	Etc/GMT			GMT0
75
+Link	Etc/GMT			Greenwich
76
+Link	Asia/Hong_Kong		Hongkong
77
+Link	Atlantic/Reykjavik	Iceland
78
+Link	Asia/Tehran		Iran
79
+Link	Asia/Jerusalem		Israel
80
+Link	America/Jamaica		Jamaica
81
+Link	Asia/Tokyo		Japan
82
+Link	Pacific/Kwajalein	Kwajalein
83
+Link	Africa/Tripoli		Libya
84
+Link	America/Tijuana		Mexico/BajaNorte
85
+Link	America/Mazatlan	Mexico/BajaSur
86
+Link	America/Mexico_City	Mexico/General
87
+Link	Pacific/Auckland	NZ
88
+Link	Pacific/Chatham		NZ-CHAT
89
+Link	America/Denver		Navajo
90
+Link	Asia/Shanghai		PRC
91
+Link	Pacific/Pago_Pago	Pacific/Samoa
92
+Link	Pacific/Chuuk		Pacific/Yap
93
+Link	Pacific/Chuuk		Pacific/Truk
94
+Link	Pacific/Pohnpei		Pacific/Ponape
95
+Link	Europe/Warsaw		Poland
96
+Link	Europe/Lisbon		Portugal
97
+Link	Asia/Taipei		ROC
98
+Link	Asia/Seoul		ROK
99
+Link	Asia/Singapore		Singapore
100
+Link	Europe/Istanbul		Turkey
101
+Link	Etc/UCT			UCT
102
+Link	America/Anchorage	US/Alaska
103
+Link	America/Adak		US/Aleutian
104
+Link	America/Phoenix		US/Arizona
105
+Link	America/Chicago		US/Central
106
+Link	America/Indiana/Indianapolis	US/East-Indiana
107
+Link	America/New_York	US/Eastern
108
+Link	Pacific/Honolulu	US/Hawaii
109
+Link	America/Indiana/Knox	US/Indiana-Starke
110
+Link	America/Detroit		US/Michigan
111
+Link	America/Denver		US/Mountain
112
+Link	America/Los_Angeles	US/Pacific
113
+Link	Pacific/Pago_Pago	US/Samoa
114
+Link	Etc/UTC			UTC
115
+Link	Etc/UTC			Universal
116
+Link	Europe/Moscow		W-SU
117
+Link	Etc/UTC			Zulu
... ...
@@ -0,0 +1,81 @@
1
+# <pre>
2
+# This file is in the public domain, so clarified as of
3
+# 2009-05-17 by Arthur David Olson.
4
+
5
+# These entries are mostly present for historical reasons, so that
6
+# people in areas not otherwise covered by the tz files could "zic -l"
7
+# to a time zone that was right for their area.  These days, the
8
+# tz files cover almost all the inhabited world, and the only practical
9
+# need now for the entries that are not on UTC are for ships at sea
10
+# that cannot use POSIX TZ settings.
11
+
12
+Zone	Etc/GMT		0	-	GMT
13
+Zone	Etc/UTC		0	-	UTC
14
+Zone	Etc/UCT		0	-	UCT
15
+
16
+# The following link uses older naming conventions,
17
+# but it belongs here, not in the file `backward',
18
+# as functions like gmtime load the "GMT" file to handle leap seconds properly.
19
+# We want this to work even on installations that omit the other older names.
20
+Link	Etc/GMT				GMT
21
+
22
+Link	Etc/UTC				Etc/Universal
23
+Link	Etc/UTC				Etc/Zulu
24
+
25
+Link	Etc/GMT				Etc/Greenwich
26
+Link	Etc/GMT				Etc/GMT-0
27
+Link	Etc/GMT				Etc/GMT+0
28
+Link	Etc/GMT				Etc/GMT0
29
+
30
+# We use POSIX-style signs in the Zone names and the output abbreviations,
31
+# even though this is the opposite of what many people expect.
32
+# POSIX has positive signs west of Greenwich, but many people expect
33
+# positive signs east of Greenwich.  For example, TZ='Etc/GMT+4' uses
34
+# the abbreviation "GMT+4" and corresponds to 4 hours behind UTC
35
+# (i.e. west of Greenwich) even though many people would expect it to
36
+# mean 4 hours ahead of UTC (i.e. east of Greenwich).
37
+#
38
+# In the draft 5 of POSIX 1003.1-200x, the angle bracket notation allows for
39
+# TZ='<GMT-4>+4'; if you want time zone abbreviations conforming to
40
+# ISO 8601 you can use TZ='<-0400>+4'.  Thus the commonly-expected
41
+# offset is kept within the angle bracket (and is used for display)
42
+# while the POSIX sign is kept outside the angle bracket (and is used
43
+# for calculation).
44
+#
45
+# Do not use a TZ setting like TZ='GMT+4', which is four hours behind
46
+# GMT but uses the completely misleading abbreviation "GMT".
47
+
48
+# Earlier incarnations of this package were not POSIX-compliant,
49
+# and had lines such as
50
+#		Zone	GMT-12		-12	-	GMT-1200
51
+# We did not want things to change quietly if someone accustomed to the old
52
+# way does a
53
+#		zic -l GMT-12
54
+# so we moved the names into the Etc subdirectory.
55
+
56
+Zone	Etc/GMT-14	14	-	GMT-14	# 14 hours ahead of GMT
57
+Zone	Etc/GMT-13	13	-	GMT-13
58
+Zone	Etc/GMT-12	12	-	GMT-12
59
+Zone	Etc/GMT-11	11	-	GMT-11
60
+Zone	Etc/GMT-10	10	-	GMT-10
61
+Zone	Etc/GMT-9	9	-	GMT-9
62
+Zone	Etc/GMT-8	8	-	GMT-8
63
+Zone	Etc/GMT-7	7	-	GMT-7
64
+Zone	Etc/GMT-6	6	-	GMT-6
65
+Zone	Etc/GMT-5	5	-	GMT-5
66
+Zone	Etc/GMT-4	4	-	GMT-4
67
+Zone	Etc/GMT-3	3	-	GMT-3
68
+Zone	Etc/GMT-2	2	-	GMT-2
69
+Zone	Etc/GMT-1	1	-	GMT-1
70
+Zone	Etc/GMT+1	-1	-	GMT+1
71
+Zone	Etc/GMT+2	-2	-	GMT+2
72
+Zone	Etc/GMT+3	-3	-	GMT+3
73
+Zone	Etc/GMT+4	-4	-	GMT+4
74
+Zone	Etc/GMT+5	-5	-	GMT+5
75
+Zone	Etc/GMT+6	-6	-	GMT+6
76
+Zone	Etc/GMT+7	-7	-	GMT+7
77
+Zone	Etc/GMT+8	-8	-	GMT+8
78
+Zone	Etc/GMT+9	-9	-	GMT+9
79
+Zone	Etc/GMT+10	-10	-	GMT+10
80
+Zone	Etc/GMT+11	-11	-	GMT+11
81
+Zone	Etc/GMT+12	-12	-	GMT+12
... ...
@@ -0,0 +1,2856 @@
1
+# <pre>
2
+# This file is in the public domain, so clarified as of
3
+# 2009-05-17 by Arthur David Olson.
4
+
5
+# This data is by no means authoritative; if you think you know better,
6
+# go ahead and edit the file (and please send any changes to
7
+# tz@iana.org for general use in the future).
8
+
9
+# From Paul Eggert (2006-03-22):
10
+# A good source for time zone historical data outside the U.S. is
11
+# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
12
+# San Diego: ACS Publications, Inc. (2003).
13
+#
14
+# Gwillim Law writes that a good source
15
+# for recent time zone data is the International Air Transport
16
+# Association's Standard Schedules Information Manual (IATA SSIM),
17
+# published semiannually.  Law sent in several helpful summaries
18
+# of the IATA's data after 1990.
19
+#
20
+# Except where otherwise noted, Shanks & Pottenger is the source for
21
+# entries through 1991, and IATA SSIM is the source for entries afterwards.
22
+#
23
+# Other sources occasionally used include:
24
+#
25
+#	Edward W. Whitman, World Time Differences,
26
+#	Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated),
27
+#	which I found in the UCLA library.
28
+#
29
+#	<a href="http://www.pettswoodvillage.co.uk/Daylight_Savings_William_Willett.pdf">
30
+#	William Willett, The Waste of Daylight, 19th edition
31
+#	</a> (1914-03)
32
+#
33
+#	Brazil's Departamento Servico da Hora (DSH),
34
+#	<a href="http://pcdsh01.on.br/HISTHV.htm">
35
+#	History of Summer Time
36
+#	</a> (1998-09-21, in Portuguese)
37
+
38
+#
39
+# I invented the abbreviations marked `*' in the following table;
40
+# the rest are from earlier versions of this file, or from other sources.
41
+# Corrections are welcome!
42
+#                   std dst  2dst
43
+#                   LMT           Local Mean Time
44
+#       -4:00       AST ADT       Atlantic
45
+#       -3:00       WGT WGST      Western Greenland*
46
+#       -1:00       EGT EGST      Eastern Greenland*
47
+#        0:00       GMT BST  BDST Greenwich, British Summer
48
+#        0:00       GMT IST       Greenwich, Irish Summer
49
+#        0:00       WET WEST WEMT Western Europe
50
+#        0:19:32.13 AMT NST       Amsterdam, Netherlands Summer (1835-1937)*
51
+#        0:20       NET NEST      Netherlands (1937-1940)*
52
+#        1:00       CET CEST CEMT Central Europe
53
+#        1:00:14    SET           Swedish (1879-1899)*
54
+#        2:00       EET EEST      Eastern Europe
55
+#        3:00       MSK MSD       Moscow
56
+#
57
+# A reliable and entertaining source about time zones, especially in Britain,
58
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
59
+
60
+# From Peter Ilieve (1994-12-04),
61
+# The original six [EU members]: Belgium, France, (West) Germany, Italy,
62
+# Luxembourg, the Netherlands.
63
+# Plus, from 1 Jan 73: Denmark, Ireland, United Kingdom.
64
+# Plus, from 1 Jan 81: Greece.
65
+# Plus, from 1 Jan 86: Spain, Portugal.
66
+# Plus, from 1 Jan 95: Austria, Finland, Sweden. (Norway negotiated terms for
67
+# entry but in a referendum on 28 Nov 94 the people voted No by 52.2% to 47.8%
68
+# on a turnout of 88.6%. This was almost the same result as Norway's previous
69
+# referendum in 1972, they are the only country to have said No twice.
70
+# Referendums in the other three countries voted Yes.)
71
+# ...
72
+# Estonia ... uses EU dates but not at 01:00 GMT, they use midnight GMT.
73
+# I don't think they know yet what they will do from 1996 onwards.
74
+# ...
75
+# There shouldn't be any [current members who are not using EU rules].
76
+# A Directive has the force of law, member states are obliged to enact
77
+# national law to implement it. The only contentious issue was the
78
+# different end date for the UK and Ireland, and this was always allowed
79
+# in the Directive.
80
+
81
+
82
+###############################################################################
83
+
84
+# Britain (United Kingdom) and Ireland (Eire)
85
+
86
+# From Peter Ilieve (1994-07-06):
87
+#
88
+# On 17 Jan 1994 the Independent, a UK quality newspaper, had a piece about
89
+# historical vistas along the Thames in west London. There was a photo
90
+# and a sketch map showing some of the sightlines involved. One paragraph
91
+# of the text said:
92
+#
93
+# `An old stone obelisk marking a forgotten terrestrial meridian stands
94
+# beside the river at Kew. In the 18th century, before time and longitude
95
+# was standardised by the Royal Observatory in Greenwich, scholars observed
96
+# this stone and the movement of stars from Kew Observatory nearby. They
97
+# made their calculations and set the time for the Horse Guards and Parliament,
98
+# but now the stone is obscured by scrubwood and can only be seen by walking
99
+# along the towpath within a few yards of it.'
100
+#
101
+# I have a one inch to one mile map of London and my estimate of the stone's
102
+# position is 51 deg. 28' 30" N, 0 deg. 18' 45" W. The longitude should
103
+# be within about +-2". The Ordnance Survey grid reference is TQ172761.
104
+#
105
+# [This yields GMTOFF = -0:01:15 for London LMT in the 18th century.]
106
+
107
+# From Paul Eggert (1993-11-18):
108
+#
109
+# Howse writes that Britain was the first country to use standard time.
110
+# The railways cared most about the inconsistencies of local mean time,
111
+# and it was they who forced a uniform time on the country.
112
+# The original idea was credited to Dr. William Hyde Wollaston (1766-1828)
113
+# and was popularized by Abraham Follett Osler (1808-1903).
114
+# The first railway to adopt London time was the Great Western Railway
115
+# in November 1840; other railways followed suit, and by 1847 most
116
+# (though not all) railways used London time.  On 1847-09-22 the
117
+# Railway Clearing House, an industry standards body, recommended that GMT be
118
+# adopted at all stations as soon as the General Post Office permitted it.
119
+# The transition occurred on 12-01 for the L&NW, the Caledonian,
120
+# and presumably other railways; the January 1848 Bradshaw's lists many
121
+# railways as using GMT.  By 1855 the vast majority of public
122
+# clocks in Britain were set to GMT (though some, like the great clock
123
+# on Tom Tower at Christ Church, Oxford, were fitted with two minute hands,
124
+# one for local time and one for GMT).  The last major holdout was the legal
125
+# system, which stubbornly stuck to local time for many years, leading
126
+# to oddities like polls opening at 08:13 and closing at 16:13.
127
+# The legal system finally switched to GMT when the Statutes (Definition
128
+# of Time) Act took effect; it received the Royal Assent on 1880-08-02.
129
+#
130
+# In the tables below, we condense this complicated story into a single
131
+# transition date for London, namely 1847-12-01.  We don't know as much
132
+# about Dublin, so we use 1880-08-02, the legal transition time.
133
+
134
+# From Paul Eggert (2003-09-27):
135
+# Summer Time was first seriously proposed by William Willett (1857-1915),
136
+# a London builder and member of the Royal Astronomical Society
137
+# who circulated a pamphlet ``The Waste of Daylight'' (1907)
138
+# that proposed advancing clocks 20 minutes on each of four Sundays in April,
139
+# and retarding them by the same amount on four Sundays in September.
140
+# A bill was drafted in 1909 and introduced in Parliament several times,
141
+# but it met with ridicule and opposition, especially from farming interests.
142
+# Later editions of the pamphlet proposed one-hour summer time, and
143
+# it was eventually adopted as a wartime measure in 1916.
144
+# See: Summer Time Arrives Early, The Times (2000-05-18).
145
+# A monument to Willett was unveiled on 1927-05-21, in an open space in
146
+# a 45-acre wood near Chislehurst, Kent that was purchased by popular
147
+# subscription and open to the public.  On the south face of the monolith,
148
+# designed by G. W. Miller, is the...William Willett Memorial Sundial,
149
+# which is permanently set to Summer Time.
150
+
151
+# From Winston Churchill (1934-04-28):
152
+# It is one of the paradoxes of history that we should owe the boon of
153
+# summer time, which gives every year to the people of this country
154
+# between 160 and 170 hours more daylight leisure, to a war which
155
+# plunged Europe into darkness for four years, and shook the
156
+# foundations of civilization throughout the world.
157
+#	-- <a href="http://www.winstonchurchill.org/fh114willett.htm">
158
+#	"A Silent Toast to William Willett", Pictorial Weekly
159
+#	</a>
160
+
161
+# From Paul Eggert (1996-09-03):
162
+# The OED Supplement says that the English originally said ``Daylight Saving''
163
+# when they were debating the adoption of DST in 1908; but by 1916 this
164
+# term appears only in quotes taken from DST's opponents, whereas the
165
+# proponents (who eventually won the argument) are quoted as using ``Summer''.
166
+
167
+# From Arthur David Olson (1989-01-19):
168
+#
169
+# A source at the British Information Office in New York avers that it's
170
+# known as "British" Summer Time in all parts of the United Kingdom.
171
+
172
+# Date: 4 Jan 89 08:57:25 GMT (Wed)
173
+# From: Jonathan Leffler
174
+# [British Summer Time] is fixed annually by Act of Parliament.
175
+# If you can predict what Parliament will do, you should be in
176
+# politics making a fortune, not computing.
177
+
178
+# From Chris Carrier (1996-06-14):
179
+# I remember reading in various wartime issues of the London Times the
180
+# acronym BDST for British Double Summer Time.  Look for the published
181
+# time of sunrise and sunset in The Times, when BDST was in effect, and
182
+# if you find a zone reference it will say, "All times B.D.S.T."
183
+
184
+# From Joseph S. Myers (1999-09-02):
185
+# ... some military cables (WO 219/4100 - this is a copy from the
186
+# main SHAEF archives held in the US National Archives, SHAEF/5252/8/516)
187
+# agree that the usage is BDST (this appears in a message dated 17 Feb 1945).
188
+
189
+# From Joseph S. Myers (2000-10-03):
190
+# On 18th April 1941, Sir Stephen Tallents of the BBC wrote to Sir
191
+# Alexander Maxwell of the Home Office asking whether there was any
192
+# official designation; the reply of the 21st was that there wasn't
193
+# but he couldn't think of anything better than the "Double British
194
+# Summer Time" that the BBC had been using informally.
195
+# http://student.cusu.cam.ac.uk/~jsm28/british-time/bbc-19410418.png
196
+# http://student.cusu.cam.ac.uk/~jsm28/british-time/ho-19410421.png
197
+
198
+# From Sir Alexander Maxwell in the above-mentioned letter (1941-04-21):
199
+# [N]o official designation has as far as I know been adopted for the time
200
+# which is to be introduced in May....
201
+# I cannot think of anything better than "Double British Summer Time"
202
+# which could not be said to run counter to any official description.
203
+
204
+# From Paul Eggert (2000-10-02):
205
+# Howse writes (p 157) `DBST' too, but `BDST' seems to have been common
206
+# and follows the more usual convention of putting the location name first,
207
+# so we use `BDST'.
208
+
209
+# Peter Ilieve (1998-04-19) described at length
210
+# the history of summer time legislation in the United Kingdom.
211
+# Since 1998 Joseph S. Myers has been updating
212
+# and extending this list, which can be found in
213
+# http://student.cusu.cam.ac.uk/~jsm28/british-time/
214
+# <a href="http://www.polyomino.org.uk/british-time/">
215
+# History of legal time in Britain
216
+# </a>
217
+# Rob Crowther (2012-01-04) reports that that URL no longer
218
+# exists, and the article can now be found at:
219
+# <a href="http://www.polyomino.org.uk/british-time/">
220
+# http://www.polyomino.org.uk/british-time/
221
+# </a>
222
+
223
+# From Joseph S. Myers (1998-01-06):
224
+#
225
+# The legal time in the UK outside of summer time is definitely GMT, not UTC;
226
+# see Lord Tanlaw's speech
227
+# <a href="http://www.parliament.the-stationery-office.co.uk/pa/ld199697/ldhansrd/pdvn/lds97/text/70611-20.htm#70611-20_head0">
228
+# (Lords Hansard 11 June 1997 columns 964 to 976)
229
+# </a>.
230
+
231
+# From Paul Eggert (2006-03-22):
232
+#
233
+# For lack of other data, follow Shanks & Pottenger for Eire in 1940-1948.
234
+#
235
+# Given Ilieve and Myers's data, the following claims by Shanks & Pottenger
236
+# are incorrect:
237
+#     * Wales did not switch from GMT to daylight saving time until
238
+#	1921 Apr 3, when they began to conform with the rest of Great Britain.
239
+# Actually, Wales was identical after 1880.
240
+#     * Eire had two transitions on 1916 Oct 1.
241
+# It actually just had one transition.
242
+#     * Northern Ireland used single daylight saving time throughout WW II.
243
+# Actually, it conformed to Britain.
244
+#     * GB-Eire changed standard time to 1 hour ahead of GMT on 1968-02-18.
245
+# Actually, that date saw the usual switch to summer time.
246
+# Standard time was not changed until 1968-10-27 (the clocks didn't change).
247
+#
248
+# Here is another incorrect claim by Shanks & Pottenger:
249
+#     * Jersey, Guernsey, and the Isle of Man did not switch from GMT
250
+#	to daylight saving time until 1921 Apr 3, when they began to
251
+#	conform with Great Britain.
252
+# S.R.&O. 1916, No. 382 and HO 45/10811/312364 (quoted above) say otherwise.
253
+#
254
+# The following claim by Shanks & Pottenger is possible though doubtful;
255
+# we'll ignore it for now.
256
+#     * Dublin's 1971-10-31 switch was at 02:00, even though London's was 03:00.
257
+#
258
+#
259
+# Whitman says Dublin Mean Time was -0:25:21, which is more precise than
260
+# Shanks & Pottenger.
261
+# Perhaps this was Dunsink Observatory Time, as Dunsink Observatory
262
+# (8 km NW of Dublin's center) seemingly was to Dublin as Greenwich was
263
+# to London.  For example:
264
+#
265
+#   "Timeball on the ballast office is down.  Dunsink time."
266
+#   -- James Joyce, Ulysses
267
+
268
+# From Joseph S. Myers (2005-01-26):
269
+# Irish laws are available online at www.irishstatutebook.ie.  These include
270
+# various relating to legal time, for example:
271
+#
272
+# ZZA13Y1923.html ZZA12Y1924.html ZZA8Y1925.html ZZSIV20PG1267.html
273
+#
274
+# ZZSI71Y1947.html ZZSI128Y1948.html ZZSI23Y1949.html ZZSI41Y1950.html
275
+# ZZSI27Y1951.html ZZSI73Y1952.html
276
+#
277
+# ZZSI11Y1961.html ZZSI232Y1961.html ZZSI182Y1962.html
278
+# ZZSI167Y1963.html ZZSI257Y1964.html ZZSI198Y1967.html
279
+# ZZA23Y1968.html ZZA17Y1971.html
280
+#
281
+# ZZSI67Y1981.html ZZSI212Y1982.html ZZSI45Y1986.html
282
+# ZZSI264Y1988.html ZZSI52Y1990.html ZZSI371Y1992.html
283
+# ZZSI395Y1994.html ZZSI484Y1997.html ZZSI506Y2001.html
284
+#
285
+# [These are all relative to the root, e.g., the first is
286
+# <http://www.irishstatutebook.ie/ZZA13Y1923.html>.]
287
+#
288
+# (These are those I found, but there could be more.  In any case these
289
+# should allow various updates to the comments in the europe file to cover
290
+# the laws applicable in Ireland.)
291
+#
292
+# (Note that the time in the Republic of Ireland since 1968 has been defined
293
+# in terms of standard time being GMT+1 with a period of winter time when it
294
+# is GMT, rather than standard time being GMT with a period of summer time
295
+# being GMT+1.)
296
+
297
+# From Paul Eggert (1999-03-28):
298
+# Clive Feather (<news:859845706.26043.0@office.demon.net>, 1997-03-31)
299
+# reports that Folkestone (Cheriton) Shuttle Terminal uses Concession Time
300
+# (CT), equivalent to French civil time.
301
+# Julian Hill (<news:36118128.5A14@virgin.net>, 1998-09-30) reports that
302
+# trains between Dollands Moor (the freight facility next door)
303
+# and Frethun run in CT.
304
+# My admittedly uninformed guess is that the terminal has two authorities,
305
+# the French concession operators and the British civil authorities,
306
+# and that the time depends on who you're talking to.
307
+# If, say, the British police were called to the station for some reason,
308
+# I would expect the official police report to use GMT/BST and not CET/CEST.
309
+# This is a borderline case, but for now let's stick to GMT/BST.
310
+
311
+# From an anonymous contributor (1996-06-02):
312
+# The law governing time in Ireland is under Statutory Instrument SI 395/94,
313
+# which gives force to European Union 7th Council Directive # 94/21/EC.
314
+# Under this directive, the Minister for Justice in Ireland makes appropriate
315
+# regulations. I spoke this morning with the Secretary of the Department of
316
+# Justice (tel +353 1 678 9711) who confirmed to me that the correct name is
317
+# "Irish Summer Time", abbreviated to "IST".
318
+
319
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
320
+# Summer Time Act, 1916
321
+Rule	GB-Eire	1916	only	-	May	21	2:00s	1:00	BST
322
+Rule	GB-Eire	1916	only	-	Oct	 1	2:00s	0	GMT
323
+# S.R.&O. 1917, No. 358
324
+Rule	GB-Eire	1917	only	-	Apr	 8	2:00s	1:00	BST
325
+Rule	GB-Eire	1917	only	-	Sep	17	2:00s	0	GMT
326
+# S.R.&O. 1918, No. 274
327
+Rule	GB-Eire	1918	only	-	Mar	24	2:00s	1:00	BST
328
+Rule	GB-Eire	1918	only	-	Sep	30	2:00s	0	GMT
329
+# S.R.&O. 1919, No. 297
330
+Rule	GB-Eire	1919	only	-	Mar	30	2:00s	1:00	BST
331
+Rule	GB-Eire	1919	only	-	Sep	29	2:00s	0	GMT
332
+# S.R.&O. 1920, No. 458
333
+Rule	GB-Eire	1920	only	-	Mar	28	2:00s	1:00	BST
334
+# S.R.&O. 1920, No. 1844
335
+Rule	GB-Eire	1920	only	-	Oct	25	2:00s	0	GMT
336
+# S.R.&O. 1921, No. 363
337
+Rule	GB-Eire	1921	only	-	Apr	 3	2:00s	1:00	BST
338
+Rule	GB-Eire	1921	only	-	Oct	 3	2:00s	0	GMT
339
+# S.R.&O. 1922, No. 264
340
+Rule	GB-Eire	1922	only	-	Mar	26	2:00s	1:00	BST
341
+Rule	GB-Eire	1922	only	-	Oct	 8	2:00s	0	GMT
342
+# The Summer Time Act, 1922
343
+Rule	GB-Eire	1923	only	-	Apr	Sun>=16	2:00s	1:00	BST
344
+Rule	GB-Eire	1923	1924	-	Sep	Sun>=16	2:00s	0	GMT
345
+Rule	GB-Eire	1924	only	-	Apr	Sun>=9	2:00s	1:00	BST
346
+Rule	GB-Eire	1925	1926	-	Apr	Sun>=16	2:00s	1:00	BST
347
+# The Summer Time Act, 1925
348
+Rule	GB-Eire	1925	1938	-	Oct	Sun>=2	2:00s	0	GMT
349
+Rule	GB-Eire	1927	only	-	Apr	Sun>=9	2:00s	1:00	BST
350
+Rule	GB-Eire	1928	1929	-	Apr	Sun>=16	2:00s	1:00	BST
351
+Rule	GB-Eire	1930	only	-	Apr	Sun>=9	2:00s	1:00	BST
352
+Rule	GB-Eire	1931	1932	-	Apr	Sun>=16	2:00s	1:00	BST
353
+Rule	GB-Eire	1933	only	-	Apr	Sun>=9	2:00s	1:00	BST
354
+Rule	GB-Eire	1934	only	-	Apr	Sun>=16	2:00s	1:00	BST
355
+Rule	GB-Eire	1935	only	-	Apr	Sun>=9	2:00s	1:00	BST
356
+Rule	GB-Eire	1936	1937	-	Apr	Sun>=16	2:00s	1:00	BST
357
+Rule	GB-Eire	1938	only	-	Apr	Sun>=9	2:00s	1:00	BST
358
+Rule	GB-Eire	1939	only	-	Apr	Sun>=16	2:00s	1:00	BST
359
+# S.R.&O. 1939, No. 1379
360
+Rule	GB-Eire	1939	only	-	Nov	Sun>=16	2:00s	0	GMT
361
+# S.R.&O. 1940, No. 172 and No. 1883
362
+Rule	GB-Eire	1940	only	-	Feb	Sun>=23	2:00s	1:00	BST
363
+# S.R.&O. 1941, No. 476
364
+Rule	GB-Eire	1941	only	-	May	Sun>=2	1:00s	2:00	BDST
365
+Rule	GB-Eire	1941	1943	-	Aug	Sun>=9	1:00s	1:00	BST
366
+# S.R.&O. 1942, No. 506
367
+Rule	GB-Eire	1942	1944	-	Apr	Sun>=2	1:00s	2:00	BDST
368
+# S.R.&O. 1944, No. 932
369
+Rule	GB-Eire	1944	only	-	Sep	Sun>=16	1:00s	1:00	BST
370
+# S.R.&O. 1945, No. 312
371
+Rule	GB-Eire	1945	only	-	Apr	Mon>=2	1:00s	2:00	BDST
372
+Rule	GB-Eire	1945	only	-	Jul	Sun>=9	1:00s	1:00	BST
373
+# S.R.&O. 1945, No. 1208
374
+Rule	GB-Eire	1945	1946	-	Oct	Sun>=2	2:00s	0	GMT
375
+Rule	GB-Eire	1946	only	-	Apr	Sun>=9	2:00s	1:00	BST
376
+# The Summer Time Act, 1947
377
+Rule	GB-Eire	1947	only	-	Mar	16	2:00s	1:00	BST
378
+Rule	GB-Eire	1947	only	-	Apr	13	1:00s	2:00	BDST
379
+Rule	GB-Eire	1947	only	-	Aug	10	1:00s	1:00	BST
380
+Rule	GB-Eire	1947	only	-	Nov	 2	2:00s	0	GMT
381
+# Summer Time Order, 1948 (S.I. 1948/495)
382
+Rule	GB-Eire	1948	only	-	Mar	14	2:00s	1:00	BST
383
+Rule	GB-Eire	1948	only	-	Oct	31	2:00s	0	GMT
384
+# Summer Time Order, 1949 (S.I. 1949/373)
385
+Rule	GB-Eire	1949	only	-	Apr	 3	2:00s	1:00	BST
386
+Rule	GB-Eire	1949	only	-	Oct	30	2:00s	0	GMT
387
+# Summer Time Order, 1950 (S.I. 1950/518)
388
+# Summer Time Order, 1951 (S.I. 1951/430)
389
+# Summer Time Order, 1952 (S.I. 1952/451)
390
+Rule	GB-Eire	1950	1952	-	Apr	Sun>=14	2:00s	1:00	BST
391
+Rule	GB-Eire	1950	1952	-	Oct	Sun>=21	2:00s	0	GMT
392
+# revert to the rules of the Summer Time Act, 1925
393
+Rule	GB-Eire	1953	only	-	Apr	Sun>=16	2:00s	1:00	BST
394
+Rule	GB-Eire	1953	1960	-	Oct	Sun>=2	2:00s	0	GMT
395
+Rule	GB-Eire	1954	only	-	Apr	Sun>=9	2:00s	1:00	BST
396
+Rule	GB-Eire	1955	1956	-	Apr	Sun>=16	2:00s	1:00	BST
397
+Rule	GB-Eire	1957	only	-	Apr	Sun>=9	2:00s	1:00	BST
398
+Rule	GB-Eire	1958	1959	-	Apr	Sun>=16	2:00s	1:00	BST
399
+Rule	GB-Eire	1960	only	-	Apr	Sun>=9	2:00s	1:00	BST
400
+# Summer Time Order, 1961 (S.I. 1961/71)
401
+# Summer Time (1962) Order, 1961 (S.I. 1961/2465)
402
+# Summer Time Order, 1963 (S.I. 1963/81)
403
+Rule	GB-Eire	1961	1963	-	Mar	lastSun	2:00s	1:00	BST
404
+Rule	GB-Eire	1961	1968	-	Oct	Sun>=23	2:00s	0	GMT
405
+# Summer Time (1964) Order, 1963 (S.I. 1963/2101)
406
+# Summer Time Order, 1964 (S.I. 1964/1201)
407
+# Summer Time Order, 1967 (S.I. 1967/1148)
408
+Rule	GB-Eire	1964	1967	-	Mar	Sun>=19	2:00s	1:00	BST
409
+# Summer Time Order, 1968 (S.I. 1968/117)
410
+Rule	GB-Eire	1968	only	-	Feb	18	2:00s	1:00	BST
411
+# The British Standard Time Act, 1968
412
+#	(no summer time)
413
+# The Summer Time Act, 1972
414
+Rule	GB-Eire	1972	1980	-	Mar	Sun>=16	2:00s	1:00	BST
415
+Rule	GB-Eire	1972	1980	-	Oct	Sun>=23	2:00s	0	GMT
416
+# Summer Time Order, 1980 (S.I. 1980/1089)
417
+# Summer Time Order, 1982 (S.I. 1982/1673)
418
+# Summer Time Order, 1986 (S.I. 1986/223)
419
+# Summer Time Order, 1988 (S.I. 1988/931)
420
+Rule	GB-Eire	1981	1995	-	Mar	lastSun	1:00u	1:00	BST
421
+Rule	GB-Eire 1981	1989	-	Oct	Sun>=23	1:00u	0	GMT
422
+# Summer Time Order, 1989 (S.I. 1989/985)
423
+# Summer Time Order, 1992 (S.I. 1992/1729)
424
+# Summer Time Order 1994 (S.I. 1994/2798)
425
+Rule	GB-Eire 1990	1995	-	Oct	Sun>=22	1:00u	0	GMT
426
+# Summer Time Order 1997 (S.I. 1997/2982)
427
+# See EU for rules starting in 1996.
428
+
429
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
430
+Zone	Europe/London	-0:01:15 -	LMT	1847 Dec  1 0:00s
431
+			 0:00	GB-Eire	%s	1968 Oct 27
432
+			 1:00	-	BST	1971 Oct 31 2:00u
433
+			 0:00	GB-Eire	%s	1996
434
+			 0:00	EU	GMT/BST
435
+Link	Europe/London	Europe/Jersey
436
+Link	Europe/London	Europe/Guernsey
437
+Link	Europe/London	Europe/Isle_of_Man
438
+Zone	Europe/Dublin	-0:25:00 -	LMT	1880 Aug  2
439
+			-0:25:21 -	DMT	1916 May 21 2:00
440
+			-0:25:21 1:00	IST	1916 Oct  1 2:00s
441
+			 0:00	GB-Eire	%s	1921 Dec  6 # independence
442
+			 0:00	GB-Eire	GMT/IST	1940 Feb 25 2:00
443
+			 0:00	1:00	IST	1946 Oct  6 2:00
444
+			 0:00	-	GMT	1947 Mar 16 2:00
445
+			 0:00	1:00	IST	1947 Nov  2 2:00
446
+			 0:00	-	GMT	1948 Apr 18 2:00
447
+			 0:00	GB-Eire	GMT/IST	1968 Oct 27
448
+			 1:00	-	IST	1971 Oct 31 2:00u
449
+			 0:00	GB-Eire	GMT/IST	1996
450
+			 0:00	EU	GMT/IST
451
+
452
+###############################################################################
453
+
454
+# Europe
455
+
456
+# EU rules are for the European Union, previously known as the EC, EEC,
457
+# Common Market, etc.
458
+
459
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
460
+Rule	EU	1977	1980	-	Apr	Sun>=1	 1:00u	1:00	S
461
+Rule	EU	1977	only	-	Sep	lastSun	 1:00u	0	-
462
+Rule	EU	1978	only	-	Oct	 1	 1:00u	0	-
463
+Rule	EU	1979	1995	-	Sep	lastSun	 1:00u	0	-
464
+Rule	EU	1981	max	-	Mar	lastSun	 1:00u	1:00	S
465
+Rule	EU	1996	max	-	Oct	lastSun	 1:00u	0	-
466
+# The most recent directive covers the years starting in 2002.  See:
467
+# <a="http://eur-lex.europa.eu/LexUriServ/LexUriServ.do?uri=CELEX:32000L0084:EN:NOT">
468
+# Directive 2000/84/EC of the European Parliament and of the Council
469
+# of 19 January 2001 on summer-time arrangements.
470
+# </a>
471
+
472
+# W-Eur differs from EU only in that W-Eur uses standard time.
473
+Rule	W-Eur	1977	1980	-	Apr	Sun>=1	 1:00s	1:00	S
474
+Rule	W-Eur	1977	only	-	Sep	lastSun	 1:00s	0	-
475
+Rule	W-Eur	1978	only	-	Oct	 1	 1:00s	0	-
476
+Rule	W-Eur	1979	1995	-	Sep	lastSun	 1:00s	0	-
477
+Rule	W-Eur	1981	max	-	Mar	lastSun	 1:00s	1:00	S
478
+Rule	W-Eur	1996	max	-	Oct	lastSun	 1:00s	0	-
479
+
480
+# Older C-Eur rules are for convenience in the tables.
481
+# From 1977 on, C-Eur differs from EU only in that C-Eur uses standard time.
482
+Rule	C-Eur	1916	only	-	Apr	30	23:00	1:00	S
483
+Rule	C-Eur	1916	only	-	Oct	 1	 1:00	0	-
484
+Rule	C-Eur	1917	1918	-	Apr	Mon>=15	 2:00s	1:00	S
485
+Rule	C-Eur	1917	1918	-	Sep	Mon>=15	 2:00s	0	-
486
+Rule	C-Eur	1940	only	-	Apr	 1	 2:00s	1:00	S
487
+Rule	C-Eur	1942	only	-	Nov	 2	 2:00s	0	-
488
+Rule	C-Eur	1943	only	-	Mar	29	 2:00s	1:00	S
489
+Rule	C-Eur	1943	only	-	Oct	 4	 2:00s	0	-
490
+Rule	C-Eur	1944	1945	-	Apr	Mon>=1	 2:00s	1:00	S
491
+# Whitman gives 1944 Oct 7; go with Shanks & Pottenger.
492
+Rule	C-Eur	1944	only	-	Oct	 2	 2:00s	0	-
493
+# From Jesper Norgaard Welen (2008-07-13):
494
+#
495
+# I found what is probably a typo of 2:00 which should perhaps be 2:00s
496
+# in the C-Eur rule from tz database version 2008d (this part was
497
+# corrected in version 2008d). The circumstancial evidence is simply the
498
+# tz database itself, as seen below:
499
+#
500
+# Zone Europe/Paris 0:09:21 - LMT 1891 Mar 15  0:01
501
+#    0:00 France WE%sT 1945 Sep 16  3:00
502
+#
503
+# Zone Europe/Monaco 0:29:32 - LMT 1891 Mar 15
504
+#    0:00 France WE%sT 1945 Sep 16 3:00
505
+#
506
+# Zone Europe/Belgrade 1:22:00 - LMT 1884
507
+#    1:00 1:00 CEST 1945 Sep 16  2:00s
508
+#
509
+# Rule France 1945 only - Sep 16  3:00 0 -
510
+# Rule Belgium 1945 only - Sep 16  2:00s 0 -
511
+# Rule Neth 1945 only - Sep 16 2:00s 0 -
512
+#
513
+# The rule line to be changed is:
514
+#
515
+# Rule C-Eur 1945 only - Sep 16  2:00 0 -
516
+#
517
+# It seems that Paris, Monaco, Rule France, Rule Belgium all agree on
518
+# 2:00 standard time, e.g. 3:00 local time.  However there are no
519
+# countries that use C-Eur rules in September 1945, so the only items
520
+# affected are apparently these ficticious zones that translates acronyms
521
+# CET and MET:
522
+#
523
+# Zone CET  1:00 C-Eur CE%sT
524
+# Zone MET  1:00 C-Eur ME%sT
525
+#
526
+# It this is right then the corrected version would look like:
527
+#
528
+# Rule C-Eur 1945 only - Sep 16  2:00s 0 -
529
+#
530
+# A small step for mankind though 8-)
531
+Rule	C-Eur	1945	only	-	Sep	16	 2:00s	0	-
532
+Rule	C-Eur	1977	1980	-	Apr	Sun>=1	 2:00s	1:00	S
533
+Rule	C-Eur	1977	only	-	Sep	lastSun	 2:00s	0	-
534
+Rule	C-Eur	1978	only	-	Oct	 1	 2:00s	0	-
535
+Rule	C-Eur	1979	1995	-	Sep	lastSun	 2:00s	0	-
536
+Rule	C-Eur	1981	max	-	Mar	lastSun	 2:00s	1:00	S
537
+Rule	C-Eur	1996	max	-	Oct	lastSun	 2:00s	0	-
538
+
539
+# E-Eur differs from EU only in that E-Eur switches at midnight local time.
540
+Rule	E-Eur	1977	1980	-	Apr	Sun>=1	 0:00	1:00	S
541
+Rule	E-Eur	1977	only	-	Sep	lastSun	 0:00	0	-
542
+Rule	E-Eur	1978	only	-	Oct	 1	 0:00	0	-
543
+Rule	E-Eur	1979	1995	-	Sep	lastSun	 0:00	0	-
544
+Rule	E-Eur	1981	max	-	Mar	lastSun	 0:00	1:00	S
545
+Rule	E-Eur	1996	max	-	Oct	lastSun	 0:00	0	-
546
+
547
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
548
+Rule	Russia	1917	only	-	Jul	 1	23:00	1:00	MST	# Moscow Summer Time
549
+Rule	Russia	1917	only	-	Dec	28	 0:00	0	MMT	# Moscow Mean Time
550
+Rule	Russia	1918	only	-	May	31	22:00	2:00	MDST	# Moscow Double Summer Time
551
+Rule	Russia	1918	only	-	Sep	16	 1:00	1:00	MST
552
+Rule	Russia	1919	only	-	May	31	23:00	2:00	MDST
553
+Rule	Russia	1919	only	-	Jul	 1	 2:00	1:00	S
554
+Rule	Russia	1919	only	-	Aug	16	 0:00	0	-
555
+Rule	Russia	1921	only	-	Feb	14	23:00	1:00	S
556
+Rule	Russia	1921	only	-	Mar	20	23:00	2:00	M # Midsummer
557
+Rule	Russia	1921	only	-	Sep	 1	 0:00	1:00	S
558
+Rule	Russia	1921	only	-	Oct	 1	 0:00	0	-
559
+# Act No.925 of the Council of Ministers of the USSR (1980-10-24):
560
+Rule	Russia	1981	1984	-	Apr	 1	 0:00	1:00	S
561
+Rule	Russia	1981	1983	-	Oct	 1	 0:00	0	-
562
+# Act No.967 of the Council of Ministers of the USSR (1984-09-13), repeated in
563
+# Act No.227 of the Council of Ministers of the USSR (1989-03-14):
564
+Rule	Russia	1984	1991	-	Sep	lastSun	 2:00s	0	-
565
+Rule	Russia	1985	1991	-	Mar	lastSun	 2:00s	1:00	S
566
+#
567
+Rule	Russia	1992	only	-	Mar	lastSat	 23:00	1:00	S
568
+Rule	Russia	1992	only	-	Sep	lastSat	 23:00	0	-
569
+Rule	Russia	1993	2010	-	Mar	lastSun	 2:00s	1:00	S
570
+Rule	Russia	1993	1995	-	Sep	lastSun	 2:00s	0	-
571
+Rule	Russia	1996	2010	-	Oct	lastSun	 2:00s	0	-
572
+
573
+# From Alexander Krivenyshev (2011-06-14):
574
+# According to Kremlin press service, Russian President Dmitry Medvedev
575
+# signed a federal law "On calculation of time" on June 9, 2011.
576
+# According to the law Russia is abolishing daylight saving time.
577
+#
578
+# Medvedev signed a law "On the Calculation of Time" (in russian):
579
+# <a href="http://bmockbe.ru/events/?ID=7583">
580
+# http://bmockbe.ru/events/?ID=7583
581
+# </a>
582
+#
583
+# Medvedev signed a law on the calculation of the time (in russian):
584
+# <a href="http://www.regnum.ru/news/polit/1413906.html">
585
+# http://www.regnum.ru/news/polit/1413906.html
586
+# </a>
587
+
588
+# From Arthur David Olson (2011-06-15):
589
+# Take "abolishing daylight saving time" to mean that time is now considered
590
+# to be standard.
591
+
592
+# These are for backward compatibility with older versions.
593
+
594
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
595
+Zone	WET		0:00	EU	WE%sT
596
+Zone	CET		1:00	C-Eur	CE%sT
597
+Zone	MET		1:00	C-Eur	ME%sT
598
+Zone	EET		2:00	EU	EE%sT
599
+
600
+# Previous editions of this database used abbreviations like MET DST
601
+# for Central European Summer Time, but this didn't agree with common usage.
602
+
603
+# From Markus Kuhn (1996-07-12):
604
+# The official German names ... are
605
+#
606
+#	Mitteleuropaeische Zeit (MEZ)         = UTC+01:00
607
+#	Mitteleuropaeische Sommerzeit (MESZ)  = UTC+02:00
608
+#
609
+# as defined in the German Time Act (Gesetz ueber die Zeitbestimmung (ZeitG),
610
+# 1978-07-25, Bundesgesetzblatt, Jahrgang 1978, Teil I, S. 1110-1111)....
611
+# I wrote ... to the German Federal Physical-Technical Institution
612
+#
613
+#	Physikalisch-Technische Bundesanstalt (PTB)
614
+#	Laboratorium 4.41 "Zeiteinheit"
615
+#	Postfach 3345
616
+#	D-38023 Braunschweig
617
+#	phone: +49 531 592-0
618
+#
619
+# ... I received today an answer letter from Dr. Peter Hetzel, head of the PTB
620
+# department for time and frequency transmission.  He explained that the
621
+# PTB translates MEZ and MESZ into English as
622
+#
623
+#	Central European Time (CET)         = UTC+01:00
624
+#	Central European Summer Time (CEST) = UTC+02:00
625
+
626
+
627
+# Albania
628
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
629
+Rule	Albania	1940	only	-	Jun	16	0:00	1:00	S
630
+Rule	Albania	1942	only	-	Nov	 2	3:00	0	-
631
+Rule	Albania	1943	only	-	Mar	29	2:00	1:00	S
632
+Rule	Albania	1943	only	-	Apr	10	3:00	0	-
633
+Rule	Albania	1974	only	-	May	 4	0:00	1:00	S
634
+Rule	Albania	1974	only	-	Oct	 2	0:00	0	-
635
+Rule	Albania	1975	only	-	May	 1	0:00	1:00	S
636
+Rule	Albania	1975	only	-	Oct	 2	0:00	0	-
637
+Rule	Albania	1976	only	-	May	 2	0:00	1:00	S
638
+Rule	Albania	1976	only	-	Oct	 3	0:00	0	-
639
+Rule	Albania	1977	only	-	May	 8	0:00	1:00	S
640
+Rule	Albania	1977	only	-	Oct	 2	0:00	0	-
641
+Rule	Albania	1978	only	-	May	 6	0:00	1:00	S
642
+Rule	Albania	1978	only	-	Oct	 1	0:00	0	-
643
+Rule	Albania	1979	only	-	May	 5	0:00	1:00	S
644
+Rule	Albania	1979	only	-	Sep	30	0:00	0	-
645
+Rule	Albania	1980	only	-	May	 3	0:00	1:00	S
646
+Rule	Albania	1980	only	-	Oct	 4	0:00	0	-
647
+Rule	Albania	1981	only	-	Apr	26	0:00	1:00	S
648
+Rule	Albania	1981	only	-	Sep	27	0:00	0	-
649
+Rule	Albania	1982	only	-	May	 2	0:00	1:00	S
650
+Rule	Albania	1982	only	-	Oct	 3	0:00	0	-
651
+Rule	Albania	1983	only	-	Apr	18	0:00	1:00	S
652
+Rule	Albania	1983	only	-	Oct	 1	0:00	0	-
653
+Rule	Albania	1984	only	-	Apr	 1	0:00	1:00	S
654
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
655
+Zone	Europe/Tirane	1:19:20 -	LMT	1914
656
+			1:00	-	CET	1940 Jun 16
657
+			1:00	Albania	CE%sT	1984 Jul
658
+			1:00	EU	CE%sT
659
+
660
+# Andorra
661
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
662
+Zone	Europe/Andorra	0:06:04 -	LMT	1901
663
+			0:00	-	WET	1946 Sep 30
664
+			1:00	-	CET	1985 Mar 31 2:00
665
+			1:00	EU	CE%sT
666
+
667
+# Austria
668
+
669
+# From Paul Eggert (2006-03-22): Shanks & Pottenger give 1918-06-16 and
670
+# 1945-11-18, but the Austrian Federal Office of Metrology and
671
+# Surveying (BEV) gives 1918-09-16 and for Vienna gives the "alleged"
672
+# date of 1945-04-12 with no time.  For the 1980-04-06 transition
673
+# Shanks & Pottenger give 02:00, the BEV 00:00.  Go with the BEV,
674
+# and guess 02:00 for 1945-04-12.
675
+
676
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
677
+Rule	Austria	1920	only	-	Apr	 5	2:00s	1:00	S
678
+Rule	Austria	1920	only	-	Sep	13	2:00s	0	-
679
+Rule	Austria	1946	only	-	Apr	14	2:00s	1:00	S
680
+Rule	Austria	1946	1948	-	Oct	Sun>=1	2:00s	0	-
681
+Rule	Austria	1947	only	-	Apr	 6	2:00s	1:00	S
682
+Rule	Austria	1948	only	-	Apr	18	2:00s	1:00	S
683
+Rule	Austria	1980	only	-	Apr	 6	0:00	1:00	S
684
+Rule	Austria	1980	only	-	Sep	28	0:00	0	-
685
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
686
+Zone	Europe/Vienna	1:05:20 -	LMT	1893 Apr
687
+			1:00	C-Eur	CE%sT	1920
688
+			1:00	Austria	CE%sT	1940 Apr  1 2:00s
689
+			1:00	C-Eur	CE%sT	1945 Apr  2 2:00s
690
+			1:00	1:00	CEST	1945 Apr 12 2:00s
691
+			1:00	-	CET	1946
692
+			1:00	Austria	CE%sT	1981
693
+			1:00	EU	CE%sT
694
+
695
+# Belarus
696
+# From Yauhen Kharuzhy (2011-09-16):
697
+# By latest Belarus government act Europe/Minsk timezone was changed to
698
+# GMT+3 without DST (was GMT+2 with DST).
699
+#
700
+# Sources (Russian language):
701
+# 1.
702
+# <a href="http://www.belta.by/ru/all_news/society/V-Belarusi-otmenjaetsja-perexod-na-sezonnoe-vremja_i_572952.html">
703
+# http://www.belta.by/ru/all_news/society/V-Belarusi-otmenjaetsja-perexod-na-sezonnoe-vremja_i_572952.html
704
+# </a>
705
+# 2.
706
+# <a href="http://naviny.by/rubrics/society/2011/09/16/ic_articles_116_175144/">
707
+# http://naviny.by/rubrics/society/2011/09/16/ic_articles_116_175144/
708
+# </a>
709
+# 3.
710
+# <a href="http://news.tut.by/society/250578.html">
711
+# http://news.tut.by/society/250578.html
712
+# </a>
713
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
714
+Zone	Europe/Minsk	1:50:16 -	LMT	1880
715
+			1:50	-	MMT	1924 May 2 # Minsk Mean Time
716
+			2:00	-	EET	1930 Jun 21
717
+			3:00	-	MSK	1941 Jun 28
718
+			1:00	C-Eur	CE%sT	1944 Jul  3
719
+			3:00	Russia	MSK/MSD	1990
720
+			3:00	-	MSK	1991 Mar 31 2:00s
721
+			2:00	1:00	EEST	1991 Sep 29 2:00s
722
+			2:00	-	EET	1992 Mar 29 0:00s
723
+			2:00	1:00	EEST	1992 Sep 27 0:00s
724
+			2:00	Russia	EE%sT	2011 Mar 27 2:00s
725
+			3:00	-	FET # Further-eastern European Time
726
+
727
+# Belgium
728
+#
729
+# From Paul Eggert (1997-07-02):
730
+# Entries from 1918 through 1991 are taken from:
731
+#	Annuaire de L'Observatoire Royal de Belgique,
732
+#	Avenue Circulaire, 3, B-1180 BRUXELLES, CLVIIe annee, 1991
733
+#	(Imprimerie HAYEZ, s.p.r.l., Rue Fin, 4, 1080 BRUXELLES, MCMXC),
734
+#	pp 8-9.
735
+# LMT before 1892 was 0:17:30, according to the official journal of Belgium:
736
+#	Moniteur Belge, Samedi 30 Avril 1892, N.121.
737
+# Thanks to Pascal Delmoitie for these references.
738
+# The 1918 rules are listed for completeness; they apply to unoccupied Belgium.
739
+# Assume Brussels switched to WET in 1918 when the armistice took effect.
740
+#
741
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
742
+Rule	Belgium	1918	only	-	Mar	 9	 0:00s	1:00	S
743
+Rule	Belgium	1918	1919	-	Oct	Sat>=1	23:00s	0	-
744
+Rule	Belgium	1919	only	-	Mar	 1	23:00s	1:00	S
745
+Rule	Belgium	1920	only	-	Feb	14	23:00s	1:00	S
746
+Rule	Belgium	1920	only	-	Oct	23	23:00s	0	-
747
+Rule	Belgium	1921	only	-	Mar	14	23:00s	1:00	S
748
+Rule	Belgium	1921	only	-	Oct	25	23:00s	0	-
749
+Rule	Belgium	1922	only	-	Mar	25	23:00s	1:00	S
750
+Rule	Belgium	1922	1927	-	Oct	Sat>=1	23:00s	0	-
751
+Rule	Belgium	1923	only	-	Apr	21	23:00s	1:00	S
752
+Rule	Belgium	1924	only	-	Mar	29	23:00s	1:00	S
753
+Rule	Belgium	1925	only	-	Apr	 4	23:00s	1:00	S
754
+# DSH writes that a royal decree of 1926-02-22 specified the Sun following 3rd
755
+# Sat in Apr (except if it's Easter, in which case it's one Sunday earlier),
756
+# to Sun following 1st Sat in Oct, and that a royal decree of 1928-09-15
757
+# changed the transition times to 02:00 GMT.
758
+Rule	Belgium	1926	only	-	Apr	17	23:00s	1:00	S
759
+Rule	Belgium	1927	only	-	Apr	 9	23:00s	1:00	S
760
+Rule	Belgium	1928	only	-	Apr	14	23:00s	1:00	S
761
+Rule	Belgium	1928	1938	-	Oct	Sun>=2	 2:00s	0	-
762
+Rule	Belgium	1929	only	-	Apr	21	 2:00s	1:00	S
763
+Rule	Belgium	1930	only	-	Apr	13	 2:00s	1:00	S
764
+Rule	Belgium	1931	only	-	Apr	19	 2:00s	1:00	S
765
+Rule	Belgium	1932	only	-	Apr	 3	 2:00s	1:00	S
766
+Rule	Belgium	1933	only	-	Mar	26	 2:00s	1:00	S
767
+Rule	Belgium	1934	only	-	Apr	 8	 2:00s	1:00	S
768
+Rule	Belgium	1935	only	-	Mar	31	 2:00s	1:00	S
769
+Rule	Belgium	1936	only	-	Apr	19	 2:00s	1:00	S
770
+Rule	Belgium	1937	only	-	Apr	 4	 2:00s	1:00	S
771
+Rule	Belgium	1938	only	-	Mar	27	 2:00s	1:00	S
772
+Rule	Belgium	1939	only	-	Apr	16	 2:00s	1:00	S
773
+Rule	Belgium	1939	only	-	Nov	19	 2:00s	0	-
774
+Rule	Belgium	1940	only	-	Feb	25	 2:00s	1:00	S
775
+Rule	Belgium	1944	only	-	Sep	17	 2:00s	0	-
776
+Rule	Belgium	1945	only	-	Apr	 2	 2:00s	1:00	S
777
+Rule	Belgium	1945	only	-	Sep	16	 2:00s	0	-
778
+Rule	Belgium	1946	only	-	May	19	 2:00s	1:00	S
779
+Rule	Belgium	1946	only	-	Oct	 7	 2:00s	0	-
780
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
781
+Zone	Europe/Brussels	0:17:30 -	LMT	1880
782
+			0:17:30	-	BMT	1892 May  1 12:00 # Brussels MT
783
+			0:00	-	WET	1914 Nov  8
784
+			1:00	-	CET	1916 May  1  0:00
785
+			1:00	C-Eur	CE%sT	1918 Nov 11 11:00u
786
+			0:00	Belgium	WE%sT	1940 May 20  2:00s
787
+			1:00	C-Eur	CE%sT	1944 Sep  3
788
+			1:00	Belgium	CE%sT	1977
789
+			1:00	EU	CE%sT
790
+
791
+# Bosnia and Herzegovina
792
+# see Serbia
793
+
794
+# Bulgaria
795
+#
796
+# From Plamen Simenov via Steffen Thorsen (1999-09-09):
797
+# A document of Government of Bulgaria (No.94/1997) says:
798
+# EET --> EETDST is in 03:00 Local time in last Sunday of March ...
799
+# EETDST --> EET is in 04:00 Local time in last Sunday of October
800
+#
801
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
802
+Rule	Bulg	1979	only	-	Mar	31	23:00	1:00	S
803
+Rule	Bulg	1979	only	-	Oct	 1	 1:00	0	-
804
+Rule	Bulg	1980	1982	-	Apr	Sat>=1	23:00	1:00	S
805
+Rule	Bulg	1980	only	-	Sep	29	 1:00	0	-
806
+Rule	Bulg	1981	only	-	Sep	27	 2:00	0	-
807
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
808
+Zone	Europe/Sofia	1:33:16 -	LMT	1880
809
+			1:56:56	-	IMT	1894 Nov 30 # Istanbul MT?
810
+			2:00	-	EET	1942 Nov  2  3:00
811
+			1:00	C-Eur	CE%sT	1945
812
+			1:00	-	CET	1945 Apr 2 3:00
813
+			2:00	-	EET	1979 Mar 31 23:00
814
+			2:00	Bulg	EE%sT	1982 Sep 26  2:00
815
+			2:00	C-Eur	EE%sT	1991
816
+			2:00	E-Eur	EE%sT	1997
817
+			2:00	EU	EE%sT
818
+
819
+# Croatia
820
+# see Serbia
821
+
822
+# Cyprus
823
+# Please see the `asia' file for Asia/Nicosia.
824
+
825
+# Czech Republic
826
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
827
+Rule	Czech	1945	only	-	Apr	 8	2:00s	1:00	S
828
+Rule	Czech	1945	only	-	Nov	18	2:00s	0	-
829
+Rule	Czech	1946	only	-	May	 6	2:00s	1:00	S
830
+Rule	Czech	1946	1949	-	Oct	Sun>=1	2:00s	0	-
831
+Rule	Czech	1947	only	-	Apr	20	2:00s	1:00	S
832
+Rule	Czech	1948	only	-	Apr	18	2:00s	1:00	S
833
+Rule	Czech	1949	only	-	Apr	 9	2:00s	1:00	S
834
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
835
+Zone	Europe/Prague	0:57:44 -	LMT	1850
836
+			0:57:44	-	PMT	1891 Oct     # Prague Mean Time
837
+			1:00	C-Eur	CE%sT	1944 Sep 17 2:00s
838
+			1:00	Czech	CE%sT	1979
839
+			1:00	EU	CE%sT
840
+
841
+# Denmark, Faroe Islands, and Greenland
842
+
843
+# From Jesper Norgaard Welen (2005-04-26):
844
+# http://www.hum.aau.dk/~poe/tid/tine/DanskTid.htm says that the law
845
+# [introducing standard time] was in effect from 1894-01-01....
846
+# The page http://www.retsinfo.dk/_GETDOCI_/ACCN/A18930008330-REGL
847
+# confirms this, and states that the law was put forth 1893-03-29.
848
+#
849
+# The EU treaty with effect from 1973:
850
+# http://www.retsinfo.dk/_GETDOCI_/ACCN/A19722110030-REGL
851
+#
852
+# This provoked a new law from 1974 to make possible summer time changes
853
+# in subsequenet decrees with the law
854
+# http://www.retsinfo.dk/_GETDOCI_/ACCN/A19740022330-REGL
855
+#
856
+# It seems however that no decree was set forward until 1980.  I have
857
+# not found any decree, but in another related law, the effecting DST
858
+# changes are stated explicitly to be from 1980-04-06 at 02:00 to
859
+# 1980-09-28 at 02:00.  If this is true, this differs slightly from
860
+# the EU rule in that DST runs to 02:00, not 03:00.  We don't know
861
+# when Denmark began using the EU rule correctly, but we have only
862
+# confirmation of the 1980-time, so I presume it was correct in 1981:
863
+# The law is about the management of the extra hour, concerning
864
+# working hours reported and effect on obligatory-rest rules (which
865
+# was suspended on that night):
866
+# http://www.retsinfo.dk/_GETDOCI_/ACCN/C19801120554-REGL
867
+
868
+# From Jesper Norgaard Welen (2005-06-11):
869
+# The Herning Folkeblad (1980-09-26) reported that the night between
870
+# Saturday and Sunday the clock is set back from three to two.
871
+
872
+# From Paul Eggert (2005-06-11):
873
+# Hence the "02:00" of the 1980 law refers to standard time, not
874
+# wall-clock time, and so the EU rules were in effect in 1980.
875
+
876
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
877
+Rule	Denmark	1916	only	-	May	14	23:00	1:00	S
878
+Rule	Denmark	1916	only	-	Sep	30	23:00	0	-
879
+Rule	Denmark	1940	only	-	May	15	 0:00	1:00	S
880
+Rule	Denmark	1945	only	-	Apr	 2	 2:00s	1:00	S
881
+Rule	Denmark	1945	only	-	Aug	15	 2:00s	0	-
882
+Rule	Denmark	1946	only	-	May	 1	 2:00s	1:00	S
883
+Rule	Denmark	1946	only	-	Sep	 1	 2:00s	0	-
884
+Rule	Denmark	1947	only	-	May	 4	 2:00s	1:00	S
885
+Rule	Denmark	1947	only	-	Aug	10	 2:00s	0	-
886
+Rule	Denmark	1948	only	-	May	 9	 2:00s	1:00	S
887
+Rule	Denmark	1948	only	-	Aug	 8	 2:00s	0	-
888
+#
889
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
890
+Zone Europe/Copenhagen	 0:50:20 -	LMT	1890
891
+			 0:50:20 -	CMT	1894 Jan  1 # Copenhagen MT
892
+			 1:00	Denmark	CE%sT	1942 Nov  2 2:00s
893
+			 1:00	C-Eur	CE%sT	1945 Apr  2 2:00
894
+			 1:00	Denmark	CE%sT	1980
895
+			 1:00	EU	CE%sT
896
+Zone Atlantic/Faroe	-0:27:04 -	LMT	1908 Jan 11	# Torshavn
897
+			 0:00	-	WET	1981
898
+			 0:00	EU	WE%sT
899
+#
900
+# From Paul Eggert (2004-10-31):
901
+# During World War II, Germany maintained secret manned weather stations in
902
+# East Greenland and Franz Josef Land, but we don't know their time zones.
903
+# My source for this is Wilhelm Dege's book mentioned under Svalbard.
904
+#
905
+# From Paul Eggert (2006-03-22):
906
+# Greenland joined the EU as part of Denmark, obtained home rule on 1979-05-01,
907
+# and left the EU on 1985-02-01.  It therefore should have been using EU
908
+# rules at least through 1984.  Shanks & Pottenger say Scoresbysund and Godthab
909
+# used C-Eur rules after 1980, but IATA SSIM (1991/1996) says they use EU
910
+# rules since at least 1991.  Assume EU rules since 1980.
911
+
912
+# From Gwillin Law (2001-06-06), citing
913
+# <http://www.statkart.no/efs/efshefter/2001/efs5-2001.pdf> (2001-03-15),
914
+# and with translations corrected by Steffen Thorsen:
915
+#
916
+# Greenland has four local times, and the relation to UTC
917
+# is according to the following time line:
918
+#
919
+# The military zone near Thule	UTC-4
920
+# Standard Greenland time	UTC-3
921
+# Scoresbysund			UTC-1
922
+# Danmarkshavn			UTC
923
+#
924
+# In the military area near Thule and in Danmarkshavn DST will not be
925
+# introduced.
926
+
927
+# From Rives McDow (2001-11-01):
928
+#
929
+# I correspond regularly with the Dansk Polarcenter, and wrote them at
930
+# the time to clarify the situation in Thule.  Unfortunately, I have
931
+# not heard back from them regarding my recent letter.  [But I have
932
+# info from earlier correspondence.]
933
+#
934
+# According to the center, a very small local time zone around Thule
935
+# Air Base keeps the time according to UTC-4, implementing daylight
936
+# savings using North America rules, changing the time at 02:00 local time....
937
+#
938
+# The east coast of Greenland north of the community of Scoresbysund
939
+# uses UTC in the same way as in Iceland, year round, with no dst.
940
+# There are just a few stations on this coast, including the
941
+# Danmarkshavn ICAO weather station mentioned in your September 29th
942
+# email.  The other stations are two sledge patrol stations in
943
+# Mestersvig and Daneborg, the air force base at Station Nord, and the
944
+# DPC research station at Zackenberg.
945
+#
946
+# Scoresbysund and two small villages nearby keep time UTC-1 and use
947
+# the same daylight savings time period as in West Greenland (Godthab).
948
+#
949
+# The rest of Greenland, including Godthab (this area, although it
950
+# includes central Greenland, is known as west Greenland), keeps time
951
+# UTC-3, with daylight savings methods according to European rules.
952
+#
953
+# It is common procedure to use UTC 0 in the wilderness of East and
954
+# North Greenland, because it is mainly Icelandic aircraft operators
955
+# maintaining traffic in these areas.  However, the official status of
956
+# this area is that it sticks with Godthab time.  This area might be
957
+# considered a dual time zone in some respects because of this.
958
+
959
+# From Rives McDow (2001-11-19):
960
+# I heard back from someone stationed at Thule; the time change took place
961
+# there at 2:00 AM.
962
+
963
+# From Paul Eggert (2006-03-22):
964
+# From 1997 on the CIA map shows Danmarkshavn on GMT;
965
+# the 1995 map as like Godthab.
966
+# For lack of better info, assume they were like Godthab before 1996.
967
+# startkart.no says Thule does not observe DST, but this is clearly an error,
968
+# so go with Shanks & Pottenger for Thule transitions until this year.
969
+# For 2007 on assume Thule will stay in sync with US DST rules.
970
+#
971
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
972
+Rule	Thule	1991	1992	-	Mar	lastSun	2:00	1:00	D
973
+Rule	Thule	1991	1992	-	Sep	lastSun	2:00	0	S
974
+Rule	Thule	1993	2006	-	Apr	Sun>=1	2:00	1:00	D
975
+Rule	Thule	1993	2006	-	Oct	lastSun	2:00	0	S
976
+Rule	Thule	2007	max	-	Mar	Sun>=8	2:00	1:00	D
977
+Rule	Thule	2007	max	-	Nov	Sun>=1	2:00	0	S
978
+#
979
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
980
+Zone America/Danmarkshavn -1:14:40 -	LMT	1916 Jul 28
981
+			-3:00	-	WGT	1980 Apr  6 2:00
982
+			-3:00	EU	WG%sT	1996
983
+			0:00	-	GMT
984
+Zone America/Scoresbysund -1:27:52 -	LMT	1916 Jul 28 # Ittoqqortoormiit
985
+			-2:00	-	CGT	1980 Apr  6 2:00
986
+			-2:00	C-Eur	CG%sT	1981 Mar 29
987
+			-1:00	EU	EG%sT
988
+Zone America/Godthab	-3:26:56 -	LMT	1916 Jul 28 # Nuuk
989
+			-3:00	-	WGT	1980 Apr  6 2:00
990
+			-3:00	EU	WG%sT
991
+Zone America/Thule	-4:35:08 -	LMT	1916 Jul 28 # Pituffik air base
992
+			-4:00	Thule	A%sT
993
+
994
+# Estonia
995
+# From Peter Ilieve (1994-10-15):
996
+# A relative in Tallinn confirms the accuracy of the data for 1989 onwards
997
+# [through 1994] and gives the legal authority for it,
998
+# a regulation of the Government of Estonia, No. 111 of 1989....
999
+#
1000
+# From Peter Ilieve (1996-10-28):
1001
+# [IATA SSIM (1992/1996) claims that the Baltic republics switch at 01:00s,
1002
+# but a relative confirms that Estonia still switches at 02:00s, writing:]
1003
+# ``I do not [know] exactly but there are some little different
1004
+# (confusing) rules for International Air and Railway Transport Schedules
1005
+# conversion in Sunday connected with end of summer time in Estonia....
1006
+# A discussion is running about the summer time efficiency and effect on
1007
+# human physiology.  It seems that Estonia maybe will not change to
1008
+# summer time next spring.''
1009
+
1010
+# From Peter Ilieve (1998-11-04), heavily edited:
1011
+# <a href="http://trip.rk.ee/cgi-bin/thw?${BASE}=akt&${OOHTML}=rtd&TA=1998&TO=1&AN=1390">
1012
+# The 1998-09-22 Estonian time law
1013
+# </a>
1014
+# refers to the Eighth Directive and cites the association agreement between
1015
+# the EU and Estonia, ratified by the Estonian law (RT II 1995, 22--27, 120).
1016
+#
1017
+# I also asked [my relative] whether they use any standard abbreviation
1018
+# for their standard and summer times. He says no, they use "suveaeg"
1019
+# (summer time) and "talveaeg" (winter time).
1020
+
1021
+# From <a href="http://www.baltictimes.com/">The Baltic Times</a> (1999-09-09)
1022
+# via Steffen Thorsen:
1023
+# This year will mark the last time Estonia shifts to summer time,
1024
+# a council of the ruling coalition announced Sept. 6....
1025
+# But what this could mean for Estonia's chances of joining the European
1026
+# Union are still unclear.  In 1994, the EU declared summer time compulsory
1027
+# for all member states until 2001.  Brussels has yet to decide what to do
1028
+# after that.
1029
+
1030
+# From Mart Oruaas (2000-01-29):
1031
+# Regulation no. 301 (1999-10-12) obsoletes previous regulation
1032
+# no. 206 (1998-09-22) and thus sticks Estonia to +02:00 GMT for all
1033
+# the year round.  The regulation is effective 1999-11-01.
1034
+
1035
+# From Toomas Soome (2002-02-21):
1036
+# The Estonian government has changed once again timezone politics.
1037
+# Now we are using again EU rules.
1038
+#
1039
+# From Urmet Jaanes (2002-03-28):
1040
+# The legislative reference is Government decree No. 84 on 2002-02-21.
1041
+
1042
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1043
+Zone	Europe/Tallinn	1:39:00	-	LMT	1880
1044
+			1:39:00	-	TMT	1918 Feb # Tallinn Mean Time
1045
+			1:00	C-Eur	CE%sT	1919 Jul
1046
+			1:39:00	-	TMT	1921 May
1047
+			2:00	-	EET	1940 Aug  6
1048
+			3:00	-	MSK	1941 Sep 15
1049
+			1:00	C-Eur	CE%sT	1944 Sep 22
1050
+			3:00	Russia	MSK/MSD	1989 Mar 26 2:00s
1051
+			2:00	1:00	EEST	1989 Sep 24 2:00s
1052
+			2:00	C-Eur	EE%sT	1998 Sep 22
1053
+			2:00	EU	EE%sT	1999 Nov  1
1054
+			2:00	-	EET	2002 Feb 21
1055
+			2:00	EU	EE%sT
1056
+
1057
+# Finland
1058
+
1059
+# From Hannu Strang (1994-09-25 06:03:37 UTC):
1060
+# Well, here in Helsinki we're just changing from summer time to regular one,
1061
+# and it's supposed to change at 4am...
1062
+
1063
+# From Janne Snabb (2010-0715):
1064
+#
1065
+# I noticed that the Finland data is not accurate for years 1981 and 1982.
1066
+# During these two first trial years the DST adjustment was made one hour
1067
+# earlier than in forthcoming years. Starting 1983 the adjustment was made
1068
+# according to the central European standards.
1069
+#
1070
+# This is documented in Heikki Oja: Aikakirja 2007, published by The Almanac
1071
+# Office of University of Helsinki, ISBN 952-10-3221-9, available online (in
1072
+# Finnish) at
1073
+#
1074
+# <a href="http://almanakka.helsinki.fi/aikakirja/Aikakirja2007kokonaan.pdf">
1075
+# http://almanakka.helsinki.fi/aikakirja/Aikakirja2007kokonaan.pdf
1076
+# </a>
1077
+#
1078
+# Page 105 (56 in PDF version) has a handy table of all past daylight savings
1079
+# transitions. It is easy enough to interpret without Finnish skills.
1080
+#
1081
+# This is also confirmed by Finnish Broadcasting Company's archive at:
1082
+#
1083
+# <a href="http://www.yle.fi/elavaarkisto/?s=s&g=1&ag=5&t=&a=3401">
1084
+# http://www.yle.fi/elavaarkisto/?s=s&g=1&ag=5&t=&a=3401
1085
+# </a>
1086
+#
1087
+# The news clip from 1981 says that "the time between 2 and 3 o'clock does not
1088
+# exist tonight."
1089
+
1090
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1091
+Rule	Finland	1942	only	-	Apr	3	0:00	1:00	S
1092
+Rule	Finland	1942	only	-	Oct	3	0:00	0	-
1093
+Rule	Finland	1981	1982	-	Mar	lastSun	2:00	1:00	S
1094
+Rule	Finland	1981	1982	-	Sep	lastSun	3:00	0	-
1095
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1096
+Zone	Europe/Helsinki	1:39:52 -	LMT	1878 May 31
1097
+			1:39:52	-	HMT	1921 May    # Helsinki Mean Time
1098
+			2:00	Finland	EE%sT	1983
1099
+			2:00	EU	EE%sT
1100
+
1101
+# Aaland Is
1102
+Link	Europe/Helsinki	Europe/Mariehamn
1103
+
1104
+
1105
+# France
1106
+
1107
+# From Ciro Discepolo (2000-12-20):
1108
+#
1109
+# Henri Le Corre, Regimes Horaires pour le monde entier, Editions
1110
+# Traditionnelles - Paris 2 books, 1993
1111
+#
1112
+# Gabriel, Traite de l'heure dans le monde, Guy Tredaniel editeur,
1113
+# Paris, 1991
1114
+#
1115
+# Francoise Gauquelin, Problemes de l'heure resolus en astrologie,
1116
+# Guy tredaniel, Paris 1987
1117
+
1118
+
1119
+#
1120
+# Shank & Pottenger seem to use `24:00' ambiguously; resolve it with Whitman.
1121
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1122
+Rule	France	1916	only	-	Jun	14	23:00s	1:00	S
1123
+Rule	France	1916	1919	-	Oct	Sun>=1	23:00s	0	-
1124
+Rule	France	1917	only	-	Mar	24	23:00s	1:00	S
1125
+Rule	France	1918	only	-	Mar	 9	23:00s	1:00	S
1126
+Rule	France	1919	only	-	Mar	 1	23:00s	1:00	S
1127
+Rule	France	1920	only	-	Feb	14	23:00s	1:00	S
1128
+Rule	France	1920	only	-	Oct	23	23:00s	0	-
1129
+Rule	France	1921	only	-	Mar	14	23:00s	1:00	S
1130
+Rule	France	1921	only	-	Oct	25	23:00s	0	-
1131
+Rule	France	1922	only	-	Mar	25	23:00s	1:00	S
1132
+# DSH writes that a law of 1923-05-24 specified 3rd Sat in Apr at 23:00 to 1st
1133
+# Sat in Oct at 24:00; and that in 1930, because of Easter, the transitions
1134
+# were Apr 12 and Oct 5.  Go with Shanks & Pottenger.
1135
+Rule	France	1922	1938	-	Oct	Sat>=1	23:00s	0	-
1136
+Rule	France	1923	only	-	May	26	23:00s	1:00	S
1137
+Rule	France	1924	only	-	Mar	29	23:00s	1:00	S
1138
+Rule	France	1925	only	-	Apr	 4	23:00s	1:00	S
1139
+Rule	France	1926	only	-	Apr	17	23:00s	1:00	S
1140
+Rule	France	1927	only	-	Apr	 9	23:00s	1:00	S
1141
+Rule	France	1928	only	-	Apr	14	23:00s	1:00	S
1142
+Rule	France	1929	only	-	Apr	20	23:00s	1:00	S
1143
+Rule	France	1930	only	-	Apr	12	23:00s	1:00	S
1144
+Rule	France	1931	only	-	Apr	18	23:00s	1:00	S
1145
+Rule	France	1932	only	-	Apr	 2	23:00s	1:00	S
1146
+Rule	France	1933	only	-	Mar	25	23:00s	1:00	S
1147
+Rule	France	1934	only	-	Apr	 7	23:00s	1:00	S
1148
+Rule	France	1935	only	-	Mar	30	23:00s	1:00	S
1149
+Rule	France	1936	only	-	Apr	18	23:00s	1:00	S
1150
+Rule	France	1937	only	-	Apr	 3	23:00s	1:00	S
1151
+Rule	France	1938	only	-	Mar	26	23:00s	1:00	S
1152
+Rule	France	1939	only	-	Apr	15	23:00s	1:00	S
1153
+Rule	France	1939	only	-	Nov	18	23:00s	0	-
1154
+Rule	France	1940	only	-	Feb	25	 2:00	1:00	S
1155
+# The French rules for 1941-1944 were not used in Paris, but Shanks & Pottenger
1156
+# write that they were used in Monaco and in many French locations.
1157
+# Le Corre writes that the upper limit of the free zone was Arneguy, Orthez,
1158
+# Mont-de-Marsan, Bazas, Langon, Lamotte-Montravel, Marouil, La
1159
+# Rochefoucault, Champagne-Mouton, La Roche-Posay, La Haye-Descartes,
1160
+# Loches, Montrichard, Vierzon, Bourges, Moulins, Digoin,
1161
+# Paray-le-Monial, Montceau-les-Mines, Chalons-sur-Saone, Arbois,
1162
+# Dole, Morez, St-Claude, and Collonges (Haute-Savoie).
1163
+Rule	France	1941	only	-	May	 5	 0:00	2:00	M # Midsummer
1164
+# Shanks & Pottenger say this transition occurred at Oct 6 1:00,
1165
+# but go with Denis Excoffier (1997-12-12),
1166
+# who quotes the Ephemerides Astronomiques for 1998 from Bureau des Longitudes
1167
+# as saying 5/10/41 22hUT.
1168
+Rule	France	1941	only	-	Oct	 6	 0:00	1:00	S
1169
+Rule	France	1942	only	-	Mar	 9	 0:00	2:00	M
1170
+Rule	France	1942	only	-	Nov	 2	 3:00	1:00	S
1171
+Rule	France	1943	only	-	Mar	29	 2:00	2:00	M
1172
+Rule	France	1943	only	-	Oct	 4	 3:00	1:00	S
1173
+Rule	France	1944	only	-	Apr	 3	 2:00	2:00	M
1174
+Rule	France	1944	only	-	Oct	 8	 1:00	1:00	S
1175
+Rule	France	1945	only	-	Apr	 2	 2:00	2:00	M
1176
+Rule	France	1945	only	-	Sep	16	 3:00	0	-
1177
+# Shanks & Pottenger give Mar 28 2:00 and Sep 26 3:00;
1178
+# go with Excoffier's 28/3/76 0hUT and 25/9/76 23hUT.
1179
+Rule	France	1976	only	-	Mar	28	 1:00	1:00	S
1180
+Rule	France	1976	only	-	Sep	26	 1:00	0	-
1181
+# Shanks & Pottenger give 0:09:20 for Paris Mean Time, and Whitman 0:09:05,
1182
+# but Howse quotes the actual French legislation as saying 0:09:21.
1183
+# Go with Howse.  Howse writes that the time in France was officially based
1184
+# on PMT-0:09:21 until 1978-08-09, when the time base finally switched to UTC.
1185
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1186
+Zone	Europe/Paris	0:09:21 -	LMT	1891 Mar 15  0:01
1187
+			0:09:21	-	PMT	1911 Mar 11  0:01  # Paris MT
1188
+# Shanks & Pottenger give 1940 Jun 14 0:00; go with Excoffier and Le Corre.
1189
+			0:00	France	WE%sT	1940 Jun 14 23:00
1190
+# Le Corre says Paris stuck with occupied-France time after the liberation;
1191
+# go with Shanks & Pottenger.
1192
+			1:00	C-Eur	CE%sT	1944 Aug 25
1193
+			0:00	France	WE%sT	1945 Sep 16  3:00
1194
+			1:00	France	CE%sT	1977
1195
+			1:00	EU	CE%sT
1196
+
1197
+# Germany
1198
+
1199
+# From Markus Kuhn (1998-09-29):
1200
+# The German time zone web site by the Physikalisch-Technische
1201
+# Bundesanstalt contains DST information back to 1916.
1202
+# [See tz-link.htm for the URL.]
1203
+
1204
+# From Joerg Schilling (2002-10-23):
1205
+# In 1945, Berlin was switched to Moscow Summer time (GMT+4) by
1206
+# <a href="http://www.dhm.de/lemo/html/biografien/BersarinNikolai/">
1207
+# General [Nikolai] Bersarin</a>.
1208
+
1209
+# From Paul Eggert (2003-03-08):
1210
+# <a href="http://www.parlament-berlin.de/pds-fraktion.nsf/727459127c8b66ee8525662300459099/defc77cb784f180ac1256c2b0030274b/$FILE/bersarint.pdf">
1211
+# http://www.parlament-berlin.de/pds-fraktion.nsf/727459127c8b66ee8525662300459099/defc77cb784f180ac1256c2b0030274b/$FILE/bersarint.pdf
1212
+# </a>
1213
+# says that Bersarin issued an order to use Moscow time on May 20.
1214
+# However, Moscow did not observe daylight saving in 1945, so
1215
+# this was equivalent to CEMT (GMT+3), not GMT+4.
1216
+
1217
+
1218
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1219
+Rule	Germany	1946	only	-	Apr	14	2:00s	1:00	S
1220
+Rule	Germany	1946	only	-	Oct	 7	2:00s	0	-
1221
+Rule	Germany	1947	1949	-	Oct	Sun>=1	2:00s	0	-
1222
+# http://www.ptb.de/de/org/4/44/441/salt.htm says the following transition
1223
+# occurred at 3:00 MEZ, not the 2:00 MEZ given in Shanks & Pottenger.
1224
+# Go with the PTB.
1225
+Rule	Germany	1947	only	-	Apr	 6	3:00s	1:00	S
1226
+Rule	Germany	1947	only	-	May	11	2:00s	2:00	M
1227
+Rule	Germany	1947	only	-	Jun	29	3:00	1:00	S
1228
+Rule	Germany	1948	only	-	Apr	18	2:00s	1:00	S
1229
+Rule	Germany	1949	only	-	Apr	10	2:00s	1:00	S
1230
+
1231
+Rule SovietZone	1945	only	-	May	24	2:00	2:00	M # Midsummer
1232
+Rule SovietZone	1945	only	-	Sep	24	3:00	1:00	S
1233
+Rule SovietZone	1945	only	-	Nov	18	2:00s	0	-
1234
+
1235
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1236
+Zone	Europe/Berlin	0:53:28 -	LMT	1893 Apr
1237
+			1:00	C-Eur	CE%sT	1945 May 24 2:00
1238
+			1:00 SovietZone	CE%sT	1946
1239
+			1:00	Germany	CE%sT	1980
1240
+			1:00	EU	CE%sT
1241
+
1242
+# Georgia
1243
+# Please see the "asia" file for Asia/Tbilisi.
1244
+# Herodotus (Histories, IV.45) says Georgia north of the Phasis (now Rioni)
1245
+# is in Europe.  Our reference location Tbilisi is in the Asian part.
1246
+
1247
+# Gibraltar
1248
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1249
+Zone Europe/Gibraltar	-0:21:24 -	LMT	1880 Aug  2 0:00s
1250
+			0:00	GB-Eire	%s	1957 Apr 14 2:00
1251
+			1:00	-	CET	1982
1252
+			1:00	EU	CE%sT
1253
+
1254
+# Greece
1255
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1256
+# Whitman gives 1932 Jul 5 - Nov 1; go with Shanks & Pottenger.
1257
+Rule	Greece	1932	only	-	Jul	 7	0:00	1:00	S
1258
+Rule	Greece	1932	only	-	Sep	 1	0:00	0	-
1259
+# Whitman gives 1941 Apr 25 - ?; go with Shanks & Pottenger.
1260
+Rule	Greece	1941	only	-	Apr	 7	0:00	1:00	S
1261
+# Whitman gives 1942 Feb 2 - ?; go with Shanks & Pottenger.
1262
+Rule	Greece	1942	only	-	Nov	 2	3:00	0	-
1263
+Rule	Greece	1943	only	-	Mar	30	0:00	1:00	S
1264
+Rule	Greece	1943	only	-	Oct	 4	0:00	0	-
1265
+# Whitman gives 1944 Oct 3 - Oct 31; go with Shanks & Pottenger.
1266
+Rule	Greece	1952	only	-	Jul	 1	0:00	1:00	S
1267
+Rule	Greece	1952	only	-	Nov	 2	0:00	0	-
1268
+Rule	Greece	1975	only	-	Apr	12	0:00s	1:00	S
1269
+Rule	Greece	1975	only	-	Nov	26	0:00s	0	-
1270
+Rule	Greece	1976	only	-	Apr	11	2:00s	1:00	S
1271
+Rule	Greece	1976	only	-	Oct	10	2:00s	0	-
1272
+Rule	Greece	1977	1978	-	Apr	Sun>=1	2:00s	1:00	S
1273
+Rule	Greece	1977	only	-	Sep	26	2:00s	0	-
1274
+Rule	Greece	1978	only	-	Sep	24	4:00	0	-
1275
+Rule	Greece	1979	only	-	Apr	 1	9:00	1:00	S
1276
+Rule	Greece	1979	only	-	Sep	29	2:00	0	-
1277
+Rule	Greece	1980	only	-	Apr	 1	0:00	1:00	S
1278
+Rule	Greece	1980	only	-	Sep	28	0:00	0	-
1279
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1280
+Zone	Europe/Athens	1:34:52 -	LMT	1895 Sep 14
1281
+			1:34:52	-	AMT	1916 Jul 28 0:01     # Athens MT
1282
+			2:00	Greece	EE%sT	1941 Apr 30
1283
+			1:00	Greece	CE%sT	1944 Apr  4
1284
+			2:00	Greece	EE%sT	1981
1285
+			# Shanks & Pottenger say it switched to C-Eur in 1981;
1286
+			# go with EU instead, since Greece joined it on Jan 1.
1287
+			2:00	EU	EE%sT
1288
+
1289
+# Hungary
1290
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1291
+Rule	Hungary	1918	only	-	Apr	 1	 3:00	1:00	S
1292
+Rule	Hungary	1918	only	-	Sep	29	 3:00	0	-
1293
+Rule	Hungary	1919	only	-	Apr	15	 3:00	1:00	S
1294
+Rule	Hungary	1919	only	-	Sep	15	 3:00	0	-
1295
+Rule	Hungary	1920	only	-	Apr	 5	 3:00	1:00	S
1296
+Rule	Hungary	1920	only	-	Sep	30	 3:00	0	-
1297
+Rule	Hungary	1945	only	-	May	 1	23:00	1:00	S
1298
+Rule	Hungary	1945	only	-	Nov	 3	 0:00	0	-
1299
+Rule	Hungary	1946	only	-	Mar	31	 2:00s	1:00	S
1300
+Rule	Hungary	1946	1949	-	Oct	Sun>=1	 2:00s	0	-
1301
+Rule	Hungary	1947	1949	-	Apr	Sun>=4	 2:00s	1:00	S
1302
+Rule	Hungary	1950	only	-	Apr	17	 2:00s	1:00	S
1303
+Rule	Hungary	1950	only	-	Oct	23	 2:00s	0	-
1304
+Rule	Hungary	1954	1955	-	May	23	 0:00	1:00	S
1305
+Rule	Hungary	1954	1955	-	Oct	 3	 0:00	0	-
1306
+Rule	Hungary	1956	only	-	Jun	Sun>=1	 0:00	1:00	S
1307
+Rule	Hungary	1956	only	-	Sep	lastSun	 0:00	0	-
1308
+Rule	Hungary	1957	only	-	Jun	Sun>=1	 1:00	1:00	S
1309
+Rule	Hungary	1957	only	-	Sep	lastSun	 3:00	0	-
1310
+Rule	Hungary	1980	only	-	Apr	 6	 1:00	1:00	S
1311
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1312
+Zone	Europe/Budapest	1:16:20 -	LMT	1890 Oct
1313
+			1:00	C-Eur	CE%sT	1918
1314
+			1:00	Hungary	CE%sT	1941 Apr  6  2:00
1315
+			1:00	C-Eur	CE%sT	1945
1316
+			1:00	Hungary	CE%sT	1980 Sep 28  2:00s
1317
+			1:00	EU	CE%sT
1318
+
1319
+# Iceland
1320
+#
1321
+# From Adam David (1993-11-06):
1322
+# The name of the timezone in Iceland for system / mail / news purposes is GMT.
1323
+#
1324
+# (1993-12-05):
1325
+# This material is paraphrased from the 1988 edition of the University of
1326
+# Iceland Almanak.
1327
+#
1328
+# From January 1st, 1908 the whole of Iceland was standardised at 1 hour
1329
+# behind GMT. Previously, local mean solar time was used in different parts
1330
+# of Iceland, the almanak had been based on Reykjavik mean solar time which
1331
+# was 1 hour and 28 minutes behind GMT.
1332
+#
1333
+# "first day of winter" referred to [below] means the first day of the 26 weeks
1334
+# of winter, according to the old icelandic calendar that dates back to the
1335
+# time the norsemen first settled Iceland.  The first day of winter is always
1336
+# Saturday, but is not dependent on the Julian or Gregorian calendars.
1337
+#
1338
+# (1993-12-10):
1339
+# I have a reference from the Oxford Icelandic-English dictionary for the
1340
+# beginning of winter, which ties it to the ecclesiastical calendar (and thus
1341
+# to the julian/gregorian calendar) over the period in question.
1342
+#	the winter begins on the Saturday next before St. Luke's day
1343
+#	(old style), or on St. Luke's day, if a Saturday.
1344
+# St. Luke's day ought to be traceable from ecclesiastical sources. "old style"
1345
+# might be a reference to the Julian calendar as opposed to Gregorian, or it
1346
+# might mean something else (???).
1347
+#
1348
+# From Paul Eggert (2006-03-22):
1349
+# The Iceland Almanak, Shanks & Pottenger, and Whitman disagree on many points.
1350
+# We go with the Almanak, except for one claim from Shanks & Pottenger, namely
1351
+# that Reykavik was 21W57 from 1837 to 1908, local mean time before that.
1352
+#
1353
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1354
+Rule	Iceland	1917	1918	-	Feb	19	23:00	1:00	S
1355
+Rule	Iceland	1917	only	-	Oct	21	 1:00	0	-
1356
+Rule	Iceland	1918	only	-	Nov	16	 1:00	0	-
1357
+Rule	Iceland	1939	only	-	Apr	29	23:00	1:00	S
1358
+Rule	Iceland	1939	only	-	Nov	29	 2:00	0	-
1359
+Rule	Iceland	1940	only	-	Feb	25	 2:00	1:00	S
1360
+Rule	Iceland	1940	only	-	Nov	 3	 2:00	0	-
1361
+Rule	Iceland	1941	only	-	Mar	 2	 1:00s	1:00	S
1362
+Rule	Iceland	1941	only	-	Nov	 2	 1:00s	0	-
1363
+Rule	Iceland	1942	only	-	Mar	 8	 1:00s	1:00	S
1364
+Rule	Iceland	1942	only	-	Oct	25	 1:00s	0	-
1365
+# 1943-1946 - first Sunday in March until first Sunday in winter
1366
+Rule	Iceland	1943	1946	-	Mar	Sun>=1	 1:00s	1:00	S
1367
+Rule	Iceland	1943	1948	-	Oct	Sun>=22	 1:00s	0	-
1368
+# 1947-1967 - first Sunday in April until first Sunday in winter
1369
+Rule	Iceland	1947	1967	-	Apr	Sun>=1	 1:00s	1:00	S
1370
+# 1949 Oct transition delayed by 1 week
1371
+Rule	Iceland	1949	only	-	Oct	30	 1:00s	0	-
1372
+Rule	Iceland	1950	1966	-	Oct	Sun>=22	 1:00s	0	-
1373
+Rule	Iceland	1967	only	-	Oct	29	 1:00s	0	-
1374
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1375
+Zone Atlantic/Reykjavik	-1:27:24 -	LMT	1837
1376
+			-1:27:48 -	RMT	1908 # Reykjavik Mean Time?
1377
+			-1:00	Iceland	IS%sT	1968 Apr 7 1:00s
1378
+			 0:00	-	GMT
1379
+
1380
+# Italy
1381
+#
1382
+# From Paul Eggert (2001-03-06):
1383
+# Sicily and Sardinia each had their own time zones from 1866 to 1893,
1384
+# called Palermo Time (+00:53:28) and Cagliari Time (+00:36:32).
1385
+# During World War II, German-controlled Italy used German time.
1386
+# But these events all occurred before the 1970 cutoff,
1387
+# so record only the time in Rome.
1388
+#
1389
+# From Paul Eggert (2006-03-22):
1390
+# For Italian DST we have three sources: Shanks & Pottenger, Whitman, and
1391
+# F. Pollastri
1392
+# <a href="http://toi.iriti.cnr.it/uk/ienitlt.html">
1393
+# Day-light Saving Time in Italy (2006-02-03)
1394
+# </a>
1395
+# (`FP' below), taken from an Italian National Electrotechnical Institute
1396
+# publication. When the three sources disagree, guess who's right, as follows:
1397
+#
1398
+# year	FP	Shanks&P. (S)	Whitman (W)	Go with:
1399
+# 1916	06-03	06-03 24:00	06-03 00:00	FP & W
1400
+#	09-30	09-30 24:00	09-30 01:00	FP; guess 24:00s
1401
+# 1917	04-01	03-31 24:00	03-31 00:00	FP & S
1402
+#	09-30	09-29 24:00	09-30 01:00	FP & W
1403
+# 1918	03-09	03-09 24:00	03-09 00:00	FP & S
1404
+#	10-06	10-05 24:00	10-06 01:00	FP & W
1405
+# 1919	03-01	03-01 24:00	03-01 00:00	FP & S
1406
+#	10-04	10-04 24:00	10-04 01:00	FP; guess 24:00s
1407
+# 1920	03-20	03-20 24:00	03-20 00:00	FP & S
1408
+#	09-18	09-18 24:00	10-01 01:00	FP; guess 24:00s
1409
+# 1944	04-02	04-03 02:00			S (see C-Eur)
1410
+#	09-16	10-02 03:00			FP; guess 24:00s
1411
+# 1945	09-14	09-16 24:00			FP; guess 24:00s
1412
+# 1970	05-21	05-31 00:00			S
1413
+#	09-20	09-27 00:00			S
1414
+#
1415
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1416
+Rule	Italy	1916	only	-	Jun	 3	0:00s	1:00	S
1417
+Rule	Italy	1916	only	-	Oct	 1	0:00s	0	-
1418
+Rule	Italy	1917	only	-	Apr	 1	0:00s	1:00	S
1419
+Rule	Italy	1917	only	-	Sep	30	0:00s	0	-
1420
+Rule	Italy	1918	only	-	Mar	10	0:00s	1:00	S
1421
+Rule	Italy	1918	1919	-	Oct	Sun>=1	0:00s	0	-
1422
+Rule	Italy	1919	only	-	Mar	 2	0:00s	1:00	S
1423
+Rule	Italy	1920	only	-	Mar	21	0:00s	1:00	S
1424
+Rule	Italy	1920	only	-	Sep	19	0:00s	0	-
1425
+Rule	Italy	1940	only	-	Jun	15	0:00s	1:00	S
1426
+Rule	Italy	1944	only	-	Sep	17	0:00s	0	-
1427
+Rule	Italy	1945	only	-	Apr	 2	2:00	1:00	S
1428
+Rule	Italy	1945	only	-	Sep	15	0:00s	0	-
1429
+Rule	Italy	1946	only	-	Mar	17	2:00s	1:00	S
1430
+Rule	Italy	1946	only	-	Oct	 6	2:00s	0	-
1431
+Rule	Italy	1947	only	-	Mar	16	0:00s	1:00	S
1432
+Rule	Italy	1947	only	-	Oct	 5	0:00s	0	-
1433
+Rule	Italy	1948	only	-	Feb	29	2:00s	1:00	S
1434
+Rule	Italy	1948	only	-	Oct	 3	2:00s	0	-
1435
+Rule	Italy	1966	1968	-	May	Sun>=22	0:00	1:00	S
1436
+Rule	Italy	1966	1969	-	Sep	Sun>=22	0:00	0	-
1437
+Rule	Italy	1969	only	-	Jun	 1	0:00	1:00	S
1438
+Rule	Italy	1970	only	-	May	31	0:00	1:00	S
1439
+Rule	Italy	1970	only	-	Sep	lastSun	0:00	0	-
1440
+Rule	Italy	1971	1972	-	May	Sun>=22	0:00	1:00	S
1441
+Rule	Italy	1971	only	-	Sep	lastSun	1:00	0	-
1442
+Rule	Italy	1972	only	-	Oct	 1	0:00	0	-
1443
+Rule	Italy	1973	only	-	Jun	 3	0:00	1:00	S
1444
+Rule	Italy	1973	1974	-	Sep	lastSun	0:00	0	-
1445
+Rule	Italy	1974	only	-	May	26	0:00	1:00	S
1446
+Rule	Italy	1975	only	-	Jun	 1	0:00s	1:00	S
1447
+Rule	Italy	1975	1977	-	Sep	lastSun	0:00s	0	-
1448
+Rule	Italy	1976	only	-	May	30	0:00s	1:00	S
1449
+Rule	Italy	1977	1979	-	May	Sun>=22	0:00s	1:00	S
1450
+Rule	Italy	1978	only	-	Oct	 1	0:00s	0	-
1451
+Rule	Italy	1979	only	-	Sep	30	0:00s	0	-
1452
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1453
+Zone	Europe/Rome	0:49:56 -	LMT	1866 Sep 22
1454
+			0:49:56	-	RMT	1893 Nov  1 0:00s # Rome Mean
1455
+			1:00	Italy	CE%sT	1942 Nov  2 2:00s
1456
+			1:00	C-Eur	CE%sT	1944 Jul
1457
+			1:00	Italy	CE%sT	1980
1458
+			1:00	EU	CE%sT
1459
+
1460
+Link	Europe/Rome	Europe/Vatican
1461
+Link	Europe/Rome	Europe/San_Marino
1462
+
1463
+# Latvia
1464
+
1465
+# From Liene Kanepe (1998-09-17):
1466
+
1467
+# I asked about this matter Scientific Secretary of the Institute of Astronomy
1468
+# of The University of Latvia Dr. paed Mr. Ilgonis Vilks. I also searched the
1469
+# correct data in juridical acts and I found some juridical documents about
1470
+# changes in the counting of time in Latvia from 1981....
1471
+#
1472
+# Act No.35 of the Council of Ministers of Latvian SSR of 1981-01-22 ...
1473
+# according to the Act No.925 of the Council of Ministers of USSR of 1980-10-24
1474
+# ...: all year round the time of 2nd time zone + 1 hour, in addition turning
1475
+# the hands of the clock 1 hour forward on 1 April at 00:00 (GMT 31 March 21:00)
1476
+# and 1 hour backward on the 1 October at 00:00 (GMT 30 September 20:00).
1477
+#
1478
+# Act No.592 of the Council of Ministers of Latvian SSR of 1984-09-24 ...
1479
+# according to the Act No.967 of the Council of Ministers of USSR of 1984-09-13
1480
+# ...: all year round the time of 2nd time zone + 1 hour, in addition turning
1481
+# the hands of the clock 1 hour forward on the last Sunday of March at 02:00
1482
+# (GMT 23:00 on the previous day) and 1 hour backward on the last Sunday of
1483
+# September at 03:00 (GMT 23:00 on the previous day).
1484
+#
1485
+# Act No.81 of the Council of Ministers of Latvian SSR of 1989-03-22 ...
1486
+# according to the Act No.227 of the Council of Ministers of USSR of 1989-03-14
1487
+# ...: since the last Sunday of March 1989 in Lithuanian SSR, Latvian SSR,
1488
+# Estonian SSR and Kaliningrad region of Russian Federation all year round the
1489
+# time of 2nd time zone (Moscow time minus one hour). On the territory of Latvia
1490
+# transition to summer time is performed on the last Sunday of March at 02:00
1491
+# (GMT 00:00), turning the hands of the clock 1 hour forward.  The end of
1492
+# daylight saving time is performed on the last Sunday of September at 03:00
1493
+# (GMT 00:00), turning the hands of the clock 1 hour backward. Exception is
1494
+# 1989-03-26, when we must not turn the hands of the clock....
1495
+#
1496
+# The Regulations of the Cabinet of Ministers of the Republic of Latvia of
1497
+# 1997-01-21 on transition to Summer time ... established the same order of
1498
+# daylight savings time settings as in the States of the European Union.
1499
+
1500
+# From Andrei Ivanov (2000-03-06):
1501
+# This year Latvia will not switch to Daylight Savings Time (as specified in
1502
+# <a href="http://www.lv-laiks.lv/wwwraksti/2000/071072/vd4.htm">
1503
+# The Regulations of the Cabinet of Ministers of the Rep. of Latvia of
1504
+# 29-Feb-2000 (#79)</a>, in Latvian for subscribers only).
1505
+
1506
+# <a href="http://www.rferl.org/newsline/2001/01/3-CEE/cee-030101.html">
1507
+# From RFE/RL Newsline (2001-01-03), noted after a heads-up by Rives McDow:
1508
+# </a>
1509
+# The Latvian government on 2 January decided that the country will
1510
+# institute daylight-saving time this spring, LETA reported.
1511
+# Last February the three Baltic states decided not to turn back their
1512
+# clocks one hour in the spring....
1513
+# Minister of Economy Aigars Kalvitis noted that Latvia had too few
1514
+# daylight hours and thus decided to comply with a draft European
1515
+# Commission directive that provides for instituting daylight-saving
1516
+# time in EU countries between 2002 and 2006. The Latvian government
1517
+# urged Lithuania and Estonia to adopt a similar time policy, but it
1518
+# appears that they will not do so....
1519
+
1520
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1521
+Rule	Latvia	1989	1996	-	Mar	lastSun	 2:00s	1:00	S
1522
+Rule	Latvia	1989	1996	-	Sep	lastSun	 2:00s	0	-
1523
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1524
+Zone	Europe/Riga	1:36:24	-	LMT	1880
1525
+			1:36:24	-	RMT	1918 Apr 15 2:00 #Riga Mean Time
1526
+			1:36:24	1:00	LST	1918 Sep 16 3:00 #Latvian Summer
1527
+			1:36:24	-	RMT	1919 Apr  1 2:00
1528
+			1:36:24	1:00	LST	1919 May 22 3:00
1529
+			1:36:24	-	RMT	1926 May 11
1530
+			2:00	-	EET	1940 Aug  5
1531
+			3:00	-	MSK	1941 Jul
1532
+			1:00	C-Eur	CE%sT	1944 Oct 13
1533
+			3:00	Russia	MSK/MSD	1989 Mar lastSun 2:00s
1534
+			2:00	1:00	EEST	1989 Sep lastSun 2:00s
1535
+			2:00	Latvia	EE%sT	1997 Jan 21
1536
+			2:00	EU	EE%sT	2000 Feb 29
1537
+			2:00	-	EET	2001 Jan  2
1538
+			2:00	EU	EE%sT
1539
+
1540
+# Liechtenstein
1541
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1542
+Zone	Europe/Vaduz	0:38:04 -	LMT	1894 Jun
1543
+			1:00	-	CET	1981
1544
+			1:00	EU	CE%sT
1545
+
1546
+# Lithuania
1547
+
1548
+# From Paul Eggert (1996-11-22):
1549
+# IATA SSIM (1992/1996) says Lithuania uses W-Eur rules, but since it is
1550
+# known to be wrong about Estonia and Latvia, assume it's wrong here too.
1551
+
1552
+# From Marius Gedminas (1998-08-07):
1553
+# I would like to inform that in this year Lithuanian time zone
1554
+# (Europe/Vilnius) was changed.
1555
+
1556
+# From <a href="http://www.elta.lt/">ELTA</a> No. 972 (2582) (1999-09-29),
1557
+# via Steffen Thorsen:
1558
+# Lithuania has shifted back to the second time zone (GMT plus two hours)
1559
+# to be valid here starting from October 31,
1560
+# as decided by the national government on Wednesday....
1561
+# The Lithuanian government also announced plans to consider a
1562
+# motion to give up shifting to summer time in spring, as it was
1563
+# already done by Estonia.
1564
+
1565
+# From the <a href="http://www.tourism.lt/informa/ff.htm">
1566
+# Fact File, Lithuanian State Department of Tourism
1567
+# </a> (2000-03-27): Local time is GMT+2 hours ..., no daylight saving.
1568
+
1569
+# From a user via Klaus Marten (2003-02-07):
1570
+# As a candidate for membership of the European Union, Lithuania will
1571
+# observe Summer Time in 2003, changing its clocks at the times laid
1572
+# down in EU Directive 2000/84 of 19.I.01 (i.e. at the same times as its
1573
+# neighbour Latvia). The text of the Lithuanian government Order of
1574
+# 7.XI.02 to this effect can be found at
1575
+# http://www.lrvk.lt/nut/11/n1749.htm
1576
+
1577
+
1578
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1579
+Zone	Europe/Vilnius	1:41:16	-	LMT	1880
1580
+			1:24:00	-	WMT	1917	    # Warsaw Mean Time
1581
+			1:35:36	-	KMT	1919 Oct 10 # Kaunas Mean Time
1582
+			1:00	-	CET	1920 Jul 12
1583
+			2:00	-	EET	1920 Oct  9
1584
+			1:00	-	CET	1940 Aug  3
1585
+			3:00	-	MSK	1941 Jun 24
1586
+			1:00	C-Eur	CE%sT	1944 Aug
1587
+			3:00	Russia	MSK/MSD	1991 Mar 31 2:00s
1588
+			2:00	1:00	EEST	1991 Sep 29 2:00s
1589
+			2:00	C-Eur	EE%sT	1998
1590
+			2:00	-	EET	1998 Mar 29 1:00u
1591
+			1:00	EU	CE%sT	1999 Oct 31 1:00u
1592
+			2:00	-	EET	2003 Jan  1
1593
+			2:00	EU	EE%sT
1594
+
1595
+# Luxembourg
1596
+# Whitman disagrees with most of these dates in minor ways;
1597
+# go with Shanks & Pottenger.
1598
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1599
+Rule	Lux	1916	only	-	May	14	23:00	1:00	S
1600
+Rule	Lux	1916	only	-	Oct	 1	 1:00	0	-
1601
+Rule	Lux	1917	only	-	Apr	28	23:00	1:00	S
1602
+Rule	Lux	1917	only	-	Sep	17	 1:00	0	-
1603
+Rule	Lux	1918	only	-	Apr	Mon>=15	 2:00s	1:00	S
1604
+Rule	Lux	1918	only	-	Sep	Mon>=15	 2:00s	0	-
1605
+Rule	Lux	1919	only	-	Mar	 1	23:00	1:00	S
1606
+Rule	Lux	1919	only	-	Oct	 5	 3:00	0	-
1607
+Rule	Lux	1920	only	-	Feb	14	23:00	1:00	S
1608
+Rule	Lux	1920	only	-	Oct	24	 2:00	0	-
1609
+Rule	Lux	1921	only	-	Mar	14	23:00	1:00	S
1610
+Rule	Lux	1921	only	-	Oct	26	 2:00	0	-
1611
+Rule	Lux	1922	only	-	Mar	25	23:00	1:00	S
1612
+Rule	Lux	1922	only	-	Oct	Sun>=2	 1:00	0	-
1613
+Rule	Lux	1923	only	-	Apr	21	23:00	1:00	S
1614
+Rule	Lux	1923	only	-	Oct	Sun>=2	 2:00	0	-
1615
+Rule	Lux	1924	only	-	Mar	29	23:00	1:00	S
1616
+Rule	Lux	1924	1928	-	Oct	Sun>=2	 1:00	0	-
1617
+Rule	Lux	1925	only	-	Apr	 5	23:00	1:00	S
1618
+Rule	Lux	1926	only	-	Apr	17	23:00	1:00	S
1619
+Rule	Lux	1927	only	-	Apr	 9	23:00	1:00	S
1620
+Rule	Lux	1928	only	-	Apr	14	23:00	1:00	S
1621
+Rule	Lux	1929	only	-	Apr	20	23:00	1:00	S
1622
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1623
+Zone Europe/Luxembourg	0:24:36 -	LMT	1904 Jun
1624
+			1:00	Lux	CE%sT	1918 Nov 25
1625
+			0:00	Lux	WE%sT	1929 Oct  6 2:00s
1626
+			0:00	Belgium	WE%sT	1940 May 14 3:00
1627
+			1:00	C-Eur	WE%sT	1944 Sep 18 3:00
1628
+			1:00	Belgium	CE%sT	1977
1629
+			1:00	EU	CE%sT
1630
+
1631
+# Macedonia
1632
+# see Serbia
1633
+
1634
+# Malta
1635
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1636
+Rule	Malta	1973	only	-	Mar	31	0:00s	1:00	S
1637
+Rule	Malta	1973	only	-	Sep	29	0:00s	0	-
1638
+Rule	Malta	1974	only	-	Apr	21	0:00s	1:00	S
1639
+Rule	Malta	1974	only	-	Sep	16	0:00s	0	-
1640
+Rule	Malta	1975	1979	-	Apr	Sun>=15	2:00	1:00	S
1641
+Rule	Malta	1975	1980	-	Sep	Sun>=15	2:00	0	-
1642
+Rule	Malta	1980	only	-	Mar	31	2:00	1:00	S
1643
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1644
+Zone	Europe/Malta	0:58:04 -	LMT	1893 Nov  2 0:00s # Valletta
1645
+			1:00	Italy	CE%sT	1942 Nov  2 2:00s
1646
+			1:00	C-Eur	CE%sT	1945 Apr  2 2:00s
1647
+			1:00	Italy	CE%sT	1973 Mar 31
1648
+			1:00	Malta	CE%sT	1981
1649
+			1:00	EU	CE%sT
1650
+
1651
+# Moldova
1652
+
1653
+# From Paul Eggert (2006-03-22):
1654
+# A previous version of this database followed Shanks & Pottenger, who write
1655
+# that Tiraspol switched to Moscow time on 1992-01-19 at 02:00.
1656
+# However, this is most likely an error, as Moldova declared independence
1657
+# on 1991-08-27 (the 1992-01-19 date is that of a Russian decree).
1658
+# In early 1992 there was large-scale interethnic violence in the area
1659
+# and it's possible that some Russophones continued to observe Moscow time.
1660
+# But [two people] separately reported via
1661
+# Jesper Norgaard that as of 2001-01-24 Tiraspol was like Chisinau.
1662
+# The Tiraspol entry has therefore been removed for now.
1663
+#
1664
+# From Alexander Krivenyshev (2011-10-17):
1665
+# Pridnestrovian Moldavian Republic (PMR, also known as
1666
+# "Pridnestrovie") has abolished seasonal clock change (no transition
1667
+# to the Winter Time).
1668
+#
1669
+# News (in Russian):
1670
+# <a href="http://www.kyivpost.ua/russia/news/pridnestrove-otkazalos-ot-perehoda-na-zimnee-vremya-30954.html">
1671
+# http://www.kyivpost.ua/russia/news/pridnestrove-otkazalos-ot-perehoda-na-zimnee-vremya-30954.html
1672
+# </a>
1673
+#
1674
+# <a href="http://www.allmoldova.com/moldova-news/1249064116.html">
1675
+# http://www.allmoldova.com/moldova-news/1249064116.html
1676
+# </a>
1677
+#
1678
+# The substance of this change (reinstatement of the Tiraspol entry)
1679
+# is from a patch from Petr Machata (2011-10-17)
1680
+#
1681
+# From Tim Parenti (2011-10-19)
1682
+# In addition, being situated at +4651+2938 would give Tiraspol
1683
+# a pre-1880 LMT offset of 1:58:32.
1684
+#
1685
+# (which agrees with the earlier entry that had been removed)
1686
+#
1687
+# From Alexander Krivenyshev (2011-10-26)
1688
+# NO need to divide Moldova into two timezones at this point.
1689
+# As of today, Transnistria (Pridnestrovie)- Tiraspol reversed its own
1690
+# decision to abolish DST this winter.
1691
+# Following Moldova and neighboring Ukraine- Transnistria (Pridnestrovie)-
1692
+# Tiraspol will go back to winter time on October 30, 2011.
1693
+# News from Moldova (in russian):
1694
+# <a href="http://ru.publika.md/link_317061.html">
1695
+# http://ru.publika.md/link_317061.html
1696
+# </a>
1697
+
1698
+
1699
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1700
+Zone	Europe/Chisinau	1:55:20 -	LMT	1880
1701
+			1:55	-	CMT	1918 Feb 15 # Chisinau MT
1702
+			1:44:24	-	BMT	1931 Jul 24 # Bucharest MT
1703
+			2:00	Romania	EE%sT	1940 Aug 15
1704
+			2:00	1:00	EEST	1941 Jul 17
1705
+			1:00	C-Eur	CE%sT	1944 Aug 24
1706
+			3:00	Russia	MSK/MSD	1990
1707
+			3:00	-	MSK	1990 May 6
1708
+			2:00	-	EET	1991
1709
+			2:00	Russia	EE%sT	1992
1710
+			2:00	E-Eur	EE%sT	1997
1711
+# See Romania commentary for the guessed 1997 transition to EU rules.
1712
+			2:00	EU	EE%sT
1713
+
1714
+# Monaco
1715
+# Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
1716
+# more precise 0:09:21.
1717
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1718
+Zone	Europe/Monaco	0:29:32 -	LMT	1891 Mar 15
1719
+			0:09:21	-	PMT	1911 Mar 11    # Paris Mean Time
1720
+			0:00	France	WE%sT	1945 Sep 16 3:00
1721
+			1:00	France	CE%sT	1977
1722
+			1:00	EU	CE%sT
1723
+
1724
+# Montenegro
1725
+# see Serbia
1726
+
1727
+# Netherlands
1728
+
1729
+# Howse writes that the Netherlands' railways used GMT between 1892 and 1940,
1730
+# but for other purposes the Netherlands used Amsterdam mean time.
1731
+
1732
+# However, Robert H. van Gent writes (2001-04-01):
1733
+# Howse's statement is only correct up to 1909. From 1909-05-01 (00:00:00
1734
+# Amsterdam mean time) onwards, the whole of the Netherlands (including
1735
+# the Dutch railways) was required by law to observe Amsterdam mean time
1736
+# (19 minutes 32.13 seconds ahead of GMT). This had already been the
1737
+# common practice (except for the railways) for many decades but it was
1738
+# not until 1909 when the Dutch government finally defined this by law.
1739
+# On 1937-07-01 this was changed to 20 minutes (exactly) ahead of GMT and
1740
+# was generally known as Dutch Time ("Nederlandse Tijd").
1741
+#
1742
+# (2001-04-08):
1743
+# 1892-05-01 was the date when the Dutch railways were by law required to
1744
+# observe GMT while the remainder of the Netherlands adhered to the common
1745
+# practice of following Amsterdam mean time.
1746
+#
1747
+# (2001-04-09):
1748
+# In 1835 the authorities of the province of North Holland requested the
1749
+# municipal authorities of the towns and cities in the province to observe
1750
+# Amsterdam mean time but I do not know in how many cases this request was
1751
+# actually followed.
1752
+#
1753
+# From 1852 onwards the Dutch telegraph offices were by law required to
1754
+# observe Amsterdam mean time. As the time signals from the observatory of
1755
+# Leiden were also distributed by the telegraph system, I assume that most
1756
+# places linked up with the telegraph (and railway) system automatically
1757
+# adopted Amsterdam mean time.
1758
+#
1759
+# Although the early Dutch railway companies initially observed a variety
1760
+# of times, most of them had adopted Amsterdam mean time by 1858 but it
1761
+# was not until 1866 when they were all required by law to observe
1762
+# Amsterdam mean time.
1763
+
1764
+# The data before 1945 are taken from
1765
+# <http://www.phys.uu.nl/~vgent/wettijd/wettijd.htm>.
1766
+
1767
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1768
+Rule	Neth	1916	only	-	May	 1	0:00	1:00	NST	# Netherlands Summer Time
1769
+Rule	Neth	1916	only	-	Oct	 1	0:00	0	AMT	# Amsterdam Mean Time
1770
+Rule	Neth	1917	only	-	Apr	16	2:00s	1:00	NST
1771
+Rule	Neth	1917	only	-	Sep	17	2:00s	0	AMT
1772
+Rule	Neth	1918	1921	-	Apr	Mon>=1	2:00s	1:00	NST
1773
+Rule	Neth	1918	1921	-	Sep	lastMon	2:00s	0	AMT
1774
+Rule	Neth	1922	only	-	Mar	lastSun	2:00s	1:00	NST
1775
+Rule	Neth	1922	1936	-	Oct	Sun>=2	2:00s	0	AMT
1776
+Rule	Neth	1923	only	-	Jun	Fri>=1	2:00s	1:00	NST
1777
+Rule	Neth	1924	only	-	Mar	lastSun	2:00s	1:00	NST
1778
+Rule	Neth	1925	only	-	Jun	Fri>=1	2:00s	1:00	NST
1779
+# From 1926 through 1939 DST began 05-15, except that it was delayed by a week
1780
+# in years when 05-15 fell in the Pentecost weekend.
1781
+Rule	Neth	1926	1931	-	May	15	2:00s	1:00	NST
1782
+Rule	Neth	1932	only	-	May	22	2:00s	1:00	NST
1783
+Rule	Neth	1933	1936	-	May	15	2:00s	1:00	NST
1784
+Rule	Neth	1937	only	-	May	22	2:00s	1:00	NST
1785
+Rule	Neth	1937	only	-	Jul	 1	0:00	1:00	S
1786
+Rule	Neth	1937	1939	-	Oct	Sun>=2	2:00s	0	-
1787
+Rule	Neth	1938	1939	-	May	15	2:00s	1:00	S
1788
+Rule	Neth	1945	only	-	Apr	 2	2:00s	1:00	S
1789
+Rule	Neth	1945	only	-	Sep	16	2:00s	0	-
1790
+#
1791
+# Amsterdam Mean Time was +00:19:32.13 exactly, but the .13 is omitted
1792
+# below because the current format requires GMTOFF to be an integer.
1793
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1794
+Zone Europe/Amsterdam	0:19:32 -	LMT	1835
1795
+			0:19:32	Neth	%s	1937 Jul  1
1796
+			0:20	Neth	NE%sT	1940 May 16 0:00 # Dutch Time
1797
+			1:00	C-Eur	CE%sT	1945 Apr  2 2:00
1798
+			1:00	Neth	CE%sT	1977
1799
+			1:00	EU	CE%sT
1800
+
1801
+# Norway
1802
+# http://met.no/met/met_lex/q_u/sommertid.html (2004-01) agrees with Shanks &
1803
+# Pottenger.
1804
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1805
+Rule	Norway	1916	only	-	May	22	1:00	1:00	S
1806
+Rule	Norway	1916	only	-	Sep	30	0:00	0	-
1807
+Rule	Norway	1945	only	-	Apr	 2	2:00s	1:00	S
1808
+Rule	Norway	1945	only	-	Oct	 1	2:00s	0	-
1809
+Rule	Norway	1959	1964	-	Mar	Sun>=15	2:00s	1:00	S
1810
+Rule	Norway	1959	1965	-	Sep	Sun>=15	2:00s	0	-
1811
+Rule	Norway	1965	only	-	Apr	25	2:00s	1:00	S
1812
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1813
+Zone	Europe/Oslo	0:43:00 -	LMT	1895 Jan  1
1814
+			1:00	Norway	CE%sT	1940 Aug 10 23:00
1815
+			1:00	C-Eur	CE%sT	1945 Apr  2  2:00
1816
+			1:00	Norway	CE%sT	1980
1817
+			1:00	EU	CE%sT
1818
+
1819
+# Svalbard & Jan Mayen
1820
+
1821
+# From Steffen Thorsen (2001-05-01):
1822
+# Although I could not find it explicitly, it seems that Jan Mayen and
1823
+# Svalbard have been using the same time as Norway at least since the
1824
+# time they were declared as parts of Norway.  Svalbard was declared
1825
+# as a part of Norway by law of 1925-07-17 no 11, section 4 and Jan
1826
+# Mayen by law of 1930-02-27 no 2, section 2. (From
1827
+# http://www.lovdata.no/all/nl-19250717-011.html and
1828
+# http://www.lovdata.no/all/nl-19300227-002.html).  The law/regulation
1829
+# for normal/standard time in Norway is from 1894-06-29 no 1 (came
1830
+# into operation on 1895-01-01) and Svalbard/Jan Mayen seem to be a
1831
+# part of this law since 1925/1930. (From
1832
+# http://www.lovdata.no/all/nl-18940629-001.html ) I have not been
1833
+# able to find if Jan Mayen used a different time zone (e.g. -0100)
1834
+# before 1930. Jan Mayen has only been "inhabitated" since 1921 by
1835
+# Norwegian meteorologists and maybe used the same time as Norway ever
1836
+# since 1921.  Svalbard (Arctic/Longyearbyen) has been inhabited since
1837
+# before 1895, and therefore probably changed the local time somewhere
1838
+# between 1895 and 1925 (inclusive).
1839
+
1840
+# From Paul Eggert (2001-05-01):
1841
+#
1842
+# Actually, Jan Mayen was never occupied by Germany during World War II,
1843
+# so it must have diverged from Oslo time during the war, as Oslo was
1844
+# keeping Berlin time.
1845
+#
1846
+# <http://home.no.net/janmayen/history.htm> says that the meteorologists
1847
+# burned down their station in 1940 and left the island, but returned in
1848
+# 1941 with a small Norwegian garrison and continued operations despite
1849
+# frequent air ttacks from Germans.  In 1943 the Americans established a
1850
+# radiolocating station on the island, called "Atlantic City".  Possibly
1851
+# the UTC offset changed during the war, but I think it unlikely that
1852
+# Jan Mayen used German daylight-saving rules.
1853
+#
1854
+# Svalbard is more complicated, as it was raided in August 1941 by an
1855
+# Allied party that evacuated the civilian population to England (says
1856
+# <http://www.bartleby.com/65/sv/Svalbard.html>).  The Svalbard FAQ
1857
+# <http://www.svalbard.com/SvalbardFAQ.html> says that the Germans were
1858
+# expelled on 1942-05-14.  However, small parties of Germans did return,
1859
+# and according to Wilhelm Dege's book "War North of 80" (1954)
1860
+# <http://www.ucalgary.ca/UofC/departments/UP/1-55238/1-55238-110-2.html>
1861
+# the German armed forces at the Svalbard weather station code-named
1862
+# Haudegen did not surrender to the Allies until September 1945.
1863
+#
1864
+# All these events predate our cutoff date of 1970.  Unless we can
1865
+# come up with more definitive info about the timekeeping during the
1866
+# war years it's probably best just do...the following for now:
1867
+Link	Europe/Oslo	Arctic/Longyearbyen
1868
+
1869
+# Poland
1870
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1871
+Rule	Poland	1918	1919	-	Sep	16	2:00s	0	-
1872
+Rule	Poland	1919	only	-	Apr	15	2:00s	1:00	S
1873
+Rule	Poland	1944	only	-	Apr	 3	2:00s	1:00	S
1874
+# Whitman gives 1944 Nov 30; go with Shanks & Pottenger.
1875
+Rule	Poland	1944	only	-	Oct	 4	2:00	0	-
1876
+# For 1944-1948 Whitman gives the previous day; go with Shanks & Pottenger.
1877
+Rule	Poland	1945	only	-	Apr	29	0:00	1:00	S
1878
+Rule	Poland	1945	only	-	Nov	 1	0:00	0	-
1879
+# For 1946 on the source is Kazimierz Borkowski,
1880
+# Torun Center for Astronomy, Dept. of Radio Astronomy, Nicolaus Copernicus U.,
1881
+# <http://www.astro.uni.torun.pl/~kb/Artykuly/U-PA/Czas2.htm#tth_tAb1>
1882
+# Thanks to Przemyslaw Augustyniak (2005-05-28) for this reference.
1883
+# He also gives these further references:
1884
+# Mon Pol nr 13, poz 162 (1995) <http://www.abc.com.pl/serwis/mp/1995/0162.htm>
1885
+# Druk nr 2180 (2003) <http://www.senat.gov.pl/k5/dok/sejm/053/2180.pdf>
1886
+Rule	Poland	1946	only	-	Apr	14	0:00s	1:00	S
1887
+Rule	Poland	1946	only	-	Oct	 7	2:00s	0	-
1888
+Rule	Poland	1947	only	-	May	 4	2:00s	1:00	S
1889
+Rule	Poland	1947	1949	-	Oct	Sun>=1	2:00s	0	-
1890
+Rule	Poland	1948	only	-	Apr	18	2:00s	1:00	S
1891
+Rule	Poland	1949	only	-	Apr	10	2:00s	1:00	S
1892
+Rule	Poland	1957	only	-	Jun	 2	1:00s	1:00	S
1893
+Rule	Poland	1957	1958	-	Sep	lastSun	1:00s	0	-
1894
+Rule	Poland	1958	only	-	Mar	30	1:00s	1:00	S
1895
+Rule	Poland	1959	only	-	May	31	1:00s	1:00	S
1896
+Rule	Poland	1959	1961	-	Oct	Sun>=1	1:00s	0	-
1897
+Rule	Poland	1960	only	-	Apr	 3	1:00s	1:00	S
1898
+Rule	Poland	1961	1964	-	May	lastSun	1:00s	1:00	S
1899
+Rule	Poland	1962	1964	-	Sep	lastSun	1:00s	0	-
1900
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1901
+Zone	Europe/Warsaw	1:24:00 -	LMT	1880
1902
+			1:24:00	-	WMT	1915 Aug  5   # Warsaw Mean Time
1903
+			1:00	C-Eur	CE%sT	1918 Sep 16 3:00
1904
+			2:00	Poland	EE%sT	1922 Jun
1905
+			1:00	Poland	CE%sT	1940 Jun 23 2:00
1906
+			1:00	C-Eur	CE%sT	1944 Oct
1907
+			1:00	Poland	CE%sT	1977
1908
+			1:00	W-Eur	CE%sT	1988
1909
+			1:00	EU	CE%sT
1910
+
1911
+# Portugal
1912
+#
1913
+# From Rui Pedro Salgueiro (1992-11-12):
1914
+# Portugal has recently (September, 27) changed timezone
1915
+# (from WET to MET or CET) to harmonize with EEC.
1916
+#
1917
+# Martin Bruckmann (1996-02-29) reports via Peter Ilieve
1918
+# that Portugal is reverting to 0:00 by not moving its clocks this spring.
1919
+# The new Prime Minister was fed up with getting up in the dark in the winter.
1920
+#
1921
+# From Paul Eggert (1996-11-12):
1922
+# IATA SSIM (1991-09) reports several 1991-09 and 1992-09 transitions
1923
+# at 02:00u, not 01:00u.  Assume that these are typos.
1924
+# IATA SSIM (1991/1992) reports that the Azores were at -1:00.
1925
+# IATA SSIM (1993-02) says +0:00; later issues (through 1996-09) say -1:00.
1926
+# Guess that the Azores changed to EU rules in 1992 (since that's when Portugal
1927
+# harmonized with the EU), and that they stayed +0:00 that winter.
1928
+#
1929
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1930
+# DSH writes that despite Decree 1,469 (1915), the change to the clocks was not
1931
+# done every year, depending on what Spain did, because of railroad schedules.
1932
+# Go with Shanks & Pottenger.
1933
+Rule	Port	1916	only	-	Jun	17	23:00	1:00	S
1934
+# Whitman gives 1916 Oct 31; go with Shanks & Pottenger.
1935
+Rule	Port	1916	only	-	Nov	 1	 1:00	0	-
1936
+Rule	Port	1917	only	-	Feb	28	23:00s	1:00	S
1937
+Rule	Port	1917	1921	-	Oct	14	23:00s	0	-
1938
+Rule	Port	1918	only	-	Mar	 1	23:00s	1:00	S
1939
+Rule	Port	1919	only	-	Feb	28	23:00s	1:00	S
1940
+Rule	Port	1920	only	-	Feb	29	23:00s	1:00	S
1941
+Rule	Port	1921	only	-	Feb	28	23:00s	1:00	S
1942
+Rule	Port	1924	only	-	Apr	16	23:00s	1:00	S
1943
+Rule	Port	1924	only	-	Oct	14	23:00s	0	-
1944
+Rule	Port	1926	only	-	Apr	17	23:00s	1:00	S
1945
+Rule	Port	1926	1929	-	Oct	Sat>=1	23:00s	0	-
1946
+Rule	Port	1927	only	-	Apr	 9	23:00s	1:00	S
1947
+Rule	Port	1928	only	-	Apr	14	23:00s	1:00	S
1948
+Rule	Port	1929	only	-	Apr	20	23:00s	1:00	S
1949
+Rule	Port	1931	only	-	Apr	18	23:00s	1:00	S
1950
+# Whitman gives 1931 Oct 8; go with Shanks & Pottenger.
1951
+Rule	Port	1931	1932	-	Oct	Sat>=1	23:00s	0	-
1952
+Rule	Port	1932	only	-	Apr	 2	23:00s	1:00	S
1953
+Rule	Port	1934	only	-	Apr	 7	23:00s	1:00	S
1954
+# Whitman gives 1934 Oct 5; go with Shanks & Pottenger.
1955
+Rule	Port	1934	1938	-	Oct	Sat>=1	23:00s	0	-
1956
+# Shanks & Pottenger give 1935 Apr 30; go with Whitman.
1957
+Rule	Port	1935	only	-	Mar	30	23:00s	1:00	S
1958
+Rule	Port	1936	only	-	Apr	18	23:00s	1:00	S
1959
+# Whitman gives 1937 Apr 2; go with Shanks & Pottenger.
1960
+Rule	Port	1937	only	-	Apr	 3	23:00s	1:00	S
1961
+Rule	Port	1938	only	-	Mar	26	23:00s	1:00	S
1962
+Rule	Port	1939	only	-	Apr	15	23:00s	1:00	S
1963
+# Whitman gives 1939 Oct 7; go with Shanks & Pottenger.
1964
+Rule	Port	1939	only	-	Nov	18	23:00s	0	-
1965
+Rule	Port	1940	only	-	Feb	24	23:00s	1:00	S
1966
+# Shanks & Pottenger give 1940 Oct 7; go with Whitman.
1967
+Rule	Port	1940	1941	-	Oct	 5	23:00s	0	-
1968
+Rule	Port	1941	only	-	Apr	 5	23:00s	1:00	S
1969
+Rule	Port	1942	1945	-	Mar	Sat>=8	23:00s	1:00	S
1970
+Rule	Port	1942	only	-	Apr	25	22:00s	2:00	M # Midsummer
1971
+Rule	Port	1942	only	-	Aug	15	22:00s	1:00	S
1972
+Rule	Port	1942	1945	-	Oct	Sat>=24	23:00s	0	-
1973
+Rule	Port	1943	only	-	Apr	17	22:00s	2:00	M
1974
+Rule	Port	1943	1945	-	Aug	Sat>=25	22:00s	1:00	S
1975
+Rule	Port	1944	1945	-	Apr	Sat>=21	22:00s	2:00	M
1976
+Rule	Port	1946	only	-	Apr	Sat>=1	23:00s	1:00	S
1977
+Rule	Port	1946	only	-	Oct	Sat>=1	23:00s	0	-
1978
+Rule	Port	1947	1949	-	Apr	Sun>=1	 2:00s	1:00	S
1979
+Rule	Port	1947	1949	-	Oct	Sun>=1	 2:00s	0	-
1980
+# Shanks & Pottenger say DST was observed in 1950; go with Whitman.
1981
+# Whitman gives Oct lastSun for 1952 on; go with Shanks & Pottenger.
1982
+Rule	Port	1951	1965	-	Apr	Sun>=1	 2:00s	1:00	S
1983
+Rule	Port	1951	1965	-	Oct	Sun>=1	 2:00s	0	-
1984
+Rule	Port	1977	only	-	Mar	27	 0:00s	1:00	S
1985
+Rule	Port	1977	only	-	Sep	25	 0:00s	0	-
1986
+Rule	Port	1978	1979	-	Apr	Sun>=1	 0:00s	1:00	S
1987
+Rule	Port	1978	only	-	Oct	 1	 0:00s	0	-
1988
+Rule	Port	1979	1982	-	Sep	lastSun	 1:00s	0	-
1989
+Rule	Port	1980	only	-	Mar	lastSun	 0:00s	1:00	S
1990
+Rule	Port	1981	1982	-	Mar	lastSun	 1:00s	1:00	S
1991
+Rule	Port	1983	only	-	Mar	lastSun	 2:00s	1:00	S
1992
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1993
+# Shanks & Pottenger say the transition from LMT to WET occurred 1911-05-24;
1994
+# Willett says 1912-01-01.  Go with Willett.
1995
+Zone	Europe/Lisbon	-0:36:32 -	LMT	1884
1996
+			-0:36:32 -	LMT	1912 Jan  1  # Lisbon Mean Time
1997
+			 0:00	Port	WE%sT	1966 Apr  3 2:00
1998
+			 1:00	-	CET	1976 Sep 26 1:00
1999
+			 0:00	Port	WE%sT	1983 Sep 25 1:00s
2000
+			 0:00	W-Eur	WE%sT	1992 Sep 27 1:00s
2001
+			 1:00	EU	CE%sT	1996 Mar 31 1:00u
2002
+			 0:00	EU	WE%sT
2003
+Zone Atlantic/Azores	-1:42:40 -	LMT	1884		# Ponta Delgada
2004
+			-1:54:32 -	HMT	1911 May 24  # Horta Mean Time
2005
+			-2:00	Port	AZO%sT	1966 Apr  3 2:00 # Azores Time
2006
+			-1:00	Port	AZO%sT	1983 Sep 25 1:00s
2007
+			-1:00	W-Eur	AZO%sT	1992 Sep 27 1:00s
2008
+			 0:00	EU	WE%sT	1993 Mar 28 1:00u
2009
+			-1:00	EU	AZO%sT
2010
+Zone Atlantic/Madeira	-1:07:36 -	LMT	1884		# Funchal
2011
+			-1:07:36 -	FMT	1911 May 24  # Funchal Mean Time
2012
+			-1:00	Port	MAD%sT	1966 Apr  3 2:00 # Madeira Time
2013
+			 0:00	Port	WE%sT	1983 Sep 25 1:00s
2014
+			 0:00	EU	WE%sT
2015
+
2016
+# Romania
2017
+#
2018
+# From Paul Eggert (1999-10-07):
2019
+# <a href="http://www.nineoclock.ro/POL/1778pol.html">
2020
+# Nine O'clock</a> (1998-10-23) reports that the switch occurred at
2021
+# 04:00 local time in fall 1998.  For lack of better info,
2022
+# assume that Romania and Moldova switched to EU rules in 1997,
2023
+# the same year as Bulgaria.
2024
+#
2025
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
2026
+Rule	Romania	1932	only	-	May	21	 0:00s	1:00	S
2027
+Rule	Romania	1932	1939	-	Oct	Sun>=1	 0:00s	0	-
2028
+Rule	Romania	1933	1939	-	Apr	Sun>=2	 0:00s	1:00	S
2029
+Rule	Romania	1979	only	-	May	27	 0:00	1:00	S
2030
+Rule	Romania	1979	only	-	Sep	lastSun	 0:00	0	-
2031
+Rule	Romania	1980	only	-	Apr	 5	23:00	1:00	S
2032
+Rule	Romania	1980	only	-	Sep	lastSun	 1:00	0	-
2033
+Rule	Romania	1991	1993	-	Mar	lastSun	 0:00s	1:00	S
2034
+Rule	Romania	1991	1993	-	Sep	lastSun	 0:00s	0	-
2035
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2036
+Zone Europe/Bucharest	1:44:24 -	LMT	1891 Oct
2037
+			1:44:24	-	BMT	1931 Jul 24	# Bucharest MT
2038
+			2:00	Romania	EE%sT	1981 Mar 29 2:00s
2039
+			2:00	C-Eur	EE%sT	1991
2040
+			2:00	Romania	EE%sT	1994
2041
+			2:00	E-Eur	EE%sT	1997
2042
+			2:00	EU	EE%sT
2043
+
2044
+# Russia
2045
+
2046
+# From Paul Eggert (2006-03-22):
2047
+# Except for Moscow after 1919-07-01, I invented the time zone abbreviations.
2048
+# Moscow time zone abbreviations after 1919-07-01, and Moscow rules after 1991,
2049
+# are from Andrey A. Chernov.  The rest is from Shanks & Pottenger,
2050
+# except we follow Chernov's report that 1992 DST transitions were Sat
2051
+# 23:00, not Sun 02:00s.
2052
+#
2053
+# From Stanislaw A. Kuzikowski (1994-06-29):
2054
+# But now it is some months since Novosibirsk is 3 hours ahead of Moscow!
2055
+# I do not know why they have decided to make this change;
2056
+# as far as I remember it was done exactly during winter->summer switching
2057
+# so we (Novosibirsk) simply did not switch.
2058
+#
2059
+# From Andrey A. Chernov (1996-10-04):
2060
+# `MSK' and `MSD' were born and used initially on Moscow computers with
2061
+# UNIX-like OSes by several developer groups (e.g. Demos group, Kiae group)....
2062
+# The next step was the UUCP network, the Relcom predecessor
2063
+# (used mainly for mail), and MSK/MSD was actively used there.
2064
+#
2065
+# From Chris Carrier (1996-10-30):
2066
+# According to a friend of mine who rode the Trans-Siberian Railroad from
2067
+# Moscow to Irkutsk in 1995, public air and rail transport in Russia ...
2068
+# still follows Moscow time, no matter where in Russia it is located.
2069
+#
2070
+# For Grozny, Chechnya, we have the following story from
2071
+# John Daniszewski, "Scavengers in the Rubble", Los Angeles Times (2001-02-07):
2072
+# News--often false--is spread by word of mouth.  A rumor that it was
2073
+# time to move the clocks back put this whole city out of sync with
2074
+# the rest of Russia for two weeks--even soldiers stationed here began
2075
+# enforcing curfew at the wrong time.
2076
+#
2077
+# From Gwillim Law (2001-06-05):
2078
+# There's considerable evidence that Sakhalin Island used to be in
2079
+# UTC+11, and has changed to UTC+10, in this decade.  I start with the
2080
+# SSIM, which listed Yuzhno-Sakhalinsk in zone RU10 along with Magadan
2081
+# until February 1997, and then in RU9 with Khabarovsk and Vladivostok
2082
+# since September 1997....  Although the Kuril Islands are
2083
+# administratively part of Sakhalin oblast', they appear to have
2084
+# remained on UTC+11 along with Magadan.
2085
+#
2086
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2087
+#
2088
+# Kaliningradskaya oblast'.
2089
+Zone Europe/Kaliningrad	 1:22:00 -	LMT	1893 Apr
2090
+			 1:00	C-Eur	CE%sT	1945
2091
+			 2:00	Poland	CE%sT	1946
2092
+			 3:00	Russia	MSK/MSD	1991 Mar 31 2:00s
2093
+			 2:00	Russia	EE%sT	2011 Mar 27 2:00s
2094
+			 3:00	-	FET # Further-eastern European Time
2095
+#
2096
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
2097
+# Respublika Adygeya, Arkhangel'skaya oblast',
2098
+# Belgorodskaya oblast', Bryanskaya oblast', Vladimirskaya oblast',
2099
+# Vologodskaya oblast', Voronezhskaya oblast',
2100
+# Respublika Dagestan, Ivanovskaya oblast', Respublika Ingushetiya,
2101
+# Kabarbino-Balkarskaya Respublika, Respublika Kalmykiya,
2102
+# Kalyzhskaya oblast', Respublika Karachaevo-Cherkessiya,
2103
+# Respublika Kareliya, Respublika Komi,
2104
+# Kostromskaya oblast', Krasnodarskij kraj, Kurskaya oblast',
2105
+# Leningradskaya oblast', Lipetskaya oblast', Respublika Marij El,
2106
+# Respublika Mordoviya, Moskva, Moskovskaya oblast',
2107
+# Murmanskaya oblast', Nenetskij avtonomnyj okrug,
2108
+# Nizhegorodskaya oblast', Novgorodskaya oblast', Orlovskaya oblast',
2109
+# Penzenskaya oblast', Pskovskaya oblast', Rostovskaya oblast',
2110
+# Ryazanskaya oblast', Sankt-Peterburg,
2111
+# Respublika Severnaya Osetiya, Smolenskaya oblast',
2112
+# Stavropol'skij kraj, Tambovskaya oblast', Respublika Tatarstan,
2113
+# Tverskaya oblast', Tyl'skaya oblast', Ul'yanovskaya oblast',
2114
+# Chechenskaya Respublika, Chuvashskaya oblast',
2115
+# Yaroslavskaya oblast'
2116
+Zone Europe/Moscow	 2:30:20 -	LMT	1880
2117
+			 2:30	-	MMT	1916 Jul  3 # Moscow Mean Time
2118
+			 2:30:48 Russia	%s	1919 Jul  1 2:00
2119
+			 3:00	Russia	MSK/MSD	1922 Oct
2120
+			 2:00	-	EET	1930 Jun 21
2121
+			 3:00	Russia	MSK/MSD	1991 Mar 31 2:00s
2122
+			 2:00	Russia	EE%sT	1992 Jan 19 2:00s
2123
+			 3:00	Russia	MSK/MSD	2011 Mar 27 2:00s
2124
+			 4:00	-	MSK
2125
+#
2126
+# Astrakhanskaya oblast', Kirovskaya oblast', Saratovskaya oblast',
2127
+# Volgogradskaya oblast'.  Shanks & Pottenger say Kirov is still at +0400
2128
+# but Wikipedia (2006-05-09) says +0300.  Perhaps it switched after the
2129
+# others?  But we have no data.
2130
+Zone Europe/Volgograd	 2:57:40 -	LMT	1920 Jan  3
2131
+			 3:00	-	TSAT	1925 Apr  6 # Tsaritsyn Time
2132
+			 3:00	-	STAT	1930 Jun 21 # Stalingrad Time
2133
+			 4:00	-	STAT	1961 Nov 11
2134
+			 4:00	Russia	VOL%sT	1989 Mar 26 2:00s # Volgograd T
2135
+			 3:00	Russia	VOL%sT	1991 Mar 31 2:00s
2136
+			 4:00	-	VOLT	1992 Mar 29 2:00s
2137
+			 3:00	Russia	VOL%sT	2011 Mar 27 2:00s
2138
+			 4:00	-	VOLT
2139
+#
2140
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
2141
+# Samarskaya oblast', Udmyrtskaya respublika
2142
+Zone Europe/Samara	 3:20:36 -	LMT	1919 Jul  1 2:00
2143
+			 3:00	-	SAMT	1930 Jun 21
2144
+			 4:00	-	SAMT	1935 Jan 27
2145
+			 4:00	Russia	KUY%sT	1989 Mar 26 2:00s # Kuybyshev
2146
+			 3:00	Russia	KUY%sT	1991 Mar 31 2:00s
2147
+			 2:00	Russia	KUY%sT	1991 Sep 29 2:00s
2148
+			 3:00	-	KUYT	1991 Oct 20 3:00
2149
+			 4:00	Russia	SAM%sT	2010 Mar 28 2:00s # Samara Time
2150
+			 3:00	Russia	SAM%sT	2011 Mar 27 2:00s
2151
+			 4:00	-	SAMT
2152
+
2153
+#
2154
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
2155
+# Respublika Bashkortostan, Komi-Permyatskij avtonomnyj okrug,
2156
+# Kurganskaya oblast', Orenburgskaya oblast', Permskaya oblast',
2157
+# Sverdlovskaya oblast', Tyumenskaya oblast',
2158
+# Khanty-Manskijskij avtonomnyj okrug, Chelyabinskaya oblast',
2159
+# Yamalo-Nenetskij avtonomnyj okrug.
2160
+Zone Asia/Yekaterinburg	 4:02:24 -	LMT	1919 Jul 15 4:00
2161
+			 4:00	-	SVET	1930 Jun 21 # Sverdlovsk Time
2162
+			 5:00	Russia	SVE%sT	1991 Mar 31 2:00s
2163
+			 4:00	Russia	SVE%sT	1992 Jan 19 2:00s
2164
+			 5:00	Russia	YEK%sT	2011 Mar 27 2:00s
2165
+			 6:00	-	YEKT	# Yekaterinburg Time
2166
+#
2167
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
2168
+# Respublika Altaj, Altajskij kraj, Omskaya oblast'.
2169
+Zone Asia/Omsk		 4:53:36 -	LMT	1919 Nov 14
2170
+			 5:00	-	OMST	1930 Jun 21 # Omsk TIme
2171
+			 6:00	Russia	OMS%sT	1991 Mar 31 2:00s
2172
+			 5:00	Russia	OMS%sT	1992 Jan 19 2:00s
2173
+			 6:00	Russia	OMS%sT	2011 Mar 27 2:00s
2174
+			 7:00	-	OMST
2175
+#
2176
+# From Paul Eggert (2006-08-19): I'm guessing about Tomsk here; it's
2177
+# not clear when it switched from +7 to +6.
2178
+# Novosibirskaya oblast', Tomskaya oblast'.
2179
+Zone Asia/Novosibirsk	 5:31:40 -	LMT	1919 Dec 14 6:00
2180
+			 6:00	-	NOVT	1930 Jun 21 # Novosibirsk Time
2181
+			 7:00	Russia	NOV%sT	1991 Mar 31 2:00s
2182
+			 6:00	Russia	NOV%sT	1992 Jan 19 2:00s
2183
+			 7:00	Russia	NOV%sT	1993 May 23 # say Shanks & P.
2184
+			 6:00	Russia	NOV%sT	2011 Mar 27 2:00s
2185
+			 7:00	-	NOVT
2186
+
2187
+# From Alexander Krivenyshev (2009-10-13):
2188
+# Kemerovo oblast' (Kemerovo region) in Russia will change current time zone on
2189
+# March 28, 2010:
2190
+# from current Russia Zone 6 - Krasnoyarsk Time Zone (KRA) UTC +0700
2191
+# to Russia Zone 5 - Novosibirsk Time Zone (NOV) UTC +0600
2192
+#
2193
+# This is according to Government of Russia decree # 740, on September
2194
+# 14, 2009 "Application in the territory of the Kemerovo region the Fifth
2195
+# time zone." ("Russia Zone 5" or old "USSR Zone 5" is GMT +0600)
2196
+#
2197
+# Russian Government web site (Russian language)
2198
+# <a href="http://www.government.ru/content/governmentactivity/rfgovernmentdecisions/archiv">
2199
+# http://www.government.ru/content/governmentactivity/rfgovernmentdecisions/archive/2009/09/14/991633.htm
2200
+# </a>
2201
+# or Russian-English translation by WorldTimeZone.com with reference
2202
+# map to local region and new Russia Time Zone map after March 28, 2010
2203
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_russia03.html">
2204
+# http://www.worldtimezone.com/dst_news/dst_news_russia03.html
2205
+# </a>
2206
+#
2207
+# Thus, when Russia will switch to DST on the night of March 28, 2010
2208
+# Kemerovo region (Kemerovo oblast') will not change the clock.
2209
+#
2210
+# As a result, Kemerovo oblast' will be in the same time zone as
2211
+# Novosibirsk, Omsk, Tomsk, Barnaul and Altai Republic.
2212
+
2213
+Zone Asia/Novokuznetsk	 5:48:48 -	NMT	1920 Jan  6
2214
+			 6:00	-	KRAT	1930 Jun 21 # Krasnoyarsk Time
2215
+			 7:00	Russia	KRA%sT	1991 Mar 31 2:00s
2216
+			 6:00	Russia	KRA%sT	1992 Jan 19 2:00s
2217
+			 7:00	Russia	KRA%sT	2010 Mar 28 2:00s
2218
+			 6:00	Russia	NOV%sT	2011 Mar 27 2:00s
2219
+			 7:00	-	NOVT # Novosibirsk/Novokuznetsk Time
2220
+
2221
+#
2222
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
2223
+# Krasnoyarskij kraj,
2224
+# Tajmyrskij (Dolgano-Nenetskij) avtonomnyj okrug,
2225
+# Respublika Tuva, Respublika Khakasiya, Evenkijskij avtonomnyj okrug.
2226
+Zone Asia/Krasnoyarsk	 6:11:20 -	LMT	1920 Jan  6
2227
+			 6:00	-	KRAT	1930 Jun 21 # Krasnoyarsk Time
2228
+			 7:00	Russia	KRA%sT	1991 Mar 31 2:00s
2229
+			 6:00	Russia	KRA%sT	1992 Jan 19 2:00s
2230
+			 7:00	Russia	KRA%sT	2011 Mar 27 2:00s
2231
+			 8:00	-	KRAT
2232
+#
2233
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
2234
+# Respublika Buryatiya, Irkutskaya oblast',
2235
+# Ust'-Ordynskij Buryatskij avtonomnyj okrug.
2236
+Zone Asia/Irkutsk	 6:57:20 -	LMT	1880
2237
+			 6:57:20 -	IMT	1920 Jan 25 # Irkutsk Mean Time
2238
+			 7:00	-	IRKT	1930 Jun 21 # Irkutsk Time
2239
+			 8:00	Russia	IRK%sT	1991 Mar 31 2:00s
2240
+			 7:00	Russia	IRK%sT	1992 Jan 19 2:00s
2241
+			 8:00	Russia	IRK%sT	2011 Mar 27 2:00s
2242
+			 9:00	-	IRKT
2243
+#
2244
+# From Oscar van Vlijmen (2003-10-18): [This region consists of]
2245
+# Aginskij Buryatskij avtonomnyj okrug, Amurskaya oblast',
2246
+# [parts of] Respublika Sakha (Yakutiya), Chitinskaya oblast'.
2247
+
2248
+# From Oscar van Vlijmen (2009-11-29):
2249
+# ...some regions of [Russia] were merged with others since 2005...
2250
+# Some names were changed, no big deal, except for one instance: a new name.
2251
+# YAK/YAKST: UTC+9 Zabajkal'skij kraj.
2252
+
2253
+# From Oscar van Vlijmen (2009-11-29):
2254
+# The Sakha districts are: Aldanskij, Amginskij, Anabarskij,
2255
+# Verkhnevilyujskij, Vilyujskij, Gornyj,
2256
+# Zhiganskij, Kobyajskij, Lenskij, Megino-Kangalasskij, Mirninskij,
2257
+# Namskij, Nyurbinskij, Olenyokskij, Olyokminskij,
2258
+# Suntarskij, Tattinskij, Ust'-Aldanskij, Khangalasskij,
2259
+# Churapchinskij, Eveno-Bytantajskij Natsional'nij.
2260
+
2261
+Zone Asia/Yakutsk	 8:38:40 -	LMT	1919 Dec 15
2262
+			 8:00	-	YAKT	1930 Jun 21 # Yakutsk Time
2263
+			 9:00	Russia	YAK%sT	1991 Mar 31 2:00s
2264
+			 8:00	Russia	YAK%sT	1992 Jan 19 2:00s
2265
+			 9:00	Russia	YAK%sT	2011 Mar 27 2:00s
2266
+			 10:00	-	YAKT
2267
+#
2268
+# From Oscar van Vlijmen (2003-10-18): [This region consists of]
2269
+# Evrejskaya avtonomnaya oblast', Khabarovskij kraj, Primorskij kraj,
2270
+# [parts of] Respublika Sakha (Yakutiya).
2271
+
2272
+# From Oscar van Vlijmen (2009-11-29):
2273
+# The Sakha districts are: Bulunskij, Verkhoyanskij, Tomponskij, Ust'-Majskij,
2274
+# Ust'-Yanskij.
2275
+Zone Asia/Vladivostok	 8:47:44 -	LMT	1922 Nov 15
2276
+			 9:00	-	VLAT	1930 Jun 21 # Vladivostok Time
2277
+			10:00	Russia	VLA%sT	1991 Mar 31 2:00s
2278
+			 9:00	Russia	VLA%sST	1992 Jan 19 2:00s
2279
+			10:00	Russia	VLA%sT	2011 Mar 27 2:00s
2280
+			11:00	-	VLAT
2281
+#
2282
+# Sakhalinskaya oblast'.
2283
+# The Zone name should be Yuzhno-Sakhalinsk, but that's too long.
2284
+Zone Asia/Sakhalin	 9:30:48 -	LMT	1905 Aug 23
2285
+			 9:00	-	CJT	1938
2286
+			 9:00	-	JST	1945 Aug 25
2287
+			11:00	Russia	SAK%sT	1991 Mar 31 2:00s # Sakhalin T.
2288
+			10:00	Russia	SAK%sT	1992 Jan 19 2:00s
2289
+			11:00	Russia	SAK%sT	1997 Mar lastSun 2:00s
2290
+			10:00	Russia	SAK%sT	2011 Mar 27 2:00s
2291
+			11:00	-	SAKT
2292
+#
2293
+# From Oscar van Vlijmen (2003-10-18): [This region consists of]
2294
+# Magadanskaya oblast', Respublika Sakha (Yakutiya).
2295
+# Probably also: Kuril Islands.
2296
+
2297
+# From Oscar van Vlijmen (2009-11-29):
2298
+# The Sakha districts are: Abyjskij, Allaikhovskij, Verkhhhnekolymskij, Momskij,
2299
+# Nizhnekolymskij, Ojmyakonskij, Srednekolymskij.
2300
+Zone Asia/Magadan	10:03:12 -	LMT	1924 May  2
2301
+			10:00	-	MAGT	1930 Jun 21 # Magadan Time
2302
+			11:00	Russia	MAG%sT	1991 Mar 31 2:00s
2303
+			10:00	Russia	MAG%sT	1992 Jan 19 2:00s
2304
+			11:00	Russia	MAG%sT	2011 Mar 27 2:00s
2305
+			12:00	-	MAGT
2306
+#
2307
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
2308
+# Kamchatskaya oblast', Koryakskij avtonomnyj okrug.
2309
+#
2310
+# The Zone name should be Asia/Petropavlovsk-Kamchatski, but that's too long.
2311
+Zone Asia/Kamchatka	10:34:36 -	LMT	1922 Nov 10
2312
+			11:00	-	PETT	1930 Jun 21 # P-K Time
2313
+			12:00	Russia	PET%sT	1991 Mar 31 2:00s
2314
+			11:00	Russia	PET%sT	1992 Jan 19 2:00s
2315
+			12:00	Russia	PET%sT	2010 Mar 28 2:00s
2316
+			11:00	Russia	PET%sT	2011 Mar 27 2:00s
2317
+			12:00	-	PETT
2318
+#
2319
+# Chukotskij avtonomnyj okrug
2320
+Zone Asia/Anadyr	11:49:56 -	LMT	1924 May  2
2321
+			12:00	-	ANAT	1930 Jun 21 # Anadyr Time
2322
+			13:00	Russia	ANA%sT	1982 Apr  1 0:00s
2323
+			12:00	Russia	ANA%sT	1991 Mar 31 2:00s
2324
+			11:00	Russia	ANA%sT	1992 Jan 19 2:00s
2325
+			12:00	Russia	ANA%sT	2010 Mar 28 2:00s
2326
+			11:00	Russia	ANA%sT	2011 Mar 27 2:00s
2327
+			12:00	-	ANAT
2328
+
2329
+# Serbia
2330
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2331
+Zone	Europe/Belgrade	1:22:00	-	LMT	1884
2332
+			1:00	-	CET	1941 Apr 18 23:00
2333
+			1:00	C-Eur	CE%sT	1945
2334
+			1:00	-	CET	1945 May 8 2:00s
2335
+			1:00	1:00	CEST	1945 Sep 16  2:00s
2336
+# Metod Kozelj reports that the legal date of
2337
+# transition to EU rules was 1982-11-27, for all of Yugoslavia at the time.
2338
+# Shanks & Pottenger don't give as much detail, so go with Kozelj.
2339
+			1:00	-	CET	1982 Nov 27
2340
+			1:00	EU	CE%sT
2341
+Link Europe/Belgrade Europe/Ljubljana	# Slovenia
2342
+Link Europe/Belgrade Europe/Podgorica	# Montenegro
2343
+Link Europe/Belgrade Europe/Sarajevo	# Bosnia and Herzegovina
2344
+Link Europe/Belgrade Europe/Skopje	# Macedonia
2345
+Link Europe/Belgrade Europe/Zagreb	# Croatia
2346
+
2347
+# Slovakia
2348
+Link Europe/Prague Europe/Bratislava
2349
+
2350
+# Slovenia
2351
+# see Serbia
2352
+
2353
+# Spain
2354
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
2355
+# For 1917-1919 Whitman gives Apr Sat>=1 - Oct Sat>=1;
2356
+# go with Shanks & Pottenger.
2357
+Rule	Spain	1917	only	-	May	 5	23:00s	1:00	S
2358
+Rule	Spain	1917	1919	-	Oct	 6	23:00s	0	-
2359
+Rule	Spain	1918	only	-	Apr	15	23:00s	1:00	S
2360
+Rule	Spain	1919	only	-	Apr	 5	23:00s	1:00	S
2361
+# Whitman gives 1921 Feb 28 - Oct 14; go with Shanks & Pottenger.
2362
+Rule	Spain	1924	only	-	Apr	16	23:00s	1:00	S
2363
+# Whitman gives 1924 Oct 14; go with Shanks & Pottenger.
2364
+Rule	Spain	1924	only	-	Oct	 4	23:00s	0	-
2365
+Rule	Spain	1926	only	-	Apr	17	23:00s	1:00	S
2366
+# Whitman says no DST in 1929; go with Shanks & Pottenger.
2367
+Rule	Spain	1926	1929	-	Oct	Sat>=1	23:00s	0	-
2368
+Rule	Spain	1927	only	-	Apr	 9	23:00s	1:00	S
2369
+Rule	Spain	1928	only	-	Apr	14	23:00s	1:00	S
2370
+Rule	Spain	1929	only	-	Apr	20	23:00s	1:00	S
2371
+# Whitman gives 1937 Jun 16, 1938 Apr 16, 1940 Apr 13;
2372
+# go with Shanks & Pottenger.
2373
+Rule	Spain	1937	only	-	May	22	23:00s	1:00	S
2374
+Rule	Spain	1937	1939	-	Oct	Sat>=1	23:00s	0	-
2375
+Rule	Spain	1938	only	-	Mar	22	23:00s	1:00	S
2376
+Rule	Spain	1939	only	-	Apr	15	23:00s	1:00	S
2377
+Rule	Spain	1940	only	-	Mar	16	23:00s	1:00	S
2378
+# Whitman says no DST 1942-1945; go with Shanks & Pottenger.
2379
+Rule	Spain	1942	only	-	May	 2	22:00s	2:00	M # Midsummer
2380
+Rule	Spain	1942	only	-	Sep	 1	22:00s	1:00	S
2381
+Rule	Spain	1943	1946	-	Apr	Sat>=13	22:00s	2:00	M
2382
+Rule	Spain	1943	only	-	Oct	 3	22:00s	1:00	S
2383
+Rule	Spain	1944	only	-	Oct	10	22:00s	1:00	S
2384
+Rule	Spain	1945	only	-	Sep	30	 1:00	1:00	S
2385
+Rule	Spain	1946	only	-	Sep	30	 0:00	0	-
2386
+Rule	Spain	1949	only	-	Apr	30	23:00	1:00	S
2387
+Rule	Spain	1949	only	-	Sep	30	 1:00	0	-
2388
+Rule	Spain	1974	1975	-	Apr	Sat>=13	23:00	1:00	S
2389
+Rule	Spain	1974	1975	-	Oct	Sun>=1	 1:00	0	-
2390
+Rule	Spain	1976	only	-	Mar	27	23:00	1:00	S
2391
+Rule	Spain	1976	1977	-	Sep	lastSun	 1:00	0	-
2392
+Rule	Spain	1977	1978	-	Apr	 2	23:00	1:00	S
2393
+Rule	Spain	1978	only	-	Oct	 1	 1:00	0	-
2394
+# The following rules are copied from Morocco from 1967 through 1978.
2395
+Rule SpainAfrica 1967	only	-	Jun	 3	12:00	1:00	S
2396
+Rule SpainAfrica 1967	only	-	Oct	 1	 0:00	0	-
2397
+Rule SpainAfrica 1974	only	-	Jun	24	 0:00	1:00	S
2398
+Rule SpainAfrica 1974	only	-	Sep	 1	 0:00	0	-
2399
+Rule SpainAfrica 1976	1977	-	May	 1	 0:00	1:00	S
2400
+Rule SpainAfrica 1976	only	-	Aug	 1	 0:00	0	-
2401
+Rule SpainAfrica 1977	only	-	Sep	28	 0:00	0	-
2402
+Rule SpainAfrica 1978	only	-	Jun	 1	 0:00	1:00	S
2403
+Rule SpainAfrica 1978	only	-	Aug	 4	 0:00	0	-
2404
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2405
+Zone	Europe/Madrid	-0:14:44 -	LMT	1901 Jan  1  0:00s
2406
+			 0:00	Spain	WE%sT	1946 Sep 30
2407
+			 1:00	Spain	CE%sT	1979
2408
+			 1:00	EU	CE%sT
2409
+Zone	Africa/Ceuta	-0:21:16 -	LMT	1901
2410
+			 0:00	-	WET	1918 May  6 23:00
2411
+			 0:00	1:00	WEST	1918 Oct  7 23:00
2412
+			 0:00	-	WET	1924
2413
+			 0:00	Spain	WE%sT	1929
2414
+			 0:00 SpainAfrica WE%sT 1984 Mar 16
2415
+			 1:00	-	CET	1986
2416
+			 1:00	EU	CE%sT
2417
+Zone	Atlantic/Canary	-1:01:36 -	LMT	1922 Mar # Las Palmas de Gran C.
2418
+			-1:00	-	CANT	1946 Sep 30 1:00 # Canaries Time
2419
+			 0:00	-	WET	1980 Apr  6 0:00s
2420
+			 0:00	1:00	WEST	1980 Sep 28 0:00s
2421
+			 0:00	EU	WE%sT
2422
+# IATA SSIM (1996-09) says the Canaries switch at 2:00u, not 1:00u.
2423
+# Ignore this for now, as the Canaries are part of the EU.
2424
+
2425
+# Sweden
2426
+
2427
+# From Ivan Nilsson (2001-04-13), superseding Shanks & Pottenger:
2428
+#
2429
+# The law "Svensk forfattningssamling 1878, no 14" about standard time in 1879:
2430
+# From the beginning of 1879 (that is 01-01 00:00) the time for all
2431
+# places in the country is "the mean solar time for the meridian at
2432
+# three degrees, or twelve minutes of time, to the west of the
2433
+# meridian of the Observatory of Stockholm".  The law is dated 1878-05-31.
2434
+#
2435
+# The observatory at that time had the meridian 18 degrees 03' 30"
2436
+# eastern longitude = 01:12:14 in time.  Less 12 minutes gives the
2437
+# national standard time as 01:00:14 ahead of GMT....
2438
+#
2439
+# About the beginning of CET in Sweden. The lawtext ("Svensk
2440
+# forfattningssamling 1899, no 44") states, that "from the beginning
2441
+# of 1900... ... the same as the mean solar time for the meridian at
2442
+# the distance of one hour of time from the meridian of the English
2443
+# observatory at Greenwich, or at 12 minutes 14 seconds to the west
2444
+# from the meridian of the Observatory of Stockholm". The law is dated
2445
+# 1899-06-16.  In short: At 1900-01-01 00:00:00 the new standard time
2446
+# in Sweden is 01:00:00 ahead of GMT.
2447
+#
2448
+# 1916: The lawtext ("Svensk forfattningssamling 1916, no 124") states
2449
+# that "1916-05-15 is considered to begin one hour earlier". It is
2450
+# pretty obvious that at 05-14 23:00 the clocks are set to 05-15 00:00....
2451
+# Further the law says, that "1916-09-30 is considered to end one hour later".
2452
+#
2453
+# The laws regulating [DST] are available on the site of the Swedish
2454
+# Parliament beginning with 1985 - the laws regulating 1980/1984 are
2455
+# not available on the site (to my knowledge they are only available
2456
+# in Swedish): <http://www.riksdagen.se/english/work/sfst.asp> (type
2457
+# "sommartid" without the quotes in the field "Fritext" and then click
2458
+# the Sok-button).
2459
+#
2460
+# (2001-05-13):
2461
+#
2462
+# I have now found a newspaper stating that at 1916-10-01 01:00
2463
+# summertime the church-clocks etc were set back one hour to show
2464
+# 1916-10-01 00:00 standard time.  The article also reports that some
2465
+# people thought the switch to standard time would take place already
2466
+# at 1916-10-01 00:00 summer time, but they had to wait for another
2467
+# hour before the event took place.
2468
+#
2469
+# Source: The newspaper "Dagens Nyheter", 1916-10-01, page 7 upper left.
2470
+
2471
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2472
+Zone Europe/Stockholm	1:12:12 -	LMT	1879 Jan  1
2473
+			1:00:14	-	SET	1900 Jan  1	# Swedish Time
2474
+			1:00	-	CET	1916 May 14 23:00
2475
+			1:00	1:00	CEST	1916 Oct  1 01:00
2476
+			1:00	-	CET	1980
2477
+			1:00	EU	CE%sT
2478
+
2479
+# Switzerland
2480
+# From Howse:
2481
+# By the end of the 18th century clocks and watches became commonplace
2482
+# and their performance improved enormously.  Communities began to keep
2483
+# mean time in preference to apparent time -- Geneva from 1780 ....
2484
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
2485
+# From Whitman (who writes ``Midnight?''):
2486
+# Rule	Swiss	1940	only	-	Nov	 2	0:00	1:00	S
2487
+# Rule	Swiss	1940	only	-	Dec	31	0:00	0	-
2488
+# From Shanks & Pottenger:
2489
+# Rule	Swiss	1941	1942	-	May	Sun>=1	2:00	1:00	S
2490
+# Rule	Swiss	1941	1942	-	Oct	Sun>=1	0:00	0	-
2491
+
2492
+# From Alois Treindl (2008-12-17):
2493
+# I have researched the DST usage in Switzerland during the 1940ies.
2494
+#
2495
+# As I wrote in an earlier message, I suspected the current tzdata values
2496
+# to be wrong. This is now verified.
2497
+#
2498
+# I have found copies of the original ruling by the Swiss Federal
2499
+# government, in 'Eidgen[o]ssische Gesetzessammlung 1941 and 1942' (Swiss
2500
+# federal law collection)...
2501
+#
2502
+# DST began on Monday 5 May 1941, 1:00 am by shifting the clocks to 2:00 am
2503
+# DST ended on Monday 6 Oct 1941, 2:00 am by shifting the clocks to 1:00 am.
2504
+#
2505
+# DST began on Monday, 4 May 1942 at 01:00 am
2506
+# DST ended on Monday, 5 Oct 1942 at 02:00 am
2507
+#
2508
+# There was no DST in 1940, I have checked the law collection carefully.
2509
+# It is also indicated by the fact that the 1942 entry in the law
2510
+# collection points back to 1941 as a reference, but no reference to any
2511
+# other years are made.
2512
+#
2513
+# Newspaper articles I have read in the archives on 6 May 1941 reported
2514
+# about the introduction of DST (Sommerzeit in German) during the previous
2515
+# night as an absolute novelty, because this was the first time that such
2516
+# a thing had happened in Switzerland.
2517
+#
2518
+# I have also checked 1916, because one book source (Gabriel, Traite de
2519
+# l'heure dans le monde) claims that Switzerland had DST in 1916. This is
2520
+# false, no official document could be found. Probably Gabriel got misled
2521
+# by references to Germany, which introduced DST in 1916 for the first time.
2522
+#
2523
+# The tzdata rules for Switzerland must be changed to:
2524
+# Rule  Swiss   1941    1942    -       May     Mon>=1  1:00    1:00    S
2525
+# Rule  Swiss   1941    1942    -       Oct     Mon>=1  2:00    0       -
2526
+#
2527
+# The 1940 rules must be deleted.
2528
+#
2529
+# One further detail for Switzerland, which is probably out of scope for
2530
+# most users of tzdata:
2531
+# The zone file
2532
+# Zone    Europe/Zurich   0:34:08 -       LMT     1848 Sep 12
2533
+#                          0:29:44 -       BMT     1894 Jun #Bern Mean Time
2534
+#                          1:00    Swiss   CE%sT   1981
2535
+#                          1:00    EU      CE%sT
2536
+# describes all of Switzerland correctly, with the exception of
2537
+# the Cantone Geneve (Geneva, Genf). Between 1848 and 1894 Geneve did not
2538
+# follow Bern Mean Time but kept its own local mean time.
2539
+# To represent this, an extra zone would be needed.
2540
+
2541
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
2542
+Rule	Swiss	1941	1942	-	May	Mon>=1	1:00	1:00	S
2543
+Rule	Swiss	1941	1942	-	Oct	Mon>=1	2:00	0	-
2544
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2545
+Zone	Europe/Zurich	0:34:08 -	LMT	1848 Sep 12
2546
+			0:29:44	-	BMT	1894 Jun # Bern Mean Time
2547
+			1:00	Swiss	CE%sT	1981
2548
+			1:00	EU	CE%sT
2549
+
2550
+# Turkey
2551
+
2552
+# From Amar Devegowda (2007-01-03):
2553
+# The time zone rules for Istanbul, Turkey have not been changed for years now.
2554
+# ... The latest rules are available at -
2555
+# http://www.timeanddate.com/worldclock/timezone.html?n=107
2556
+# From Steffen Thorsen (2007-01-03):
2557
+# I have been able to find press records back to 1996 which all say that
2558
+# DST started 01:00 local time and end at 02:00 local time.  I am not sure
2559
+# what happened before that.  One example for each year from 1996 to 2001:
2560
+# http://newspot.byegm.gov.tr/arsiv/1996/21/N4.htm
2561
+# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING97/03/97X03X25.TXT
2562
+# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING98/03/98X03X02.HTM
2563
+# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING99/10/99X10X26.HTM#%2016
2564
+# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING2000/03/00X03X06.HTM#%2021
2565
+# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING2001/03/23x03x01.HTM#%2027
2566
+# From Paul Eggert (2007-01-03):
2567
+# Prefer the above source to Shanks & Pottenger for time stamps after 1990.
2568
+
2569
+# From Steffen Thorsen (2007-03-09):
2570
+# Starting 2007 though, it seems that they are adopting EU's 1:00 UTC
2571
+# start/end time, according to the following page (2007-03-07):
2572
+# http://www.ntvmsnbc.com/news/402029.asp
2573
+# The official document is located here - it is in Turkish...:
2574
+# http://rega.basbakanlik.gov.tr/eskiler/2007/03/20070307-7.htm
2575
+# I was able to locate the following seemingly official document
2576
+# (on a non-government server though) describing dates between 2002 and 2006:
2577
+# http://www.alomaliye.com/bkk_2002_3769.htm
2578
+
2579
+# From G&ouml;kdeniz Karada&#x011f; (2011-03-10):
2580
+#
2581
+# According to the articles linked below, Turkey will change into summer
2582
+# time zone (GMT+3) on March 28, 2011 at 3:00 a.m. instead of March 27.
2583
+# This change is due to a nationwide exam on 27th.
2584
+#
2585
+# <a href="http://www.worldbulletin.net/?aType=haber&ArticleID=70872">
2586
+# http://www.worldbulletin.net/?aType=haber&ArticleID=70872
2587
+# </a>
2588
+# Turkish:
2589
+# <a href="http://www.hurriyet.com.tr/ekonomi/17230464.asp?gid=373">
2590
+# http://www.hurriyet.com.tr/ekonomi/17230464.asp?gid=373
2591
+# </a>
2592
+
2593
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
2594
+Rule	Turkey	1916	only	-	May	 1	0:00	1:00	S
2595
+Rule	Turkey	1916	only	-	Oct	 1	0:00	0	-
2596
+Rule	Turkey	1920	only	-	Mar	28	0:00	1:00	S
2597
+Rule	Turkey	1920	only	-	Oct	25	0:00	0	-
2598
+Rule	Turkey	1921	only	-	Apr	 3	0:00	1:00	S
2599
+Rule	Turkey	1921	only	-	Oct	 3	0:00	0	-
2600
+Rule	Turkey	1922	only	-	Mar	26	0:00	1:00	S
2601
+Rule	Turkey	1922	only	-	Oct	 8	0:00	0	-
2602
+# Whitman gives 1923 Apr 28 - Sep 16 and no DST in 1924-1925;
2603
+# go with Shanks & Pottenger.
2604
+Rule	Turkey	1924	only	-	May	13	0:00	1:00	S
2605
+Rule	Turkey	1924	1925	-	Oct	 1	0:00	0	-
2606
+Rule	Turkey	1925	only	-	May	 1	0:00	1:00	S
2607
+Rule	Turkey	1940	only	-	Jun	30	0:00	1:00	S
2608
+Rule	Turkey	1940	only	-	Oct	 5	0:00	0	-
2609
+Rule	Turkey	1940	only	-	Dec	 1	0:00	1:00	S
2610
+Rule	Turkey	1941	only	-	Sep	21	0:00	0	-
2611
+Rule	Turkey	1942	only	-	Apr	 1	0:00	1:00	S
2612
+# Whitman omits the next two transition and gives 1945 Oct 1;
2613
+# go with Shanks & Pottenger.
2614
+Rule	Turkey	1942	only	-	Nov	 1	0:00	0	-
2615
+Rule	Turkey	1945	only	-	Apr	 2	0:00	1:00	S
2616
+Rule	Turkey	1945	only	-	Oct	 8	0:00	0	-
2617
+Rule	Turkey	1946	only	-	Jun	 1	0:00	1:00	S
2618
+Rule	Turkey	1946	only	-	Oct	 1	0:00	0	-
2619
+Rule	Turkey	1947	1948	-	Apr	Sun>=16	0:00	1:00	S
2620
+Rule	Turkey	1947	1950	-	Oct	Sun>=2	0:00	0	-
2621
+Rule	Turkey	1949	only	-	Apr	10	0:00	1:00	S
2622
+Rule	Turkey	1950	only	-	Apr	19	0:00	1:00	S
2623
+Rule	Turkey	1951	only	-	Apr	22	0:00	1:00	S
2624
+Rule	Turkey	1951	only	-	Oct	 8	0:00	0	-
2625
+Rule	Turkey	1962	only	-	Jul	15	0:00	1:00	S
2626
+Rule	Turkey	1962	only	-	Oct	 8	0:00	0	-
2627
+Rule	Turkey	1964	only	-	May	15	0:00	1:00	S
2628
+Rule	Turkey	1964	only	-	Oct	 1	0:00	0	-
2629
+Rule	Turkey	1970	1972	-	May	Sun>=2	0:00	1:00	S
2630
+Rule	Turkey	1970	1972	-	Oct	Sun>=2	0:00	0	-
2631
+Rule	Turkey	1973	only	-	Jun	 3	1:00	1:00	S
2632
+Rule	Turkey	1973	only	-	Nov	 4	3:00	0	-
2633
+Rule	Turkey	1974	only	-	Mar	31	2:00	1:00	S
2634
+Rule	Turkey	1974	only	-	Nov	 3	5:00	0	-
2635
+Rule	Turkey	1975	only	-	Mar	30	0:00	1:00	S
2636
+Rule	Turkey	1975	1976	-	Oct	lastSun	0:00	0	-
2637
+Rule	Turkey	1976	only	-	Jun	 1	0:00	1:00	S
2638
+Rule	Turkey	1977	1978	-	Apr	Sun>=1	0:00	1:00	S
2639
+Rule	Turkey	1977	only	-	Oct	16	0:00	0	-
2640
+Rule	Turkey	1979	1980	-	Apr	Sun>=1	3:00	1:00	S
2641
+Rule	Turkey	1979	1982	-	Oct	Mon>=11	0:00	0	-
2642
+Rule	Turkey	1981	1982	-	Mar	lastSun	3:00	1:00	S
2643
+Rule	Turkey	1983	only	-	Jul	31	0:00	1:00	S
2644
+Rule	Turkey	1983	only	-	Oct	 2	0:00	0	-
2645
+Rule	Turkey	1985	only	-	Apr	20	0:00	1:00	S
2646
+Rule	Turkey	1985	only	-	Sep	28	0:00	0	-
2647
+Rule	Turkey	1986	1990	-	Mar	lastSun	2:00s	1:00	S
2648
+Rule	Turkey	1986	1990	-	Sep	lastSun	2:00s	0	-
2649
+Rule	Turkey	1991	2006	-	Mar	lastSun	1:00s	1:00	S
2650
+Rule	Turkey	1991	1995	-	Sep	lastSun	1:00s	0	-
2651
+Rule	Turkey	1996	2006	-	Oct	lastSun	1:00s	0	-
2652
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2653
+Zone	Europe/Istanbul	1:55:52 -	LMT	1880
2654
+			1:56:56	-	IMT	1910 Oct # Istanbul Mean Time?
2655
+			2:00	Turkey	EE%sT	1978 Oct 15
2656
+			3:00	Turkey	TR%sT	1985 Apr 20 # Turkey Time
2657
+			2:00	Turkey	EE%sT	2007
2658
+			2:00	EU	EE%sT	2011 Mar 27 1:00u
2659
+			2:00	-	EET	2011 Mar 28 1:00u
2660
+			2:00	EU	EE%sT
2661
+Link	Europe/Istanbul	Asia/Istanbul	# Istanbul is in both continents.
2662
+
2663
+# Ukraine
2664
+#
2665
+# From Igor Karpov, who works for the Ukranian Ministry of Justice,
2666
+# via Garrett Wollman (2003-01-27):
2667
+# BTW, I've found the official document on this matter. It's goverment
2668
+# regulations number 509, May 13, 1996. In my poor translation it says:
2669
+# "Time in Ukraine is set to second timezone (Kiev time). Each last Sunday
2670
+# of March at 3am the time is changing to 4am and each last Sunday of
2671
+# October the time at 4am is changing to 3am"
2672
+
2673
+# From Alexander Krivenyshev (2011-09-20):
2674
+# On September 20, 2011 the deputies of the Verkhovna Rada agreed to
2675
+# abolish the transfer clock to winter time.
2676
+#
2677
+# Bill number 8330 of MP from the Party of Regions Oleg Nadoshi got
2678
+# approval from 266 deputies.
2679
+#
2680
+# Ukraine abolishes transter back to the winter time (in Russian)
2681
+# <a href="http://news.mail.ru/politics/6861560/">
2682
+# http://news.mail.ru/politics/6861560/
2683
+# </a>
2684
+#
2685
+# The Ukrainians will no longer change the clock (in Russian)
2686
+# <a href="http://www.segodnya.ua/news/14290482.html">
2687
+# http://www.segodnya.ua/news/14290482.html
2688
+# </a>
2689
+#
2690
+# Deputies cancelled the winter time (in Russian)
2691
+# <a href="http://www.pravda.com.ua/rus/news/2011/09/20/6600616/">
2692
+# http://www.pravda.com.ua/rus/news/2011/09/20/6600616/
2693
+# </a>
2694
+#
2695
+# From Philip Pizzey (2011-10-18):
2696
+# Today my Ukrainian colleagues have informed me that the
2697
+# Ukrainian parliament have decided that they will go to winter
2698
+# time this year after all.
2699
+#
2700
+# From Udo Schwedt (2011-10-18):
2701
+# As far as I understand, the recent change to the Ukranian time zone
2702
+# (Europe/Kiev) to introduce permanent daylight saving time (similar
2703
+# to Russia) was reverted today:
2704
+#
2705
+# <a href="http://portal.rada.gov.ua/rada/control/en/publish/article/info_left?art_id=287324&cat_id=105995">
2706
+# http://portal.rada.gov.ua/rada/control/en/publish/article/info_left?art_id=287324&cat_id=105995
2707
+# </a>
2708
+#
2709
+# Also reported by Alexander Bokovoy (2011-10-18) who also noted:
2710
+# The law documents themselves are at
2711
+#
2712
+# <a href="http://w1.c1.rada.gov.ua/pls/zweb_n/webproc4_1?id=&pf3511=41484">
2713
+# http://w1.c1.rada.gov.ua/pls/zweb_n/webproc4_1?id=&pf3511=41484
2714
+# </a>
2715
+
2716
+
2717
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2718
+# Most of Ukraine since 1970 has been like Kiev.
2719
+# "Kyiv" is the transliteration of the Ukrainian name, but
2720
+# "Kiev" is more common in English.
2721
+Zone Europe/Kiev	2:02:04 -	LMT	1880
2722
+			2:02:04	-	KMT	1924 May  2 # Kiev Mean Time
2723
+			2:00	-	EET	1930 Jun 21
2724
+			3:00	-	MSK	1941 Sep 20
2725
+			1:00	C-Eur	CE%sT	1943 Nov  6
2726
+			3:00	Russia	MSK/MSD	1990
2727
+			3:00	-	MSK	1990 Jul  1 2:00
2728
+			2:00	-	EET	1992
2729
+			2:00	E-Eur	EE%sT	1995
2730
+			2:00	EU	EE%sT
2731
+# Ruthenia used CET 1990/1991.
2732
+# "Uzhhorod" is the transliteration of the Ukrainian name, but
2733
+# "Uzhgorod" is more common in English.
2734
+Zone Europe/Uzhgorod	1:29:12 -	LMT	1890 Oct
2735
+			1:00	-	CET	1940
2736
+			1:00	C-Eur	CE%sT	1944 Oct
2737
+			1:00	1:00	CEST	1944 Oct 26
2738
+			1:00	-	CET	1945 Jun 29
2739
+			3:00	Russia	MSK/MSD	1990
2740
+			3:00	-	MSK	1990 Jul  1 2:00
2741
+			1:00	-	CET	1991 Mar 31 3:00
2742
+			2:00	-	EET	1992
2743
+			2:00	E-Eur	EE%sT	1995
2744
+			2:00	EU	EE%sT
2745
+# Zaporozh'ye and eastern Lugansk oblasts observed DST 1990/1991.
2746
+# "Zaporizhia" is the transliteration of the Ukrainian name, but
2747
+# "Zaporozh'ye" is more common in English.  Use the common English
2748
+# spelling, except omit the apostrophe as it is not allowed in
2749
+# portable Posix file names.
2750
+Zone Europe/Zaporozhye	2:20:40 -	LMT	1880
2751
+			2:20	-	CUT	1924 May  2 # Central Ukraine T
2752
+			2:00	-	EET	1930 Jun 21
2753
+			3:00	-	MSK	1941 Aug 25
2754
+			1:00	C-Eur	CE%sT	1943 Oct 25
2755
+			3:00	Russia	MSK/MSD	1991 Mar 31 2:00
2756
+			2:00	E-Eur	EE%sT	1995
2757
+			2:00	EU	EE%sT
2758
+# Central Crimea used Moscow time 1994/1997.
2759
+Zone Europe/Simferopol	2:16:24 -	LMT	1880
2760
+			2:16	-	SMT	1924 May  2 # Simferopol Mean T
2761
+			2:00	-	EET	1930 Jun 21
2762
+			3:00	-	MSK	1941 Nov
2763
+			1:00	C-Eur	CE%sT	1944 Apr 13
2764
+			3:00	Russia	MSK/MSD	1990
2765
+			3:00	-	MSK	1990 Jul  1 2:00
2766
+			2:00	-	EET	1992
2767
+# From Paul Eggert (2006-03-22):
2768
+# The _Economist_ (1994-05-28, p 45) reports that central Crimea switched
2769
+# from Kiev to Moscow time sometime after the January 1994 elections.
2770
+# Shanks (1999) says ``date of change uncertain'', but implies that it happened
2771
+# sometime between the 1994 DST switches.  Shanks & Pottenger simply say
2772
+# 1994-09-25 03:00, but that can't be right.  For now, guess it
2773
+# changed in May.
2774
+			2:00	E-Eur	EE%sT	1994 May
2775
+# From IATA SSIM (1994/1997), which also says that Kerch is still like Kiev.
2776
+			3:00	E-Eur	MSK/MSD	1996 Mar 31 3:00s
2777
+			3:00	1:00	MSD	1996 Oct 27 3:00s
2778
+# IATA SSIM (1997-09) says Crimea switched to EET/EEST.
2779
+# Assume it happened in March by not changing the clocks.
2780
+			3:00	Russia	MSK/MSD	1997
2781
+			3:00	-	MSK	1997 Mar lastSun 1:00u
2782
+			2:00	EU	EE%sT
2783
+
2784
+###############################################################################
2785
+
2786
+# One source shows that Bulgaria, Cyprus, Finland, and Greece observe DST from
2787
+# the last Sunday in March to the last Sunday in September in 1986.
2788
+# The source shows Romania changing a day later than everybody else.
2789
+#
2790
+# According to Bernard Sieloff's source, Poland is in the MET time zone but
2791
+# uses the WE DST rules.  The Western USSR uses EET+1 and ME DST rules.
2792
+# Bernard Sieloff's source claims Romania switches on the same day, but at
2793
+# 00:00 standard time (i.e., 01:00 DST).  It also claims that Turkey
2794
+# switches on the same day, but switches on at 01:00 standard time
2795
+# and off at 00:00 standard time (i.e., 01:00 DST)
2796
+
2797
+# ...
2798
+# Date: Wed, 28 Jan 87 16:56:27 -0100
2799
+# From: Tom Hofmann
2800
+# ...
2801
+#
2802
+# ...the European time rules are...standardized since 1981, when
2803
+# most European coun[tr]ies started DST.  Before that year, only
2804
+# a few countries (UK, France, Italy) had DST, each according
2805
+# to own national rules.  In 1981, however, DST started on
2806
+# 'Apr firstSun', and not on 'Mar lastSun' as in the following
2807
+# years...
2808
+# But also since 1981 there are some more national exceptions
2809
+# than listed in 'europe': Switzerland, for example, joined DST
2810
+# one year later, Denmark ended DST on 'Oct 1' instead of 'Sep
2811
+# lastSun' in 1981---I don't know how they handle now.
2812
+#
2813
+# Finally, DST ist always from 'Apr 1' to 'Oct 1' in the
2814
+# Soviet Union (as far as I know).
2815
+#
2816
+# Tom Hofmann, Scientific Computer Center, CIBA-GEIGY AG,
2817
+# 4002 Basle, Switzerland
2818
+# ...
2819
+
2820
+# ...
2821
+# Date: Wed, 4 Feb 87 22:35:22 +0100
2822
+# From: Dik T. Winter
2823
+# ...
2824
+#
2825
+# The information from Tom Hofmann is (as far as I know) not entirely correct.
2826
+# After a request from chongo at amdahl I tried to retrieve all information
2827
+# about DST in Europe.  I was able to find all from about 1969.
2828
+#
2829
+# ...standardization on DST in Europe started in about 1977 with switches on
2830
+# first Sunday in April and last Sunday in September...
2831
+# In 1981 UK joined Europe insofar that
2832
+# the starting day for both shifted to last Sunday in March.  And from 1982
2833
+# the whole of Europe used DST, with switch dates April 1 and October 1 in
2834
+# the Sov[i]et Union.  In 1985 the SU reverted to standard Europe[a]n switch
2835
+# dates...
2836
+#
2837
+# It should also be remembered that time-zones are not constants; e.g.
2838
+# Portugal switched in 1976 from MET (or CET) to WET with DST...
2839
+# Note also that though there were rules for switch dates not
2840
+# all countries abided to these dates, and many individual deviations
2841
+# occurred, though not since 1982 I believe.  Another note: it is always
2842
+# assumed that DST is 1 hour ahead of normal time, this need not be the
2843
+# case; at least in the Netherlands there have been times when DST was 2 hours
2844
+# in advance of normal time.
2845
+#
2846
+# ...
2847
+# dik t. winter, cwi, amsterdam, nederland
2848
+# ...
2849
+
2850
+# From Bob Devine (1988-01-28):
2851
+# ...
2852
+# Greece: Last Sunday in April to last Sunday in September (iffy on dates).
2853
+# Since 1978.  Change at midnight.
2854
+# ...
2855
+# Monaco: has same DST as France.
2856
+# ...
... ...
@@ -0,0 +1,10 @@
1
+# <pre>
2
+# This file is in the public domain, so clarified as of
3
+# 2009-05-17 by Arthur David Olson.
4
+
5
+# For companies who don't want to put time zone specification in
6
+# their installation procedures.  When users run date, they'll get the message.
7
+# Also useful for the "comp.sources" version.
8
+
9
+# Zone	NAME	GMTOFF	RULES	FORMAT
10
+Zone	Factory	0	- "Local time zone must be set--see zic manual page"
... ...
@@ -0,0 +1,276 @@
1
+# <pre>
2
+# This file is in the public domain, so clarified as of
3
+# 2009-05-17 by Arthur David Olson.
4
+# ISO 3166 alpha-2 country codes
5
+#
6
+# From Paul Eggert (2006-09-27):
7
+#
8
+# This file contains a table with the following columns:
9
+# 1.  ISO 3166-1 alpha-2 country code, current as of
10
+#     ISO 3166-1 Newsletter VI-1 (2007-09-21).  See:
11
+#     <a href="http://www.iso.org/iso/en/prods-services/iso3166ma/index.html">
12
+#     ISO 3166 Maintenance agency (ISO 3166/MA)
13
+#     </a>.
14
+# 2.  The usual English name for the country,
15
+#     chosen so that alphabetic sorting of subsets produces helpful lists.
16
+#     This is not the same as the English name in the ISO 3166 tables.
17
+#
18
+# Columns are separated by a single tab.
19
+# The table is sorted by country code.
20
+#
21
+# Lines beginning with `#' are comments.
22
+#
23
+# From Arthur David Olson (2011-08-17):
24
+# Resynchronized today with the ISO 3166 site (adding SS for South Sudan).
25
+#
26
+#country-
27
+#code	country name
28
+AD	Andorra
29
+AE	United Arab Emirates
30
+AF	Afghanistan
31
+AG	Antigua & Barbuda
32
+AI	Anguilla
33
+AL	Albania
34
+AM	Armenia
35
+AO	Angola
36
+AQ	Antarctica
37
+AR	Argentina
38
+AS	Samoa (American)
39
+AT	Austria
40
+AU	Australia
41
+AW	Aruba
42
+AX	Aaland Islands
43
+AZ	Azerbaijan
44
+BA	Bosnia & Herzegovina
45
+BB	Barbados
46
+BD	Bangladesh
47
+BE	Belgium
48
+BF	Burkina Faso
49
+BG	Bulgaria
50
+BH	Bahrain
51
+BI	Burundi
52
+BJ	Benin
53
+BL	St Barthelemy
54
+BM	Bermuda
55
+BN	Brunei
56
+BO	Bolivia
57
+BQ	Bonaire Sint Eustatius & Saba
58
+BR	Brazil
59
+BS	Bahamas
60
+BT	Bhutan
61
+BV	Bouvet Island
62
+BW	Botswana
63
+BY	Belarus
64
+BZ	Belize
65
+CA	Canada
66
+CC	Cocos (Keeling) Islands
67
+CD	Congo (Dem. Rep.)
68
+CF	Central African Rep.
69
+CG	Congo (Rep.)
70
+CH	Switzerland
71
+CI	Cote d'Ivoire
72
+CK	Cook Islands
73
+CL	Chile
74
+CM	Cameroon
75
+CN	China
76
+CO	Colombia
77
+CR	Costa Rica
78
+CU	Cuba
79
+CV	Cape Verde
80
+CW	Curacao
81
+CX	Christmas Island
82
+CY	Cyprus
83
+CZ	Czech Republic
84
+DE	Germany
85
+DJ	Djibouti
86
+DK	Denmark
87
+DM	Dominica
88
+DO	Dominican Republic
89
+DZ	Algeria
90
+EC	Ecuador
91
+EE	Estonia
92
+EG	Egypt
93
+EH	Western Sahara
94
+ER	Eritrea
95
+ES	Spain
96
+ET	Ethiopia
97
+FI	Finland
98
+FJ	Fiji
99
+FK	Falkland Islands
100
+FM	Micronesia
101
+FO	Faroe Islands
102
+FR	France
103
+GA	Gabon
104
+GB	Britain (UK)
105
+GD	Grenada
106
+GE	Georgia
107
+GF	French Guiana
108
+GG	Guernsey
109
+GH	Ghana
110
+GI	Gibraltar
111
+GL	Greenland
112
+GM	Gambia
113
+GN	Guinea
114
+GP	Guadeloupe
115
+GQ	Equatorial Guinea
116
+GR	Greece
117
+GS	South Georgia & the South Sandwich Islands
118
+GT	Guatemala
119
+GU	Guam
120
+GW	Guinea-Bissau
121
+GY	Guyana
122
+HK	Hong Kong
123
+HM	Heard Island & McDonald Islands
124
+HN	Honduras
125
+HR	Croatia
126
+HT	Haiti
127
+HU	Hungary
128
+ID	Indonesia
129
+IE	Ireland
130
+IL	Israel
131
+IM	Isle of Man
132
+IN	India
133
+IO	British Indian Ocean Territory
134
+IQ	Iraq
135
+IR	Iran
136
+IS	Iceland
137
+IT	Italy
138
+JE	Jersey
139
+JM	Jamaica
140
+JO	Jordan
141
+JP	Japan
142
+KE	Kenya
143
+KG	Kyrgyzstan
144
+KH	Cambodia
145
+KI	Kiribati
146
+KM	Comoros
147
+KN	St Kitts & Nevis
148
+KP	Korea (North)
149
+KR	Korea (South)
150
+KW	Kuwait
151
+KY	Cayman Islands
152
+KZ	Kazakhstan
153
+LA	Laos
154
+LB	Lebanon
155
+LC	St Lucia
156
+LI	Liechtenstein
157
+LK	Sri Lanka
158
+LR	Liberia
159
+LS	Lesotho
160
+LT	Lithuania
161
+LU	Luxembourg
162
+LV	Latvia
163
+LY	Libya
164
+MA	Morocco
165
+MC	Monaco
166
+MD	Moldova
167
+ME	Montenegro
168
+MF	St Martin (French part)
169
+MG	Madagascar
170
+MH	Marshall Islands
171
+MK	Macedonia
172
+ML	Mali
173
+MM	Myanmar (Burma)
174
+MN	Mongolia
175
+MO	Macau
176
+MP	Northern Mariana Islands
177
+MQ	Martinique
178
+MR	Mauritania
179
+MS	Montserrat
180
+MT	Malta
181
+MU	Mauritius
182
+MV	Maldives
183
+MW	Malawi
184
+MX	Mexico
185
+MY	Malaysia
186
+MZ	Mozambique
187
+NA	Namibia
188
+NC	New Caledonia
189
+NE	Niger
190
+NF	Norfolk Island
191
+NG	Nigeria
192
+NI	Nicaragua
193
+NL	Netherlands
194
+NO	Norway
195
+NP	Nepal
196
+NR	Nauru
197
+NU	Niue
198
+NZ	New Zealand
199
+OM	Oman
200
+PA	Panama
201
+PE	Peru
202
+PF	French Polynesia
203
+PG	Papua New Guinea
204
+PH	Philippines
205
+PK	Pakistan
206
+PL	Poland
207
+PM	St Pierre & Miquelon
208
+PN	Pitcairn
209
+PR	Puerto Rico
210
+PS	Palestine
211
+PT	Portugal
212
+PW	Palau
213
+PY	Paraguay
214
+QA	Qatar
215
+RE	Reunion
216
+RO	Romania
217
+RS	Serbia
218
+RU	Russia
219
+RW	Rwanda
220
+SA	Saudi Arabia
221
+SB	Solomon Islands
222
+SC	Seychelles
223
+SD	Sudan
224
+SE	Sweden
225
+SG	Singapore
226
+SH	St Helena
227
+SI	Slovenia
228
+SJ	Svalbard & Jan Mayen
229
+SK	Slovakia
230
+SL	Sierra Leone
231
+SM	San Marino
232
+SN	Senegal
233
+SO	Somalia
234
+SR	Suriname
235
+SS	South Sudan
236
+ST	Sao Tome & Principe
237
+SV	El Salvador
238
+SX	Sint Maarten
239
+SY	Syria
240
+SZ	Swaziland
241
+TC	Turks & Caicos Is
242
+TD	Chad
243
+TF	French Southern & Antarctic Lands
244
+TG	Togo
245
+TH	Thailand
246
+TJ	Tajikistan
247
+TK	Tokelau
248
+TL	East Timor
249
+TM	Turkmenistan
250
+TN	Tunisia
251
+TO	Tonga
252
+TR	Turkey
253
+TT	Trinidad & Tobago
254
+TV	Tuvalu
255
+TW	Taiwan
256
+TZ	Tanzania
257
+UA	Ukraine
258
+UG	Uganda
259
+UM	US minor outlying islands
260
+US	United States
261
+UY	Uruguay
262
+UZ	Uzbekistan
263
+VA	Vatican City
264
+VC	St Vincent
265
+VE	Venezuela
266
+VG	Virgin Islands (UK)
267
+VI	Virgin Islands (US)
268
+VN	Vietnam
269
+VU	Vanuatu
270
+WF	Wallis & Futuna
271
+WS	Samoa (western)
272
+YE	Yemen
273
+YT	Mayotte
274
+ZA	South Africa
275
+ZM	Zambia
276
+ZW	Zimbabwe
... ...
@@ -0,0 +1,100 @@
1
+# <pre>
2
+# This file is in the public domain, so clarified as of
3
+# 2009-05-17 by Arthur David Olson.
4
+
5
+# Allowance for leapseconds added to each timezone file.
6
+
7
+# The International Earth Rotation Service periodically uses leap seconds
8
+# to keep UTC to within 0.9 s of UT1
9
+# (which measures the true angular orientation of the earth in space); see
10
+# Terry J Quinn, The BIPM and the accurate measure of time,
11
+# Proc IEEE 79, 7 (July 1991), 894-905.
12
+# There were no leap seconds before 1972, because the official mechanism
13
+# accounting for the discrepancy between atomic time and the earth's rotation
14
+# did not exist until the early 1970s.
15
+
16
+# The correction (+ or -) is made at the given time, so lines
17
+# will typically look like:
18
+#	Leap	YEAR	MON	DAY	23:59:60	+	R/S
19
+# or
20
+#	Leap	YEAR	MON	DAY	23:59:59	-	R/S
21
+
22
+# If the leapsecond is Rolling (R) the given time is local time
23
+# If the leapsecond is Stationary (S) the given time is UTC
24
+
25
+# Leap	YEAR	MONTH	DAY	HH:MM:SS	CORR	R/S
26
+Leap	1972	Jun	30	23:59:60	+	S
27
+Leap	1972	Dec	31	23:59:60	+	S
28
+Leap	1973	Dec	31	23:59:60	+	S
29
+Leap	1974	Dec	31	23:59:60	+	S
30
+Leap	1975	Dec	31	23:59:60	+	S
31
+Leap	1976	Dec	31	23:59:60	+	S
32
+Leap	1977	Dec	31	23:59:60	+	S
33
+Leap	1978	Dec	31	23:59:60	+	S
34
+Leap	1979	Dec	31	23:59:60	+	S
35
+Leap	1981	Jun	30	23:59:60	+	S
36
+Leap	1982	Jun	30	23:59:60	+	S
37
+Leap	1983	Jun	30	23:59:60	+	S
38
+Leap	1985	Jun	30	23:59:60	+	S
39
+Leap	1987	Dec	31	23:59:60	+	S
40
+Leap	1989	Dec	31	23:59:60	+	S
41
+Leap	1990	Dec	31	23:59:60	+	S
42
+Leap	1992	Jun	30	23:59:60	+	S
43
+Leap	1993	Jun	30	23:59:60	+	S
44
+Leap	1994	Jun	30	23:59:60	+	S
45
+Leap	1995	Dec	31	23:59:60	+	S
46
+Leap	1997	Jun	30	23:59:60	+	S
47
+Leap	1998	Dec	31	23:59:60	+	S
48
+Leap	2005	Dec	31	23:59:60	+	S
49
+Leap	2008	Dec	31	23:59:60	+	S
50
+Leap	2012	Jun	30	23:59:60	+	S
51
+
52
+# INTERNATIONAL EARTH ROTATION AND REFERENCE SYSTEMS SERVICE (IERS)
53
+#
54
+# SERVICE INTERNATIONAL DE LA ROTATION TERRESTRE ET DES SYSTEMES DE REFERENCE
55
+#
56
+#
57
+# SERVICE DE LA ROTATION TERRESTRE
58
+# OBSERVATOIRE DE PARIS
59
+# 61, Av. de l'Observatoire 75014 PARIS (France)
60
+# Tel.      : 33 (0) 1 40 51 22 26
61
+# FAX       : 33 (0) 1 40 51 22 91
62
+# e-mail    : (E-Mail Removed)
63
+# http://hpiers.obspm.fr/eop-pc
64
+#
65
+# Paris, 5 January 2012
66
+#
67
+#
68
+# Bulletin C 43
69
+#
70
+# To authorities responsible
71
+# for the measurement and
72
+# distribution of time
73
+#
74
+#
75
+# UTC TIME STEP
76
+# on the 1st of July 2012
77
+#
78
+#
79
+# A positive leap second will be introduced at the end of June 2012.
80
+# The sequence of dates of the UTC second markers will be:
81
+#
82
+#                          2012 June 30,     23h 59m 59s
83
+#                          2012 June 30,     23h 59m 60s
84
+#                          2012 July  1,      0h  0m  0s
85
+#
86
+# The difference between UTC and the International Atomic Time TAI is:
87
+#
88
+# from 2009 January 1, 0h UTC, to 2012 July 1  0h UTC  : UTC-TAI = - 34s
89
+# from 2012 July 1,    0h UTC, until further notice    : UTC-TAI = - 35s
90
+#
91
+# Leap seconds can be introduced in UTC at the end of the months of December
92
+# or June, depending on the evolution of UT1-TAI. Bulletin C is mailed every
93
+# six months, either to announce a time step in UTC or to confirm that there
94
+# will be no time step at the next possible date.
95
+#
96
+#
97
+# Daniel GAMBIS
98
+# Head
99
+# Earth Orientation Center of IERS
100
+# Observatoire de Paris, France
... ...
@@ -0,0 +1,3235 @@
1
+# <pre>
2
+# This file is in the public domain, so clarified as of
3
+# 2009-05-17 by Arthur David Olson.
4
+
5
+# also includes Central America and the Caribbean
6
+
7
+# This data is by no means authoritative; if you think you know better,
8
+# go ahead and edit the file (and please send any changes to
9
+# tz@iana.org for general use in the future).
10
+
11
+# From Paul Eggert (1999-03-22):
12
+# A reliable and entertaining source about time zones is
13
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
14
+
15
+###############################################################################
16
+
17
+# United States
18
+
19
+# From Paul Eggert (1999-03-31):
20
+# Howse writes (pp 121-125) that time zones were invented by
21
+# Professor Charles Ferdinand Dowd (1825-1904),
22
+# Principal of Temple Grove Ladies' Seminary (Saratoga Springs, NY).
23
+# His pamphlet ``A System of National Time for Railroads'' (1870)
24
+# was the result of his proposals at the Convention of Railroad Trunk Lines
25
+# in New York City (1869-10).  His 1870 proposal was based on Washington, DC,
26
+# but in 1872-05 he moved the proposed origin to Greenwich.
27
+# His proposal was adopted by the railroads on 1883-11-18 at 12:00,
28
+# and the most of the country soon followed suit.
29
+
30
+# From Paul Eggert (2005-04-16):
31
+# That 1883 transition occurred at 12:00 new time, not at 12:00 old time.
32
+# See p 46 of David Prerau, Seize the daylight, Thunder's Mouth Press (2005).
33
+
34
+# From Paul Eggert (2006-03-22):
35
+# A good source for time zone historical data in the US is
36
+# Thomas G. Shanks, The American Atlas (5th edition),
37
+# San Diego: ACS Publications, Inc. (1991).
38
+# Make sure you have the errata sheet; the book is somewhat useless without it.
39
+# It is the source for most of the pre-1991 US entries below.
40
+
41
+# From Paul Eggert (2001-03-06):
42
+# Daylight Saving Time was first suggested as a joke by Benjamin Franklin
43
+# in his whimsical essay ``An Economical Project for Diminishing the Cost
44
+# of Light'' published in the Journal de Paris (1784-04-26).
45
+# Not everyone is happy with the results:
46
+#
47
+#	I don't really care how time is reckoned so long as there is some
48
+#	agreement about it, but I object to being told that I am saving
49
+#	daylight when my reason tells me that I am doing nothing of the kind.
50
+#	I even object to the implication that I am wasting something
51
+#	valuable if I stay in bed after the sun has risen.  As an admirer
52
+#	of moonlight I resent the bossy insistence of those who want to
53
+#	reduce my time for enjoying it.  At the back of the Daylight Saving
54
+#	scheme I detect the bony, blue-fingered hand of Puritanism, eager
55
+#	to push people into bed earlier, and get them up earlier, to make
56
+#	them healthy, wealthy and wise in spite of themselves.
57
+#
58
+#	-- Robertson Davies, The diary of Samuel Marchbanks,
59
+#	   Clarke, Irwin (1947), XIX, Sunday
60
+#
61
+# For more about the first ten years of DST in the United States, see
62
+# Robert Garland's <a href="http://www.clpgh.org/exhibit/dst.html">
63
+# Ten years of daylight saving from the Pittsburgh standpoint
64
+# (Carnegie Library of Pittsburgh, 1927)</a>.
65
+#
66
+# Shanks says that DST was called "War Time" in the US in 1918 and 1919.
67
+# However, DST was imposed by the Standard Time Act of 1918, which
68
+# was the first nationwide legal time standard, and apparently
69
+# time was just called "Standard Time" or "Daylight Saving Time".
70
+
71
+# From Arthur David Olson:
72
+# US Daylight Saving Time ended on the last Sunday of *October* in 1974.
73
+# See, for example, the front page of the Saturday, 1974-10-26
74
+# and Sunday, 1974-10-27 editions of the Washington Post.
75
+
76
+# From Arthur David Olson:
77
+# Before the Uniform Time Act of 1966 took effect in 1967, observance of
78
+# Daylight Saving Time in the US was by local option, except during wartime.
79
+
80
+# From Arthur David Olson (2000-09-25):
81
+# Last night I heard part of a rebroadcast of a 1945 Arch Oboler radio drama.
82
+# In the introduction, Oboler spoke of "Eastern Peace Time."
83
+# An AltaVista search turned up
84
+# <a href="http://rowayton.org/rhs/hstaug45.html">:
85
+# "When the time is announced over the radio now, it is 'Eastern Peace
86
+# Time' instead of the old familiar 'Eastern War Time.'  Peace is wonderful."
87
+# </a> (August 1945) by way of confirmation.
88
+
89
+# From Joseph Gallant citing
90
+# George H. Douglas, _The Early Days of Radio Broadcasting_ (1987):
91
+# At 7 P.M. (Eastern War Time) [on 1945-08-14], the networks were set
92
+# to switch to London for Attlee's address, but the American people
93
+# never got to hear his speech live. According to one press account,
94
+# CBS' Bob Trout was first to announce the word of Japan's surrender,
95
+# but a few seconds later, NBC, ABC and Mutual also flashed the word
96
+# of surrender, all of whom interrupting the bells of Big Ben in
97
+# London which were to precede Mr. Attlee's speech.
98
+
99
+# From Paul Eggert (2003-02-09): It was Robert St John, not Bob Trout.  From
100
+# Myrna Oliver's obituary of St John on page B16 of today's Los Angeles Times:
101
+#
102
+# ... a war-weary U.S. clung to radios, awaiting word of Japan's surrender.
103
+# Any announcement from Asia would reach St. John's New York newsroom on a
104
+# wire service teletype machine, which had prescribed signals for major news.
105
+# Associated Press, for example, would ring five bells before spewing out
106
+# typed copy of an important story, and 10 bells for news "of transcendental
107
+# importance."
108
+#
109
+# On Aug. 14, stalling while talking steadily into the NBC networks' open
110
+# microphone, St. John heard five bells and waited only to hear a sixth bell,
111
+# before announcing confidently: "Ladies and gentlemen, World War II is over.
112
+# The Japanese have agreed to our surrender terms."
113
+#
114
+# He had scored a 20-second scoop on other broadcasters.
115
+
116
+# From Arthur David Olson (2005-08-22):
117
+# Paul has been careful to use the "US" rules only in those locations
118
+# that are part of the United States; this reflects the real scope of
119
+# U.S. government action.  So even though the "US" rules have changed
120
+# in the latest release, other countries won't be affected.
121
+
122
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
123
+Rule	US	1918	1919	-	Mar	lastSun	2:00	1:00	D
124
+Rule	US	1918	1919	-	Oct	lastSun	2:00	0	S
125
+Rule	US	1942	only	-	Feb	9	2:00	1:00	W # War
126
+Rule	US	1945	only	-	Aug	14	23:00u	1:00	P # Peace
127
+Rule	US	1945	only	-	Sep	30	2:00	0	S
128
+Rule	US	1967	2006	-	Oct	lastSun	2:00	0	S
129
+Rule	US	1967	1973	-	Apr	lastSun	2:00	1:00	D
130
+Rule	US	1974	only	-	Jan	6	2:00	1:00	D
131
+Rule	US	1975	only	-	Feb	23	2:00	1:00	D
132
+Rule	US	1976	1986	-	Apr	lastSun	2:00	1:00	D
133
+Rule	US	1987	2006	-	Apr	Sun>=1	2:00	1:00	D
134
+Rule	US	2007	max	-	Mar	Sun>=8	2:00	1:00	D
135
+Rule	US	2007	max	-	Nov	Sun>=1	2:00	0	S
136
+
137
+# From Arthur David Olson, 2005-12-19
138
+# We generate the files specified below to guard against old files with
139
+# obsolete information being left in the time zone binary directory.
140
+# We limit the list to names that have appeared in previous versions of
141
+# this time zone package.
142
+# We do these as separate Zones rather than as Links to avoid problems if
143
+# a particular place changes whether it observes DST.
144
+# We put these specifications here in the northamerica file both to
145
+# increase the chances that they'll actually get compiled and to
146
+# avoid the need to duplicate the US rules in another file.
147
+
148
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
149
+Zone	EST		 -5:00	-	EST
150
+Zone	MST		 -7:00	-	MST
151
+Zone	HST		-10:00	-	HST
152
+Zone	EST5EDT		 -5:00	US	E%sT
153
+Zone	CST6CDT		 -6:00	US	C%sT
154
+Zone	MST7MDT		 -7:00	US	M%sT
155
+Zone	PST8PDT		 -8:00	US	P%sT
156
+
157
+# From Bob Devine (1988-01-28):
158
+# ...Alaska (and Hawaii) had the timezone names changed in 1967.
159
+#    old			 new
160
+#    Pacific Standard Time(PST)  -same-
161
+#    Yukon Standard Time(YST)    -same-
162
+#    Central Alaska S.T. (CAT)   Alaska-Hawaii St[an]dard Time (AHST)
163
+#    Nome Standard Time (NT)     Bering Standard Time (BST)
164
+#
165
+# ...Alaska's timezone lines were redrawn in 1983 to give only 2 tz.
166
+#    The YST zone now covers nearly all of the state, AHST just part
167
+#    of the Aleutian islands.   No DST.
168
+
169
+# From Paul Eggert (1995-12-19):
170
+# The tables below use `NST', not `NT', for Nome Standard Time.
171
+# I invented `CAWT' for Central Alaska War Time.
172
+
173
+# From U. S. Naval Observatory (1989-01-19):
174
+# USA  EASTERN       5 H  BEHIND UTC    NEW YORK, WASHINGTON
175
+# USA  EASTERN       4 H  BEHIND UTC    APR 3 - OCT 30
176
+# USA  CENTRAL       6 H  BEHIND UTC    CHICAGO, HOUSTON
177
+# USA  CENTRAL       5 H  BEHIND UTC    APR 3 - OCT 30
178
+# USA  MOUNTAIN      7 H  BEHIND UTC    DENVER
179
+# USA  MOUNTAIN      6 H  BEHIND UTC    APR 3 - OCT 30
180
+# USA  PACIFIC       8 H  BEHIND UTC    L.A., SAN FRANCISCO
181
+# USA  PACIFIC       7 H  BEHIND UTC    APR 3 - OCT 30
182
+# USA  ALASKA STD    9 H  BEHIND UTC    MOST OF ALASKA     (AKST)
183
+# USA  ALASKA STD    8 H  BEHIND UTC    APR 3 - OCT 30 (AKDT)
184
+# USA  ALEUTIAN     10 H  BEHIND UTC    ISLANDS WEST OF 170W
185
+# USA  - " -         9 H  BEHIND UTC    APR 3 - OCT 30
186
+# USA  HAWAII       10 H  BEHIND UTC
187
+# USA  BERING       11 H  BEHIND UTC    SAMOA, MIDWAY
188
+
189
+# From Arthur David Olson (1989-01-21):
190
+# The above dates are for 1988.
191
+# Note the "AKST" and "AKDT" abbreviations, the claim that there's
192
+# no DST in Samoa, and the claim that there is DST in Alaska and the
193
+# Aleutians.
194
+
195
+# From Arthur David Olson (1988-02-13):
196
+# Legal standard time zone names, from United States Code (1982 Edition and
197
+# Supplement III), Title 15, Chapter 6, Section 260 and forward.  First, names
198
+# up to 1967-04-01 (when most provisions of the Uniform Time Act of 1966
199
+# took effect), as explained in sections 263 and 261:
200
+#	(none)
201
+#	United States standard eastern time
202
+#	United States standard mountain time
203
+#	United States standard central time
204
+#	United States standard Pacific time
205
+#	(none)
206
+#	United States standard Alaska time
207
+#	(none)
208
+# Next, names from 1967-04-01 until 1983-11-30 (the date for
209
+# public law 98-181):
210
+#	Atlantic standard time
211
+#	eastern standard time
212
+#	central standard time
213
+#	mountain standard time
214
+#	Pacific standard time
215
+#	Yukon standard time
216
+#	Alaska-Hawaii standard time
217
+#	Bering standard time
218
+# And after 1983-11-30:
219
+#	Atlantic standard time
220
+#	eastern standard time
221
+#	central standard time
222
+#	mountain standard time
223
+#	Pacific standard time
224
+#	Alaska standard time
225
+#	Hawaii-Aleutian standard time
226
+#	Samoa standard time
227
+# The law doesn't give abbreviations.
228
+#
229
+# From Paul Eggert (2000-01-08), following a heads-up from Rives McDow:
230
+# Public law 106-564 (2000-12-23) introduced the abbreviation
231
+# "Chamorro Standard Time" for time in Guam and the Northern Marianas.
232
+# See the file "australasia".
233
+
234
+# From Arthur David Olson, 2005-08-09
235
+# The following was signed into law on 2005-08-08.
236
+#
237
+# H.R. 6, Energy Policy Act of 2005, SEC. 110. DAYLIGHT SAVINGS.
238
+#   (a) Amendment- Section 3(a) of the Uniform Time Act of 1966 (15
239
+#   U.S.C. 260a(a)) is amended--
240
+#     (1) by striking `first Sunday of April' and inserting `second
241
+#     Sunday of March'; and
242
+#     (2) by striking `last Sunday of October' and inserting `first
243
+#     Sunday of November'.
244
+#   (b) Effective Date- Subsection (a) shall take effect 1 year after the
245
+#   date of enactment of this Act or March 1, 2007, whichever is later.
246
+#   (c) Report to Congress- Not later than 9 months after the effective
247
+#   date stated in subsection (b), the Secretary shall report to Congress
248
+#   on the impact of this section on energy consumption in the United
249
+#   States.
250
+#   (d) Right to Revert- Congress retains the right to revert the
251
+#   Daylight Saving Time back to the 2005 time schedules once the
252
+#   Department study is complete.
253
+
254
+# US eastern time, represented by New York
255
+
256
+# Connecticut, Delaware, District of Columbia, most of Florida,
257
+# Georgia, southeast Indiana (Dearborn and Ohio counties), eastern Kentucky
258
+# (except America/Kentucky/Louisville below), Maine, Maryland, Massachusetts,
259
+# New Hampshire, New Jersey, New York, North Carolina, Ohio,
260
+# Pennsylvania, Rhode Island, South Carolina, eastern Tennessee,
261
+# Vermont, Virginia, West Virginia
262
+
263
+# From Dave Cantor (2004-11-02):
264
+# Early this summer I had the occasion to visit the Mount Washington
265
+# Observatory weather station atop (of course!) Mount Washington [, NH]....
266
+# One of the staff members said that the station was on Eastern Standard Time
267
+# and didn't change their clocks for Daylight Saving ... so that their
268
+# reports will always have times which are 5 hours behind UTC.
269
+
270
+# From Paul Eggert (2005-08-26):
271
+# According to today's Huntsville Times
272
+# <http://www.al.com/news/huntsvilletimes/index.ssf?/base/news/1125047783228320.xml&coll=1>
273
+# a few towns on Alabama's "eastern border with Georgia, such as Phenix City
274
+# in Russell County, Lanett in Chambers County and some towns in Lee County,
275
+# set their watches and clocks on Eastern time."  It quotes H.H. "Bubba"
276
+# Roberts, city administrator in Phenix City. as saying "We are in the Central
277
+# time zone, but we do go by the Eastern time zone because so many people work
278
+# in Columbus."
279
+
280
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
281
+Rule	NYC	1920	only	-	Mar	lastSun	2:00	1:00	D
282
+Rule	NYC	1920	only	-	Oct	lastSun	2:00	0	S
283
+Rule	NYC	1921	1966	-	Apr	lastSun	2:00	1:00	D
284
+Rule	NYC	1921	1954	-	Sep	lastSun	2:00	0	S
285
+Rule	NYC	1955	1966	-	Oct	lastSun	2:00	0	S
286
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
287
+Zone America/New_York	-4:56:02 -	LMT	1883 Nov 18 12:03:58
288
+			-5:00	US	E%sT	1920
289
+			-5:00	NYC	E%sT	1942
290
+			-5:00	US	E%sT	1946
291
+			-5:00	NYC	E%sT	1967
292
+			-5:00	US	E%sT
293
+
294
+# US central time, represented by Chicago
295
+
296
+# Alabama, Arkansas, Florida panhandle (Bay, Calhoun, Escambia,
297
+# Gulf, Holmes, Jackson, Okaloosa, Santa Rosa, Walton, and
298
+# Washington counties), Illinois, western Indiana
299
+# (Gibson, Jasper, Lake, LaPorte, Newton, Porter, Posey, Spencer,
300
+# Vanderburgh, and Warrick counties), Iowa, most of Kansas, western
301
+# Kentucky, Louisiana, Minnesota, Mississippi, Missouri, eastern
302
+# Nebraska, eastern North Dakota, Oklahoma, eastern South Dakota,
303
+# western Tennessee, most of Texas, Wisconsin
304
+
305
+# From Larry M. Smith (2006-04-26) re Wisconsin:
306
+# http://www.legis.state.wi.us/statutes/Stat0175.pdf ...
307
+# is currently enforced at the 01:00 time of change.  Because the local
308
+# "bar time" in the state corresponds to 02:00, a number of citations
309
+# are issued for the "sale of class 'B' alcohol after prohibited
310
+# hours" within the deviated hour of this change every year....
311
+#
312
+# From Douglas R. Bomberg (2007-03-12):
313
+# Wisconsin has enacted (nearly eleventh-hour) legislation to get WI
314
+# Statue 175 closer in synch with the US Congress' intent....
315
+# http://www.legis.state.wi.us/2007/data/acts/07Act3.pdf
316
+
317
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
318
+Rule	Chicago	1920	only	-	Jun	13	2:00	1:00	D
319
+Rule	Chicago	1920	1921	-	Oct	lastSun	2:00	0	S
320
+Rule	Chicago	1921	only	-	Mar	lastSun	2:00	1:00	D
321
+Rule	Chicago	1922	1966	-	Apr	lastSun	2:00	1:00	D
322
+Rule	Chicago	1922	1954	-	Sep	lastSun	2:00	0	S
323
+Rule	Chicago	1955	1966	-	Oct	lastSun	2:00	0	S
324
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
325
+Zone America/Chicago	-5:50:36 -	LMT	1883 Nov 18 12:09:24
326
+			-6:00	US	C%sT	1920
327
+			-6:00	Chicago	C%sT	1936 Mar  1 2:00
328
+			-5:00	-	EST	1936 Nov 15 2:00
329
+			-6:00	Chicago	C%sT	1942
330
+			-6:00	US	C%sT	1946
331
+			-6:00	Chicago	C%sT	1967
332
+			-6:00	US	C%sT
333
+# Oliver County, ND switched from mountain to central time on 1992-10-25.
334
+Zone America/North_Dakota/Center -6:45:12 - LMT	1883 Nov 18 12:14:48
335
+			-7:00	US	M%sT	1992 Oct 25 02:00
336
+			-6:00	US	C%sT
337
+# Morton County, ND, switched from mountain to central time on
338
+# 2003-10-26, except for the area around Mandan which was already central time.
339
+# See <http://dmses.dot.gov/docimages/p63/135818.pdf>.
340
+# Officially this switch also included part of Sioux County, and
341
+# Jones, Mellette, and Todd Counties in South Dakota;
342
+# but in practice these other counties were already observing central time.
343
+# See <http://www.epa.gov/fedrgstr/EPA-IMPACT/2003/October/Day-28/i27056.htm>.
344
+Zone America/North_Dakota/New_Salem -6:45:39 - LMT 1883 Nov 18 12:14:21
345
+			-7:00	US	M%sT	2003 Oct 26 02:00
346
+			-6:00	US	C%sT
347
+
348
+# From Josh Findley (2011-01-21):
349
+# ...it appears that Mercer County, North Dakota, changed from the
350
+# mountain time zone to the central time zone at the last transition from
351
+# daylight-saving to standard time (on Nov. 7, 2010):
352
+# <a href="http://www.gpo.gov/fdsys/pkg/FR-2010-09-29/html/2010-24376.htm">
353
+# http://www.gpo.gov/fdsys/pkg/FR-2010-09-29/html/2010-24376.htm
354
+# </a>
355
+# <a href="http://www.bismarcktribune.com/news/local/article_1eb1b588-c758-11df-b472-001cc4c03286.html">
356
+# http://www.bismarcktribune.com/news/local/article_1eb1b588-c758-11df-b472-001cc4c03286.html
357
+# </a>
358
+
359
+# From Andy Lipscomb (2011-01-24):
360
+# ...according to the Census Bureau, the largest city is Beulah (although
361
+# it's commonly referred to as Beulah-Hazen, with Hazen being the next
362
+# largest city in Mercer County).  Google Maps places Beulah's city hall
363
+# at 4715'51" north, 10146'40" west, which yields an offset of 6h47'07".
364
+
365
+Zone America/North_Dakota/Beulah -6:47:07 - LMT 1883 Nov 18 12:12:53
366
+			-7:00	US	M%sT	2010 Nov  7 2:00
367
+			-6:00	US	C%sT
368
+
369
+# US mountain time, represented by Denver
370
+#
371
+# Colorado, far western Kansas, Montana, western
372
+# Nebraska, Nevada border (Jackpot, Owyhee, and Mountain City),
373
+# New Mexico, southwestern North Dakota,
374
+# western South Dakota, far western Texas (El Paso County, Hudspeth County,
375
+# and Pine Springs and Nickel Creek in Culberson County), Utah, Wyoming
376
+#
377
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
378
+Rule	Denver	1920	1921	-	Mar	lastSun	2:00	1:00	D
379
+Rule	Denver	1920	only	-	Oct	lastSun	2:00	0	S
380
+Rule	Denver	1921	only	-	May	22	2:00	0	S
381
+Rule	Denver	1965	1966	-	Apr	lastSun	2:00	1:00	D
382
+Rule	Denver	1965	1966	-	Oct	lastSun	2:00	0	S
383
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
384
+Zone America/Denver	-6:59:56 -	LMT	1883 Nov 18 12:00:04
385
+			-7:00	US	M%sT	1920
386
+			-7:00	Denver	M%sT	1942
387
+			-7:00	US	M%sT	1946
388
+			-7:00	Denver	M%sT	1967
389
+			-7:00	US	M%sT
390
+
391
+# US Pacific time, represented by Los Angeles
392
+#
393
+# California, northern Idaho (Benewah, Bonner, Boundary, Clearwater,
394
+# Idaho, Kootenai, Latah, Lewis, Nez Perce, and Shoshone counties,
395
+# and the northern three-quarters of Idaho county),
396
+# most of Nevada, most of Oregon, and Washington
397
+#
398
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
399
+Rule	CA	1948	only	-	Mar	14	2:00	1:00	D
400
+Rule	CA	1949	only	-	Jan	 1	2:00	0	S
401
+Rule	CA	1950	1966	-	Apr	lastSun	2:00	1:00	D
402
+Rule	CA	1950	1961	-	Sep	lastSun	2:00	0	S
403
+Rule	CA	1962	1966	-	Oct	lastSun	2:00	0	S
404
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
405
+Zone America/Los_Angeles -7:52:58 -	LMT	1883 Nov 18 12:07:02
406
+			-8:00	US	P%sT	1946
407
+			-8:00	CA	P%sT	1967
408
+			-8:00	US	P%sT
409
+
410
+# Alaska
411
+# AK%sT is the modern abbreviation for -9:00 per USNO.
412
+#
413
+# From Paul Eggert (2001-05-30):
414
+# Howse writes that Alaska switched from the Julian to the Gregorian calendar,
415
+# and from east-of-GMT to west-of-GMT days, when the US bought it from Russia.
416
+# This was on 1867-10-18, a Friday; the previous day was 1867-10-06 Julian,
417
+# also a Friday.  Include only the time zone part of this transition,
418
+# ignoring the switch from Julian to Gregorian, since we can't represent
419
+# the Julian calendar.
420
+#
421
+# As far as we know, none of the exact locations mentioned below were
422
+# permanently inhabited in 1867 by anyone using either calendar.
423
+# (Yakutat was colonized by the Russians in 1799, but the settlement
424
+# was destroyed in 1805 by a Yakutat-kon war party.)  However, there
425
+# were nearby inhabitants in some cases and for our purposes perhaps
426
+# it's best to simply use the official transition.
427
+#
428
+
429
+# From Steve Ferguson (2011-01-31):
430
+# The author lives in Alaska and many of the references listed are only
431
+# available to Alaskan residents.
432
+#
433
+# <a href="http://www.alaskahistoricalsociety.org/index.cfm?section=discover%20alaska&page=Glimpses%20of%20the%20Past&viewpost=2&ContentId=98">
434
+# http://www.alaskahistoricalsociety.org/index.cfm?section=discover%20alaska&page=Glimpses%20of%20the%20Past&viewpost=2&ContentId=98
435
+# </a>
436
+
437
+# From Arthur David Olson (2011-02-01):
438
+# Here's database-relevant material from the 2001 "Alaska History" article:
439
+#
440
+# On September 20 [1979]...DOT...officials decreed that on April 27,
441
+# 1980, Juneau and other nearby communities would move to Yukon Time.
442
+# Sitka, Petersburg, Wrangell, and Ketchikan, however, would remain on
443
+# Pacific Time.
444
+#
445
+# ...on September 22, 1980, DOT Secretary Neil E. Goldschmidt rescinded the
446
+# Department's September 1979 decision. Juneau and other communities in
447
+# northern Southeast reverted to Pacific Time on October 26.
448
+#
449
+# On October 28 [1983]...the Metlakatla Indian Community Council voted
450
+# unanimously to keep the reservation on Pacific Time.
451
+#
452
+# According to DOT official Joanne Petrie, Indian reservations are not
453
+# bound to follow time zones imposed by neighboring jurisdictions.
454
+#
455
+# (The last is consistent with how the database now handles the Navajo
456
+# Nation.)
457
+
458
+# From Arthur David Olson (2011-02-09):
459
+# I just spoke by phone with a staff member at the Metlakatla Indian
460
+# Community office (using contact information available at
461
+# <a href="http://www.commerce.state.ak.us/dca/commdb/CIS.cfm?Comm_Boro_name=Metlakatla">
462
+# http://www.commerce.state.ak.us/dca/commdb/CIS.cfm?Comm_Boro_name=Metlakatla
463
+# </a>).
464
+# It's shortly after 1:00 here on the east coast of the United States;
465
+# the staffer said it was shortly after 10:00 there. When I asked whether
466
+# that meant they were on Pacific time, they said no--they were on their
467
+# own time. I asked about daylight saving; they said it wasn't used. I
468
+# did not inquire about practices in the past.
469
+
470
+# From Arthur David Olson (2011-08-17):
471
+# For lack of better information, assume that Metlakatla's
472
+# abandonment of use of daylight saving resulted from the 1983 vote.
473
+
474
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
475
+Zone America/Juneau	 15:02:19 -	LMT	1867 Oct 18
476
+			 -8:57:41 -	LMT	1900 Aug 20 12:00
477
+			 -8:00	-	PST	1942
478
+			 -8:00	US	P%sT	1946
479
+			 -8:00	-	PST	1969
480
+			 -8:00	US	P%sT	1980 Apr 27 2:00
481
+			 -9:00	US	Y%sT	1980 Oct 26 2:00
482
+			 -8:00	US	P%sT	1983 Oct 30 2:00
483
+			 -9:00	US	Y%sT	1983 Nov 30
484
+			 -9:00	US	AK%sT
485
+Zone America/Sitka	 14:58:47 -	LMT	1867 Oct 18
486
+			 -9:01:13 -	LMT	1900 Aug 20 12:00
487
+			 -8:00	-	PST	1942
488
+			 -8:00	US	P%sT	1946
489
+			 -8:00	-	PST	1969
490
+			 -8:00	US	P%sT	1983 Oct 30 2:00
491
+			 -9:00	US	Y%sT	1983 Nov 30
492
+			 -9:00	US	AK%sT
493
+Zone America/Metlakatla	 15:13:42 -	LMT	1867 Oct 18
494
+			 -8:46:18 -	LMT	1900 Aug 20 12:00
495
+			 -8:00	-	PST	1942
496
+			 -8:00	US	P%sT	1946
497
+			 -8:00	-	PST	1969
498
+			 -8:00	US	P%sT	1983 Oct 30 2:00
499
+			 -8:00	-	MeST
500
+Zone America/Yakutat	 14:41:05 -	LMT	1867 Oct 18
501
+			 -9:18:55 -	LMT	1900 Aug 20 12:00
502
+			 -9:00	-	YST	1942
503
+			 -9:00	US	Y%sT	1946
504
+			 -9:00	-	YST	1969
505
+			 -9:00	US	Y%sT	1983 Nov 30
506
+			 -9:00	US	AK%sT
507
+Zone America/Anchorage	 14:00:24 -	LMT	1867 Oct 18
508
+			 -9:59:36 -	LMT	1900 Aug 20 12:00
509
+			-10:00	-	CAT	1942
510
+			-10:00	US	CAT/CAWT 1945 Aug 14 23:00u
511
+			-10:00	US	CAT/CAPT 1946 # Peace
512
+			-10:00	-	CAT	1967 Apr
513
+			-10:00	-	AHST	1969
514
+			-10:00	US	AH%sT	1983 Oct 30 2:00
515
+			 -9:00	US	Y%sT	1983 Nov 30
516
+			 -9:00	US	AK%sT
517
+Zone America/Nome	 12:58:21 -	LMT	1867 Oct 18
518
+			-11:01:38 -	LMT	1900 Aug 20 12:00
519
+			-11:00	-	NST	1942
520
+			-11:00	US	N%sT	1946
521
+			-11:00	-	NST	1967 Apr
522
+			-11:00	-	BST	1969
523
+			-11:00	US	B%sT	1983 Oct 30 2:00
524
+			 -9:00	US	Y%sT	1983 Nov 30
525
+			 -9:00	US	AK%sT
526
+Zone America/Adak	 12:13:21 -	LMT	1867 Oct 18
527
+			-11:46:38 -	LMT	1900 Aug 20 12:00
528
+			-11:00	-	NST	1942
529
+			-11:00	US	N%sT	1946
530
+			-11:00	-	NST	1967 Apr
531
+			-11:00	-	BST	1969
532
+			-11:00	US	B%sT	1983 Oct 30 2:00
533
+			-10:00	US	AH%sT	1983 Nov 30
534
+			-10:00	US	HA%sT
535
+# The following switches don't quite make our 1970 cutoff.
536
+#
537
+# Shanks writes that part of southwest Alaska (e.g. Aniak)
538
+# switched from -11:00 to -10:00 on 1968-09-22 at 02:00,
539
+# and another part (e.g. Akiak) made the same switch five weeks later.
540
+#
541
+# From David Flater (2004-11-09):
542
+# In e-mail, 2004-11-02, Ray Hudson, historian/liaison to the Unalaska
543
+# Historic Preservation Commission, provided this information, which
544
+# suggests that Unalaska deviated from statutory time from early 1967
545
+# possibly until 1983:
546
+#
547
+#  Minutes of the Unalaska City Council Meeting, January 10, 1967:
548
+#  "Except for St. Paul and Akutan, Unalaska is the only important
549
+#  location not on Alaska Standard Time.  The following resolution was
550
+#  made by William Robinson and seconded by Henry Swanson:  Be it
551
+#  resolved that the City of Unalaska hereby goes to Alaska Standard
552
+#  Time as of midnight Friday, January 13, 1967 (1 A.M. Saturday,
553
+#  January 14, Alaska Standard Time.)  This resolution was passed with
554
+#  three votes for and one against."
555
+
556
+# Hawaii
557
+
558
+# From Arthur David Olson (2010-12-09):
559
+# "Hawaiian Time" by Robert C. Schmitt and Doak C. Cox appears on pages 207-225
560
+# of volume 26 of The Hawaiian Journal of History (1992). As of 2010-12-09,
561
+# the article is available at
562
+# <a href="http://evols.library.manoa.hawaii.edu/bitstream/10524/239/2/JL26215.pdf">
563
+# http://evols.library.manoa.hawaii.edu/bitstream/10524/239/2/JL26215.pdf
564
+# </a>
565
+# and indicates that standard time was adopted effective noon, January
566
+# 13, 1896 (page 218), that in "1933, the Legislature decreed daylight
567
+# saving for the period between the last Sunday of each April and the
568
+# last Sunday of each September, but less than a month later repealed the
569
+# act," (page 220), that year-round daylight saving time was in effect
570
+# from 1942-02-09 to 1945-09-30 (page 221, with no time of day given for
571
+# when clocks changed) and that clocks were changed by 30 minutes
572
+# effective the second Sunday of June, 1947 (page 219, with no time of
573
+# day given for when clocks changed). A footnote for the 1933 changes
574
+# cites Session Laws of Hawaii 1933, "Act. 90 (approved 26 Apr. 1933)
575
+# and Act 163 (approved 21 May 1933)."
576
+
577
+# From Arthur David Olson (2011-01-19):
578
+# The following is from "Laws of the Territory of Hawaii Passed by the
579
+# Seventeenth Legislature: Regular Session 1933," available (as of
580
+# 2011-01-19) at American University's Pence Law Library. Page 85: "Act
581
+# 90...At 2 o'clock ante meridian of the last Sunday in April of each
582
+# year, the standard time of this Territory shall be advanced one
583
+# hour...This Act shall take effect upon its approval. Approved this 26th
584
+# day of April, A. D. 1933. LAWRENCE M JUDD, Governor of the Territory of
585
+# Hawaii." Page 172:  "Act 163...Act 90 of the Session Laws of 1933 is
586
+# hereby repealed...This Act shall take effect upon its approval, upon
587
+# which date the standard time of this Territory shall be restored to
588
+# that existing immediately prior to the taking effect of said Act 90.
589
+# Approved this 21st day of May, A. D. 1933. LAWRENCE M. JUDD, Governor
590
+# of the Territory of Hawaii."
591
+#
592
+# Note that 1933-05-21 was a Sunday.
593
+# We're left to guess the time of day when Act 163 was approved; guess noon.
594
+
595
+Zone Pacific/Honolulu	-10:31:26 -	LMT	1896 Jan 13 12:00 #Schmitt&Cox
596
+			-10:30	-	HST	1933 Apr 30 2:00 #Laws 1933
597
+			-10:30	1:00	HDT	1933 May 21 12:00 #Laws 1933+12
598
+			-10:30	-	HST	1942 Feb 09 2:00 #Schmitt&Cox+2
599
+			-10:30	1:00	HDT	1945 Sep 30 2:00 #Schmitt&Cox+2
600
+			-10:30	-	HST	1947 Jun  8 2:00 #Schmitt&Cox+2
601
+			-10:00	-	HST
602
+
603
+# Now we turn to US areas that have diverged from the consensus since 1970.
604
+
605
+# Arizona mostly uses MST.
606
+
607
+# From Paul Eggert (2002-10-20):
608
+#
609
+# The information in the rest of this paragraph is derived from the
610
+# <a href="http://www.dlapr.lib.az.us/links/daylight.htm">
611
+# Daylight Saving Time web page (2002-01-23)</a> maintained by the
612
+# Arizona State Library, Archives and Public Records.
613
+# Between 1944-01-01 and 1944-04-01 the State of Arizona used standard
614
+# time, but by federal law railroads, airlines, bus lines, military
615
+# personnel, and some engaged in interstate commerce continued to
616
+# observe war (i.e., daylight saving) time.  The 1944-03-17 Phoenix
617
+# Gazette says that was the date the law changed, and that 04-01 was
618
+# the date the state's clocks would change.  In 1945 the State of
619
+# Arizona used standard time all year, again with exceptions only as
620
+# mandated by federal law.  Arizona observed DST in 1967, but Arizona
621
+# Laws 1968, ch. 183 (effective 1968-03-21) repealed DST.
622
+#
623
+# Shanks says the 1944 experiment came to an end on 1944-03-17.
624
+# Go with the Arizona State Library instead.
625
+
626
+Zone America/Phoenix	-7:28:18 -	LMT	1883 Nov 18 11:31:42
627
+			-7:00	US	M%sT	1944 Jan  1 00:01
628
+			-7:00	-	MST	1944 Apr  1 00:01
629
+			-7:00	US	M%sT	1944 Oct  1 00:01
630
+			-7:00	-	MST	1967
631
+			-7:00	US	M%sT	1968 Mar 21
632
+			-7:00	-	MST
633
+# From Arthur David Olson (1988-02-13):
634
+# A writer from the Inter Tribal Council of Arizona, Inc.,
635
+# notes in private correspondence dated 1987-12-28 that "Presently, only the
636
+# Navajo Nation participates in the Daylight Saving Time policy, due to its
637
+# large size and location in three states."  (The "only" means that other
638
+# tribal nations don't use DST.)
639
+
640
+Link America/Denver America/Shiprock
641
+
642
+# Southern Idaho (Ada, Adams, Bannock, Bear Lake, Bingham, Blaine,
643
+# Boise, Bonneville, Butte, Camas, Canyon, Caribou, Cassia, Clark,
644
+# Custer, Elmore, Franklin, Fremont, Gem, Gooding, Jefferson, Jerome,
645
+# Lemhi, Lincoln, Madison, Minidoka, Oneida, Owyhee, Payette, Power,
646
+# Teton, Twin Falls, Valley, Washington counties, and the southern
647
+# quarter of Idaho county) and eastern Oregon (most of Malheur County)
648
+# switched four weeks late in 1974.
649
+#
650
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
651
+Zone America/Boise	-7:44:49 -	LMT	1883 Nov 18 12:15:11
652
+			-8:00	US	P%sT	1923 May 13 2:00
653
+			-7:00	US	M%sT	1974
654
+			-7:00	-	MST	1974 Feb  3 2:00
655
+			-7:00	US	M%sT
656
+
657
+# Indiana
658
+#
659
+# For a map of Indiana's time zone regions, see:
660
+# <a href="http://www.mccsc.edu/time.html">
661
+# What time is it in Indiana?
662
+# </a> (2006-03-01)
663
+#
664
+# From Paul Eggert (2007-08-17):
665
+# Since 1970, most of Indiana has been like America/Indiana/Indianapolis,
666
+# with the following exceptions:
667
+#
668
+# - Gibson, Jasper, Lake, LaPorte, Newton, Porter, Posey, Spencer,
669
+#   Vandenburgh, and Warrick counties have been like America/Chicago.
670
+#
671
+# - Dearborn and Ohio counties have been like America/New_York.
672
+#
673
+# - Clark, Floyd, and Harrison counties have been like
674
+#   America/Kentucky/Louisville.
675
+#
676
+# - Crawford, Daviess, Dubois, Knox, Martin, Perry, Pike, Pulaski, Starke,
677
+#   and Switzerland counties have their own time zone histories as noted below.
678
+#
679
+# Shanks partitioned Indiana into 345 regions, each with its own time history,
680
+# and wrote ``Even newspaper reports present contradictory information.''
681
+# Those Hoosiers!  Such a flighty and changeable people!
682
+# Fortunately, most of the complexity occurred before our cutoff date of 1970.
683
+#
684
+# Other than Indianapolis, the Indiana place names are so nondescript
685
+# that they would be ambiguous if we left them at the `America' level.
686
+# So we reluctantly put them all in a subdirectory `America/Indiana'.
687
+
688
+# From Paul Eggert (2005-08-16):
689
+# http://www.mccsc.edu/time.html says that Indiana will use DST starting 2006.
690
+
691
+# From Nathan Stratton Treadway (2006-03-30):
692
+# http://www.dot.gov/affairs/dot0406.htm [3705 B]
693
+# From Deborah Goldsmith (2006-01-18):
694
+# http://dmses.dot.gov/docimages/pdf95/382329_web.pdf [2.9 MB]
695
+# From Paul Eggert (2006-01-20):
696
+# It says "DOT is relocating the time zone boundary in Indiana to move Starke,
697
+# Pulaski, Knox, Daviess, Martin, Pike, Dubois, and Perry Counties from the
698
+# Eastern Time Zone to the Central Time Zone.... The effective date of
699
+# this rule is 2:OO a.m. EST Sunday, April 2, 2006, which is the
700
+# changeover date from standard time to Daylight Saving Time."
701
+# Strictly speaking, this means the affected counties will change their
702
+# clocks twice that night, but this obviously is in error.  The intent
703
+# is that 01:59:59 EST be followed by 02:00:00 CDT.
704
+
705
+# From Gwillim Law (2007-02-10):
706
+# The Associated Press has been reporting that Pulaski County, Indiana is
707
+# going to switch from Central to Eastern Time on March 11, 2007....
708
+# http://www.indystar.com/apps/pbcs.dll/article?AID=/20070207/LOCAL190108/702070524/0/LOCAL
709
+
710
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
711
+Rule Indianapolis 1941	only	-	Jun	22	2:00	1:00	D
712
+Rule Indianapolis 1941	1954	-	Sep	lastSun	2:00	0	S
713
+Rule Indianapolis 1946	1954	-	Apr	lastSun	2:00	1:00	D
714
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
715
+Zone America/Indiana/Indianapolis -5:44:38 - LMT 1883 Nov 18 12:15:22
716
+			-6:00	US	C%sT	1920
717
+			-6:00 Indianapolis C%sT	1942
718
+			-6:00	US	C%sT	1946
719
+			-6:00 Indianapolis C%sT	1955 Apr 24 2:00
720
+			-5:00	-	EST	1957 Sep 29 2:00
721
+			-6:00	-	CST	1958 Apr 27 2:00
722
+			-5:00	-	EST	1969
723
+			-5:00	US	E%sT	1971
724
+			-5:00	-	EST	2006
725
+			-5:00	US	E%sT
726
+#
727
+# Eastern Crawford County, Indiana, left its clocks alone in 1974,
728
+# as well as from 1976 through 2005.
729
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
730
+Rule	Marengo	1951	only	-	Apr	lastSun	2:00	1:00	D
731
+Rule	Marengo	1951	only	-	Sep	lastSun	2:00	0	S
732
+Rule	Marengo	1954	1960	-	Apr	lastSun	2:00	1:00	D
733
+Rule	Marengo	1954	1960	-	Sep	lastSun	2:00	0	S
734
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
735
+Zone America/Indiana/Marengo -5:45:23 -	LMT	1883 Nov 18 12:14:37
736
+			-6:00	US	C%sT	1951
737
+			-6:00	Marengo	C%sT	1961 Apr 30 2:00
738
+			-5:00	-	EST	1969
739
+			-5:00	US	E%sT	1974 Jan  6 2:00
740
+			-6:00	1:00	CDT	1974 Oct 27 2:00
741
+			-5:00	US	E%sT	1976
742
+			-5:00	-	EST	2006
743
+			-5:00	US	E%sT
744
+#
745
+# Daviess, Dubois, Knox, and Martin Counties, Indiana,
746
+# switched from eastern to central time in April 2006, then switched back
747
+# in November 2007.
748
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
749
+Rule Vincennes	1946	only	-	Apr	lastSun	2:00	1:00	D
750
+Rule Vincennes	1946	only	-	Sep	lastSun	2:00	0	S
751
+Rule Vincennes	1953	1954	-	Apr	lastSun	2:00	1:00	D
752
+Rule Vincennes	1953	1959	-	Sep	lastSun	2:00	0	S
753
+Rule Vincennes	1955	only	-	May	 1	0:00	1:00	D
754
+Rule Vincennes	1956	1963	-	Apr	lastSun	2:00	1:00	D
755
+Rule Vincennes	1960	only	-	Oct	lastSun	2:00	0	S
756
+Rule Vincennes	1961	only	-	Sep	lastSun	2:00	0	S
757
+Rule Vincennes	1962	1963	-	Oct	lastSun	2:00	0	S
758
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
759
+Zone America/Indiana/Vincennes -5:50:07 - LMT	1883 Nov 18 12:09:53
760
+			-6:00	US	C%sT	1946
761
+			-6:00 Vincennes	C%sT	1964 Apr 26 2:00
762
+			-5:00	-	EST	1969
763
+			-5:00	US	E%sT	1971
764
+			-5:00	-	EST	2006 Apr  2 2:00
765
+			-6:00	US	C%sT	2007 Nov  4 2:00
766
+			-5:00	US	E%sT
767
+#
768
+# Perry County, Indiana, switched from eastern to central time in April 2006.
769
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
770
+Rule Perry	1946	only	-	Apr	lastSun	2:00	1:00	D
771
+Rule Perry	1946	only	-	Sep	lastSun	2:00	0	S
772
+Rule Perry	1953	1954	-	Apr	lastSun	2:00	1:00	D
773
+Rule Perry	1953	1959	-	Sep	lastSun	2:00	0	S
774
+Rule Perry	1955	only	-	May	 1	0:00	1:00	D
775
+Rule Perry	1956	1963	-	Apr	lastSun	2:00	1:00	D
776
+Rule Perry	1960	only	-	Oct	lastSun	2:00	0	S
777
+Rule Perry	1961	only	-	Sep	lastSun	2:00	0	S
778
+Rule Perry	1962	1963	-	Oct	lastSun	2:00	0	S
779
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
780
+Zone America/Indiana/Tell_City -5:47:03 - LMT	1883 Nov 18 12:12:57
781
+			-6:00	US	C%sT	1946
782
+			-6:00 Perry	C%sT	1964 Apr 26 2:00
783
+			-5:00	-	EST	1969
784
+			-5:00	US	E%sT	1971
785
+			-5:00	-	EST	2006 Apr  2 2:00
786
+			-6:00	US	C%sT
787
+#
788
+# Pike County, Indiana moved from central to eastern time in 1977,
789
+# then switched back in 2006, then switched back again in 2007.
790
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
791
+Rule	Pike	1955	only	-	May	 1	0:00	1:00	D
792
+Rule	Pike	1955	1960	-	Sep	lastSun	2:00	0	S
793
+Rule	Pike	1956	1964	-	Apr	lastSun	2:00	1:00	D
794
+Rule	Pike	1961	1964	-	Oct	lastSun	2:00	0	S
795
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
796
+Zone America/Indiana/Petersburg -5:49:07 - LMT	1883 Nov 18 12:10:53
797
+			-6:00	US	C%sT	1955
798
+			-6:00	Pike	C%sT	1965 Apr 25 2:00
799
+			-5:00	-	EST	1966 Oct 30 2:00
800
+			-6:00	US	C%sT	1977 Oct 30 2:00
801
+			-5:00	-	EST	2006 Apr  2 2:00
802
+			-6:00	US	C%sT	2007 Nov  4 2:00
803
+			-5:00	US	E%sT
804
+#
805
+# Starke County, Indiana moved from central to eastern time in 1991,
806
+# then switched back in 2006.
807
+# From Arthur David Olson (1991-10-28):
808
+# An article on page A3 of the Sunday, 1991-10-27 Washington Post
809
+# notes that Starke County switched from Central time to Eastern time as of
810
+# 1991-10-27.
811
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
812
+Rule	Starke	1947	1961	-	Apr	lastSun	2:00	1:00	D
813
+Rule	Starke	1947	1954	-	Sep	lastSun	2:00	0	S
814
+Rule	Starke	1955	1956	-	Oct	lastSun	2:00	0	S
815
+Rule	Starke	1957	1958	-	Sep	lastSun	2:00	0	S
816
+Rule	Starke	1959	1961	-	Oct	lastSun	2:00	0	S
817
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
818
+Zone America/Indiana/Knox -5:46:30 -	LMT	1883 Nov 18 12:13:30
819
+			-6:00	US	C%sT	1947
820
+			-6:00	Starke	C%sT	1962 Apr 29 2:00
821
+			-5:00	-	EST	1963 Oct 27 2:00
822
+			-6:00	US	C%sT	1991 Oct 27 2:00
823
+			-5:00	-	EST	2006 Apr  2 2:00
824
+			-6:00	US	C%sT
825
+#
826
+# Pulaski County, Indiana, switched from eastern to central time in
827
+# April 2006 and then switched back in March 2007.
828
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
829
+Rule	Pulaski	1946	1960	-	Apr	lastSun	2:00	1:00	D
830
+Rule	Pulaski	1946	1954	-	Sep	lastSun	2:00	0	S
831
+Rule	Pulaski	1955	1956	-	Oct	lastSun	2:00	0	S
832
+Rule	Pulaski	1957	1960	-	Sep	lastSun	2:00	0	S
833
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
834
+Zone America/Indiana/Winamac -5:46:25 - LMT	1883 Nov 18 12:13:35
835
+			-6:00	US	C%sT	1946
836
+			-6:00	Pulaski	C%sT	1961 Apr 30 2:00
837
+			-5:00	-	EST	1969
838
+			-5:00	US	E%sT	1971
839
+			-5:00	-	EST	2006 Apr  2 2:00
840
+			-6:00	US	C%sT	2007 Mar 11 2:00
841
+			-5:00	US	E%sT
842
+#
843
+# Switzerland County, Indiana, did not observe DST from 1973 through 2005.
844
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
845
+Zone America/Indiana/Vevay -5:40:16 -	LMT	1883 Nov 18 12:19:44
846
+			-6:00	US	C%sT	1954 Apr 25 2:00
847
+			-5:00	-	EST	1969
848
+			-5:00	US	E%sT	1973
849
+			-5:00	-	EST	2006
850
+			-5:00	US	E%sT
851
+
852
+# Part of Kentucky left its clocks alone in 1974.
853
+# This also includes Clark, Floyd, and Harrison counties in Indiana.
854
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
855
+Rule Louisville	1921	only	-	May	1	2:00	1:00	D
856
+Rule Louisville	1921	only	-	Sep	1	2:00	0	S
857
+Rule Louisville	1941	1961	-	Apr	lastSun	2:00	1:00	D
858
+Rule Louisville	1941	only	-	Sep	lastSun	2:00	0	S
859
+Rule Louisville	1946	only	-	Jun	2	2:00	0	S
860
+Rule Louisville	1950	1955	-	Sep	lastSun	2:00	0	S
861
+Rule Louisville	1956	1960	-	Oct	lastSun	2:00	0	S
862
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
863
+Zone America/Kentucky/Louisville -5:43:02 -	LMT	1883 Nov 18 12:16:58
864
+			-6:00	US	C%sT	1921
865
+			-6:00 Louisville C%sT	1942
866
+			-6:00	US	C%sT	1946
867
+			-6:00 Louisville C%sT	1961 Jul 23 2:00
868
+			-5:00	-	EST	1968
869
+			-5:00	US	E%sT	1974 Jan  6 2:00
870
+			-6:00	1:00	CDT	1974 Oct 27 2:00
871
+			-5:00	US	E%sT
872
+#
873
+# Wayne County, Kentucky
874
+#
875
+# From
876
+# <a href="http://www.lake-cumberland.com/life/archive/news990129time.shtml">
877
+# Lake Cumberland LIFE
878
+# </a> (1999-01-29) via WKYM-101.7:
879
+# Clinton County has joined Wayne County in asking the DoT to change from
880
+# the Central to the Eastern time zone....  The Wayne County government made
881
+# the same request in December.  And while Russell County officials have not
882
+# taken action, the majority of respondents to a poll conducted there in
883
+# August indicated they would like to change to "fast time" also.
884
+# The three Lake Cumberland counties are the farthest east of any U.S.
885
+# location in the Central time zone.
886
+#
887
+# From Rich Wales (2000-08-29):
888
+# After prolonged debate, and despite continuing deep differences of opinion,
889
+# Wayne County (central Kentucky) is switching from Central (-0600) to Eastern
890
+# (-0500) time.  They won't "fall back" this year.  See Sara Shipley,
891
+# The difference an hour makes, Nando Times (2000-08-29 15:33 -0400).
892
+#
893
+# From Paul Eggert (2001-07-16):
894
+# The final rule was published in the
895
+# <a href="http://frwebgate.access.gpo.gov/cgi-bin/getdoc.cgi?dbname=2000_register&docid=fr17au00-22">
896
+# Federal Register 65, 160 (2000-08-17), page 50154-50158.
897
+# </a>
898
+#
899
+Zone America/Kentucky/Monticello -5:39:24 - LMT	1883 Nov 18 12:20:36
900
+			-6:00	US	C%sT	1946
901
+			-6:00	-	CST	1968
902
+			-6:00	US	C%sT	2000 Oct 29  2:00
903
+			-5:00	US	E%sT
904
+
905
+
906
+# From Rives McDow (2000-08-30):
907
+# Here ... are all the changes in the US since 1985.
908
+# Kearny County, KS (put all of county on central;
909
+#	previously split between MST and CST) ... 1990-10
910
+# Starke County, IN (from CST to EST) ... 1991-10
911
+# Oliver County, ND (from MST to CST) ... 1992-10
912
+# West Wendover, NV (from PST TO MST) ... 1999-10
913
+# Wayne County, KY (from CST to EST) ... 2000-10
914
+#
915
+# From Paul Eggert (2001-07-17):
916
+# We don't know where the line used to be within Kearny County, KS,
917
+# so omit that change for now.
918
+# See America/Indiana/Knox for the Starke County, IN change.
919
+# See America/North_Dakota/Center for the Oliver County, ND change.
920
+# West Wendover, NV officially switched from Pacific to mountain time on
921
+# 1999-10-31.  See the
922
+# <a href="http://frwebgate.access.gpo.gov/cgi-bin/getdoc.cgi?dbname=1999_register&docid=fr21oc99-15">
923
+# Federal Register 64, 203 (1999-10-21), page 56705-56707.
924
+# </a>
925
+# However, the Federal Register says that West Wendover already operated
926
+# on mountain time, and the rule merely made this official;
927
+# hence a separate tz entry is not needed.
928
+
929
+# Michigan
930
+#
931
+# From Bob Devine (1988-01-28):
932
+# Michigan didn't observe DST from 1968 to 1973.
933
+#
934
+# From Paul Eggert (1999-03-31):
935
+# Shanks writes that Michigan started using standard time on 1885-09-18,
936
+# but Howse writes (pp 124-125, referring to Popular Astronomy, 1901-01)
937
+# that Detroit kept
938
+#
939
+#	local time until 1900 when the City Council decreed that clocks should
940
+#	be put back twenty-eight minutes to Central Standard Time.  Half the
941
+#	city obeyed, half refused.  After considerable debate, the decision
942
+#	was rescinded and the city reverted to Sun time.  A derisive offer to
943
+#	erect a sundial in front of the city hall was referred to the
944
+#	Committee on Sewers.  Then, in 1905, Central time was adopted
945
+#	by city vote.
946
+#
947
+# This story is too entertaining to be false, so go with Howse over Shanks.
948
+#
949
+# From Paul Eggert (2001-03-06):
950
+# Garland (1927) writes ``Cleveland and Detroit advanced their clocks
951
+# one hour in 1914.''  This change is not in Shanks.  We have no more
952
+# info, so omit this for now.
953
+#
954
+# Most of Michigan observed DST from 1973 on, but was a bit late in 1975.
955
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
956
+Rule	Detroit	1948	only	-	Apr	lastSun	2:00	1:00	D
957
+Rule	Detroit	1948	only	-	Sep	lastSun	2:00	0	S
958
+Rule	Detroit	1967	only	-	Jun	14	2:00	1:00	D
959
+Rule	Detroit	1967	only	-	Oct	lastSun	2:00	0	S
960
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
961
+Zone America/Detroit	-5:32:11 -	LMT	1905
962
+			-6:00	-	CST	1915 May 15 2:00
963
+			-5:00	-	EST	1942
964
+			-5:00	US	E%sT	1946
965
+			-5:00	Detroit	E%sT	1973
966
+			-5:00	US	E%sT	1975
967
+			-5:00	-	EST	1975 Apr 27 2:00
968
+			-5:00	US	E%sT
969
+#
970
+# Dickinson, Gogebic, Iron, and Menominee Counties, Michigan,
971
+# switched from EST to CST/CDT in 1973.
972
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
973
+Rule Menominee	1946	only	-	Apr	lastSun	2:00	1:00	D
974
+Rule Menominee	1946	only	-	Sep	lastSun	2:00	0	S
975
+Rule Menominee	1966	only	-	Apr	lastSun	2:00	1:00	D
976
+Rule Menominee	1966	only	-	Oct	lastSun	2:00	0	S
977
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
978
+Zone America/Menominee	-5:50:27 -	LMT	1885 Sep 18 12:00
979
+			-6:00	US	C%sT	1946
980
+			-6:00 Menominee	C%sT	1969 Apr 27 2:00
981
+			-5:00	-	EST	1973 Apr 29 2:00
982
+			-6:00	US	C%sT
983
+
984
+# Navassa
985
+# administered by the US Fish and Wildlife Service
986
+# claimed by US under the provisions of the 1856 Guano Islands Act
987
+# also claimed by Haiti
988
+# occupied 1857/1900 by the Navassa Phosphate Co
989
+# US lighthouse 1917/1996-09
990
+# currently uninhabited
991
+# see Mark Fineman, ``An Isle Rich in Guano and Discord'',
992
+# _Los Angeles Times_ (1998-11-10), A1, A10; it cites
993
+# Jimmy Skaggs, _The Great Guano Rush_ (1994).
994
+
995
+################################################################################
996
+
997
+
998
+# From Paul Eggert (2006-03-22):
999
+# A good source for time zone historical data outside the U.S. is
1000
+# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
1001
+# San Diego: ACS Publications, Inc. (2003).
1002
+#
1003
+# Gwillim Law writes that a good source
1004
+# for recent time zone data is the International Air Transport
1005
+# Association's Standard Schedules Information Manual (IATA SSIM),
1006
+# published semiannually.  Law sent in several helpful summaries
1007
+# of the IATA's data after 1990.
1008
+#
1009
+# Except where otherwise noted, Shanks & Pottenger is the source for
1010
+# entries through 1990, and IATA SSIM is the source for entries afterwards.
1011
+#
1012
+# Other sources occasionally used include:
1013
+#
1014
+#	Edward W. Whitman, World Time Differences,
1015
+#	Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated),
1016
+#	which I found in the UCLA library.
1017
+#
1018
+#	<a href="http://www.pettswoodvillage.co.uk/Daylight_Savings_William_Willett.pdf">
1019
+#	William Willett, The Waste of Daylight, 19th edition
1020
+#	</a> (1914-03)
1021
+#
1022
+# See the `europe' file for Greenland.
1023
+
1024
+# Canada
1025
+
1026
+# From Alain LaBont<e'> (1994-11-14):
1027
+# I post here the time zone abbreviations standardized in Canada
1028
+# for both English and French in the CAN/CSA-Z234.4-89 standard....
1029
+#
1030
+#	UTC	Standard time	Daylight savings time
1031
+#	offset	French	English	French	English
1032
+#	-2:30	-	-	HAT	NDT
1033
+#	-3	-	-	HAA	ADT
1034
+#	-3:30	HNT	NST	-	-
1035
+#	-4	HNA	AST	HAE	EDT
1036
+#	-5	HNE	EST	HAC	CDT
1037
+#	-6	HNC	CST	HAR	MDT
1038
+#	-7	HNR	MST	HAP	PDT
1039
+#	-8	HNP	PST	HAY	YDT
1040
+#	-9	HNY	YST	-	-
1041
+#
1042
+#	HN: Heure Normale	ST: Standard Time
1043
+#	HA: Heure Avanc<e'>e	DT: Daylight saving Time
1044
+#
1045
+#	A: de l'Atlantique	Atlantic
1046
+#	C: du Centre		Central
1047
+#	E: de l'Est		Eastern
1048
+#	M:			Mountain
1049
+#	N:			Newfoundland
1050
+#	P: du Pacifique		Pacific
1051
+#	R: des Rocheuses
1052
+#	T: de Terre-Neuve
1053
+#	Y: du Yukon		Yukon
1054
+#
1055
+# From Paul Eggert (1994-11-22):
1056
+# Alas, this sort of thing must be handled by localization software.
1057
+
1058
+# Unless otherwise specified, the data for Canada are all from Shanks
1059
+# & Pottenger.
1060
+
1061
+# From Chris Walton (2006-04-01, 2006-04-25, 2006-06-26, 2007-01-31,
1062
+# 2007-03-01):
1063
+# The British Columbia government announced yesterday that it will
1064
+# adjust daylight savings next year to align with changes in the
1065
+# U.S. and the rest of Canada....
1066
+# http://www2.news.gov.bc.ca/news_releases_2005-2009/2006AG0014-000330.htm
1067
+# ...
1068
+# Nova Scotia
1069
+# Daylight saving time will be extended by four weeks starting in 2007....
1070
+# http://www.gov.ns.ca/just/regulations/rg2/2006/ma1206.pdf
1071
+#
1072
+# [For New Brunswick] the new legislation dictates that the time change is to
1073
+# be done at 02:00 instead of 00:01.
1074
+# http://www.gnb.ca/0062/acts/BBA-2006/Chap-19.pdf
1075
+# ...
1076
+# Manitoba has traditionally changed the clock every fall at 03:00.
1077
+# As of 2006, the transition is to take place one hour earlier at 02:00.
1078
+# http://web2.gov.mb.ca/laws/statutes/ccsm/o030e.php
1079
+# ...
1080
+# [Alberta, Ontario, Quebec] will follow US rules.
1081
+# http://www.qp.gov.ab.ca/documents/spring/CH03_06.CFM
1082
+# http://www.e-laws.gov.on.ca/DBLaws/Source/Regs/English/2006/R06111_e.htm
1083
+# http://www2.publicationsduquebec.gouv.qc.ca/dynamicSearch/telecharge.php?type=5&file=2006C39A.PDF
1084
+# ...
1085
+# P.E.I. will follow US rules....
1086
+# http://www.assembly.pe.ca/bills/pdf_chapter/62/3/chapter-41.pdf
1087
+# ...
1088
+# Province of Newfoundland and Labrador....
1089
+# http://www.hoa.gov.nl.ca/hoa/bills/Bill0634.htm
1090
+# ...
1091
+# Yukon
1092
+# http://www.gov.yk.ca/legislation/regs/oic2006_127.pdf
1093
+# ...
1094
+# N.W.T. will follow US rules.  Whoever maintains the government web site
1095
+# does not seem to believe in bookmarks.  To see the news release, click the
1096
+# following link and search for "Daylight Savings Time Change".  Press the
1097
+# "Daylight Savings Time Change" link; it will fire off a popup using
1098
+# JavaScript.
1099
+# http://www.exec.gov.nt.ca/currentnews/currentPR.asp?mode=archive
1100
+# ...
1101
+# Nunavut
1102
+# An amendment to the Interpretation Act was registered on February 19/2007....
1103
+# http://action.attavik.ca/home/justice-gn/attach/2007/gaz02part2.pdf
1104
+
1105
+# From Paul Eggert (2006-04-25):
1106
+# H. David Matthews and Mary Vincent's map
1107
+# <a href="http://www.canadiangeographic.ca/Magazine/SO98/geomap.asp">
1108
+# "It's about TIME", _Canadian Geographic_ (September-October 1998)
1109
+# </a> contains detailed boundaries for regions observing nonstandard
1110
+# time and daylight saving time arrangements in Canada circa 1998.
1111
+#
1112
+# INMS, the Institute for National Measurement Standards in Ottawa, has <a
1113
+# href="http://inms-ienm.nrc-cnrc.gc.ca/en/time_services/daylight_saving_e.php">
1114
+# information about standard and daylight saving time zones in Canada.
1115
+# </a> (updated periodically).
1116
+# Its unofficial information is often taken from Matthews and Vincent.
1117
+
1118
+# From Paul Eggert (2006-06-27):
1119
+# For now, assume all of DST-observing Canada will fall into line with the
1120
+# new US DST rules,
1121
+
1122
+# From Chris Walton (2011-12-01)
1123
+# In the first of Tammy Hardwick's articles
1124
+# <a href="http://www.ilovecreston.com/?p=articles&t=spec&ar=260">
1125
+# http://www.ilovecreston.com/?p=articles&t=spec&ar=260
1126
+# </a>
1127
+# she quotes the Friday November 1/1918 edition of the Creston Review.
1128
+# The quote includes these two statements:
1129
+# 'Sunday the CPR went back to the old system of time...'
1130
+# '... The daylight saving scheme was dropped all over Canada at the same time,'
1131
+# These statements refer to a transition from daylight time to standard time
1132
+# that occurred nationally on Sunday October 27/1918.  This transition was
1133
+# also documented in the Saturday October 26/1918 edition of the Toronto Star.
1134
+
1135
+# In light of that evidence, we alter the date from the earlier believed
1136
+# Oct 31, to Oct 27, 1918 (and Sunday is a more likely transition day
1137
+# than Thursday) in all Canadian rulesets.
1138
+
1139
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1140
+Rule	Canada	1918	only	-	Apr	14	2:00	1:00	D
1141
+Rule	Canada	1918	only	-	Oct	27	2:00	0	S
1142
+Rule	Canada	1942	only	-	Feb	 9	2:00	1:00	W # War
1143
+Rule	Canada	1945	only	-	Aug	14	23:00u	1:00	P # Peace
1144
+Rule	Canada	1945	only	-	Sep	30	2:00	0	S
1145
+Rule	Canada	1974	1986	-	Apr	lastSun	2:00	1:00	D
1146
+Rule	Canada	1974	2006	-	Oct	lastSun	2:00	0	S
1147
+Rule	Canada	1987	2006	-	Apr	Sun>=1	2:00	1:00	D
1148
+Rule	Canada	2007	max	-	Mar	Sun>=8	2:00	1:00	D
1149
+Rule	Canada	2007	max	-	Nov	Sun>=1	2:00	0	S
1150
+
1151
+
1152
+# Newfoundland and Labrador
1153
+
1154
+# From Paul Eggert (2000-10-02):
1155
+# Matthews and Vincent (1998) write that Labrador should use NST/NDT,
1156
+# but the only part of Labrador that follows the rules is the
1157
+# southeast corner, including Port Hope Simpson and Mary's Harbour,
1158
+# but excluding, say, Black Tickle.
1159
+
1160
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1161
+Rule	StJohns	1917	only	-	Apr	 8	2:00	1:00	D
1162
+Rule	StJohns	1917	only	-	Sep	17	2:00	0	S
1163
+# Whitman gives 1919 Apr 5 and 1920 Apr 5; go with Shanks & Pottenger.
1164
+Rule	StJohns	1919	only	-	May	 5	23:00	1:00	D
1165
+Rule	StJohns	1919	only	-	Aug	12	23:00	0	S
1166
+# For 1931-1935 Whitman gives Apr same date; go with Shanks & Pottenger.
1167
+Rule	StJohns	1920	1935	-	May	Sun>=1	23:00	1:00	D
1168
+Rule	StJohns	1920	1935	-	Oct	lastSun	23:00	0	S
1169
+# For 1936-1941 Whitman gives May Sun>=8 and Oct Sun>=1; go with Shanks &
1170
+# Pottenger.
1171
+Rule	StJohns	1936	1941	-	May	Mon>=9	0:00	1:00	D
1172
+Rule	StJohns	1936	1941	-	Oct	Mon>=2	0:00	0	S
1173
+# Whitman gives the following transitions:
1174
+# 1942 03-01/12-31, 1943 05-30/09-05, 1944 07-10/09-02, 1945 01-01/10-07
1175
+# but go with Shanks & Pottenger and assume they used Canadian rules.
1176
+# For 1946-9 Whitman gives May 5,4,9,1 - Oct 1,5,3,2, and for 1950 he gives
1177
+# Apr 30 - Sep 24; go with Shanks & Pottenger.
1178
+Rule	StJohns	1946	1950	-	May	Sun>=8	2:00	1:00	D
1179
+Rule	StJohns	1946	1950	-	Oct	Sun>=2	2:00	0	S
1180
+Rule	StJohns	1951	1986	-	Apr	lastSun	2:00	1:00	D
1181
+Rule	StJohns	1951	1959	-	Sep	lastSun	2:00	0	S
1182
+Rule	StJohns	1960	1986	-	Oct	lastSun	2:00	0	S
1183
+# From Paul Eggert (2000-10-02):
1184
+# INMS (2000-09-12) says that, since 1988 at least, Newfoundland switches
1185
+# at 00:01 local time.  For now, assume it started in 1987.
1186
+
1187
+# From Michael Pelley (2011-09-12):
1188
+# We received today, Monday, September 12, 2011, notification that the
1189
+# changes to the Newfoundland Standard Time Act have been proclaimed.
1190
+# The change in the Act stipulates that the change from Daylight Savings
1191
+# Time to Standard Time and from Standard Time to Daylight Savings Time
1192
+# now occurs at 2:00AM.
1193
+# ...
1194
+# <a href="http://www.assembly.nl.ca/legislation/sr/annualstatutes/2011/1106.chp.htm">
1195
+# http://www.assembly.nl.ca/legislation/sr/annualstatutes/2011/1106.chp.htm
1196
+# </a>
1197
+# ...
1198
+# MICHAEL PELLEY  |  Manager of Enterprise Architecture - Solution Delivery
1199
+# Office of the Chief Information Officer
1200
+# Executive Council
1201
+# Government of Newfoundland & Labrador
1202
+
1203
+Rule	StJohns	1987	only	-	Apr	Sun>=1	0:01	1:00	D
1204
+Rule	StJohns	1987	2006	-	Oct	lastSun	0:01	0	S
1205
+Rule	StJohns	1988	only	-	Apr	Sun>=1	0:01	2:00	DD
1206
+Rule	StJohns	1989	2006	-	Apr	Sun>=1	0:01	1:00	D
1207
+Rule	StJohns	2007	2011	-	Mar	Sun>=8	0:01	1:00	D
1208
+Rule	StJohns	2007	2010	-	Nov	Sun>=1	0:01	0	S
1209
+#
1210
+# St John's has an apostrophe, but Posix file names can't have apostrophes.
1211
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1212
+Zone America/St_Johns	-3:30:52 -	LMT	1884
1213
+			-3:30:52 StJohns N%sT	1918
1214
+			-3:30:52 Canada	N%sT	1919
1215
+			-3:30:52 StJohns N%sT	1935 Mar 30
1216
+			-3:30	StJohns	N%sT	1942 May 11
1217
+			-3:30	Canada	N%sT	1946
1218
+			-3:30	StJohns	N%sT	2011 Nov
1219
+			-3:30	Canada	N%sT
1220
+
1221
+# most of east Labrador
1222
+
1223
+# The name `Happy Valley-Goose Bay' is too long; use `Goose Bay'.
1224
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1225
+Zone America/Goose_Bay	-4:01:40 -	LMT	1884 # Happy Valley-Goose Bay
1226
+			-3:30:52 -	NST	1918
1227
+			-3:30:52 Canada N%sT	1919
1228
+			-3:30:52 -	NST	1935 Mar 30
1229
+			-3:30	-	NST	1936
1230
+			-3:30	StJohns	N%sT	1942 May 11
1231
+			-3:30	Canada	N%sT	1946
1232
+			-3:30	StJohns	N%sT	1966 Mar 15 2:00
1233
+			-4:00	StJohns	A%sT	2011 Nov
1234
+			-4:00	Canada	A%sT
1235
+
1236
+
1237
+# west Labrador, Nova Scotia, Prince Edward I
1238
+
1239
+# From Paul Eggert (2006-03-22):
1240
+# Shanks & Pottenger write that since 1970 most of this region has been like
1241
+# Halifax.  Many locales did not observe peacetime DST until 1972;
1242
+# Glace Bay, NS is the largest that we know of.
1243
+# Shanks & Pottenger also write that Liverpool, NS was the only town
1244
+# in Canada to observe DST in 1971 but not 1970; for now we'll assume
1245
+# this is a typo.
1246
+
1247
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1248
+Rule	Halifax	1916	only	-	Apr	 1	0:00	1:00	D
1249
+Rule	Halifax	1916	only	-	Oct	 1	0:00	0	S
1250
+Rule	Halifax	1920	only	-	May	 9	0:00	1:00	D
1251
+Rule	Halifax	1920	only	-	Aug	29	0:00	0	S
1252
+Rule	Halifax	1921	only	-	May	 6	0:00	1:00	D
1253
+Rule	Halifax	1921	1922	-	Sep	 5	0:00	0	S
1254
+Rule	Halifax	1922	only	-	Apr	30	0:00	1:00	D
1255
+Rule	Halifax	1923	1925	-	May	Sun>=1	0:00	1:00	D
1256
+Rule	Halifax	1923	only	-	Sep	 4	0:00	0	S
1257
+Rule	Halifax	1924	only	-	Sep	15	0:00	0	S
1258
+Rule	Halifax	1925	only	-	Sep	28	0:00	0	S
1259
+Rule	Halifax	1926	only	-	May	16	0:00	1:00	D
1260
+Rule	Halifax	1926	only	-	Sep	13	0:00	0	S
1261
+Rule	Halifax	1927	only	-	May	 1	0:00	1:00	D
1262
+Rule	Halifax	1927	only	-	Sep	26	0:00	0	S
1263
+Rule	Halifax	1928	1931	-	May	Sun>=8	0:00	1:00	D
1264
+Rule	Halifax	1928	only	-	Sep	 9	0:00	0	S
1265
+Rule	Halifax	1929	only	-	Sep	 3	0:00	0	S
1266
+Rule	Halifax	1930	only	-	Sep	15	0:00	0	S
1267
+Rule	Halifax	1931	1932	-	Sep	Mon>=24	0:00	0	S
1268
+Rule	Halifax	1932	only	-	May	 1	0:00	1:00	D
1269
+Rule	Halifax	1933	only	-	Apr	30	0:00	1:00	D
1270
+Rule	Halifax	1933	only	-	Oct	 2	0:00	0	S
1271
+Rule	Halifax	1934	only	-	May	20	0:00	1:00	D
1272
+Rule	Halifax	1934	only	-	Sep	16	0:00	0	S
1273
+Rule	Halifax	1935	only	-	Jun	 2	0:00	1:00	D
1274
+Rule	Halifax	1935	only	-	Sep	30	0:00	0	S
1275
+Rule	Halifax	1936	only	-	Jun	 1	0:00	1:00	D
1276
+Rule	Halifax	1936	only	-	Sep	14	0:00	0	S
1277
+Rule	Halifax	1937	1938	-	May	Sun>=1	0:00	1:00	D
1278
+Rule	Halifax	1937	1941	-	Sep	Mon>=24	0:00	0	S
1279
+Rule	Halifax	1939	only	-	May	28	0:00	1:00	D
1280
+Rule	Halifax	1940	1941	-	May	Sun>=1	0:00	1:00	D
1281
+Rule	Halifax	1946	1949	-	Apr	lastSun	2:00	1:00	D
1282
+Rule	Halifax	1946	1949	-	Sep	lastSun	2:00	0	S
1283
+Rule	Halifax	1951	1954	-	Apr	lastSun	2:00	1:00	D
1284
+Rule	Halifax	1951	1954	-	Sep	lastSun	2:00	0	S
1285
+Rule	Halifax	1956	1959	-	Apr	lastSun	2:00	1:00	D
1286
+Rule	Halifax	1956	1959	-	Sep	lastSun	2:00	0	S
1287
+Rule	Halifax	1962	1973	-	Apr	lastSun	2:00	1:00	D
1288
+Rule	Halifax	1962	1973	-	Oct	lastSun	2:00	0	S
1289
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1290
+Zone America/Halifax	-4:14:24 -	LMT	1902 Jun 15
1291
+			-4:00	Halifax	A%sT	1918
1292
+			-4:00	Canada	A%sT	1919
1293
+			-4:00	Halifax	A%sT	1942 Feb  9 2:00s
1294
+			-4:00	Canada	A%sT	1946
1295
+			-4:00	Halifax	A%sT	1974
1296
+			-4:00	Canada	A%sT
1297
+Zone America/Glace_Bay	-3:59:48 -	LMT	1902 Jun 15
1298
+			-4:00	Canada	A%sT	1953
1299
+			-4:00	Halifax	A%sT	1954
1300
+			-4:00	-	AST	1972
1301
+			-4:00	Halifax	A%sT	1974
1302
+			-4:00	Canada	A%sT
1303
+
1304
+# New Brunswick
1305
+
1306
+# From Paul Eggert (2007-01-31):
1307
+# The Time Definition Act <http://www.gnb.ca/0062/PDF-acts/t-06.pdf>
1308
+# says they changed at 00:01 through 2006, and
1309
+# <http://www.canlii.org/nb/laws/sta/t-6/20030127/whole.html> makes it
1310
+# clear that this was the case since at least 1993.
1311
+# For now, assume it started in 1993.
1312
+
1313
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1314
+Rule	Moncton	1933	1935	-	Jun	Sun>=8	1:00	1:00	D
1315
+Rule	Moncton	1933	1935	-	Sep	Sun>=8	1:00	0	S
1316
+Rule	Moncton	1936	1938	-	Jun	Sun>=1	1:00	1:00	D
1317
+Rule	Moncton	1936	1938	-	Sep	Sun>=1	1:00	0	S
1318
+Rule	Moncton	1939	only	-	May	27	1:00	1:00	D
1319
+Rule	Moncton	1939	1941	-	Sep	Sat>=21	1:00	0	S
1320
+Rule	Moncton	1940	only	-	May	19	1:00	1:00	D
1321
+Rule	Moncton	1941	only	-	May	 4	1:00	1:00	D
1322
+Rule	Moncton	1946	1972	-	Apr	lastSun	2:00	1:00	D
1323
+Rule	Moncton	1946	1956	-	Sep	lastSun	2:00	0	S
1324
+Rule	Moncton	1957	1972	-	Oct	lastSun	2:00	0	S
1325
+Rule	Moncton	1993	2006	-	Apr	Sun>=1	0:01	1:00	D
1326
+Rule	Moncton	1993	2006	-	Oct	lastSun	0:01	0	S
1327
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1328
+Zone America/Moncton	-4:19:08 -	LMT	1883 Dec  9
1329
+			-5:00	-	EST	1902 Jun 15
1330
+			-4:00	Canada	A%sT	1933
1331
+			-4:00	Moncton	A%sT	1942
1332
+			-4:00	Canada	A%sT	1946
1333
+			-4:00	Moncton	A%sT	1973
1334
+			-4:00	Canada	A%sT	1993
1335
+			-4:00	Moncton	A%sT	2007
1336
+			-4:00	Canada	A%sT
1337
+
1338
+# Quebec
1339
+
1340
+# From Paul Eggert (2006-07-09):
1341
+# Shanks & Pottenger write that since 1970 most of Quebec has been
1342
+# like Montreal.
1343
+
1344
+# From Paul Eggert (2006-06-27):
1345
+# Matthews and Vincent (1998) also write that Quebec east of the -63
1346
+# meridian is supposed to observe AST, but residents as far east as
1347
+# Natashquan use EST/EDT, and residents east of Natashquan use AST.
1348
+# In "Official time in Quebec" the Quebec department of justice writes in
1349
+# http://www.justice.gouv.qc.ca/english/publications/generale/temps-regl-1-a.htm
1350
+# that "The residents of the Municipality of the
1351
+# Cote-Nord-du-Golfe-Saint-Laurent and the municipalities of Saint-Augustin,
1352
+# Bonne-Esperance and Blanc-Sablon apply the Official Time Act as it is
1353
+# written and use Atlantic standard time all year round. The same applies to
1354
+# the residents of the Native facilities along the lower North Shore."
1355
+# <http://www.assnat.qc.ca/eng/37legislature2/Projets-loi/Publics/06-a002.htm>
1356
+# says this common practice was codified into law as of 2007.
1357
+# For lack of better info, guess this practice began around 1970, contra to
1358
+# Shanks & Pottenger who have this region observing AST/ADT.
1359
+
1360
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1361
+Rule	Mont	1917	only	-	Mar	25	2:00	1:00	D
1362
+Rule	Mont	1917	only	-	Apr	24	0:00	0	S
1363
+Rule	Mont	1919	only	-	Mar	31	2:30	1:00	D
1364
+Rule	Mont	1919	only	-	Oct	25	2:30	0	S
1365
+Rule	Mont	1920	only	-	May	 2	2:30	1:00	D
1366
+Rule	Mont	1920	1922	-	Oct	Sun>=1	2:30	0	S
1367
+Rule	Mont	1921	only	-	May	 1	2:00	1:00	D
1368
+Rule	Mont	1922	only	-	Apr	30	2:00	1:00	D
1369
+Rule	Mont	1924	only	-	May	17	2:00	1:00	D
1370
+Rule	Mont	1924	1926	-	Sep	lastSun	2:30	0	S
1371
+Rule	Mont	1925	1926	-	May	Sun>=1	2:00	1:00	D
1372
+# The 1927-to-1937 rules can be expressed more simply as
1373
+# Rule	Mont	1927	1937	-	Apr	lastSat	24:00	1:00	D
1374
+# Rule	Mont	1927	1937	-	Sep	lastSat	24:00	0	S
1375
+# The rules below avoid use of 24:00
1376
+# (which pre-1998 versions of zic cannot handle).
1377
+Rule	Mont	1927	only	-	May	1	0:00	1:00	D
1378
+Rule	Mont	1927	1932	-	Sep	lastSun	0:00	0	S
1379
+Rule	Mont	1928	1931	-	Apr	lastSun	0:00	1:00	D
1380
+Rule	Mont	1932	only	-	May	1	0:00	1:00	D
1381
+Rule	Mont	1933	1940	-	Apr	lastSun	0:00	1:00	D
1382
+Rule	Mont	1933	only	-	Oct	1	0:00	0	S
1383
+Rule	Mont	1934	1939	-	Sep	lastSun	0:00	0	S
1384
+Rule	Mont	1946	1973	-	Apr	lastSun	2:00	1:00	D
1385
+Rule	Mont	1945	1948	-	Sep	lastSun	2:00	0	S
1386
+Rule	Mont	1949	1950	-	Oct	lastSun	2:00	0	S
1387
+Rule	Mont	1951	1956	-	Sep	lastSun	2:00	0	S
1388
+Rule	Mont	1957	1973	-	Oct	lastSun	2:00	0	S
1389
+
1390
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1391
+Zone America/Blanc-Sablon -3:48:28 -	LMT	1884
1392
+			-4:00	Canada	A%sT	1970
1393
+			-4:00	-	AST
1394
+Zone America/Montreal	-4:54:16 -	LMT	1884
1395
+			-5:00	Mont	E%sT	1918
1396
+			-5:00	Canada	E%sT	1919
1397
+			-5:00	Mont	E%sT	1942 Feb  9 2:00s
1398
+			-5:00	Canada	E%sT	1946
1399
+			-5:00	Mont	E%sT	1974
1400
+			-5:00	Canada	E%sT
1401
+
1402
+
1403
+# Ontario
1404
+
1405
+# From Paul Eggert (2006-07-09):
1406
+# Shanks & Pottenger write that since 1970 most of Ontario has been like
1407
+# Toronto.
1408
+# Thunder Bay skipped DST in 1973.
1409
+# Many smaller locales did not observe peacetime DST until 1974;
1410
+# Nipigon (EST) and Rainy River (CST) are the largest that we know of.
1411
+# Far west Ontario is like Winnipeg; far east Quebec is like Halifax.
1412
+
1413
+# From Mark Brader (2003-07-26):
1414
+# [According to the Toronto Star] Orillia, Ontario, adopted DST
1415
+# effective Saturday, 1912-06-22, 22:00; the article mentions that
1416
+# Port Arthur (now part of Thunder Bay, Ontario) as well as Moose Jaw
1417
+# have already done so.  In Orillia DST was to run until Saturday,
1418
+# 1912-08-31 (no time mentioned), but it was met with considerable
1419
+# hostility from certain segments of the public, and was revoked after
1420
+# only two weeks -- I copied it as Saturday, 1912-07-07, 22:00, but
1421
+# presumably that should be -07-06.  (1912-06-19, -07-12; also letters
1422
+# earlier in June).
1423
+#
1424
+# Kenora, Ontario, was to abandon DST on 1914-06-01 (-05-21).
1425
+
1426
+# From Paul Eggert (1997-10-17):
1427
+# Mark Brader writes that an article in the 1997-10-14 Toronto Star
1428
+# says that Atikokan, Ontario currently does not observe DST,
1429
+# but will vote on 11-10 whether to use EST/EDT.
1430
+# He also writes that the
1431
+# <a href="http://www.gov.on.ca/MBS/english/publications/statregs/conttext.html">
1432
+# Ontario Time Act (1990, Chapter T.9)
1433
+# </a>
1434
+# says that Ontario east of 90W uses EST/EDT, and west of 90W uses CST/CDT.
1435
+# Officially Atikokan is therefore on CST/CDT, and most likely this report
1436
+# concerns a non-official time observed as a matter of local practice.
1437
+#
1438
+# From Paul Eggert (2000-10-02):
1439
+# Matthews and Vincent (1998) write that Atikokan, Pickle Lake, and
1440
+# New Osnaburgh observe CST all year, that Big Trout Lake observes
1441
+# CST/CDT, and that Upsala and Shebandowan observe EST/EDT, all in
1442
+# violation of the official Ontario rules.
1443
+#
1444
+# From Paul Eggert (2006-07-09):
1445
+# Chris Walton (2006-07-06) mentioned an article by Stephanie MacLellan in the
1446
+# 2005-07-21 Chronicle-Journal, which said:
1447
+#
1448
+#	The clocks in Atikokan stay set on standard time year-round.
1449
+#	This means they spend about half the time on central time and
1450
+#	the other half on eastern time.
1451
+#
1452
+#	For the most part, the system works, Mayor Dennis Brown said.
1453
+#
1454
+#	"The majority of businesses in Atikokan deal more with Eastern
1455
+#	Canada, but there are some that deal with Western Canada," he
1456
+#	said.  "I don't see any changes happening here."
1457
+#
1458
+# Walton also writes "Supposedly Pickle Lake and Mishkeegogamang
1459
+# [New Osnaburgh] follow the same practice."
1460
+
1461
+# From Garry McKinnon (2006-07-14) via Chris Walton:
1462
+# I chatted with a member of my board who has an outstanding memory
1463
+# and a long history in Atikokan (and in the telecom industry) and he
1464
+# can say for certain that Atikokan has been practicing the current
1465
+# time keeping since 1952, at least.
1466
+
1467
+# From Paul Eggert (2006-07-17):
1468
+# Shanks & Pottenger say that Atikokan has agreed with Rainy River
1469
+# ever since standard time was introduced, but the information from
1470
+# McKinnon sounds more authoritative.  For now, assume that Atikokan
1471
+# switched to EST immediately after WWII era daylight saving time
1472
+# ended.  This matches the old (less-populous) America/Coral_Harbour
1473
+# entry since our cutoff date of 1970, so we can move
1474
+# America/Coral_Harbour to the 'backward' file.
1475
+
1476
+# From Mark Brader (2010-03-06):
1477
+#
1478
+# Currently the database has:
1479
+#
1480
+# # Ontario
1481
+#
1482
+# # From Paul Eggert (2006-07-09):
1483
+# # Shanks & Pottenger write that since 1970 most of Ontario has been like
1484
+# # Toronto.
1485
+# # Thunder Bay skipped DST in 1973.
1486
+# # Many smaller locales did not observe peacetime DST until 1974;
1487
+# # Nipigon (EST) and Rainy River (CST) are the largest that we know of.
1488
+#
1489
+# In the (Toronto) Globe and Mail for Saturday, 1955-09-24, in the bottom
1490
+# right corner of page 1, it says that Toronto will return to standard
1491
+# time at 2 am Sunday morning (which agrees with the database), and that:
1492
+#
1493
+#     The one-hour setback will go into effect throughout most of Ontario,
1494
+#     except in areas like Windsor which remains on standard time all year.
1495
+#
1496
+# Windsor is, of course, a lot larger than Nipigon.
1497
+#
1498
+# I only came across this incidentally.  I don't know if Windsor began
1499
+# observing DST when Detroit did, or in 1974, or on some other date.
1500
+#
1501
+# By the way, the article continues by noting that:
1502
+#
1503
+#     Some cities in the United States have pushed the deadline back
1504
+#     three weeks and will change over from daylight saving in October.
1505
+
1506
+# From Arthur David Olson (2010-07-17):
1507
+#
1508
+# "Standard Time and Time Zones in Canada" appeared in
1509
+# The Journal of The Royal Astronomical Society of Canada,
1510
+# volume 26, number 2 (February 1932) and, as of 2010-07-17,
1511
+# was available at
1512
+# <a href="http://adsabs.harvard.edu/full/1932JRASC..26...49S">
1513
+# http://adsabs.harvard.edu/full/1932JRASC..26...49S
1514
+# </a>
1515
+#
1516
+# It includes the text below (starting on page 57):
1517
+#
1518
+#   A list of the places in Canada using daylight saving time would
1519
+# require yearly revision. From information kindly furnished by
1520
+# the provincial governments and by the postmasters in many cities
1521
+# and towns, it is found that the following places used daylight sav-
1522
+# ing in 1930. The information for the province of Quebec is definite,
1523
+# for the other provinces only approximate:
1524
+#
1525
+# 	Province	Daylight saving time used
1526
+# Prince Edward Island	Not used.
1527
+# Nova Scotia		In Halifax only.
1528
+# New Brunswick		In St. John only.
1529
+# Quebec		In the following places:
1530
+# 			Montreal	Lachine
1531
+# 			Quebec		Mont-Royal
1532
+# 			Levis		Iberville
1533
+# 			St. Lambert	Cap de la Madeleine
1534
+# 			Verdun		Loretteville
1535
+# 			Westmount	Richmond
1536
+# 			Outremont	St. Jerome
1537
+# 			Longueuil	Greenfield Park
1538
+# 			Arvida		Waterloo
1539
+# 			Chambly-Canton	Beaulieu
1540
+# 			Melbourne	La Tuque
1541
+# 			St. Theophile	Buckingham
1542
+# Ontario		Used generally in the cities and towns along
1543
+# 			the southerly part of the province. Not
1544
+# 			used in the northwesterlhy part.
1545
+# Manitoba		Not used.
1546
+# Saskatchewan		In Regina only.
1547
+# Alberta		Not used.
1548
+# British Columbia	Not used.
1549
+#
1550
+#   With some exceptions, the use of daylight saving may be said to be limited
1551
+# to those cities and towns lying between Quebec city and Windsor, Ont.
1552
+
1553
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1554
+Rule	Toronto	1919	only	-	Mar	30	23:30	1:00	D
1555
+Rule	Toronto	1919	only	-	Oct	26	0:00	0	S
1556
+Rule	Toronto	1920	only	-	May	 2	2:00	1:00	D
1557
+Rule	Toronto	1920	only	-	Sep	26	0:00	0	S
1558
+Rule	Toronto	1921	only	-	May	15	2:00	1:00	D
1559
+Rule	Toronto	1921	only	-	Sep	15	2:00	0	S
1560
+Rule	Toronto	1922	1923	-	May	Sun>=8	2:00	1:00	D
1561
+# Shanks & Pottenger say 1923-09-19; assume it's a typo and that "-16"
1562
+# was meant.
1563
+Rule	Toronto	1922	1926	-	Sep	Sun>=15	2:00	0	S
1564
+Rule	Toronto	1924	1927	-	May	Sun>=1	2:00	1:00	D
1565
+# The 1927-to-1939 rules can be expressed more simply as
1566
+# Rule	Toronto	1927	1937	-	Sep	Sun>=25	2:00	0	S
1567
+# Rule	Toronto	1928	1937	-	Apr	Sun>=25	2:00	1:00	D
1568
+# Rule	Toronto	1938	1940	-	Apr	lastSun	2:00	1:00	D
1569
+# Rule	Toronto	1938	1939	-	Sep	lastSun	2:00	0	S
1570
+# The rules below avoid use of Sun>=25
1571
+# (which pre-2004 versions of zic cannot handle).
1572
+Rule	Toronto	1927	1932	-	Sep	lastSun	2:00	0	S
1573
+Rule	Toronto	1928	1931	-	Apr	lastSun	2:00	1:00	D
1574
+Rule	Toronto	1932	only	-	May	1	2:00	1:00	D
1575
+Rule	Toronto	1933	1940	-	Apr	lastSun	2:00	1:00	D
1576
+Rule	Toronto	1933	only	-	Oct	1	2:00	0	S
1577
+Rule	Toronto	1934	1939	-	Sep	lastSun	2:00	0	S
1578
+Rule	Toronto	1945	1946	-	Sep	lastSun	2:00	0	S
1579
+Rule	Toronto	1946	only	-	Apr	lastSun	2:00	1:00	D
1580
+Rule	Toronto	1947	1949	-	Apr	lastSun	0:00	1:00	D
1581
+Rule	Toronto	1947	1948	-	Sep	lastSun	0:00	0	S
1582
+Rule	Toronto	1949	only	-	Nov	lastSun	0:00	0	S
1583
+Rule	Toronto	1950	1973	-	Apr	lastSun	2:00	1:00	D
1584
+Rule	Toronto	1950	only	-	Nov	lastSun	2:00	0	S
1585
+Rule	Toronto	1951	1956	-	Sep	lastSun	2:00	0	S
1586
+# Shanks & Pottenger say Toronto ended DST a week early in 1971,
1587
+# namely on 1971-10-24, but Mark Brader wrote (2003-05-31) that this
1588
+# is wrong, and that he had confirmed it by checking the 1971-10-30
1589
+# Toronto Star, which said that DST was ending 1971-10-31 as usual.
1590
+Rule	Toronto	1957	1973	-	Oct	lastSun	2:00	0	S
1591
+
1592
+# From Paul Eggert (2003-07-27):
1593
+# Willett (1914-03) writes (p. 17) "In the Cities of Fort William, and
1594
+# Port Arthur, Ontario, the principle of the Bill has been in
1595
+# operation for the past three years, and in the City of Moose Jaw,
1596
+# Saskatchewan, for one year."
1597
+
1598
+# From David Bryan via Tory Tronrud, Director/Curator,
1599
+# Thunder Bay Museum (2003-11-12):
1600
+# There is some suggestion, however, that, by-law or not, daylight
1601
+# savings time was being practiced in Fort William and Port Arthur
1602
+# before 1909.... [I]n 1910, the line between the Eastern and Central
1603
+# Time Zones was permanently moved about two hundred miles west to
1604
+# include the Thunder Bay area....  When Canada adopted daylight
1605
+# savings time in 1916, Fort William and Port Arthur, having done so
1606
+# already, did not change their clocks....  During the Second World
1607
+# War,... [t]he cities agreed to implement DST during the summer
1608
+# months for the remainder of the war years.
1609
+
1610
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1611
+Zone America/Toronto	-5:17:32 -	LMT	1895
1612
+			-5:00	Canada	E%sT	1919
1613
+			-5:00	Toronto	E%sT	1942 Feb  9 2:00s
1614
+			-5:00	Canada	E%sT	1946
1615
+			-5:00	Toronto	E%sT	1974
1616
+			-5:00	Canada	E%sT
1617
+Zone America/Thunder_Bay -5:57:00 -	LMT	1895
1618
+			-6:00	-	CST	1910
1619
+			-5:00	-	EST	1942
1620
+			-5:00	Canada	E%sT	1970
1621
+			-5:00	Mont	E%sT	1973
1622
+			-5:00	-	EST	1974
1623
+			-5:00	Canada	E%sT
1624
+Zone America/Nipigon	-5:53:04 -	LMT	1895
1625
+			-5:00	Canada	E%sT	1940 Sep 29
1626
+			-5:00	1:00	EDT	1942 Feb  9 2:00s
1627
+			-5:00	Canada	E%sT
1628
+Zone America/Rainy_River -6:18:16 -	LMT	1895
1629
+			-6:00	Canada	C%sT	1940 Sep 29
1630
+			-6:00	1:00	CDT	1942 Feb  9 2:00s
1631
+			-6:00	Canada	C%sT
1632
+Zone America/Atikokan	-6:06:28 -	LMT	1895
1633
+			-6:00	Canada	C%sT	1940 Sep 29
1634
+			-6:00	1:00	CDT	1942 Feb  9 2:00s
1635
+			-6:00	Canada	C%sT	1945 Sep 30 2:00
1636
+			-5:00	-	EST
1637
+
1638
+
1639
+# Manitoba
1640
+
1641
+# From Rob Douglas (2006-04-06):
1642
+# the old Manitoba Time Act - as amended by Bill 2, assented to
1643
+# March 27, 1987 ... said ...
1644
+# "between two o'clock Central Standard Time in the morning of
1645
+# the first Sunday of April of each year and two o'clock Central
1646
+# Standard Time in the morning of the last Sunday of October next
1647
+# following, one hour in advance of Central Standard Time."...
1648
+# I believe that the English legislation [of the old time act] had =
1649
+# been assented to (March 22, 1967)....
1650
+# Also, as far as I can tell, there was no order-in-council varying
1651
+# the time of Daylight Saving Time for 2005 and so the provisions of
1652
+# the 1987 version would apply - the changeover was at 2:00 Central
1653
+# Standard Time (i.e. not until 3:00 Central Daylight Time).
1654
+
1655
+# From Paul Eggert (2006-04-10):
1656
+# Shanks & Pottenger say Manitoba switched at 02:00 (not 02:00s)
1657
+# starting 1966.  Since 02:00s is clearly correct for 1967 on, assume
1658
+# it was also 02:00s in 1966.
1659
+
1660
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1661
+Rule	Winn	1916	only	-	Apr	23	0:00	1:00	D
1662
+Rule	Winn	1916	only	-	Sep	17	0:00	0	S
1663
+Rule	Winn	1918	only	-	Apr	14	2:00	1:00	D
1664
+Rule	Winn	1918	only	-	Oct	27	2:00	0	S
1665
+Rule	Winn	1937	only	-	May	16	2:00	1:00	D
1666
+Rule	Winn	1937	only	-	Sep	26	2:00	0	S
1667
+Rule	Winn	1942	only	-	Feb	 9	2:00	1:00	W # War
1668
+Rule	Winn	1945	only	-	Aug	14	23:00u	1:00	P # Peace
1669
+Rule	Winn	1945	only	-	Sep	lastSun	2:00	0	S
1670
+Rule	Winn	1946	only	-	May	12	2:00	1:00	D
1671
+Rule	Winn	1946	only	-	Oct	13	2:00	0	S
1672
+Rule	Winn	1947	1949	-	Apr	lastSun	2:00	1:00	D
1673
+Rule	Winn	1947	1949	-	Sep	lastSun	2:00	0	S
1674
+Rule	Winn	1950	only	-	May	 1	2:00	1:00	D
1675
+Rule	Winn	1950	only	-	Sep	30	2:00	0	S
1676
+Rule	Winn	1951	1960	-	Apr	lastSun	2:00	1:00	D
1677
+Rule	Winn	1951	1958	-	Sep	lastSun	2:00	0	S
1678
+Rule	Winn	1959	only	-	Oct	lastSun	2:00	0	S
1679
+Rule	Winn	1960	only	-	Sep	lastSun	2:00	0	S
1680
+Rule	Winn	1963	only	-	Apr	lastSun	2:00	1:00	D
1681
+Rule	Winn	1963	only	-	Sep	22	2:00	0	S
1682
+Rule	Winn	1966	1986	-	Apr	lastSun	2:00s	1:00	D
1683
+Rule	Winn	1966	2005	-	Oct	lastSun	2:00s	0	S
1684
+Rule	Winn	1987	2005	-	Apr	Sun>=1	2:00s	1:00	D
1685
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1686
+Zone America/Winnipeg	-6:28:36 -	LMT	1887 Jul 16
1687
+			-6:00	Winn	C%sT	2006
1688
+			-6:00	Canada	C%sT
1689
+
1690
+
1691
+# Saskatchewan
1692
+
1693
+# From Mark Brader (2003-07-26):
1694
+# The first actual adoption of DST in Canada was at the municipal
1695
+# level.  As the [Toronto] Star put it (1912-06-07), "While people
1696
+# elsewhere have long been talking of legislation to save daylight,
1697
+# the city of Moose Jaw [Saskatchewan] has acted on its own hook."
1698
+# DST in Moose Jaw began on Saturday, 1912-06-01 (no time mentioned:
1699
+# presumably late evening, as below), and would run until "the end of
1700
+# the summer".  The discrepancy between municipal time and railroad
1701
+# time was noted.
1702
+
1703
+# From Paul Eggert (2003-07-27):
1704
+# Willett (1914-03) notes that DST "has been in operation ... in the
1705
+# City of Moose Jaw, Saskatchewan, for one year."
1706
+
1707
+# From Paul Eggert (2006-03-22):
1708
+# Shanks & Pottenger say that since 1970 this region has mostly been as Regina.
1709
+# Some western towns (e.g. Swift Current) switched from MST/MDT to CST in 1972.
1710
+# Other western towns (e.g. Lloydminster) are like Edmonton.
1711
+# Matthews and Vincent (1998) write that Denare Beach and Creighton
1712
+# are like Winnipeg, in violation of Saskatchewan law.
1713
+
1714
+# From W. Jones (1992-11-06):
1715
+# The. . .below is based on information I got from our law library, the
1716
+# provincial archives, and the provincial Community Services department.
1717
+# A precise history would require digging through newspaper archives, and
1718
+# since you didn't say what you wanted, I didn't bother.
1719
+#
1720
+# Saskatchewan is split by a time zone meridian (105W) and over the years
1721
+# the boundary became pretty ragged as communities near it reevaluated
1722
+# their affiliations in one direction or the other.  In 1965 a provincial
1723
+# referendum favoured legislating common time practices.
1724
+#
1725
+# On 15 April 1966 the Time Act (c. T-14, Revised Statutes of
1726
+# Saskatchewan 1978) was proclaimed, and established that the eastern
1727
+# part of Saskatchewan would use CST year round, that districts in
1728
+# northwest Saskatchewan would by default follow CST but could opt to
1729
+# follow Mountain Time rules (thus 1 hour difference in the winter and
1730
+# zero in the summer), and that districts in southwest Saskatchewan would
1731
+# by default follow MT but could opt to follow CST.
1732
+#
1733
+# It took a few years for the dust to settle (I know one story of a town
1734
+# on one time zone having its school in another, such that a mom had to
1735
+# serve her family lunch in two shifts), but presently it seems that only
1736
+# a few towns on the border with Alberta (e.g. Lloydminster) follow MT
1737
+# rules any more; all other districts appear to have used CST year round
1738
+# since sometime in the 1960s.
1739
+
1740
+# From Chris Walton (2006-06-26):
1741
+# The Saskatchewan time act which was last updated in 1996 is about 30 pages
1742
+# long and rather painful to read.
1743
+# http://www.qp.gov.sk.ca/documents/English/Statutes/Statutes/T14.pdf
1744
+
1745
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1746
+Rule	Regina	1918	only	-	Apr	14	2:00	1:00	D
1747
+Rule	Regina	1918	only	-	Oct	27	2:00	0	S
1748
+Rule	Regina	1930	1934	-	May	Sun>=1	0:00	1:00	D
1749
+Rule	Regina	1930	1934	-	Oct	Sun>=1	0:00	0	S
1750
+Rule	Regina	1937	1941	-	Apr	Sun>=8	0:00	1:00	D
1751
+Rule	Regina	1937	only	-	Oct	Sun>=8	0:00	0	S
1752
+Rule	Regina	1938	only	-	Oct	Sun>=1	0:00	0	S
1753
+Rule	Regina	1939	1941	-	Oct	Sun>=8	0:00	0	S
1754
+Rule	Regina	1942	only	-	Feb	 9	2:00	1:00	W # War
1755
+Rule	Regina	1945	only	-	Aug	14	23:00u	1:00	P # Peace
1756
+Rule	Regina	1945	only	-	Sep	lastSun	2:00	0	S
1757
+Rule	Regina	1946	only	-	Apr	Sun>=8	2:00	1:00	D
1758
+Rule	Regina	1946	only	-	Oct	Sun>=8	2:00	0	S
1759
+Rule	Regina	1947	1957	-	Apr	lastSun	2:00	1:00	D
1760
+Rule	Regina	1947	1957	-	Sep	lastSun	2:00	0	S
1761
+Rule	Regina	1959	only	-	Apr	lastSun	2:00	1:00	D
1762
+Rule	Regina	1959	only	-	Oct	lastSun	2:00	0	S
1763
+#
1764
+Rule	Swift	1957	only	-	Apr	lastSun	2:00	1:00	D
1765
+Rule	Swift	1957	only	-	Oct	lastSun	2:00	0	S
1766
+Rule	Swift	1959	1961	-	Apr	lastSun	2:00	1:00	D
1767
+Rule	Swift	1959	only	-	Oct	lastSun	2:00	0	S
1768
+Rule	Swift	1960	1961	-	Sep	lastSun	2:00	0	S
1769
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1770
+Zone America/Regina	-6:58:36 -	LMT	1905 Sep
1771
+			-7:00	Regina	M%sT	1960 Apr lastSun 2:00
1772
+			-6:00	-	CST
1773
+Zone America/Swift_Current -7:11:20 -	LMT	1905 Sep
1774
+			-7:00	Canada	M%sT	1946 Apr lastSun 2:00
1775
+			-7:00	Regina	M%sT	1950
1776
+			-7:00	Swift	M%sT	1972 Apr lastSun 2:00
1777
+			-6:00	-	CST
1778
+
1779
+
1780
+# Alberta
1781
+
1782
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1783
+Rule	Edm	1918	1919	-	Apr	Sun>=8	2:00	1:00	D
1784
+Rule	Edm	1918	only	-	Oct	27	2:00	0	S
1785
+Rule	Edm	1919	only	-	May	27	2:00	0	S
1786
+Rule	Edm	1920	1923	-	Apr	lastSun	2:00	1:00	D
1787
+Rule	Edm	1920	only	-	Oct	lastSun	2:00	0	S
1788
+Rule	Edm	1921	1923	-	Sep	lastSun	2:00	0	S
1789
+Rule	Edm	1942	only	-	Feb	 9	2:00	1:00	W # War
1790
+Rule	Edm	1945	only	-	Aug	14	23:00u	1:00	P # Peace
1791
+Rule	Edm	1945	only	-	Sep	lastSun	2:00	0	S
1792
+Rule	Edm	1947	only	-	Apr	lastSun	2:00	1:00	D
1793
+Rule	Edm	1947	only	-	Sep	lastSun	2:00	0	S
1794
+Rule	Edm	1967	only	-	Apr	lastSun	2:00	1:00	D
1795
+Rule	Edm	1967	only	-	Oct	lastSun	2:00	0	S
1796
+Rule	Edm	1969	only	-	Apr	lastSun	2:00	1:00	D
1797
+Rule	Edm	1969	only	-	Oct	lastSun	2:00	0	S
1798
+Rule	Edm	1972	1986	-	Apr	lastSun	2:00	1:00	D
1799
+Rule	Edm	1972	2006	-	Oct	lastSun	2:00	0	S
1800
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1801
+Zone America/Edmonton	-7:33:52 -	LMT	1906 Sep
1802
+			-7:00	Edm	M%sT	1987
1803
+			-7:00	Canada	M%sT
1804
+
1805
+
1806
+# British Columbia
1807
+
1808
+# From Paul Eggert (2006-03-22):
1809
+# Shanks & Pottenger write that since 1970 most of this region has
1810
+# been like Vancouver.
1811
+# Dawson Creek uses MST.  Much of east BC is like Edmonton.
1812
+# Matthews and Vincent (1998) write that Creston is like Dawson Creek.
1813
+
1814
+# It seems though that (re: Creston) is not entirely correct:
1815
+
1816
+# From Chris Walton (2011-12-01):
1817
+# There are two areas within the Canadian province of British Columbia
1818
+# that do not currently observe daylight saving:
1819
+# a) The Creston Valley (includes the town of Creston and surrounding area)
1820
+# b) The eastern half of the Peace River Regional District
1821
+# (includes the cities of Dawson Creek and Fort St. John)
1822
+
1823
+# Earlier this year I stumbled across a detailed article about the time
1824
+# keeping history of Creston; it was written by Tammy Hardwick who is the
1825
+# manager of the Creston & District Museum. The article was written in May 2009.
1826
+# <a href="http://www.ilovecreston.com/?p=articles&t=spec&ar=260">
1827
+# http://www.ilovecreston.com/?p=articles&t=spec&ar=260
1828
+# </a>
1829
+# According to the article, Creston has not changed its clocks since June 1918.
1830
+# i.e. Creston has been stuck on UTC-7 for 93 years.
1831
+# Dawson Creek, on the other hand, changed its clocks as recently as April 1972.
1832
+
1833
+# Unfortunately the exact date for the time change in June 1918 remains
1834
+# unknown and will be difficult to ascertain.  I e-mailed Tammy a few months
1835
+# ago to ask if Sunday June 2 was a reasonable guess.  She said it was just
1836
+# as plausible as any other date (in June).  She also said that after writing the
1837
+# article she had discovered another time change in 1916; this is the subject
1838
+# of another article which she wrote in October 2010.
1839
+# <a href="http://www.creston.museum.bc.ca/index.php?module=comments&uop=view_comment&cm+id=56">
1840
+# http://www.creston.museum.bc.ca/index.php?module=comments&uop=view_comment&cm+id=56
1841
+# </a>
1842
+
1843
+# Here is a summary of the three clock change events in Creston's history:
1844
+# 1. 1884 or 1885: adoption of Mountain Standard Time (GMT-7)
1845
+# Exact date unknown
1846
+# 2. Oct 1916: switch to Pacific Standard Time (GMT-8)
1847
+# Exact date in October unknown;  Sunday October 1 is a reasonable guess.
1848
+# 3. June 1918: switch to Pacific Daylight Time (GMT-7)
1849
+# Exact date in June unknown; Sunday June 2 is a reasonable guess.
1850
+# note#1:
1851
+# On Oct 27/1918 when daylight saving ended in the rest of Canada,
1852
+# Creston did not change its clocks.
1853
+# note#2:
1854
+# During WWII when the Federal Government legislated a mandatory clock change,
1855
+# Creston did not oblige.
1856
+# note#3:
1857
+# There is no guarantee that Creston will remain on Mountain Standard Time
1858
+# (UTC-7) forever.
1859
+# The subject was debated at least once this year by the town Council.
1860
+# <a href="http://www.bclocalnews.com/kootenay_rockies/crestonvalleyadvance/news/116760809.html">
1861
+# http://www.bclocalnews.com/kootenay_rockies/crestonvalleyadvance/news/116760809.html
1862
+# </a>
1863
+
1864
+# During a period WWII, summer time (Daylight saying) was mandatory in Canada.
1865
+# In Creston, that was handled by shifting the area to PST (-8:00) then applying
1866
+# summer time to cause the offset to be -7:00, the same as it had been before
1867
+# the change.  It can be argued that the timezone abbreviation during this
1868
+# period should be PDT rather than MST, but that doesn't seem important enough
1869
+# (to anyone) to further complicate the rules.
1870
+
1871
+# The transition dates (and times) are guesses.
1872
+
1873
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1874
+Rule	Vanc	1918	only	-	Apr	14	2:00	1:00	D
1875
+Rule	Vanc	1918	only	-	Oct	27	2:00	0	S
1876
+Rule	Vanc	1942	only	-	Feb	 9	2:00	1:00	W # War
1877
+Rule	Vanc	1945	only	-	Aug	14	23:00u	1:00	P # Peace
1878
+Rule	Vanc	1945	only	-	Sep	30	2:00	0	S
1879
+Rule	Vanc	1946	1986	-	Apr	lastSun	2:00	1:00	D
1880
+Rule	Vanc	1946	only	-	Oct	13	2:00	0	S
1881
+Rule	Vanc	1947	1961	-	Sep	lastSun	2:00	0	S
1882
+Rule	Vanc	1962	2006	-	Oct	lastSun	2:00	0	S
1883
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1884
+Zone America/Vancouver	-8:12:28 -	LMT	1884
1885
+			-8:00	Vanc	P%sT	1987
1886
+			-8:00	Canada	P%sT
1887
+Zone America/Dawson_Creek -8:00:56 -	LMT	1884
1888
+			-8:00	Canada	P%sT	1947
1889
+			-8:00	Vanc	P%sT	1972 Aug 30 2:00
1890
+			-7:00	-	MST
1891
+Zone America/Creston	-7:46:04 -	LMT	1884
1892
+			-7:00	-	MST	1916 Oct 1
1893
+			-8:00	-	PST	1918 Jun 2
1894
+			-7:00	-	MST
1895
+
1896
+# Northwest Territories, Nunavut, Yukon
1897
+
1898
+# From Paul Eggert (2006-03-22):
1899
+# Dawson switched to PST in 1973.  Inuvik switched to MST in 1979.
1900
+# Mathew Englander (1996-10-07) gives the following refs:
1901
+#	* 1967. Paragraph 28(34)(g) of the Interpretation Act, S.C. 1967-68,
1902
+#	c. 7 defines Yukon standard time as UTC-9.  This is still valid;
1903
+#	see Interpretation Act, R.S.C. 1985, c. I-21, s. 35(1).
1904
+#	* C.O. 1973/214 switched Yukon to PST on 1973-10-28 00:00.
1905
+#	* O.I.C. 1980/02 established DST.
1906
+#	* O.I.C. 1987/056 changed DST to Apr firstSun 2:00 to Oct lastSun 2:00.
1907
+# Shanks & Pottenger say Yukon's 1973-10-28 switch was at 2:00; go
1908
+# with Englander.
1909
+# From Chris Walton (2006-06-26):
1910
+# Here is a link to the old daylight saving portion of the interpretation
1911
+# act which was last updated in 1987:
1912
+# http://www.gov.yk.ca/legislation/regs/oic1987_056.pdf
1913
+
1914
+# From Rives McDow (1999-09-04):
1915
+# Nunavut ... moved ... to incorporate the whole territory into one time zone.
1916
+# <a href="http://www.nunatsiaq.com/nunavut/nvt90903_13.html">
1917
+# Nunavut moves to single time zone Oct. 31
1918
+# </a>
1919
+#
1920
+# From Antoine Leca (1999-09-06):
1921
+# We then need to create a new timezone for the Kitikmeot region of Nunavut
1922
+# to differentiate it from the Yellowknife region.
1923
+
1924
+# From Paul Eggert (1999-09-20):
1925
+# <a href="http://www.nunavut.com/basicfacts/english/basicfacts_1territory.html">
1926
+# Basic Facts: The New Territory
1927
+# </a> (1999) reports that Pangnirtung operates on eastern time,
1928
+# and that Coral Harbour does not observe DST.  We don't know when
1929
+# Pangnirtung switched to eastern time; we'll guess 1995.
1930
+
1931
+# From Rives McDow (1999-11-08):
1932
+# On October 31, when the rest of Nunavut went to Central time,
1933
+# Pangnirtung wobbled.  Here is the result of their wobble:
1934
+#
1935
+# The following businesses and organizations in Pangnirtung use Central Time:
1936
+#
1937
+#	First Air, Power Corp, Nunavut Construction, Health Center, RCMP,
1938
+#	Eastern Arctic National Parks, A & D Specialist
1939
+#
1940
+# The following businesses and organizations in Pangnirtung use Eastern Time:
1941
+#
1942
+#	Hamlet office, All other businesses, Both schools, Airport operator
1943
+#
1944
+# This has made for an interesting situation there, which warranted the news.
1945
+# No one there that I spoke with seems concerned, or has plans to
1946
+# change the local methods of keeping time, as it evidently does not
1947
+# really interfere with any activities or make things difficult locally.
1948
+# They plan to celebrate New Year's turn-over twice, one hour apart,
1949
+# so it appears that the situation will last at least that long.
1950
+# The Nunavut Intergovernmental Affairs hopes that they will "come to
1951
+# their senses", but the locals evidently don't see any problem with
1952
+# the current state of affairs.
1953
+
1954
+# From Michaela Rodrigue, writing in the
1955
+# <a href="http://www.nunatsiaq.com/archives/nunavut991130/nvt91119_17.html">
1956
+# Nunatsiaq News (1999-11-19)</a>:
1957
+# Clyde River, Pangnirtung and Sanikiluaq now operate with two time zones,
1958
+# central - or Nunavut time - for government offices, and eastern time
1959
+# for municipal offices and schools....  Igloolik [was similar but then]
1960
+# made the switch to central time on Saturday, Nov. 6.
1961
+
1962
+# From Paul Eggert (2000-10-02):
1963
+# Matthews and Vincent (1998) say the following, but we lack histories
1964
+# for these potential new Zones.
1965
+#
1966
+# The Canadian Forces station at Alert uses Eastern Time while the
1967
+# handful of residents at the Eureka weather station [in the Central
1968
+# zone] skip daylight savings.  Baffin Island, which is crossed by the
1969
+# Central, Eastern and Atlantic Time zones only uses Eastern Time.
1970
+# Gjoa Haven, Taloyoak and Pelly Bay all use Mountain instead of
1971
+# Central Time and Southampton Island [in the Central zone] is not
1972
+# required to use daylight savings.
1973
+
1974
+# From
1975
+# <a href="http://www.nunatsiaq.com/archives/nunavut001130/nvt21110_02.html">
1976
+# Nunavut now has two time zones
1977
+# </a> (2000-11-10):
1978
+# The Nunavut government would allow its employees in Kugluktuk and
1979
+# Cambridge Bay to operate on central time year-round, putting them
1980
+# one hour behind the rest of Nunavut for six months during the winter.
1981
+# At the end of October the two communities had rebelled against
1982
+# Nunavut's unified time zone, refusing to shift to eastern time with
1983
+# the rest of the territory for the winter.  Cambridge Bay remained on
1984
+# central time, while Kugluktuk, even farther west, reverted to
1985
+# mountain time, which they had used before the advent of Nunavut's
1986
+# unified time zone in 1999.
1987
+#
1988
+# From Rives McDow (2001-01-20), quoting the Nunavut government:
1989
+# The preceding decision came into effect at midnight, Saturday Nov 4, 2000.
1990
+
1991
+# From Paul Eggert (2000-12-04):
1992
+# Let's just keep track of the official times for now.
1993
+
1994
+# From Rives McDow (2001-03-07):
1995
+# The premier of Nunavut has issued a ministerial statement advising
1996
+# that effective 2001-04-01, the territory of Nunavut will revert
1997
+# back to three time zones (mountain, central, and eastern).  Of the
1998
+# cities in Nunavut, Coral Harbor is the only one that I know of that
1999
+# has said it will not observe dst, staying on EST year round.  I'm
2000
+# checking for more info, and will get back to you if I come up with
2001
+# more.
2002
+# [Also see <http://www.nunatsiaq.com/nunavut/nvt10309_06.html> (2001-03-09).]
2003
+
2004
+# From Gwillim Law (2005-05-21):
2005
+# According to maps at
2006
+# http://inms-ienm.nrc-cnrc.gc.ca/images/time_services/TZ01SWE.jpg
2007
+# http://inms-ienm.nrc-cnrc.gc.ca/images/time_services/TZ01SSE.jpg
2008
+# (both dated 2003), and
2009
+# http://www.canadiangeographic.ca/Magazine/SO98/geomap.asp
2010
+# (from a 1998 Canadian Geographic article), the de facto and de jure time
2011
+# for Southampton Island (at the north end of Hudson Bay) is UTC-5 all year
2012
+# round.  Using Google, it's easy to find other websites that confirm this.
2013
+# I wasn't able to find how far back this time regimen goes, but since it
2014
+# predates the creation of Nunavut, it probably goes back many years....
2015
+# The Inuktitut name of Coral Harbour is Sallit, but it's rarely used.
2016
+#
2017
+# From Paul Eggert (2005-07-26):
2018
+# For lack of better information, assume that Southampton Island observed
2019
+# daylight saving only during wartime.
2020
+
2021
+# From Chris Walton (2007-03-01):
2022
+# ... the community of Resolute (located on Cornwallis Island in
2023
+# Nunavut) moved from Central Time to Eastern Time last November.
2024
+# Basically the community did not change its clocks at the end of
2025
+# daylight saving....
2026
+# http://www.nnsl.com/frames/newspapers/2006-11/nov13_06none.html
2027
+
2028
+# From Chris Walton (2011-03-21):
2029
+# Back in 2007 I initiated the creation of a new "zone file" for Resolute
2030
+# Bay. Resolute Bay is a small community located about 900km north of
2031
+# the Arctic Circle. The zone file was required because Resolute Bay had
2032
+# decided to use UTC-5 instead of UTC-6 for the winter of 2006-2007.
2033
+#
2034
+# According to new information which I received last week, Resolute Bay
2035
+# went back to using UTC-6 in the winter of 2007-2008...
2036
+#
2037
+# On March 11/2007 most of Canada went onto daylight saving. On March
2038
+# 14/2007 I phoned the Resolute Bay hamlet office to do a "time check." I
2039
+# talked to somebody that was both knowledgeable and helpful. I was able
2040
+# to confirm that Resolute Bay was still operating on UTC-5. It was
2041
+# explained to me that Resolute Bay had been on the Eastern Time zone
2042
+# (EST) in the winter, and was now back on the Central Time zone (CDT).
2043
+# i.e. the time zone had changed twice in the last year but the clocks
2044
+# had not moved. The residents had to know which time zone they were in
2045
+# so they could follow the correct TV schedule...
2046
+#
2047
+# On Nov 02/2008 most of Canada went onto standard time. On Nov 03/2008 I
2048
+# phoned the Resolute Bay hamlet office...[D]ue to the challenging nature
2049
+# of the phone call, I decided to seek out an alternate source of
2050
+# information. I found an e-mail address for somebody by the name of
2051
+# Stephanie Adams whose job was listed as "Inns North Support Officer for
2052
+# Arctic Co-operatives." I was under the impression that Stephanie lived
2053
+# and worked in Resolute Bay...
2054
+#
2055
+# On March 14/2011 I phoned the hamlet office again. I was told that
2056
+# Resolute Bay had been using Central Standard Time over the winter of
2057
+# 2010-2011 and that the clocks had therefore been moved one hour ahead
2058
+# on March 13/2011. The person I talked to was aware that Resolute Bay
2059
+# had previously experimented with Eastern Standard Time but he could not
2060
+# tell me when the practice had stopped.
2061
+#
2062
+# On March 17/2011 I searched the Web to find an e-mail address of
2063
+# somebody that might be able to tell me exactly when Resolute Bay went
2064
+# off Eastern Standard Time. I stumbled on the name "Aziz Kheraj." Aziz
2065
+# used to be the mayor of Resolute Bay and he apparently owns half the
2066
+# businesses including "South Camp Inn." This website has some info on
2067
+# Aziz:
2068
+# <a href="http://www.uphere.ca/node/493">
2069
+# http://www.uphere.ca/node/493
2070
+# </a>
2071
+#
2072
+# I sent Aziz an e-mail asking when Resolute Bay had stopped using
2073
+# Eastern Standard Time.
2074
+#
2075
+# Aziz responded quickly with this: "hi, The time was not changed for the
2076
+# 1 year only, the following year, the community went back to the old way
2077
+# of "spring ahead-fall behind" currently we are zulu plus 5 hrs and in
2078
+# the winter Zulu plus 6 hrs"
2079
+#
2080
+# This of course conflicted with everything I had ascertained in November 2008.
2081
+#
2082
+# I sent Aziz a copy of my 2008 e-mail exchange with Stephanie. Aziz
2083
+# responded with this: "Hi, Stephanie lives in Winnipeg. I live here, You
2084
+# may want to check with the weather office in Resolute Bay or do a
2085
+# search on the weather through Env. Canada. web site"
2086
+#
2087
+# If I had realized the Stephanie did not live in Resolute Bay I would
2088
+# never have contacted her.  I now believe that all the information I
2089
+# obtained in November 2008 should be ignored...
2090
+# I apologize for reporting incorrect information in 2008.
2091
+
2092
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
2093
+Rule	NT_YK	1918	only	-	Apr	14	2:00	1:00	D
2094
+Rule	NT_YK	1918	only	-	Oct	27	2:00	0	S
2095
+Rule	NT_YK	1919	only	-	May	25	2:00	1:00	D
2096
+Rule	NT_YK	1919	only	-	Nov	 1	0:00	0	S
2097
+Rule	NT_YK	1942	only	-	Feb	 9	2:00	1:00	W # War
2098
+Rule	NT_YK	1945	only	-	Aug	14	23:00u	1:00	P # Peace
2099
+Rule	NT_YK	1945	only	-	Sep	30	2:00	0	S
2100
+Rule	NT_YK	1965	only	-	Apr	lastSun	0:00	2:00	DD
2101
+Rule	NT_YK	1965	only	-	Oct	lastSun	2:00	0	S
2102
+Rule	NT_YK	1980	1986	-	Apr	lastSun	2:00	1:00	D
2103
+Rule	NT_YK	1980	2006	-	Oct	lastSun	2:00	0	S
2104
+Rule	NT_YK	1987	2006	-	Apr	Sun>=1	2:00	1:00	D
2105
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2106
+# aka Panniqtuuq
2107
+Zone America/Pangnirtung 0	-	zzz	1921 # trading post est.
2108
+			-4:00	NT_YK	A%sT	1995 Apr Sun>=1 2:00
2109
+			-5:00	Canada	E%sT	1999 Oct 31 2:00
2110
+			-6:00	Canada	C%sT	2000 Oct 29 2:00
2111
+			-5:00	Canada	E%sT
2112
+# formerly Frobisher Bay
2113
+Zone America/Iqaluit	0	-	zzz	1942 Aug # Frobisher Bay est.
2114
+			-5:00	NT_YK	E%sT	1999 Oct 31 2:00
2115
+			-6:00	Canada	C%sT	2000 Oct 29 2:00
2116
+			-5:00	Canada	E%sT
2117
+# aka Qausuittuq
2118
+Zone America/Resolute	0	-	zzz	1947 Aug 31 # Resolute founded
2119
+			-6:00	NT_YK	C%sT	2000 Oct 29 2:00
2120
+			-5:00	-	EST	2001 Apr  1 3:00
2121
+			-6:00	Canada	C%sT	2006 Oct 29 2:00
2122
+			-5:00	-	EST	2007 Mar 11 3:00
2123
+			-6:00	Canada	C%sT
2124
+# aka Kangiqiniq
2125
+Zone America/Rankin_Inlet 0	-	zzz	1957 # Rankin Inlet founded
2126
+			-6:00	NT_YK	C%sT	2000 Oct 29 2:00
2127
+			-5:00	-	EST	2001 Apr  1 3:00
2128
+			-6:00	Canada	C%sT
2129
+# aka Iqaluktuuttiaq
2130
+Zone America/Cambridge_Bay 0	-	zzz	1920 # trading post est.?
2131
+			-7:00	NT_YK	M%sT	1999 Oct 31 2:00
2132
+			-6:00	Canada	C%sT	2000 Oct 29 2:00
2133
+			-5:00	-	EST	2000 Nov  5 0:00
2134
+			-6:00	-	CST	2001 Apr  1 3:00
2135
+			-7:00	Canada	M%sT
2136
+Zone America/Yellowknife 0	-	zzz	1935 # Yellowknife founded?
2137
+			-7:00	NT_YK	M%sT	1980
2138
+			-7:00	Canada	M%sT
2139
+Zone America/Inuvik	0	-	zzz	1953 # Inuvik founded
2140
+			-8:00	NT_YK	P%sT	1979 Apr lastSun 2:00
2141
+			-7:00	NT_YK	M%sT	1980
2142
+			-7:00	Canada	M%sT
2143
+Zone America/Whitehorse	-9:00:12 -	LMT	1900 Aug 20
2144
+			-9:00	NT_YK	Y%sT	1966 Jul 1 2:00
2145
+			-8:00	NT_YK	P%sT	1980
2146
+			-8:00	Canada	P%sT
2147
+Zone America/Dawson	-9:17:40 -	LMT	1900 Aug 20
2148
+			-9:00	NT_YK	Y%sT	1973 Oct 28 0:00
2149
+			-8:00	NT_YK	P%sT	1980
2150
+			-8:00	Canada	P%sT
2151
+
2152
+
2153
+###############################################################################
2154
+
2155
+# Mexico
2156
+
2157
+# From Paul Eggert (2001-03-05):
2158
+# The Investigation and Analysis Service of the
2159
+# Mexican Library of Congress (MLoC) has published a
2160
+# <a href="http://www.cddhcu.gob.mx/bibliot/publica/inveyana/polisoc/horver/">
2161
+# history of Mexican local time (in Spanish)
2162
+# </a>.
2163
+#
2164
+# Here are the discrepancies between Shanks & Pottenger (S&P) and the MLoC.
2165
+# (In all cases we go with the MLoC.)
2166
+# S&P report that Baja was at -8:00 in 1922/1923.
2167
+# S&P say the 1930 transition in Baja was 1930-11-16.
2168
+# S&P report no DST during summer 1931.
2169
+# S&P report a transition at 1932-03-30 23:00, not 1932-04-01.
2170
+
2171
+# From Gwillim Law (2001-02-20):
2172
+# There are some other discrepancies between the Decrees page and the
2173
+# tz database.  I think they can best be explained by supposing that
2174
+# the researchers who prepared the Decrees page failed to find some of
2175
+# the relevant documents.
2176
+
2177
+# From Alan Perry (1996-02-15):
2178
+# A guy from our Mexico subsidiary finally found the Presidential Decree
2179
+# outlining the timezone changes in Mexico.
2180
+#
2181
+# ------------- Begin Forwarded Message -------------
2182
+#
2183
+# I finally got my hands on the Official Presidential Decree that sets up the
2184
+# rules for the DST changes. The rules are:
2185
+#
2186
+# 1. The country is divided in 3 timezones:
2187
+#    - Baja California Norte (the Mexico/BajaNorte TZ)
2188
+#    - Baja California Sur, Nayarit, Sinaloa and Sonora (the Mexico/BajaSur TZ)
2189
+#    - The rest of the country (the Mexico/General TZ)
2190
+#
2191
+# 2. From the first Sunday in April at 2:00 AM to the last Sunday in October
2192
+#    at 2:00 AM, the times in each zone are as follows:
2193
+#    BajaNorte: GMT+7
2194
+#    BajaSur:   GMT+6
2195
+#    General:   GMT+5
2196
+#
2197
+# 3. The rest of the year, the times are as follows:
2198
+#    BajaNorte: GMT+8
2199
+#    BajaSur:   GMT+7
2200
+#    General:   GMT+6
2201
+#
2202
+# The Decree was published in Mexico's Official Newspaper on January 4th.
2203
+#
2204
+# -------------- End Forwarded Message --------------
2205
+# From Paul Eggert (1996-06-12):
2206
+# For an English translation of the decree, see
2207
+# <a href="http://mexico-travel.com/extra/timezone_eng.html">
2208
+# ``Diario Oficial: Time Zone Changeover'' (1996-01-04).
2209
+# </a>
2210
+
2211
+# From Rives McDow (1998-10-08):
2212
+# The State of Quintana Roo has reverted back to central STD and DST times
2213
+# (i.e. UTC -0600 and -0500 as of 1998-08-02).
2214
+
2215
+# From Rives McDow (2000-01-10):
2216
+# Effective April 4, 1999 at 2:00 AM local time, Sonora changed to the time
2217
+# zone 5 hours from the International Date Line, and will not observe daylight
2218
+# savings time so as to stay on the same time zone as the southern part of
2219
+# Arizona year round.
2220
+
2221
+# From Jesper Norgaard, translating
2222
+# <http://www.reforma.com/nacional/articulo/064327/> (2001-01-17):
2223
+# In Oaxaca, the 55.000 teachers from the Section 22 of the National
2224
+# Syndicate of Education Workers, refuse to apply daylight saving each
2225
+# year, so that the more than 10,000 schools work at normal hour the
2226
+# whole year.
2227
+
2228
+# From Gwillim Law (2001-01-19):
2229
+# <http://www.reforma.com/negocios_y_dinero/articulo/064481/> ... says
2230
+# (translated):...
2231
+# January 17, 2000 - The Energy Secretary, Ernesto Martens, announced
2232
+# that Summer Time will be reduced from seven to five months, starting
2233
+# this year....
2234
+# <http://www.publico.com.mx/scripts/texto3.asp?action=pagina&pag=21&pos=p&secc=naci&date=01/17/2001>
2235
+# [translated], says "summer time will ... take effect on the first Sunday
2236
+# in May, and end on the last Sunday of September.
2237
+
2238
+# From Arthur David Olson (2001-01-25):
2239
+# The 2001-01-24 traditional Washington Post contained the page one
2240
+# story "Timely Issue Divides Mexicans."...
2241
+# http://www.washingtonpost.com/wp-dyn/articles/A37383-2001Jan23.html
2242
+# ... Mexico City Mayor Lopez Obrador "...is threatening to keep
2243
+# Mexico City and its 20 million residents on a different time than
2244
+# the rest of the country..." In particular, Lopez Obrador would abolish
2245
+# observation of Daylight Saving Time.
2246
+
2247
+# <a href="http://www.conae.gob.mx/ahorro/decretohorver2001.html#decre">
2248
+# Official statute published by the Energy Department
2249
+# </a> (2001-02-01) shows Baja and Chihauhua as still using US DST rules,
2250
+# and Sonora with no DST.  This was reported by Jesper Norgaard (2001-02-03).
2251
+
2252
+# From Paul Eggert (2001-03-03):
2253
+#
2254
+# <a href="http://www.latimes.com/news/nation/20010303/t000018766.html">
2255
+# James F. Smith writes in today's LA Times
2256
+# </a>
2257
+# * Sonora will continue to observe standard time.
2258
+# * Last week Mexico City's mayor Andres Manuel Lopez Obrador decreed that
2259
+#   the Federal District will not adopt DST.
2260
+# * 4 of 16 district leaders announced they'll ignore the decree.
2261
+# * The decree does not affect federal-controlled facilities including
2262
+#   the airport, banks, hospitals, and schools.
2263
+#
2264
+# For now we'll assume that the Federal District will bow to federal rules.
2265
+
2266
+# From Jesper Norgaard (2001-04-01):
2267
+# I found some references to the Mexican application of daylight
2268
+# saving, which modifies what I had already sent you, stating earlier
2269
+# that a number of northern Mexican states would go on daylight
2270
+# saving. The modification reverts this to only cover Baja California
2271
+# (Norte), while all other states (except Sonora, who has no daylight
2272
+# saving all year) will follow the original decree of president
2273
+# Vicente Fox, starting daylight saving May 6, 2001 and ending
2274
+# September 30, 2001.
2275
+# References: "Diario de Monterrey" <www.diariodemonterrey.com/index.asp>
2276
+# Palabra <http://palabra.infosel.com/010331/primera/ppri3101.pdf> (2001-03-31)
2277
+
2278
+# From Reuters (2001-09-04):
2279
+# Mexico's Supreme Court on Tuesday declared that daylight savings was
2280
+# unconstitutional in Mexico City, creating the possibility the
2281
+# capital will be in a different time zone from the rest of the nation
2282
+# next year....  The Supreme Court's ruling takes effect at 2:00
2283
+# a.m. (0800 GMT) on Sept. 30, when Mexico is scheduled to revert to
2284
+# standard time. "This is so residents of the Federal District are not
2285
+# subject to unexpected time changes," a statement from the court said.
2286
+
2287
+# From Jesper Norgaard Welen (2002-03-12):
2288
+# ... consulting my local grocery store(!) and my coworkers, they all insisted
2289
+# that a new decision had been made to reinstate US style DST in Mexico....
2290
+# http://www.conae.gob.mx/ahorro/horaver2001_m1_2002.html (2002-02-20)
2291
+# confirms this.  Sonora as usual is the only state where DST is not applied.
2292
+
2293
+# From Steffen Thorsen (2009-12-28):
2294
+#
2295
+# Steffen Thorsen wrote:
2296
+# > Mexico's House of Representatives has approved a proposal for northern
2297
+# > Mexico's border cities to share the same daylight saving schedule as
2298
+# > the United States.
2299
+# Now this has passed both the Congress and the Senate, so starting from
2300
+# 2010, some border regions will be the same:
2301
+# <a href="http://www.signonsandiego.com/news/2009/dec/28/clocks-will-match-both-sides-border/">
2302
+# http://www.signonsandiego.com/news/2009/dec/28/clocks-will-match-both-sides-border/
2303
+# </a>
2304
+# <a href="http://www.elmananarey.com/diario/noticia/nacional/noticias/empatan_horario_de_frontera_con_eu/621939">
2305
+# http://www.elmananarey.com/diario/noticia/nacional/noticias/empatan_horario_de_frontera_con_eu/621939
2306
+# </a>
2307
+# (Spanish)
2308
+#
2309
+# Could not find the new law text, but the proposed law text changes are here:
2310
+# <a href="http://gaceta.diputados.gob.mx/Gaceta/61/2009/dic/20091210-V.pdf">
2311
+# http://gaceta.diputados.gob.mx/Gaceta/61/2009/dic/20091210-V.pdf
2312
+# </a>
2313
+# (Gaceta Parlamentaria)
2314
+#
2315
+# There is also a list of the votes here:
2316
+# <a href="http://gaceta.diputados.gob.mx/Gaceta/61/2009/dic/V2-101209.html">
2317
+# http://gaceta.diputados.gob.mx/Gaceta/61/2009/dic/V2-101209.html
2318
+# </a>
2319
+#
2320
+# Our page:
2321
+# <a href="http://www.timeanddate.com/news/time/north-mexico-dst-change.html">
2322
+# http://www.timeanddate.com/news/time/north-mexico-dst-change.html
2323
+# </a>
2324
+
2325
+# From Arthur David Olson (2010-01-20):
2326
+# The page
2327
+# <a href="http://dof.gob.mx/nota_detalle.php?codigo=5127480&fecha=06/01/2010">
2328
+# http://dof.gob.mx/nota_detalle.php?codigo=5127480&fecha=06/01/2010
2329
+# </a>
2330
+# includes this text:
2331
+# En los municipios fronterizos de Tijuana y Mexicali en Baja California;
2332
+# Ju&aacute;rez y Ojinaga en Chihuahua; Acu&ntilde;a y Piedras Negras en Coahuila;
2333
+# An&aacute;huac en Nuevo Le&oacute;n; y Nuevo Laredo, Reynosa y Matamoros en
2334
+# Tamaulipas, la aplicaci&oacute;n de este horario estacional surtir&aacute; efecto
2335
+# desde las dos horas del segundo domingo de marzo y concluir&aacute; a las dos
2336
+# horas del primer domingo de noviembre.
2337
+# En los municipios fronterizos que se encuentren ubicados en la franja
2338
+# fronteriza norte en el territorio comprendido entre la l&iacute;nea
2339
+# internacional y la l&iacute;nea paralela ubicada a una distancia de veinte
2340
+# kil&oacute;metros, as&iacute; como la Ciudad de Ensenada, Baja California, hacia el
2341
+# interior del pa&iacute;s, la aplicaci&oacute;n de este horario estacional surtir&aacute;
2342
+# efecto desde las dos horas del segundo domingo de marzo y concluir&aacute; a
2343
+# las dos horas del primer domingo de noviembre.
2344
+
2345
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
2346
+Rule	Mexico	1939	only	-	Feb	5	0:00	1:00	D
2347
+Rule	Mexico	1939	only	-	Jun	25	0:00	0	S
2348
+Rule	Mexico	1940	only	-	Dec	9	0:00	1:00	D
2349
+Rule	Mexico	1941	only	-	Apr	1	0:00	0	S
2350
+Rule	Mexico	1943	only	-	Dec	16	0:00	1:00	W # War
2351
+Rule	Mexico	1944	only	-	May	1	0:00	0	S
2352
+Rule	Mexico	1950	only	-	Feb	12	0:00	1:00	D
2353
+Rule	Mexico	1950	only	-	Jul	30	0:00	0	S
2354
+Rule	Mexico	1996	2000	-	Apr	Sun>=1	2:00	1:00	D
2355
+Rule	Mexico	1996	2000	-	Oct	lastSun	2:00	0	S
2356
+Rule	Mexico	2001	only	-	May	Sun>=1	2:00	1:00	D
2357
+Rule	Mexico	2001	only	-	Sep	lastSun	2:00	0	S
2358
+Rule	Mexico	2002	max	-	Apr	Sun>=1	2:00	1:00	D
2359
+Rule	Mexico	2002	max	-	Oct	lastSun	2:00	0	S
2360
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2361
+# Quintana Roo
2362
+Zone America/Cancun	-5:47:04 -	LMT	1922 Jan  1  0:12:56
2363
+			-6:00	-	CST	1981 Dec 23
2364
+			-5:00	Mexico	E%sT	1998 Aug  2  2:00
2365
+			-6:00	Mexico	C%sT
2366
+# Campeche, Yucatan
2367
+Zone America/Merida	-5:58:28 -	LMT	1922 Jan  1  0:01:32
2368
+			-6:00	-	CST	1981 Dec 23
2369
+			-5:00	-	EST	1982 Dec  2
2370
+			-6:00	Mexico	C%sT
2371
+# Coahuila, Durango, Nuevo Leon, Tamaulipas (near US border)
2372
+Zone America/Matamoros	-6:40:00 -	LMT	1921 Dec 31 23:20:00
2373
+			-6:00	-	CST	1988
2374
+			-6:00	US	C%sT	1989
2375
+			-6:00	Mexico	C%sT	2010
2376
+			-6:00	US	C%sT
2377
+# Coahuila, Durango, Nuevo Leon, Tamaulipas (away from US border)
2378
+Zone America/Monterrey	-6:41:16 -	LMT	1921 Dec 31 23:18:44
2379
+			-6:00	-	CST	1988
2380
+			-6:00	US	C%sT	1989
2381
+			-6:00	Mexico	C%sT
2382
+# Central Mexico
2383
+Zone America/Mexico_City -6:36:36 -	LMT	1922 Jan  1 0:23:24
2384
+			-7:00	-	MST	1927 Jun 10 23:00
2385
+			-6:00	-	CST	1930 Nov 15
2386
+			-7:00	-	MST	1931 May  1 23:00
2387
+			-6:00	-	CST	1931 Oct
2388
+			-7:00	-	MST	1932 Apr  1
2389
+			-6:00	Mexico	C%sT	2001 Sep 30 02:00
2390
+			-6:00	-	CST	2002 Feb 20
2391
+			-6:00	Mexico	C%sT
2392
+# Chihuahua (near US border)
2393
+Zone America/Ojinaga	-6:57:40 -	LMT	1922 Jan 1 0:02:20
2394
+			-7:00	-	MST	1927 Jun 10 23:00
2395
+			-6:00	-	CST	1930 Nov 15
2396
+			-7:00	-	MST	1931 May  1 23:00
2397
+			-6:00	-	CST	1931 Oct
2398
+			-7:00	-	MST	1932 Apr  1
2399
+			-6:00	-	CST	1996
2400
+			-6:00	Mexico	C%sT	1998
2401
+			-6:00	-	CST	1998 Apr Sun>=1 3:00
2402
+			-7:00	Mexico	M%sT	2010
2403
+			-7:00	US	M%sT
2404
+# Chihuahua (away from US border)
2405
+Zone America/Chihuahua	-7:04:20 -	LMT	1921 Dec 31 23:55:40
2406
+			-7:00	-	MST	1927 Jun 10 23:00
2407
+			-6:00	-	CST	1930 Nov 15
2408
+			-7:00	-	MST	1931 May  1 23:00
2409
+			-6:00	-	CST	1931 Oct
2410
+			-7:00	-	MST	1932 Apr  1
2411
+			-6:00	-	CST	1996
2412
+			-6:00	Mexico	C%sT	1998
2413
+			-6:00	-	CST	1998 Apr Sun>=1 3:00
2414
+			-7:00	Mexico	M%sT
2415
+# Sonora
2416
+Zone America/Hermosillo	-7:23:52 -	LMT	1921 Dec 31 23:36:08
2417
+			-7:00	-	MST	1927 Jun 10 23:00
2418
+			-6:00	-	CST	1930 Nov 15
2419
+			-7:00	-	MST	1931 May  1 23:00
2420
+			-6:00	-	CST	1931 Oct
2421
+			-7:00	-	MST	1932 Apr  1
2422
+			-6:00	-	CST	1942 Apr 24
2423
+			-7:00	-	MST	1949 Jan 14
2424
+			-8:00	-	PST	1970
2425
+			-7:00	Mexico	M%sT	1999
2426
+			-7:00	-	MST
2427
+
2428
+# From Alexander Krivenyshev (2010-04-21):
2429
+# According to news, Bah&iacute;a de Banderas (Mexican state of Nayarit)
2430
+# changed time zone UTC-7 to new time zone UTC-6 on April 4, 2010 (to
2431
+# share the same time zone as nearby city Puerto Vallarta, Jalisco).
2432
+#
2433
+# (Spanish)
2434
+# Bah&iacute;a de Banderas homologa su horario al del centro del
2435
+# pa&iacute;s, a partir de este domingo
2436
+# <a href="http://www.nayarit.gob.mx/notes.asp?id=20748">
2437
+# http://www.nayarit.gob.mx/notes.asp?id=20748
2438
+# </a>
2439
+#
2440
+# Bah&iacute;a de Banderas homologa su horario con el del Centro del
2441
+# Pa&iacute;s
2442
+# <a href="http://www.bahiadebanderas.gob.mx/principal/index.php?option=com_content&view=article&id=261:bahia-de-banderas-homologa-su-horario-con-el-del-centro-del-pais&catid=42:comunicacion-social&Itemid=50">
2443
+# http://www.bahiadebanderas.gob.mx/principal/index.php?option=com_content&view=article&id=261:bahia-de-banderas-homologa-su-horario-con-el-del-centro-del-pais&catid=42:comunicacion-social&Itemid=50"
2444
+# </a>
2445
+#
2446
+# (English)
2447
+# Puerto Vallarta and Bah&iacute;a de Banderas: One Time Zone
2448
+# <a href="http://virtualvallarta.com/puertovallarta/puertovallarta/localnews/2009-12-03-Puerto-Vallarta-and-Bahia-de-Banderas-One-Time-Zone.shtml">
2449
+# http://virtualvallarta.com/puertovallarta/puertovallarta/localnews/2009-12-03-Puerto-Vallarta-and-Bahia-de-Banderas-One-Time-Zone.shtml
2450
+# </a>
2451
+#
2452
+# or
2453
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_mexico08.html">
2454
+# http://www.worldtimezone.com/dst_news/dst_news_mexico08.html
2455
+# </a>
2456
+#
2457
+# "Mexico's Senate approved the amendments to the Mexican Schedule System that
2458
+# will allow Bah&iacute;a de Banderas and Puerto Vallarta to share the same time
2459
+# zone ..."
2460
+# Baja California Sur, Nayarit, Sinaloa
2461
+
2462
+# From Arthur David Olson (2010-05-01):
2463
+# Use "Bahia_Banderas" to keep the name to fourteen characters.
2464
+
2465
+Zone America/Mazatlan	-7:05:40 -	LMT	1921 Dec 31 23:54:20
2466
+			-7:00	-	MST	1927 Jun 10 23:00
2467
+			-6:00	-	CST	1930 Nov 15
2468
+			-7:00	-	MST	1931 May  1 23:00
2469
+			-6:00	-	CST	1931 Oct
2470
+			-7:00	-	MST	1932 Apr  1
2471
+			-6:00	-	CST	1942 Apr 24
2472
+			-7:00	-	MST	1949 Jan 14
2473
+			-8:00	-	PST	1970
2474
+			-7:00	Mexico	M%sT
2475
+
2476
+Zone America/Bahia_Banderas	-7:01:00 -	LMT	1921 Dec 31 23:59:00
2477
+			-7:00	-	MST	1927 Jun 10 23:00
2478
+			-6:00	-	CST	1930 Nov 15
2479
+			-7:00	-	MST	1931 May  1 23:00
2480
+			-6:00	-	CST	1931 Oct
2481
+			-7:00	-	MST	1932 Apr  1
2482
+			-6:00	-	CST	1942 Apr 24
2483
+			-7:00	-	MST	1949 Jan 14
2484
+			-8:00	-	PST	1970
2485
+			-7:00	Mexico	M%sT	2010 Apr 4 2:00
2486
+			-6:00	Mexico	C%sT
2487
+
2488
+# Baja California (near US border)
2489
+Zone America/Tijuana	-7:48:04 -	LMT	1922 Jan  1  0:11:56
2490
+			-7:00	-	MST	1924
2491
+			-8:00	-	PST	1927 Jun 10 23:00
2492
+			-7:00	-	MST	1930 Nov 15
2493
+			-8:00	-	PST	1931 Apr  1
2494
+			-8:00	1:00	PDT	1931 Sep 30
2495
+			-8:00	-	PST	1942 Apr 24
2496
+			-8:00	1:00	PWT	1945 Aug 14 23:00u
2497
+			-8:00	1:00	PPT	1945 Nov 12 # Peace
2498
+			-8:00	-	PST	1948 Apr  5
2499
+			-8:00	1:00	PDT	1949 Jan 14
2500
+			-8:00	-	PST	1954
2501
+			-8:00	CA	P%sT	1961
2502
+			-8:00	-	PST	1976
2503
+			-8:00	US	P%sT	1996
2504
+			-8:00	Mexico	P%sT	2001
2505
+			-8:00	US	P%sT	2002 Feb 20
2506
+			-8:00	Mexico	P%sT	2010
2507
+			-8:00	US	P%sT
2508
+# Baja California (away from US border)
2509
+Zone America/Santa_Isabel	-7:39:28 -	LMT	1922 Jan  1  0:20:32
2510
+			-7:00	-	MST	1924
2511
+			-8:00	-	PST	1927 Jun 10 23:00
2512
+			-7:00	-	MST	1930 Nov 15
2513
+			-8:00	-	PST	1931 Apr  1
2514
+			-8:00	1:00	PDT	1931 Sep 30
2515
+			-8:00	-	PST	1942 Apr 24
2516
+			-8:00	1:00	PWT	1945 Aug 14 23:00u
2517
+			-8:00	1:00	PPT	1945 Nov 12 # Peace
2518
+			-8:00	-	PST	1948 Apr  5
2519
+			-8:00	1:00	PDT	1949 Jan 14
2520
+			-8:00	-	PST	1954
2521
+			-8:00	CA	P%sT	1961
2522
+			-8:00	-	PST	1976
2523
+			-8:00	US	P%sT	1996
2524
+			-8:00	Mexico	P%sT	2001
2525
+			-8:00	US	P%sT	2002 Feb 20
2526
+			-8:00	Mexico	P%sT
2527
+# From Paul Eggert (2006-03-22):
2528
+# Formerly there was an America/Ensenada zone, which differed from
2529
+# America/Tijuana only in that it did not observe DST from 1976
2530
+# through 1995.  This was as per Shanks (1999).  But Shanks & Pottenger say
2531
+# Ensenada did not observe DST from 1948 through 1975.  Guy Harris reports
2532
+# that the 1987 OAG says "Only Ensenada, Mexicale, San Felipe and
2533
+# Tijuana observe DST," which agrees with Shanks & Pottenger but implies that
2534
+# DST-observance was a town-by-town matter back then.  This concerns
2535
+# data after 1970 so most likely there should be at least one Zone
2536
+# other than America/Tijuana for Baja, but it's not clear yet what its
2537
+# name or contents should be.
2538
+#
2539
+# Revillagigedo Is
2540
+# no information
2541
+
2542
+###############################################################################
2543
+
2544
+# Anguilla
2545
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2546
+Zone America/Anguilla	-4:12:16 -	LMT	1912 Mar 2
2547
+			-4:00	-	AST
2548
+
2549
+# Antigua and Barbuda
2550
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2551
+Zone	America/Antigua	-4:07:12 -	LMT	1912 Mar 2
2552
+			-5:00	-	EST	1951
2553
+			-4:00	-	AST
2554
+
2555
+# Bahamas
2556
+#
2557
+# From Sue Williams (2006-12-07):
2558
+# The Bahamas announced about a month ago that they plan to change their DST
2559
+# rules to sync with the U.S. starting in 2007....
2560
+# http://www.jonesbahamas.com/?c=45&a=10412
2561
+
2562
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
2563
+Rule	Bahamas	1964	1975	-	Oct	lastSun	2:00	0	S
2564
+Rule	Bahamas	1964	1975	-	Apr	lastSun	2:00	1:00	D
2565
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2566
+Zone	America/Nassau	-5:09:24 -	LMT	1912 Mar 2
2567
+			-5:00	Bahamas	E%sT	1976
2568
+			-5:00	US	E%sT
2569
+
2570
+# Barbados
2571
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
2572
+Rule	Barb	1977	only	-	Jun	12	2:00	1:00	D
2573
+Rule	Barb	1977	1978	-	Oct	Sun>=1	2:00	0	S
2574
+Rule	Barb	1978	1980	-	Apr	Sun>=15	2:00	1:00	D
2575
+Rule	Barb	1979	only	-	Sep	30	2:00	0	S
2576
+Rule	Barb	1980	only	-	Sep	25	2:00	0	S
2577
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2578
+Zone America/Barbados	-3:58:28 -	LMT	1924		# Bridgetown
2579
+			-3:58:28 -	BMT	1932	  # Bridgetown Mean Time
2580
+			-4:00	Barb	A%sT
2581
+
2582
+# Belize
2583
+# Whitman entirely disagrees with Shanks; go with Shanks & Pottenger.
2584
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
2585
+Rule	Belize	1918	1942	-	Oct	Sun>=2	0:00	0:30	HD
2586
+Rule	Belize	1919	1943	-	Feb	Sun>=9	0:00	0	S
2587
+Rule	Belize	1973	only	-	Dec	 5	0:00	1:00	D
2588
+Rule	Belize	1974	only	-	Feb	 9	0:00	0	S
2589
+Rule	Belize	1982	only	-	Dec	18	0:00	1:00	D
2590
+Rule	Belize	1983	only	-	Feb	12	0:00	0	S
2591
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2592
+Zone	America/Belize	-5:52:48 -	LMT	1912 Apr
2593
+			-6:00	Belize	C%sT
2594
+
2595
+# Bermuda
2596
+
2597
+# From Dan Jones, reporting in The Royal Gazette (2006-06-26):
2598
+
2599
+# Next year, however, clocks in the US will go forward on the second Sunday
2600
+# in March, until the first Sunday in November.  And, after the Time Zone
2601
+# (Seasonal Variation) Bill 2006 was passed in the House of Assembly on
2602
+# Friday, the same thing will happen in Bermuda.
2603
+# http://www.theroyalgazette.com/apps/pbcs.dll/article?AID=/20060529/NEWS/105290135
2604
+
2605
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2606
+Zone Atlantic/Bermuda	-4:19:04 -	LMT	1930 Jan  1 2:00    # Hamilton
2607
+			-4:00	-	AST	1974 Apr 28 2:00
2608
+			-4:00	Bahamas	A%sT	1976
2609
+			-4:00	US	A%sT
2610
+
2611
+# Cayman Is
2612
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2613
+Zone	America/Cayman	-5:25:32 -	LMT	1890		# Georgetown
2614
+			-5:07:12 -	KMT	1912 Feb    # Kingston Mean Time
2615
+			-5:00	-	EST
2616
+
2617
+# Costa Rica
2618
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
2619
+Rule	CR	1979	1980	-	Feb	lastSun	0:00	1:00	D
2620
+Rule	CR	1979	1980	-	Jun	Sun>=1	0:00	0	S
2621
+Rule	CR	1991	1992	-	Jan	Sat>=15	0:00	1:00	D
2622
+# IATA SSIM (1991-09) says the following was at 1:00;
2623
+# go with Shanks & Pottenger.
2624
+Rule	CR	1991	only	-	Jul	 1	0:00	0	S
2625
+Rule	CR	1992	only	-	Mar	15	0:00	0	S
2626
+# There are too many San Joses elsewhere, so we'll use `Costa Rica'.
2627
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2628
+Zone America/Costa_Rica	-5:36:20 -	LMT	1890		# San Jose
2629
+			-5:36:20 -	SJMT	1921 Jan 15 # San Jose Mean Time
2630
+			-6:00	CR	C%sT
2631
+# Coco
2632
+# no information; probably like America/Costa_Rica
2633
+
2634
+# Cuba
2635
+
2636
+# From Arthur David Olson (1999-03-29):
2637
+# The 1999-03-28 exhibition baseball game held in Havana, Cuba, between
2638
+# the Cuban National Team and the Baltimore Orioles was carried live on
2639
+# the Orioles Radio Network, including affiliate WTOP in Washington, DC.
2640
+# During the game, play-by-play announcer Jim Hunter noted that
2641
+# "We'll be losing two hours of sleep...Cuba switched to Daylight Saving
2642
+# Time today."  (The "two hour" remark referred to losing one hour of
2643
+# sleep on 1999-03-28--when the announcers were in Cuba as it switched
2644
+# to DST--and one more hour on 1999-04-04--when the announcers will have
2645
+# returned to Baltimore, which switches on that date.)
2646
+
2647
+# From Evert van der Veer via Steffen Thorsen (2004-10-28):
2648
+# Cuba is not going back to standard time this year.
2649
+# From Paul Eggert (2006-03-22):
2650
+# http://www.granma.cu/ingles/2004/septiembre/juev30/41medid-i.html
2651
+# says that it's due to a problem at the Antonio Guiteras
2652
+# thermoelectric plant, and says "This October there will be no return
2653
+# to normal hours (after daylight saving time)".
2654
+# For now, let's assume that it's a temporary measure.
2655
+
2656
+# From Carlos A. Carnero Delgado (2005-11-12):
2657
+# This year (just like in 2004-2005) there's no change in time zone
2658
+# adjustment in Cuba.  We will stay in daylight saving time:
2659
+# http://www.granma.cu/espanol/2005/noviembre/mier9/horario.html
2660
+
2661
+# From Jesper Norgaard Welen (2006-10-21):
2662
+# An article in GRANMA INTERNACIONAL claims that Cuba will end
2663
+# the 3 years of permanent DST next weekend, see
2664
+# http://www.granma.cu/ingles/2006/octubre/lun16/43horario.html
2665
+# "On Saturday night, October 28 going into Sunday, October 29, at 01:00,
2666
+# watches should be set back one hour -- going back to 00:00 hours -- returning
2667
+# to the normal schedule....
2668
+
2669
+# From Paul Eggert (2007-03-02):
2670
+# http://www.granma.cubaweb.cu/english/news/art89.html, dated yesterday,
2671
+# says Cuban clocks will advance at midnight on March 10.
2672
+# For lack of better information, assume Cuba will use US rules,
2673
+# except that it switches at midnight standard time as usual.
2674
+#
2675
+# From Steffen Thorsen (2007-10-25):
2676
+# Carlos Alberto Fonseca Arauz informed me that Cuba will end DST one week
2677
+# earlier - on the last Sunday of October, just like in 2006.
2678
+#
2679
+# He supplied these references:
2680
+#
2681
+# http://www.prensalatina.com.mx/article.asp?ID=%7B4CC32C1B-A9F7-42FB-8A07-8631AFC923AF%7D&language=ES
2682
+# http://actualidad.terra.es/sociedad/articulo/cuba_llama_ahorrar_energia_cambio_1957044.htm
2683
+#
2684
+# From Alex Kryvenishev (2007-10-25):
2685
+# Here is also article from Granma (Cuba):
2686
+#
2687
+# [Regira] el Horario Normal desde el [proximo] domingo 28 de octubre
2688
+# http://www.granma.cubaweb.cu/2007/10/24/nacional/artic07.html
2689
+#
2690
+# http://www.worldtimezone.com/dst_news/dst_news_cuba03.html
2691
+
2692
+# From Arthur David Olson (2008-03-09):
2693
+# I'm in Maryland which is now observing United States Eastern Daylight
2694
+# Time. At 9:44 local time I used RealPlayer to listen to
2695
+# <a href="http://media.enet.cu/radioreloj">
2696
+# http://media.enet.cu/radioreloj
2697
+# </a>, a Cuban information station, and heard
2698
+# the time announced as "ocho cuarenta y cuatro" ("eight forty-four"),
2699
+# indicating that Cuba is still on standard time.
2700
+
2701
+# From Steffen Thorsen (2008-03-12):
2702
+# It seems that Cuba will start DST on Sunday, 2007-03-16...
2703
+# It was announced yesterday, according to this source (in Spanish):
2704
+# <a href="http://www.nnc.cubaweb.cu/marzo-2008/cien-1-11-3-08.htm">
2705
+# http://www.nnc.cubaweb.cu/marzo-2008/cien-1-11-3-08.htm
2706
+# </a>
2707
+#
2708
+# Some more background information is posted here:
2709
+# <a href="http://www.timeanddate.com/news/time/cuba-starts-dst-march-16.html">
2710
+# http://www.timeanddate.com/news/time/cuba-starts-dst-march-16.html
2711
+# </a>
2712
+#
2713
+# The article also says that Cuba has been observing DST since 1963,
2714
+# while Shanks (and tzdata) has 1965 as the first date (except in the
2715
+# 1940's). Many other web pages in Cuba also claim that it has been
2716
+# observed since 1963, but with the exception of 1970 - an exception
2717
+# which is not present in tzdata/Shanks. So there is a chance we need to
2718
+# change some historic records as well.
2719
+#
2720
+# One example:
2721
+# <a href="http://www.radiohc.cu/espanol/noticias/mar07/11mar/hor.htm">
2722
+# http://www.radiohc.cu/espanol/noticias/mar07/11mar/hor.htm
2723
+# </a>
2724
+
2725
+# From Jesper Norgaard Welen (2008-03-13):
2726
+# The Cuban time change has just been confirmed on the most authoritative
2727
+# web site, the Granma.  Please check out
2728
+# <a href="http://www.granma.cubaweb.cu/2008/03/13/nacional/artic10.html">
2729
+# http://www.granma.cubaweb.cu/2008/03/13/nacional/artic10.html
2730
+# </a>
2731
+#
2732
+# Basically as expected after Steffen Thorsens information, the change
2733
+# will take place midnight between Saturday and Sunday.
2734
+
2735
+# From Arthur David Olson (2008-03-12):
2736
+# Assume Sun>=15 (third Sunday) going forward.
2737
+
2738
+# From Alexander Krivenyshev (2009-03-04)
2739
+# According to the Radio Reloj - Cuba will start Daylight Saving Time on
2740
+# midnight between Saturday, March 07, 2009 and Sunday, March 08, 2009-
2741
+# not on midnight March 14 / March 15 as previously thought.
2742
+#
2743
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_cuba05.html">
2744
+# http://www.worldtimezone.com/dst_news/dst_news_cuba05.html
2745
+# (in Spanish)
2746
+# </a>
2747
+
2748
+# From Arthur David Olson (2009-03-09)
2749
+# I listened over the Internet to
2750
+# <a href="http://media.enet.cu/readioreloj">
2751
+# http://media.enet.cu/readioreloj
2752
+# </a>
2753
+# this morning; when it was 10:05 a. m. here in Bethesda, Maryland the
2754
+# the time was announced as "diez cinco"--the same time as here, indicating
2755
+# that has indeed switched to DST. Assume second Sunday from 2009 forward.
2756
+
2757
+# From Steffen Thorsen (2011-03-08):
2758
+# Granma announced that Cuba is going to start DST on 2011-03-20 00:00:00
2759
+# this year. Nothing about the end date known so far (if that has
2760
+# changed at all).
2761
+#
2762
+# Source:
2763
+# <a href="http://granma.co.cu/2011/03/08/nacional/artic01.html">
2764
+# http://granma.co.cu/2011/03/08/nacional/artic01.html
2765
+# </a>
2766
+#
2767
+# Our info:
2768
+# <a href="http://www.timeanddate.com/news/time/cuba-starts-dst-2011.html">
2769
+# http://www.timeanddate.com/news/time/cuba-starts-dst-2011.html
2770
+# </a>
2771
+#
2772
+# From Steffen Thorsen (2011-10-30)
2773
+# Cuba will end DST two weeks later this year. Instead of going back
2774
+# tonight, it has been delayed to 2011-11-13 at 01:00.
2775
+#
2776
+# One source (Spanish)
2777
+# <a href="http://www.radioangulo.cu/noticias/cuba/17105-cuba-restablecera-el-horario-del-meridiano-de-greenwich.html">
2778
+# http://www.radioangulo.cu/noticias/cuba/17105-cuba-restablecera-el-horario-del-meridiano-de-greenwich.html
2779
+# </a>
2780
+#
2781
+# Our page:
2782
+# <a href="http://www.timeanddate.com/news/time/cuba-time-changes-2011.html">
2783
+# http://www.timeanddate.com/news/time/cuba-time-changes-2011.html
2784
+# </a>
2785
+#
2786
+# From Steffen Thorsen (2012-03-01)
2787
+# According to Radio Reloj, Cuba will start DST on Midnight between March
2788
+# 31 and April 1.
2789
+#
2790
+# Radio Reloj has the following info (Spanish):
2791
+# <a href="http://www.radioreloj.cu/index.php/noticias-radio-reloj/71-miscelaneas/7529-cuba-aplicara-el-horario-de-verano-desde-el-1-de-abril">
2792
+# http://www.radioreloj.cu/index.php/noticias-radio-reloj/71-miscelaneas/7529-cuba-aplicara-el-horario-de-verano-desde-el-1-de-abril
2793
+# </a>
2794
+#
2795
+# Our info on it:
2796
+# <a href="http://www.timeanddate.com/news/time/cuba-starts-dst-2012.html">
2797
+# http://www.timeanddate.com/news/time/cuba-starts-dst-2012.html
2798
+# </a>
2799
+
2800
+# From Steffen Thorsen (2012-11-03):
2801
+# Radio Reloj and many other sources report that Cuba is changing back
2802
+# to standard time on 2012-11-04:
2803
+# http://www.radioreloj.cu/index.php/noticias-radio-reloj/36-nacionales/9961-regira-horario-normal-en-cuba-desde-el-domingo-cuatro-de-noviembre
2804
+# From Paul Eggert (2012-11-03):
2805
+# For now, assume the future rule is first Sunday in November.
2806
+
2807
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
2808
+Rule	Cuba	1928	only	-	Jun	10	0:00	1:00	D
2809
+Rule	Cuba	1928	only	-	Oct	10	0:00	0	S
2810
+Rule	Cuba	1940	1942	-	Jun	Sun>=1	0:00	1:00	D
2811
+Rule	Cuba	1940	1942	-	Sep	Sun>=1	0:00	0	S
2812
+Rule	Cuba	1945	1946	-	Jun	Sun>=1	0:00	1:00	D
2813
+Rule	Cuba	1945	1946	-	Sep	Sun>=1	0:00	0	S
2814
+Rule	Cuba	1965	only	-	Jun	1	0:00	1:00	D
2815
+Rule	Cuba	1965	only	-	Sep	30	0:00	0	S
2816
+Rule	Cuba	1966	only	-	May	29	0:00	1:00	D
2817
+Rule	Cuba	1966	only	-	Oct	2	0:00	0	S
2818
+Rule	Cuba	1967	only	-	Apr	8	0:00	1:00	D
2819
+Rule	Cuba	1967	1968	-	Sep	Sun>=8	0:00	0	S
2820
+Rule	Cuba	1968	only	-	Apr	14	0:00	1:00	D
2821
+Rule	Cuba	1969	1977	-	Apr	lastSun	0:00	1:00	D
2822
+Rule	Cuba	1969	1971	-	Oct	lastSun	0:00	0	S
2823
+Rule	Cuba	1972	1974	-	Oct	8	0:00	0	S
2824
+Rule	Cuba	1975	1977	-	Oct	lastSun	0:00	0	S
2825
+Rule	Cuba	1978	only	-	May	7	0:00	1:00	D
2826
+Rule	Cuba	1978	1990	-	Oct	Sun>=8	0:00	0	S
2827
+Rule	Cuba	1979	1980	-	Mar	Sun>=15	0:00	1:00	D
2828
+Rule	Cuba	1981	1985	-	May	Sun>=5	0:00	1:00	D
2829
+Rule	Cuba	1986	1989	-	Mar	Sun>=14	0:00	1:00	D
2830
+Rule	Cuba	1990	1997	-	Apr	Sun>=1	0:00	1:00	D
2831
+Rule	Cuba	1991	1995	-	Oct	Sun>=8	0:00s	0	S
2832
+Rule	Cuba	1996	only	-	Oct	 6	0:00s	0	S
2833
+Rule	Cuba	1997	only	-	Oct	12	0:00s	0	S
2834
+Rule	Cuba	1998	1999	-	Mar	lastSun	0:00s	1:00	D
2835
+Rule	Cuba	1998	2003	-	Oct	lastSun	0:00s	0	S
2836
+Rule	Cuba	2000	2004	-	Apr	Sun>=1	0:00s	1:00	D
2837
+Rule	Cuba	2006	2010	-	Oct	lastSun	0:00s	0	S
2838
+Rule	Cuba	2007	only	-	Mar	Sun>=8	0:00s	1:00	D
2839
+Rule	Cuba	2008	only	-	Mar	Sun>=15	0:00s	1:00	D
2840
+Rule	Cuba	2009	2010	-	Mar	Sun>=8	0:00s	1:00	D
2841
+Rule	Cuba	2011	only	-	Mar	Sun>=15	0:00s	1:00	D
2842
+Rule	Cuba	2011	only	-	Nov	13	0:00s	0	S
2843
+Rule	Cuba	2012	only	-	Apr	1	0:00s	1:00	D
2844
+Rule	Cuba	2012	max	-	Nov	Sun>=1	0:00s	0	S
2845
+Rule	Cuba	2013	max	-	Mar	Sun>=8	0:00s	1:00	D
2846
+
2847
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2848
+Zone	America/Havana	-5:29:28 -	LMT	1890
2849
+			-5:29:36 -	HMT	1925 Jul 19 12:00 # Havana MT
2850
+			-5:00	Cuba	C%sT
2851
+
2852
+# Dominica
2853
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2854
+Zone America/Dominica	-4:05:36 -	LMT	1911 Jul 1 0:01		# Roseau
2855
+			-4:00	-	AST
2856
+
2857
+# Dominican Republic
2858
+
2859
+# From Steffen Thorsen (2000-10-30):
2860
+# Enrique Morales reported to me that the Dominican Republic has changed the
2861
+# time zone to Eastern Standard Time as of Sunday 29 at 2 am....
2862
+# http://www.listin.com.do/antes/261000/republica/princi.html
2863
+
2864
+# From Paul Eggert (2000-12-04):
2865
+# That URL (2000-10-26, in Spanish) says they planned to use US-style DST.
2866
+
2867
+# From Rives McDow (2000-12-01):
2868
+# Dominican Republic changed its mind and presidential decree on Tuesday,
2869
+# November 28, 2000, with a new decree.  On Sunday, December 3 at 1:00 AM the
2870
+# Dominican Republic will be reverting to 8 hours from the International Date
2871
+# Line, and will not be using DST in the foreseeable future.  The reason they
2872
+# decided to use DST was to be in synch with Puerto Rico, who was also going
2873
+# to implement DST.  When Puerto Rico didn't implement DST, the president
2874
+# decided to revert.
2875
+
2876
+
2877
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
2878
+Rule	DR	1966	only	-	Oct	30	0:00	1:00	D
2879
+Rule	DR	1967	only	-	Feb	28	0:00	0	S
2880
+Rule	DR	1969	1973	-	Oct	lastSun	0:00	0:30	HD
2881
+Rule	DR	1970	only	-	Feb	21	0:00	0	S
2882
+Rule	DR	1971	only	-	Jan	20	0:00	0	S
2883
+Rule	DR	1972	1974	-	Jan	21	0:00	0	S
2884
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2885
+Zone America/Santo_Domingo -4:39:36 -	LMT	1890
2886
+			-4:40	-	SDMT	1933 Apr  1 12:00 # S. Dom. MT
2887
+			-5:00	DR	E%sT	1974 Oct 27
2888
+			-4:00	-	AST	2000 Oct 29 02:00
2889
+			-5:00	US	E%sT	2000 Dec  3 01:00
2890
+			-4:00	-	AST
2891
+
2892
+# El Salvador
2893
+
2894
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
2895
+Rule	Salv	1987	1988	-	May	Sun>=1	0:00	1:00	D
2896
+Rule	Salv	1987	1988	-	Sep	lastSun	0:00	0	S
2897
+# There are too many San Salvadors elsewhere, so use America/El_Salvador
2898
+# instead of America/San_Salvador.
2899
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2900
+Zone America/El_Salvador -5:56:48 -	LMT	1921		# San Salvador
2901
+			-6:00	Salv	C%sT
2902
+
2903
+# Grenada
2904
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2905
+Zone	America/Grenada	-4:07:00 -	LMT	1911 Jul	# St George's
2906
+			-4:00	-	AST
2907
+
2908
+# Guadeloupe
2909
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2910
+Zone America/Guadeloupe	-4:06:08 -	LMT	1911 Jun 8	# Pointe a Pitre
2911
+			-4:00	-	AST
2912
+# St Barthelemy
2913
+Link America/Guadeloupe	America/St_Barthelemy
2914
+# St Martin (French part)
2915
+Link America/Guadeloupe	America/Marigot
2916
+
2917
+# Guatemala
2918
+#
2919
+# From Gwillim Law (2006-04-22), after a heads-up from Oscar van Vlijmen:
2920
+# Diario Co Latino, at
2921
+# http://www.diariocolatino.com/internacionales/detalles.asp?NewsID=8079,
2922
+# says in an article dated 2006-04-19 that the Guatemalan government had
2923
+# decided on that date to advance official time by 60 minutes, to lessen the
2924
+# impact of the elevated cost of oil....  Daylight saving time will last from
2925
+# 2006-04-29 24:00 (Guatemalan standard time) to 2006-09-30 (time unspecified).
2926
+# From Paul Eggert (2006-06-22):
2927
+# The Ministry of Energy and Mines, press release CP-15/2006
2928
+# (2006-04-19), says DST ends at 24:00.  See
2929
+# <http://www.sieca.org.gt/Sitio_publico/Energeticos/Doc/Medidas/Cambio_Horario_Nac_190406.pdf>.
2930
+
2931
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
2932
+Rule	Guat	1973	only	-	Nov	25	0:00	1:00	D
2933
+Rule	Guat	1974	only	-	Feb	24	0:00	0	S
2934
+Rule	Guat	1983	only	-	May	21	0:00	1:00	D
2935
+Rule	Guat	1983	only	-	Sep	22	0:00	0	S
2936
+Rule	Guat	1991	only	-	Mar	23	0:00	1:00	D
2937
+Rule	Guat	1991	only	-	Sep	 7	0:00	0	S
2938
+Rule	Guat	2006	only	-	Apr	30	0:00	1:00	D
2939
+Rule	Guat	2006	only	-	Oct	 1	0:00	0	S
2940
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
2941
+Zone America/Guatemala	-6:02:04 -	LMT	1918 Oct 5
2942
+			-6:00	Guat	C%sT
2943
+
2944
+# Haiti
2945
+# From Gwillim Law (2005-04-15):
2946
+# Risto O. Nykanen wrote me that Haiti is now on DST.
2947
+# I searched for confirmation, and I found a
2948
+# <a href="http://www.haitianconsulate.org/time.doc"> press release
2949
+# on the Web page of the Haitian Consulate in Chicago (2005-03-31),
2950
+# </a>.  Translated from French, it says:
2951
+#
2952
+#  "The Prime Minister's Communication Office notifies the public in general
2953
+#   and the press in particular that, following a decision of the Interior
2954
+#   Ministry and the Territorial Collectivities [I suppose that means the
2955
+#   provinces], Haiti will move to Eastern Daylight Time in the night from next
2956
+#   Saturday the 2nd to Sunday the 3rd.
2957
+#
2958
+#  "Consequently, the Prime Minister's Communication Office wishes to inform
2959
+#   the population that the country's clocks will be set forward one hour
2960
+#   starting at midnight.  This provision will hold until the last Saturday in
2961
+#   October 2005.
2962
+#
2963
+#  "Port-au-Prince, March 31, 2005"
2964
+#
2965
+# From Steffen Thorsen (2006-04-04):
2966
+# I have been informed by users that Haiti observes DST this year like
2967
+# last year, so the current "only" rule for 2005 might be changed to a
2968
+# "max" rule or to last until 2006. (Who knows if they will observe DST
2969
+# next year or if they will extend their DST like US/Canada next year).
2970
+#
2971
+# I have found this article about it (in French):
2972
+# http://www.haitipressnetwork.com/news.cfm?articleID=7612
2973
+#
2974
+# The reason seems to be an energy crisis.
2975
+
2976
+# From Stephen Colebourne (2007-02-22):
2977
+# Some IATA info: Haiti won't be having DST in 2007.
2978
+
2979
+# From Steffen Thorsen (2012-03-11):
2980
+# According to several news sources, Haiti will observe DST this year,
2981
+# apparently using the same start and end date as USA/Canada.
2982
+# So this means they have already changed their time.
2983
+#
2984
+# (Sources in French):
2985
+# <a href="http://www.alterpresse.org/spip.php?article12510">
2986
+# http://www.alterpresse.org/spip.php?article12510
2987
+# </a>
2988
+# <a href="http://radiovision2000haiti.net/home/?p=13253">
2989
+# http://radiovision2000haiti.net/home/?p=13253
2990
+# </a>
2991
+#
2992
+# Our coverage:
2993
+# <a href="http://www.timeanddate.com/news/time/haiti-dst-2012.html">
2994
+# http://www.timeanddate.com/news/time/haiti-dst-2012.html
2995
+# </a>
2996
+
2997
+# From Arthur David Olson (2012-03-11):
2998
+# The alterpresse.org source seems to show a US-style leap from 2:00 a.m. to
2999
+# 3:00 a.m. rather than the traditional Haitian jump at midnight.
3000
+# Assume a US-style fall back as well XXX.
3001
+# Do not yet assume that the change carries forward past 2012 XXX.
3002
+
3003
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
3004
+Rule	Haiti	1983	only	-	May	8	0:00	1:00	D
3005
+Rule	Haiti	1984	1987	-	Apr	lastSun	0:00	1:00	D
3006
+Rule	Haiti	1983	1987	-	Oct	lastSun	0:00	0	S
3007
+# Shanks & Pottenger say AT is 2:00, but IATA SSIM (1991/1997) says 1:00s.
3008
+# Go with IATA.
3009
+Rule	Haiti	1988	1997	-	Apr	Sun>=1	1:00s	1:00	D
3010
+Rule	Haiti	1988	1997	-	Oct	lastSun	1:00s	0	S
3011
+Rule	Haiti	2005	2006	-	Apr	Sun>=1	0:00	1:00	D
3012
+Rule	Haiti	2005	2006	-	Oct	lastSun	0:00	0	S
3013
+Rule	Haiti	2012	only	-	Mar	Sun>=8	2:00	1:00	D
3014
+Rule	Haiti	2012	only	-	Nov	Sun>=1	2:00	0	S
3015
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
3016
+Zone America/Port-au-Prince -4:49:20 -	LMT	1890
3017
+			-4:49	-	PPMT	1917 Jan 24 12:00 # P-a-P MT
3018
+			-5:00	Haiti	E%sT
3019
+
3020
+# Honduras
3021
+# Shanks & Pottenger say 1921 Jan 1; go with Whitman's more precise Apr 1.
3022
+
3023
+# From Paul Eggert (2006-05-05):
3024
+# worldtimezone.com reports a 2006-05-02 Spanish-language AP article
3025
+# saying Honduras will start using DST midnight Saturday, effective 4
3026
+# months until September.  La Tribuna reported today
3027
+# <http://www.latribuna.hn/99299.html> that Manuel Zelaya, the president
3028
+# of Honduras, refused to back down on this.
3029
+
3030
+# From Jesper Norgaard Welen (2006-08-08):
3031
+# It seems that Honduras has returned from DST to standard time this Monday at
3032
+# 00:00 hours (prolonging Sunday to 25 hours duration).
3033
+# http://www.worldtimezone.com/dst_news/dst_news_honduras04.html
3034
+
3035
+# From Paul Eggert (2006-08-08):
3036
+# Also see Diario El Heraldo, The country returns to standard time (2006-08-08)
3037
+# <http://www.elheraldo.hn/nota.php?nid=54941&sec=12>.
3038
+# It mentions executive decree 18-2006.
3039
+
3040
+# From Steffen Thorsen (2006-08-17):
3041
+# Honduras will observe DST from 2007 to 2009, exact dates are not
3042
+# published, I have located this authoritative source:
3043
+# http://www.presidencia.gob.hn/noticia.aspx?nId=47
3044
+
3045
+# From Steffen Thorsen (2007-03-30):
3046
+# http://www.laprensahn.com/pais_nota.php?id04962=7386
3047
+# So it seems that Honduras will not enter DST this year....
3048
+
3049
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
3050
+Rule	Hond	1987	1988	-	May	Sun>=1	0:00	1:00	D
3051
+Rule	Hond	1987	1988	-	Sep	lastSun	0:00	0	S
3052
+Rule	Hond	2006	only	-	May	Sun>=1	0:00	1:00	D
3053
+Rule	Hond	2006	only	-	Aug	Mon>=1	0:00	0	S
3054
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
3055
+Zone America/Tegucigalpa -5:48:52 -	LMT	1921 Apr
3056
+			-6:00	Hond	C%sT
3057
+#
3058
+# Great Swan I ceded by US to Honduras in 1972
3059
+
3060
+# Jamaica
3061
+
3062
+# From Bob Devine (1988-01-28):
3063
+# Follows US rules.
3064
+
3065
+# From U. S. Naval Observatory (1989-01-19):
3066
+# JAMAICA             5 H  BEHIND UTC
3067
+
3068
+# From Shanks & Pottenger:
3069
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
3070
+Zone	America/Jamaica	-5:07:12 -	LMT	1890		# Kingston
3071
+			-5:07:12 -	KMT	1912 Feb    # Kingston Mean Time
3072
+			-5:00	-	EST	1974 Apr 28 2:00
3073
+			-5:00	US	E%sT	1984
3074
+			-5:00	-	EST
3075
+
3076
+# Martinique
3077
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
3078
+Zone America/Martinique	-4:04:20 -      LMT	1890		# Fort-de-France
3079
+			-4:04:20 -	FFMT	1911 May     # Fort-de-France MT
3080
+			-4:00	-	AST	1980 Apr  6
3081
+			-4:00	1:00	ADT	1980 Sep 28
3082
+			-4:00	-	AST
3083
+
3084
+# Montserrat
3085
+# From Paul Eggert (2006-03-22):
3086
+# In 1995 volcanic eruptions forced evacuation of Plymouth, the capital.
3087
+# world.gazetteer.com says Cork Hill is the most populous location now.
3088
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
3089
+Zone America/Montserrat	-4:08:52 -	LMT	1911 Jul 1 0:01   # Cork Hill
3090
+			-4:00	-	AST
3091
+
3092
+# Nicaragua
3093
+#
3094
+# This uses Shanks & Pottenger for times before 2005.
3095
+#
3096
+# From Steffen Thorsen (2005-04-12):
3097
+# I've got reports from 8 different people that Nicaragua just started
3098
+# DST on Sunday 2005-04-10, in order to save energy because of
3099
+# expensive petroleum.  The exact end date for DST is not yet
3100
+# announced, only "September" but some sites also say "mid-September".
3101
+# Some background information is available on the President's official site:
3102
+# http://www.presidencia.gob.ni/Presidencia/Files_index/Secretaria/Notas%20de%20Prensa/Presidente/2005/ABRIL/Gobierno-de-nicaragua-adelanta-hora-oficial-06abril.htm
3103
+# The Decree, no 23-2005 is available here:
3104
+# http://www.presidencia.gob.ni/buscador_gaceta/BD/DECRETOS/2005/Decreto%2023-2005%20Se%20adelanta%20en%20una%20hora%20en%20todo%20el%20territorio%20nacional%20apartir%20de%20las%2024horas%20del%2009%20de%20Abril.pdf
3105
+#
3106
+# From Paul Eggert (2005-05-01):
3107
+# The decree doesn't say anything about daylight saving, but for now let's
3108
+# assume that it is daylight saving....
3109
+#
3110
+# From Gwillim Law (2005-04-21):
3111
+# The Associated Press story on the time change, which can be found at
3112
+# http://www.lapalmainteractivo.com/guias/content/gen/ap/America_Latina/AMC_GEN_NICARAGUA_HORA.html
3113
+# and elsewhere, says (fifth paragraph, translated from Spanish):  "The last
3114
+# time that a change of clocks was applied to save energy was in the year 2000
3115
+# during the Arnoldo Aleman administration."...
3116
+# The northamerica file says that Nicaragua has been on UTC-6 continuously
3117
+# since December 1998.  I wasn't able to find any details of Nicaraguan time
3118
+# changes in 2000.  Perhaps a note could be added to the northamerica file, to
3119
+# the effect that we have indirect evidence that DST was observed in 2000.
3120
+#
3121
+# From Jesper Norgaard Welen (2005-11-02):
3122
+# Nicaragua left DST the 2005-10-02 at 00:00 (local time).
3123
+# http://www.presidencia.gob.ni/presidencia/files_index/secretaria/comunicados/2005/septiembre/26septiembre-cambio-hora.htm
3124
+# (2005-09-26)
3125
+#
3126
+# From Jesper Norgaard Welen (2006-05-05):
3127
+# http://www.elnuevodiario.com.ni/2006/05/01/nacionales/18410
3128
+# (my informal translation)
3129
+# By order of the president of the republic, Enrique Bolanos, Nicaragua
3130
+# advanced by sixty minutes their official time, yesterday at 2 in the
3131
+# morning, and will stay that way until 30.th. of september.
3132
+#
3133
+# From Jesper Norgaard Welen (2006-09-30):
3134
+# http://www.presidencia.gob.ni/buscador_gaceta/BD/DECRETOS/2006/D-063-2006P-PRN-Cambio-Hora.pdf
3135
+# My informal translation runs:
3136
+# The natural sun time is restored in all the national territory, in that the
3137
+# time is returned one hour at 01:00 am of October 1 of 2006.
3138
+#
3139
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
3140
+Rule	Nic	1979	1980	-	Mar	Sun>=16	0:00	1:00	D
3141
+Rule	Nic	1979	1980	-	Jun	Mon>=23	0:00	0	S
3142
+Rule	Nic	2005	only	-	Apr	10	0:00	1:00	D
3143
+Rule	Nic	2005	only	-	Oct	Sun>=1	0:00	0	S
3144
+Rule	Nic	2006	only	-	Apr	30	2:00	1:00	D
3145
+Rule	Nic	2006	only	-	Oct	Sun>=1	1:00	0	S
3146
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
3147
+Zone	America/Managua	-5:45:08 -	LMT	1890
3148
+			-5:45:12 -	MMT	1934 Jun 23 # Managua Mean Time?
3149
+			-6:00	-	CST	1973 May
3150
+			-5:00	-	EST	1975 Feb 16
3151
+			-6:00	Nic	C%sT	1992 Jan  1 4:00
3152
+			-5:00	-	EST	1992 Sep 24
3153
+			-6:00	-	CST	1993
3154
+			-5:00	-	EST	1997
3155
+			-6:00	Nic	C%sT
3156
+
3157
+# Panama
3158
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
3159
+Zone	America/Panama	-5:18:08 -	LMT	1890
3160
+			-5:19:36 -	CMT	1908 Apr 22   # Colon Mean Time
3161
+			-5:00	-	EST
3162
+
3163
+# Puerto Rico
3164
+# There are too many San Juans elsewhere, so we'll use `Puerto_Rico'.
3165
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
3166
+Zone America/Puerto_Rico -4:24:25 -	LMT	1899 Mar 28 12:00    # San Juan
3167
+			-4:00	-	AST	1942 May  3
3168
+			-4:00	US	A%sT	1946
3169
+			-4:00	-	AST
3170
+
3171
+# St Kitts-Nevis
3172
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
3173
+Zone America/St_Kitts	-4:10:52 -	LMT	1912 Mar 2	# Basseterre
3174
+			-4:00	-	AST
3175
+
3176
+# St Lucia
3177
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
3178
+Zone America/St_Lucia	-4:04:00 -	LMT	1890		# Castries
3179
+			-4:04:00 -	CMT	1912	    # Castries Mean Time
3180
+			-4:00	-	AST
3181
+
3182
+# St Pierre and Miquelon
3183
+# There are too many St Pierres elsewhere, so we'll use `Miquelon'.
3184
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
3185
+Zone America/Miquelon	-3:44:40 -	LMT	1911 May 15	# St Pierre
3186
+			-4:00	-	AST	1980 May
3187
+			-3:00	-	PMST	1987 # Pierre & Miquelon Time
3188
+			-3:00	Canada	PM%sT
3189
+
3190
+# St Vincent and the Grenadines
3191
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
3192
+Zone America/St_Vincent	-4:04:56 -	LMT	1890		# Kingstown
3193
+			-4:04:56 -	KMT	1912	   # Kingstown Mean Time
3194
+			-4:00	-	AST
3195
+
3196
+# Turks and Caicos
3197
+#
3198
+# From Chris Dunn in
3199
+# <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=415007>
3200
+# (2007-03-15): In the Turks & Caicos Islands (America/Grand_Turk) the
3201
+# daylight saving dates for time changes have been adjusted to match
3202
+# the recent U.S. change of dates.
3203
+#
3204
+# From Brian Inglis (2007-04-28):
3205
+# http://www.turksandcaicos.tc/calendar/index.htm [2007-04-26]
3206
+# there is an entry for Nov 4 "Daylight Savings Time Ends 2007" and three
3207
+# rows before that there is an out of date entry for Oct:
3208
+# "Eastern Standard Times Begins 2007
3209
+# Clocks are set back one hour at 2:00 a.m. local Daylight Saving Time"
3210
+# indicating that the normal ET rules are followed.
3211
+#
3212
+# From Paul Eggert (2006-05-01):
3213
+# Shanks & Pottenger say they use US DST rules, but IATA SSIM (1991/1998)
3214
+# says they switch at midnight.  Go with Shanks & Pottenger.
3215
+#
3216
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
3217
+Rule	TC	1979	1986	-	Apr	lastSun	2:00	1:00	D
3218
+Rule	TC	1979	2006	-	Oct	lastSun	2:00	0	S
3219
+Rule	TC	1987	2006	-	Apr	Sun>=1	2:00	1:00	D
3220
+Rule	TC	2007	max	-	Mar	Sun>=8	2:00	1:00	D
3221
+Rule	TC	2007	max	-	Nov	Sun>=1	2:00	0	S
3222
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
3223
+Zone America/Grand_Turk	-4:44:32 -	LMT	1890
3224
+			-5:07:12 -	KMT	1912 Feb    # Kingston Mean Time
3225
+			-5:00	TC	E%sT
3226
+
3227
+# British Virgin Is
3228
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
3229
+Zone America/Tortola	-4:18:28 -	LMT	1911 Jul    # Road Town
3230
+			-4:00	-	AST
3231
+
3232
+# Virgin Is
3233
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
3234
+Zone America/St_Thomas	-4:19:44 -	LMT	1911 Jul    # Charlotte Amalie
3235
+			-4:00	-	AST
... ...
@@ -0,0 +1,28 @@
1
+# <pre>
2
+# This file is in the public domain, so clarified as of
3
+# 2009-05-17 by Arthur David Olson.
4
+
5
+# From Arthur David Olson (1989-04-05):
6
+# On 1989-04-05, the U. S. House of Representatives passed (238-154) a bill
7
+# establishing "Pacific Presidential Election Time"; it was not acted on
8
+# by the Senate or signed into law by the President.
9
+# You might want to change the "PE" (Presidential Election) below to
10
+# "Q" (Quadrennial) to maintain three-character zone abbreviations.
11
+# If you're really conservative, you might want to change it to "D".
12
+# Avoid "L" (Leap Year), which won't be true in 2100.
13
+
14
+# If Presidential Election Time is ever established, replace "XXXX" below
15
+# with the year the law takes effect and uncomment the "##" lines.
16
+
17
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
18
+## Rule	Twilite	XXXX	max	-	Apr	Sun>=1	2:00	1:00	D
19
+## Rule	Twilite	XXXX	max	uspres	Oct	lastSun	2:00	1:00	PE
20
+## Rule	Twilite	XXXX	max	uspres	Nov	Sun>=7	2:00	0	S
21
+## Rule	Twilite	XXXX	max	nonpres	Oct	lastSun	2:00	0	S
22
+
23
+# Zone	NAME			GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
24
+## Zone	America/Los_Angeles-PET	-8:00	US		P%sT	XXXX
25
+##				-8:00	Twilite		P%sT
26
+
27
+# For now...
28
+Link	America/Los_Angeles	US/Pacific-New	##
... ...
@@ -0,0 +1,390 @@
1
+# <pre>
2
+# This file is in the public domain, so clarified as of
3
+# 2009-05-17 by Arthur David Olson.
4
+
5
+# So much for footnotes about Saudi Arabia.
6
+# Apparent noon times below are for Riyadh; your mileage will vary.
7
+# Times were computed using formulas in the U.S. Naval Observatory's
8
+# Almanac for Computers 1987; the formulas "will give EqT to an accuracy of
9
+# [plus or minus two] seconds during the current year."
10
+#
11
+# Rounding to the nearest five seconds results in fewer than
12
+# 256 different "time types"--a limit that's faced because time types are
13
+# stored on disk as unsigned chars.
14
+
15
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
16
+Rule	sol87	1987	only	-	Jan	1	12:03:20s -0:03:20 -
17
+Rule	sol87	1987	only	-	Jan	2	12:03:50s -0:03:50 -
18
+Rule	sol87	1987	only	-	Jan	3	12:04:15s -0:04:15 -
19
+Rule	sol87	1987	only	-	Jan	4	12:04:45s -0:04:45 -
20
+Rule	sol87	1987	only	-	Jan	5	12:05:10s -0:05:10 -
21
+Rule	sol87	1987	only	-	Jan	6	12:05:40s -0:05:40 -
22
+Rule	sol87	1987	only	-	Jan	7	12:06:05s -0:06:05 -
23
+Rule	sol87	1987	only	-	Jan	8	12:06:30s -0:06:30 -
24
+Rule	sol87	1987	only	-	Jan	9	12:06:55s -0:06:55 -
25
+Rule	sol87	1987	only	-	Jan	10	12:07:20s -0:07:20 -
26
+Rule	sol87	1987	only	-	Jan	11	12:07:45s -0:07:45 -
27
+Rule	sol87	1987	only	-	Jan	12	12:08:10s -0:08:10 -
28
+Rule	sol87	1987	only	-	Jan	13	12:08:30s -0:08:30 -
29
+Rule	sol87	1987	only	-	Jan	14	12:08:55s -0:08:55 -
30
+Rule	sol87	1987	only	-	Jan	15	12:09:15s -0:09:15 -
31
+Rule	sol87	1987	only	-	Jan	16	12:09:35s -0:09:35 -
32
+Rule	sol87	1987	only	-	Jan	17	12:09:55s -0:09:55 -
33
+Rule	sol87	1987	only	-	Jan	18	12:10:15s -0:10:15 -
34
+Rule	sol87	1987	only	-	Jan	19	12:10:35s -0:10:35 -
35
+Rule	sol87	1987	only	-	Jan	20	12:10:55s -0:10:55 -
36
+Rule	sol87	1987	only	-	Jan	21	12:11:10s -0:11:10 -
37
+Rule	sol87	1987	only	-	Jan	22	12:11:30s -0:11:30 -
38
+Rule	sol87	1987	only	-	Jan	23	12:11:45s -0:11:45 -
39
+Rule	sol87	1987	only	-	Jan	24	12:12:00s -0:12:00 -
40
+Rule	sol87	1987	only	-	Jan	25	12:12:15s -0:12:15 -
41
+Rule	sol87	1987	only	-	Jan	26	12:12:30s -0:12:30 -
42
+Rule	sol87	1987	only	-	Jan	27	12:12:40s -0:12:40 -
43
+Rule	sol87	1987	only	-	Jan	28	12:12:55s -0:12:55 -
44
+Rule	sol87	1987	only	-	Jan	29	12:13:05s -0:13:05 -
45
+Rule	sol87	1987	only	-	Jan	30	12:13:15s -0:13:15 -
46
+Rule	sol87	1987	only	-	Jan	31	12:13:25s -0:13:25 -
47
+Rule	sol87	1987	only	-	Feb	1	12:13:35s -0:13:35 -
48
+Rule	sol87	1987	only	-	Feb	2	12:13:40s -0:13:40 -
49
+Rule	sol87	1987	only	-	Feb	3	12:13:50s -0:13:50 -
50
+Rule	sol87	1987	only	-	Feb	4	12:13:55s -0:13:55 -
51
+Rule	sol87	1987	only	-	Feb	5	12:14:00s -0:14:00 -
52
+Rule	sol87	1987	only	-	Feb	6	12:14:05s -0:14:05 -
53
+Rule	sol87	1987	only	-	Feb	7	12:14:10s -0:14:10 -
54
+Rule	sol87	1987	only	-	Feb	8	12:14:10s -0:14:10 -
55
+Rule	sol87	1987	only	-	Feb	9	12:14:15s -0:14:15 -
56
+Rule	sol87	1987	only	-	Feb	10	12:14:15s -0:14:15 -
57
+Rule	sol87	1987	only	-	Feb	11	12:14:15s -0:14:15 -
58
+Rule	sol87	1987	only	-	Feb	12	12:14:15s -0:14:15 -
59
+Rule	sol87	1987	only	-	Feb	13	12:14:15s -0:14:15 -
60
+Rule	sol87	1987	only	-	Feb	14	12:14:15s -0:14:15 -
61
+Rule	sol87	1987	only	-	Feb	15	12:14:10s -0:14:10 -
62
+Rule	sol87	1987	only	-	Feb	16	12:14:10s -0:14:10 -
63
+Rule	sol87	1987	only	-	Feb	17	12:14:05s -0:14:05 -
64
+Rule	sol87	1987	only	-	Feb	18	12:14:00s -0:14:00 -
65
+Rule	sol87	1987	only	-	Feb	19	12:13:55s -0:13:55 -
66
+Rule	sol87	1987	only	-	Feb	20	12:13:50s -0:13:50 -
67
+Rule	sol87	1987	only	-	Feb	21	12:13:45s -0:13:45 -
68
+Rule	sol87	1987	only	-	Feb	22	12:13:35s -0:13:35 -
69
+Rule	sol87	1987	only	-	Feb	23	12:13:30s -0:13:30 -
70
+Rule	sol87	1987	only	-	Feb	24	12:13:20s -0:13:20 -
71
+Rule	sol87	1987	only	-	Feb	25	12:13:10s -0:13:10 -
72
+Rule	sol87	1987	only	-	Feb	26	12:13:00s -0:13:00 -
73
+Rule	sol87	1987	only	-	Feb	27	12:12:50s -0:12:50 -
74
+Rule	sol87	1987	only	-	Feb	28	12:12:40s -0:12:40 -
75
+Rule	sol87	1987	only	-	Mar	1	12:12:30s -0:12:30 -
76
+Rule	sol87	1987	only	-	Mar	2	12:12:20s -0:12:20 -
77
+Rule	sol87	1987	only	-	Mar	3	12:12:05s -0:12:05 -
78
+Rule	sol87	1987	only	-	Mar	4	12:11:55s -0:11:55 -
79
+Rule	sol87	1987	only	-	Mar	5	12:11:40s -0:11:40 -
80
+Rule	sol87	1987	only	-	Mar	6	12:11:25s -0:11:25 -
81
+Rule	sol87	1987	only	-	Mar	7	12:11:15s -0:11:15 -
82
+Rule	sol87	1987	only	-	Mar	8	12:11:00s -0:11:00 -
83
+Rule	sol87	1987	only	-	Mar	9	12:10:45s -0:10:45 -
84
+Rule	sol87	1987	only	-	Mar	10	12:10:30s -0:10:30 -
85
+Rule	sol87	1987	only	-	Mar	11	12:10:15s -0:10:15 -
86
+Rule	sol87	1987	only	-	Mar	12	12:09:55s -0:09:55 -
87
+Rule	sol87	1987	only	-	Mar	13	12:09:40s -0:09:40 -
88
+Rule	sol87	1987	only	-	Mar	14	12:09:25s -0:09:25 -
89
+Rule	sol87	1987	only	-	Mar	15	12:09:10s -0:09:10 -
90
+Rule	sol87	1987	only	-	Mar	16	12:08:50s -0:08:50 -
91
+Rule	sol87	1987	only	-	Mar	17	12:08:35s -0:08:35 -
92
+Rule	sol87	1987	only	-	Mar	18	12:08:15s -0:08:15 -
93
+Rule	sol87	1987	only	-	Mar	19	12:08:00s -0:08:00 -
94
+Rule	sol87	1987	only	-	Mar	20	12:07:40s -0:07:40 -
95
+Rule	sol87	1987	only	-	Mar	21	12:07:25s -0:07:25 -
96
+Rule	sol87	1987	only	-	Mar	22	12:07:05s -0:07:05 -
97
+Rule	sol87	1987	only	-	Mar	23	12:06:50s -0:06:50 -
98
+Rule	sol87	1987	only	-	Mar	24	12:06:30s -0:06:30 -
99
+Rule	sol87	1987	only	-	Mar	25	12:06:10s -0:06:10 -
100
+Rule	sol87	1987	only	-	Mar	26	12:05:55s -0:05:55 -
101
+Rule	sol87	1987	only	-	Mar	27	12:05:35s -0:05:35 -
102
+Rule	sol87	1987	only	-	Mar	28	12:05:15s -0:05:15 -
103
+Rule	sol87	1987	only	-	Mar	29	12:05:00s -0:05:00 -
104
+Rule	sol87	1987	only	-	Mar	30	12:04:40s -0:04:40 -
105
+Rule	sol87	1987	only	-	Mar	31	12:04:25s -0:04:25 -
106
+Rule	sol87	1987	only	-	Apr	1	12:04:05s -0:04:05 -
107
+Rule	sol87	1987	only	-	Apr	2	12:03:45s -0:03:45 -
108
+Rule	sol87	1987	only	-	Apr	3	12:03:30s -0:03:30 -
109
+Rule	sol87	1987	only	-	Apr	4	12:03:10s -0:03:10 -
110
+Rule	sol87	1987	only	-	Apr	5	12:02:55s -0:02:55 -
111
+Rule	sol87	1987	only	-	Apr	6	12:02:35s -0:02:35 -
112
+Rule	sol87	1987	only	-	Apr	7	12:02:20s -0:02:20 -
113
+Rule	sol87	1987	only	-	Apr	8	12:02:05s -0:02:05 -
114
+Rule	sol87	1987	only	-	Apr	9	12:01:45s -0:01:45 -
115
+Rule	sol87	1987	only	-	Apr	10	12:01:30s -0:01:30 -
116
+Rule	sol87	1987	only	-	Apr	11	12:01:15s -0:01:15 -
117
+Rule	sol87	1987	only	-	Apr	12	12:00:55s -0:00:55 -
118
+Rule	sol87	1987	only	-	Apr	13	12:00:40s -0:00:40 -
119
+Rule	sol87	1987	only	-	Apr	14	12:00:25s -0:00:25 -
120
+Rule	sol87	1987	only	-	Apr	15	12:00:10s -0:00:10 -
121
+Rule	sol87	1987	only	-	Apr	16	11:59:55s 0:00:05 -
122
+Rule	sol87	1987	only	-	Apr	17	11:59:45s 0:00:15 -
123
+Rule	sol87	1987	only	-	Apr	18	11:59:30s 0:00:30 -
124
+Rule	sol87	1987	only	-	Apr	19	11:59:15s 0:00:45 -
125
+Rule	sol87	1987	only	-	Apr	20	11:59:05s 0:00:55 -
126
+Rule	sol87	1987	only	-	Apr	21	11:58:50s 0:01:10 -
127
+Rule	sol87	1987	only	-	Apr	22	11:58:40s 0:01:20 -
128
+Rule	sol87	1987	only	-	Apr	23	11:58:25s 0:01:35 -
129
+Rule	sol87	1987	only	-	Apr	24	11:58:15s 0:01:45 -
130
+Rule	sol87	1987	only	-	Apr	25	11:58:05s 0:01:55 -
131
+Rule	sol87	1987	only	-	Apr	26	11:57:55s 0:02:05 -
132
+Rule	sol87	1987	only	-	Apr	27	11:57:45s 0:02:15 -
133
+Rule	sol87	1987	only	-	Apr	28	11:57:35s 0:02:25 -
134
+Rule	sol87	1987	only	-	Apr	29	11:57:25s 0:02:35 -
135
+Rule	sol87	1987	only	-	Apr	30	11:57:15s 0:02:45 -
136
+Rule	sol87	1987	only	-	May	1	11:57:10s 0:02:50 -
137
+Rule	sol87	1987	only	-	May	2	11:57:00s 0:03:00 -
138
+Rule	sol87	1987	only	-	May	3	11:56:55s 0:03:05 -
139
+Rule	sol87	1987	only	-	May	4	11:56:50s 0:03:10 -
140
+Rule	sol87	1987	only	-	May	5	11:56:45s 0:03:15 -
141
+Rule	sol87	1987	only	-	May	6	11:56:40s 0:03:20 -
142
+Rule	sol87	1987	only	-	May	7	11:56:35s 0:03:25 -
143
+Rule	sol87	1987	only	-	May	8	11:56:30s 0:03:30 -
144
+Rule	sol87	1987	only	-	May	9	11:56:25s 0:03:35 -
145
+Rule	sol87	1987	only	-	May	10	11:56:25s 0:03:35 -
146
+Rule	sol87	1987	only	-	May	11	11:56:20s 0:03:40 -
147
+Rule	sol87	1987	only	-	May	12	11:56:20s 0:03:40 -
148
+Rule	sol87	1987	only	-	May	13	11:56:20s 0:03:40 -
149
+Rule	sol87	1987	only	-	May	14	11:56:20s 0:03:40 -
150
+Rule	sol87	1987	only	-	May	15	11:56:20s 0:03:40 -
151
+Rule	sol87	1987	only	-	May	16	11:56:20s 0:03:40 -
152
+Rule	sol87	1987	only	-	May	17	11:56:20s 0:03:40 -
153
+Rule	sol87	1987	only	-	May	18	11:56:20s 0:03:40 -
154
+Rule	sol87	1987	only	-	May	19	11:56:25s 0:03:35 -
155
+Rule	sol87	1987	only	-	May	20	11:56:25s 0:03:35 -
156
+Rule	sol87	1987	only	-	May	21	11:56:30s 0:03:30 -
157
+Rule	sol87	1987	only	-	May	22	11:56:35s 0:03:25 -
158
+Rule	sol87	1987	only	-	May	23	11:56:40s 0:03:20 -
159
+Rule	sol87	1987	only	-	May	24	11:56:45s 0:03:15 -
160
+Rule	sol87	1987	only	-	May	25	11:56:50s 0:03:10 -
161
+Rule	sol87	1987	only	-	May	26	11:56:55s 0:03:05 -
162
+Rule	sol87	1987	only	-	May	27	11:57:00s 0:03:00 -
163
+Rule	sol87	1987	only	-	May	28	11:57:10s 0:02:50 -
164
+Rule	sol87	1987	only	-	May	29	11:57:15s 0:02:45 -
165
+Rule	sol87	1987	only	-	May	30	11:57:25s 0:02:35 -
166
+Rule	sol87	1987	only	-	May	31	11:57:30s 0:02:30 -
167
+Rule	sol87	1987	only	-	Jun	1	11:57:40s 0:02:20 -
168
+Rule	sol87	1987	only	-	Jun	2	11:57:50s 0:02:10 -
169
+Rule	sol87	1987	only	-	Jun	3	11:58:00s 0:02:00 -
170
+Rule	sol87	1987	only	-	Jun	4	11:58:10s 0:01:50 -
171
+Rule	sol87	1987	only	-	Jun	5	11:58:20s 0:01:40 -
172
+Rule	sol87	1987	only	-	Jun	6	11:58:30s 0:01:30 -
173
+Rule	sol87	1987	only	-	Jun	7	11:58:40s 0:01:20 -
174
+Rule	sol87	1987	only	-	Jun	8	11:58:50s 0:01:10 -
175
+Rule	sol87	1987	only	-	Jun	9	11:59:05s 0:00:55 -
176
+Rule	sol87	1987	only	-	Jun	10	11:59:15s 0:00:45 -
177
+Rule	sol87	1987	only	-	Jun	11	11:59:30s 0:00:30 -
178
+Rule	sol87	1987	only	-	Jun	12	11:59:40s 0:00:20 -
179
+Rule	sol87	1987	only	-	Jun	13	11:59:50s 0:00:10 -
180
+Rule	sol87	1987	only	-	Jun	14	12:00:05s -0:00:05 -
181
+Rule	sol87	1987	only	-	Jun	15	12:00:15s -0:00:15 -
182
+Rule	sol87	1987	only	-	Jun	16	12:00:30s -0:00:30 -
183
+Rule	sol87	1987	only	-	Jun	17	12:00:45s -0:00:45 -
184
+Rule	sol87	1987	only	-	Jun	18	12:00:55s -0:00:55 -
185
+Rule	sol87	1987	only	-	Jun	19	12:01:10s -0:01:10 -
186
+Rule	sol87	1987	only	-	Jun	20	12:01:20s -0:01:20 -
187
+Rule	sol87	1987	only	-	Jun	21	12:01:35s -0:01:35 -
188
+Rule	sol87	1987	only	-	Jun	22	12:01:50s -0:01:50 -
189
+Rule	sol87	1987	only	-	Jun	23	12:02:00s -0:02:00 -
190
+Rule	sol87	1987	only	-	Jun	24	12:02:15s -0:02:15 -
191
+Rule	sol87	1987	only	-	Jun	25	12:02:25s -0:02:25 -
192
+Rule	sol87	1987	only	-	Jun	26	12:02:40s -0:02:40 -
193
+Rule	sol87	1987	only	-	Jun	27	12:02:50s -0:02:50 -
194
+Rule	sol87	1987	only	-	Jun	28	12:03:05s -0:03:05 -
195
+Rule	sol87	1987	only	-	Jun	29	12:03:15s -0:03:15 -
196
+Rule	sol87	1987	only	-	Jun	30	12:03:30s -0:03:30 -
197
+Rule	sol87	1987	only	-	Jul	1	12:03:40s -0:03:40 -
198
+Rule	sol87	1987	only	-	Jul	2	12:03:50s -0:03:50 -
199
+Rule	sol87	1987	only	-	Jul	3	12:04:05s -0:04:05 -
200
+Rule	sol87	1987	only	-	Jul	4	12:04:15s -0:04:15 -
201
+Rule	sol87	1987	only	-	Jul	5	12:04:25s -0:04:25 -
202
+Rule	sol87	1987	only	-	Jul	6	12:04:35s -0:04:35 -
203
+Rule	sol87	1987	only	-	Jul	7	12:04:45s -0:04:45 -
204
+Rule	sol87	1987	only	-	Jul	8	12:04:55s -0:04:55 -
205
+Rule	sol87	1987	only	-	Jul	9	12:05:05s -0:05:05 -
206
+Rule	sol87	1987	only	-	Jul	10	12:05:15s -0:05:15 -
207
+Rule	sol87	1987	only	-	Jul	11	12:05:20s -0:05:20 -
208
+Rule	sol87	1987	only	-	Jul	12	12:05:30s -0:05:30 -
209
+Rule	sol87	1987	only	-	Jul	13	12:05:40s -0:05:40 -
210
+Rule	sol87	1987	only	-	Jul	14	12:05:45s -0:05:45 -
211
+Rule	sol87	1987	only	-	Jul	15	12:05:50s -0:05:50 -
212
+Rule	sol87	1987	only	-	Jul	16	12:06:00s -0:06:00 -
213
+Rule	sol87	1987	only	-	Jul	17	12:06:05s -0:06:05 -
214
+Rule	sol87	1987	only	-	Jul	18	12:06:10s -0:06:10 -
215
+Rule	sol87	1987	only	-	Jul	19	12:06:15s -0:06:15 -
216
+Rule	sol87	1987	only	-	Jul	20	12:06:15s -0:06:15 -
217
+Rule	sol87	1987	only	-	Jul	21	12:06:20s -0:06:20 -
218
+Rule	sol87	1987	only	-	Jul	22	12:06:25s -0:06:25 -
219
+Rule	sol87	1987	only	-	Jul	23	12:06:25s -0:06:25 -
220
+Rule	sol87	1987	only	-	Jul	24	12:06:25s -0:06:25 -
221
+Rule	sol87	1987	only	-	Jul	25	12:06:30s -0:06:30 -
222
+Rule	sol87	1987	only	-	Jul	26	12:06:30s -0:06:30 -
223
+Rule	sol87	1987	only	-	Jul	27	12:06:30s -0:06:30 -
224
+Rule	sol87	1987	only	-	Jul	28	12:06:30s -0:06:30 -
225
+Rule	sol87	1987	only	-	Jul	29	12:06:25s -0:06:25 -
226
+Rule	sol87	1987	only	-	Jul	30	12:06:25s -0:06:25 -
227
+Rule	sol87	1987	only	-	Jul	31	12:06:25s -0:06:25 -
228
+Rule	sol87	1987	only	-	Aug	1	12:06:20s -0:06:20 -
229
+Rule	sol87	1987	only	-	Aug	2	12:06:15s -0:06:15 -
230
+Rule	sol87	1987	only	-	Aug	3	12:06:10s -0:06:10 -
231
+Rule	sol87	1987	only	-	Aug	4	12:06:05s -0:06:05 -
232
+Rule	sol87	1987	only	-	Aug	5	12:06:00s -0:06:00 -
233
+Rule	sol87	1987	only	-	Aug	6	12:05:55s -0:05:55 -
234
+Rule	sol87	1987	only	-	Aug	7	12:05:50s -0:05:50 -
235
+Rule	sol87	1987	only	-	Aug	8	12:05:40s -0:05:40 -
236
+Rule	sol87	1987	only	-	Aug	9	12:05:35s -0:05:35 -
237
+Rule	sol87	1987	only	-	Aug	10	12:05:25s -0:05:25 -
238
+Rule	sol87	1987	only	-	Aug	11	12:05:15s -0:05:15 -
239
+Rule	sol87	1987	only	-	Aug	12	12:05:05s -0:05:05 -
240
+Rule	sol87	1987	only	-	Aug	13	12:04:55s -0:04:55 -
241
+Rule	sol87	1987	only	-	Aug	14	12:04:45s -0:04:45 -
242
+Rule	sol87	1987	only	-	Aug	15	12:04:35s -0:04:35 -
243
+Rule	sol87	1987	only	-	Aug	16	12:04:25s -0:04:25 -
244
+Rule	sol87	1987	only	-	Aug	17	12:04:10s -0:04:10 -
245
+Rule	sol87	1987	only	-	Aug	18	12:04:00s -0:04:00 -
246
+Rule	sol87	1987	only	-	Aug	19	12:03:45s -0:03:45 -
247
+Rule	sol87	1987	only	-	Aug	20	12:03:30s -0:03:30 -
248
+Rule	sol87	1987	only	-	Aug	21	12:03:15s -0:03:15 -
249
+Rule	sol87	1987	only	-	Aug	22	12:03:00s -0:03:00 -
250
+Rule	sol87	1987	only	-	Aug	23	12:02:45s -0:02:45 -
251
+Rule	sol87	1987	only	-	Aug	24	12:02:30s -0:02:30 -
252
+Rule	sol87	1987	only	-	Aug	25	12:02:15s -0:02:15 -
253
+Rule	sol87	1987	only	-	Aug	26	12:02:00s -0:02:00 -
254
+Rule	sol87	1987	only	-	Aug	27	12:01:40s -0:01:40 -
255
+Rule	sol87	1987	only	-	Aug	28	12:01:25s -0:01:25 -
256
+Rule	sol87	1987	only	-	Aug	29	12:01:05s -0:01:05 -
257
+Rule	sol87	1987	only	-	Aug	30	12:00:50s -0:00:50 -
258
+Rule	sol87	1987	only	-	Aug	31	12:00:30s -0:00:30 -
259
+Rule	sol87	1987	only	-	Sep	1	12:00:10s -0:00:10 -
260
+Rule	sol87	1987	only	-	Sep	2	11:59:50s 0:00:10 -
261
+Rule	sol87	1987	only	-	Sep	3	11:59:35s 0:00:25 -
262
+Rule	sol87	1987	only	-	Sep	4	11:59:15s 0:00:45 -
263
+Rule	sol87	1987	only	-	Sep	5	11:58:55s 0:01:05 -
264
+Rule	sol87	1987	only	-	Sep	6	11:58:35s 0:01:25 -
265
+Rule	sol87	1987	only	-	Sep	7	11:58:15s 0:01:45 -
266
+Rule	sol87	1987	only	-	Sep	8	11:57:55s 0:02:05 -
267
+Rule	sol87	1987	only	-	Sep	9	11:57:30s 0:02:30 -
268
+Rule	sol87	1987	only	-	Sep	10	11:57:10s 0:02:50 -
269
+Rule	sol87	1987	only	-	Sep	11	11:56:50s 0:03:10 -
270
+Rule	sol87	1987	only	-	Sep	12	11:56:30s 0:03:30 -
271
+Rule	sol87	1987	only	-	Sep	13	11:56:10s 0:03:50 -
272
+Rule	sol87	1987	only	-	Sep	14	11:55:45s 0:04:15 -
273
+Rule	sol87	1987	only	-	Sep	15	11:55:25s 0:04:35 -
274
+Rule	sol87	1987	only	-	Sep	16	11:55:05s 0:04:55 -
275
+Rule	sol87	1987	only	-	Sep	17	11:54:45s 0:05:15 -
276
+Rule	sol87	1987	only	-	Sep	18	11:54:20s 0:05:40 -
277
+Rule	sol87	1987	only	-	Sep	19	11:54:00s 0:06:00 -
278
+Rule	sol87	1987	only	-	Sep	20	11:53:40s 0:06:20 -
279
+Rule	sol87	1987	only	-	Sep	21	11:53:15s 0:06:45 -
280
+Rule	sol87	1987	only	-	Sep	22	11:52:55s 0:07:05 -
281
+Rule	sol87	1987	only	-	Sep	23	11:52:35s 0:07:25 -
282
+Rule	sol87	1987	only	-	Sep	24	11:52:15s 0:07:45 -
283
+Rule	sol87	1987	only	-	Sep	25	11:51:55s 0:08:05 -
284
+Rule	sol87	1987	only	-	Sep	26	11:51:35s 0:08:25 -
285
+Rule	sol87	1987	only	-	Sep	27	11:51:10s 0:08:50 -
286
+Rule	sol87	1987	only	-	Sep	28	11:50:50s 0:09:10 -
287
+Rule	sol87	1987	only	-	Sep	29	11:50:30s 0:09:30 -
288
+Rule	sol87	1987	only	-	Sep	30	11:50:10s 0:09:50 -
289
+Rule	sol87	1987	only	-	Oct	1	11:49:50s 0:10:10 -
290
+Rule	sol87	1987	only	-	Oct	2	11:49:35s 0:10:25 -
291
+Rule	sol87	1987	only	-	Oct	3	11:49:15s 0:10:45 -
292
+Rule	sol87	1987	only	-	Oct	4	11:48:55s 0:11:05 -
293
+Rule	sol87	1987	only	-	Oct	5	11:48:35s 0:11:25 -
294
+Rule	sol87	1987	only	-	Oct	6	11:48:20s 0:11:40 -
295
+Rule	sol87	1987	only	-	Oct	7	11:48:00s 0:12:00 -
296
+Rule	sol87	1987	only	-	Oct	8	11:47:45s 0:12:15 -
297
+Rule	sol87	1987	only	-	Oct	9	11:47:25s 0:12:35 -
298
+Rule	sol87	1987	only	-	Oct	10	11:47:10s 0:12:50 -
299
+Rule	sol87	1987	only	-	Oct	11	11:46:55s 0:13:05 -
300
+Rule	sol87	1987	only	-	Oct	12	11:46:40s 0:13:20 -
301
+Rule	sol87	1987	only	-	Oct	13	11:46:25s 0:13:35 -
302
+Rule	sol87	1987	only	-	Oct	14	11:46:10s 0:13:50 -
303
+Rule	sol87	1987	only	-	Oct	15	11:45:55s 0:14:05 -
304
+Rule	sol87	1987	only	-	Oct	16	11:45:45s 0:14:15 -
305
+Rule	sol87	1987	only	-	Oct	17	11:45:30s 0:14:30 -
306
+Rule	sol87	1987	only	-	Oct	18	11:45:20s 0:14:40 -
307
+Rule	sol87	1987	only	-	Oct	19	11:45:05s 0:14:55 -
308
+Rule	sol87	1987	only	-	Oct	20	11:44:55s 0:15:05 -
309
+Rule	sol87	1987	only	-	Oct	21	11:44:45s 0:15:15 -
310
+Rule	sol87	1987	only	-	Oct	22	11:44:35s 0:15:25 -
311
+Rule	sol87	1987	only	-	Oct	23	11:44:25s 0:15:35 -
312
+Rule	sol87	1987	only	-	Oct	24	11:44:20s 0:15:40 -
313
+Rule	sol87	1987	only	-	Oct	25	11:44:10s 0:15:50 -
314
+Rule	sol87	1987	only	-	Oct	26	11:44:05s 0:15:55 -
315
+Rule	sol87	1987	only	-	Oct	27	11:43:55s 0:16:05 -
316
+Rule	sol87	1987	only	-	Oct	28	11:43:50s 0:16:10 -
317
+Rule	sol87	1987	only	-	Oct	29	11:43:45s 0:16:15 -
318
+Rule	sol87	1987	only	-	Oct	30	11:43:45s 0:16:15 -
319
+Rule	sol87	1987	only	-	Oct	31	11:43:40s 0:16:20 -
320
+Rule	sol87	1987	only	-	Nov	1	11:43:40s 0:16:20 -
321
+Rule	sol87	1987	only	-	Nov	2	11:43:35s 0:16:25 -
322
+Rule	sol87	1987	only	-	Nov	3	11:43:35s 0:16:25 -
323
+Rule	sol87	1987	only	-	Nov	4	11:43:35s 0:16:25 -
324
+Rule	sol87	1987	only	-	Nov	5	11:43:35s 0:16:25 -
325
+Rule	sol87	1987	only	-	Nov	6	11:43:40s 0:16:20 -
326
+Rule	sol87	1987	only	-	Nov	7	11:43:40s 0:16:20 -
327
+Rule	sol87	1987	only	-	Nov	8	11:43:45s 0:16:15 -
328
+Rule	sol87	1987	only	-	Nov	9	11:43:50s 0:16:10 -
329
+Rule	sol87	1987	only	-	Nov	10	11:43:55s 0:16:05 -
330
+Rule	sol87	1987	only	-	Nov	11	11:44:00s 0:16:00 -
331
+Rule	sol87	1987	only	-	Nov	12	11:44:05s 0:15:55 -
332
+Rule	sol87	1987	only	-	Nov	13	11:44:15s 0:15:45 -
333
+Rule	sol87	1987	only	-	Nov	14	11:44:20s 0:15:40 -
334
+Rule	sol87	1987	only	-	Nov	15	11:44:30s 0:15:30 -
335
+Rule	sol87	1987	only	-	Nov	16	11:44:40s 0:15:20 -
336
+Rule	sol87	1987	only	-	Nov	17	11:44:50s 0:15:10 -
337
+Rule	sol87	1987	only	-	Nov	18	11:45:05s 0:14:55 -
338
+Rule	sol87	1987	only	-	Nov	19	11:45:15s 0:14:45 -
339
+Rule	sol87	1987	only	-	Nov	20	11:45:30s 0:14:30 -
340
+Rule	sol87	1987	only	-	Nov	21	11:45:45s 0:14:15 -
341
+Rule	sol87	1987	only	-	Nov	22	11:46:00s 0:14:00 -
342
+Rule	sol87	1987	only	-	Nov	23	11:46:15s 0:13:45 -
343
+Rule	sol87	1987	only	-	Nov	24	11:46:30s 0:13:30 -
344
+Rule	sol87	1987	only	-	Nov	25	11:46:50s 0:13:10 -
345
+Rule	sol87	1987	only	-	Nov	26	11:47:10s 0:12:50 -
346
+Rule	sol87	1987	only	-	Nov	27	11:47:25s 0:12:35 -
347
+Rule	sol87	1987	only	-	Nov	28	11:47:45s 0:12:15 -
348
+Rule	sol87	1987	only	-	Nov	29	11:48:05s 0:11:55 -
349
+Rule	sol87	1987	only	-	Nov	30	11:48:30s 0:11:30 -
350
+Rule	sol87	1987	only	-	Dec	1	11:48:50s 0:11:10 -
351
+Rule	sol87	1987	only	-	Dec	2	11:49:10s 0:10:50 -
352
+Rule	sol87	1987	only	-	Dec	3	11:49:35s 0:10:25 -
353
+Rule	sol87	1987	only	-	Dec	4	11:50:00s 0:10:00 -
354
+Rule	sol87	1987	only	-	Dec	5	11:50:25s 0:09:35 -
355
+Rule	sol87	1987	only	-	Dec	6	11:50:50s 0:09:10 -
356
+Rule	sol87	1987	only	-	Dec	7	11:51:15s 0:08:45 -
357
+Rule	sol87	1987	only	-	Dec	8	11:51:40s 0:08:20 -
358
+Rule	sol87	1987	only	-	Dec	9	11:52:05s 0:07:55 -
359
+Rule	sol87	1987	only	-	Dec	10	11:52:30s 0:07:30 -
360
+Rule	sol87	1987	only	-	Dec	11	11:53:00s 0:07:00 -
361
+Rule	sol87	1987	only	-	Dec	12	11:53:25s 0:06:35 -
362
+Rule	sol87	1987	only	-	Dec	13	11:53:55s 0:06:05 -
363
+Rule	sol87	1987	only	-	Dec	14	11:54:25s 0:05:35 -
364
+Rule	sol87	1987	only	-	Dec	15	11:54:50s 0:05:10 -
365
+Rule	sol87	1987	only	-	Dec	16	11:55:20s 0:04:40 -
366
+Rule	sol87	1987	only	-	Dec	17	11:55:50s 0:04:10 -
367
+Rule	sol87	1987	only	-	Dec	18	11:56:20s 0:03:40 -
368
+Rule	sol87	1987	only	-	Dec	19	11:56:50s 0:03:10 -
369
+Rule	sol87	1987	only	-	Dec	20	11:57:20s 0:02:40 -
370
+Rule	sol87	1987	only	-	Dec	21	11:57:50s 0:02:10 -
371
+Rule	sol87	1987	only	-	Dec	22	11:58:20s 0:01:40 -
372
+Rule	sol87	1987	only	-	Dec	23	11:58:50s 0:01:10 -
373
+Rule	sol87	1987	only	-	Dec	24	11:59:20s 0:00:40 -
374
+Rule	sol87	1987	only	-	Dec	25	11:59:50s 0:00:10 -
375
+Rule	sol87	1987	only	-	Dec	26	12:00:20s -0:00:20 -
376
+Rule	sol87	1987	only	-	Dec	27	12:00:45s -0:00:45 -
377
+Rule	sol87	1987	only	-	Dec	28	12:01:15s -0:01:15 -
378
+Rule	sol87	1987	only	-	Dec	29	12:01:45s -0:01:45 -
379
+Rule	sol87	1987	only	-	Dec	30	12:02:15s -0:02:15 -
380
+Rule	sol87	1987	only	-	Dec	31	12:02:45s -0:02:45 -
381
+
382
+# Riyadh is at about 46 degrees 46 minutes East:  3 hrs, 7 mins, 4 secs
383
+# Before and after 1987, we'll operate on local mean solar time.
384
+
385
+# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
386
+Zone	Asia/Riyadh87	3:07:04	-		zzz	1987
387
+			3:07:04	sol87		zzz	1988
388
+			3:07:04	-		zzz
389
+# For backward compatibility...
390
+Link	Asia/Riyadh87	Mideast/Riyadh87
... ...
@@ -0,0 +1,390 @@
1
+# <pre>
2
+# This file is in the public domain, so clarified as of
3
+# 2009-05-17 by Arthur David Olson.
4
+
5
+# Apparent noon times below are for Riyadh; they're a bit off for other places.
6
+# Times were computed using formulas in the U.S. Naval Observatory's
7
+# Almanac for Computers 1988; the formulas "will give EqT to an accuracy of
8
+# [plus or minus two] seconds during the current year."
9
+#
10
+# Rounding to the nearest five seconds results in fewer than
11
+# 256 different "time types"--a limit that's faced because time types are
12
+# stored on disk as unsigned chars.
13
+
14
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
15
+Rule	sol88	1988	only	-	Jan	1	12:03:15s -0:03:15 -
16
+Rule	sol88	1988	only	-	Jan	2	12:03:40s -0:03:40 -
17
+Rule	sol88	1988	only	-	Jan	3	12:04:10s -0:04:10 -
18
+Rule	sol88	1988	only	-	Jan	4	12:04:40s -0:04:40 -
19
+Rule	sol88	1988	only	-	Jan	5	12:05:05s -0:05:05 -
20
+Rule	sol88	1988	only	-	Jan	6	12:05:30s -0:05:30 -
21
+Rule	sol88	1988	only	-	Jan	7	12:06:00s -0:06:00 -
22
+Rule	sol88	1988	only	-	Jan	8	12:06:25s -0:06:25 -
23
+Rule	sol88	1988	only	-	Jan	9	12:06:50s -0:06:50 -
24
+Rule	sol88	1988	only	-	Jan	10	12:07:15s -0:07:15 -
25
+Rule	sol88	1988	only	-	Jan	11	12:07:40s -0:07:40 -
26
+Rule	sol88	1988	only	-	Jan	12	12:08:05s -0:08:05 -
27
+Rule	sol88	1988	only	-	Jan	13	12:08:25s -0:08:25 -
28
+Rule	sol88	1988	only	-	Jan	14	12:08:50s -0:08:50 -
29
+Rule	sol88	1988	only	-	Jan	15	12:09:10s -0:09:10 -
30
+Rule	sol88	1988	only	-	Jan	16	12:09:30s -0:09:30 -
31
+Rule	sol88	1988	only	-	Jan	17	12:09:50s -0:09:50 -
32
+Rule	sol88	1988	only	-	Jan	18	12:10:10s -0:10:10 -
33
+Rule	sol88	1988	only	-	Jan	19	12:10:30s -0:10:30 -
34
+Rule	sol88	1988	only	-	Jan	20	12:10:50s -0:10:50 -
35
+Rule	sol88	1988	only	-	Jan	21	12:11:05s -0:11:05 -
36
+Rule	sol88	1988	only	-	Jan	22	12:11:25s -0:11:25 -
37
+Rule	sol88	1988	only	-	Jan	23	12:11:40s -0:11:40 -
38
+Rule	sol88	1988	only	-	Jan	24	12:11:55s -0:11:55 -
39
+Rule	sol88	1988	only	-	Jan	25	12:12:10s -0:12:10 -
40
+Rule	sol88	1988	only	-	Jan	26	12:12:25s -0:12:25 -
41
+Rule	sol88	1988	only	-	Jan	27	12:12:40s -0:12:40 -
42
+Rule	sol88	1988	only	-	Jan	28	12:12:50s -0:12:50 -
43
+Rule	sol88	1988	only	-	Jan	29	12:13:00s -0:13:00 -
44
+Rule	sol88	1988	only	-	Jan	30	12:13:10s -0:13:10 -
45
+Rule	sol88	1988	only	-	Jan	31	12:13:20s -0:13:20 -
46
+Rule	sol88	1988	only	-	Feb	1	12:13:30s -0:13:30 -
47
+Rule	sol88	1988	only	-	Feb	2	12:13:40s -0:13:40 -
48
+Rule	sol88	1988	only	-	Feb	3	12:13:45s -0:13:45 -
49
+Rule	sol88	1988	only	-	Feb	4	12:13:55s -0:13:55 -
50
+Rule	sol88	1988	only	-	Feb	5	12:14:00s -0:14:00 -
51
+Rule	sol88	1988	only	-	Feb	6	12:14:05s -0:14:05 -
52
+Rule	sol88	1988	only	-	Feb	7	12:14:10s -0:14:10 -
53
+Rule	sol88	1988	only	-	Feb	8	12:14:10s -0:14:10 -
54
+Rule	sol88	1988	only	-	Feb	9	12:14:15s -0:14:15 -
55
+Rule	sol88	1988	only	-	Feb	10	12:14:15s -0:14:15 -
56
+Rule	sol88	1988	only	-	Feb	11	12:14:15s -0:14:15 -
57
+Rule	sol88	1988	only	-	Feb	12	12:14:15s -0:14:15 -
58
+Rule	sol88	1988	only	-	Feb	13	12:14:15s -0:14:15 -
59
+Rule	sol88	1988	only	-	Feb	14	12:14:15s -0:14:15 -
60
+Rule	sol88	1988	only	-	Feb	15	12:14:10s -0:14:10 -
61
+Rule	sol88	1988	only	-	Feb	16	12:14:10s -0:14:10 -
62
+Rule	sol88	1988	only	-	Feb	17	12:14:05s -0:14:05 -
63
+Rule	sol88	1988	only	-	Feb	18	12:14:00s -0:14:00 -
64
+Rule	sol88	1988	only	-	Feb	19	12:13:55s -0:13:55 -
65
+Rule	sol88	1988	only	-	Feb	20	12:13:50s -0:13:50 -
66
+Rule	sol88	1988	only	-	Feb	21	12:13:45s -0:13:45 -
67
+Rule	sol88	1988	only	-	Feb	22	12:13:40s -0:13:40 -
68
+Rule	sol88	1988	only	-	Feb	23	12:13:30s -0:13:30 -
69
+Rule	sol88	1988	only	-	Feb	24	12:13:20s -0:13:20 -
70
+Rule	sol88	1988	only	-	Feb	25	12:13:15s -0:13:15 -
71
+Rule	sol88	1988	only	-	Feb	26	12:13:05s -0:13:05 -
72
+Rule	sol88	1988	only	-	Feb	27	12:12:55s -0:12:55 -
73
+Rule	sol88	1988	only	-	Feb	28	12:12:45s -0:12:45 -
74
+Rule	sol88	1988	only	-	Feb	29	12:12:30s -0:12:30 -
75
+Rule	sol88	1988	only	-	Mar	1	12:12:20s -0:12:20 -
76
+Rule	sol88	1988	only	-	Mar	2	12:12:10s -0:12:10 -
77
+Rule	sol88	1988	only	-	Mar	3	12:11:55s -0:11:55 -
78
+Rule	sol88	1988	only	-	Mar	4	12:11:45s -0:11:45 -
79
+Rule	sol88	1988	only	-	Mar	5	12:11:30s -0:11:30 -
80
+Rule	sol88	1988	only	-	Mar	6	12:11:15s -0:11:15 -
81
+Rule	sol88	1988	only	-	Mar	7	12:11:00s -0:11:00 -
82
+Rule	sol88	1988	only	-	Mar	8	12:10:45s -0:10:45 -
83
+Rule	sol88	1988	only	-	Mar	9	12:10:30s -0:10:30 -
84
+Rule	sol88	1988	only	-	Mar	10	12:10:15s -0:10:15 -
85
+Rule	sol88	1988	only	-	Mar	11	12:10:00s -0:10:00 -
86
+Rule	sol88	1988	only	-	Mar	12	12:09:45s -0:09:45 -
87
+Rule	sol88	1988	only	-	Mar	13	12:09:30s -0:09:30 -
88
+Rule	sol88	1988	only	-	Mar	14	12:09:10s -0:09:10 -
89
+Rule	sol88	1988	only	-	Mar	15	12:08:55s -0:08:55 -
90
+Rule	sol88	1988	only	-	Mar	16	12:08:40s -0:08:40 -
91
+Rule	sol88	1988	only	-	Mar	17	12:08:20s -0:08:20 -
92
+Rule	sol88	1988	only	-	Mar	18	12:08:05s -0:08:05 -
93
+Rule	sol88	1988	only	-	Mar	19	12:07:45s -0:07:45 -
94
+Rule	sol88	1988	only	-	Mar	20	12:07:30s -0:07:30 -
95
+Rule	sol88	1988	only	-	Mar	21	12:07:10s -0:07:10 -
96
+Rule	sol88	1988	only	-	Mar	22	12:06:50s -0:06:50 -
97
+Rule	sol88	1988	only	-	Mar	23	12:06:35s -0:06:35 -
98
+Rule	sol88	1988	only	-	Mar	24	12:06:15s -0:06:15 -
99
+Rule	sol88	1988	only	-	Mar	25	12:06:00s -0:06:00 -
100
+Rule	sol88	1988	only	-	Mar	26	12:05:40s -0:05:40 -
101
+Rule	sol88	1988	only	-	Mar	27	12:05:20s -0:05:20 -
102
+Rule	sol88	1988	only	-	Mar	28	12:05:05s -0:05:05 -
103
+Rule	sol88	1988	only	-	Mar	29	12:04:45s -0:04:45 -
104
+Rule	sol88	1988	only	-	Mar	30	12:04:25s -0:04:25 -
105
+Rule	sol88	1988	only	-	Mar	31	12:04:10s -0:04:10 -
106
+Rule	sol88	1988	only	-	Apr	1	12:03:50s -0:03:50 -
107
+Rule	sol88	1988	only	-	Apr	2	12:03:35s -0:03:35 -
108
+Rule	sol88	1988	only	-	Apr	3	12:03:15s -0:03:15 -
109
+Rule	sol88	1988	only	-	Apr	4	12:03:00s -0:03:00 -
110
+Rule	sol88	1988	only	-	Apr	5	12:02:40s -0:02:40 -
111
+Rule	sol88	1988	only	-	Apr	6	12:02:25s -0:02:25 -
112
+Rule	sol88	1988	only	-	Apr	7	12:02:05s -0:02:05 -
113
+Rule	sol88	1988	only	-	Apr	8	12:01:50s -0:01:50 -
114
+Rule	sol88	1988	only	-	Apr	9	12:01:35s -0:01:35 -
115
+Rule	sol88	1988	only	-	Apr	10	12:01:15s -0:01:15 -
116
+Rule	sol88	1988	only	-	Apr	11	12:01:00s -0:01:00 -
117
+Rule	sol88	1988	only	-	Apr	12	12:00:45s -0:00:45 -
118
+Rule	sol88	1988	only	-	Apr	13	12:00:30s -0:00:30 -
119
+Rule	sol88	1988	only	-	Apr	14	12:00:15s -0:00:15 -
120
+Rule	sol88	1988	only	-	Apr	15	12:00:00s 0:00:00 -
121
+Rule	sol88	1988	only	-	Apr	16	11:59:45s 0:00:15 -
122
+Rule	sol88	1988	only	-	Apr	17	11:59:30s 0:00:30 -
123
+Rule	sol88	1988	only	-	Apr	18	11:59:20s 0:00:40 -
124
+Rule	sol88	1988	only	-	Apr	19	11:59:05s 0:00:55 -
125
+Rule	sol88	1988	only	-	Apr	20	11:58:55s 0:01:05 -
126
+Rule	sol88	1988	only	-	Apr	21	11:58:40s 0:01:20 -
127
+Rule	sol88	1988	only	-	Apr	22	11:58:30s 0:01:30 -
128
+Rule	sol88	1988	only	-	Apr	23	11:58:15s 0:01:45 -
129
+Rule	sol88	1988	only	-	Apr	24	11:58:05s 0:01:55 -
130
+Rule	sol88	1988	only	-	Apr	25	11:57:55s 0:02:05 -
131
+Rule	sol88	1988	only	-	Apr	26	11:57:45s 0:02:15 -
132
+Rule	sol88	1988	only	-	Apr	27	11:57:35s 0:02:25 -
133
+Rule	sol88	1988	only	-	Apr	28	11:57:30s 0:02:30 -
134
+Rule	sol88	1988	only	-	Apr	29	11:57:20s 0:02:40 -
135
+Rule	sol88	1988	only	-	Apr	30	11:57:10s 0:02:50 -
136
+Rule	sol88	1988	only	-	May	1	11:57:05s 0:02:55 -
137
+Rule	sol88	1988	only	-	May	2	11:56:55s 0:03:05 -
138
+Rule	sol88	1988	only	-	May	3	11:56:50s 0:03:10 -
139
+Rule	sol88	1988	only	-	May	4	11:56:45s 0:03:15 -
140
+Rule	sol88	1988	only	-	May	5	11:56:40s 0:03:20 -
141
+Rule	sol88	1988	only	-	May	6	11:56:35s 0:03:25 -
142
+Rule	sol88	1988	only	-	May	7	11:56:30s 0:03:30 -
143
+Rule	sol88	1988	only	-	May	8	11:56:25s 0:03:35 -
144
+Rule	sol88	1988	only	-	May	9	11:56:25s 0:03:35 -
145
+Rule	sol88	1988	only	-	May	10	11:56:20s 0:03:40 -
146
+Rule	sol88	1988	only	-	May	11	11:56:20s 0:03:40 -
147
+Rule	sol88	1988	only	-	May	12	11:56:20s 0:03:40 -
148
+Rule	sol88	1988	only	-	May	13	11:56:20s 0:03:40 -
149
+Rule	sol88	1988	only	-	May	14	11:56:20s 0:03:40 -
150
+Rule	sol88	1988	only	-	May	15	11:56:20s 0:03:40 -
151
+Rule	sol88	1988	only	-	May	16	11:56:20s 0:03:40 -
152
+Rule	sol88	1988	only	-	May	17	11:56:20s 0:03:40 -
153
+Rule	sol88	1988	only	-	May	18	11:56:25s 0:03:35 -
154
+Rule	sol88	1988	only	-	May	19	11:56:25s 0:03:35 -
155
+Rule	sol88	1988	only	-	May	20	11:56:30s 0:03:30 -
156
+Rule	sol88	1988	only	-	May	21	11:56:35s 0:03:25 -
157
+Rule	sol88	1988	only	-	May	22	11:56:40s 0:03:20 -
158
+Rule	sol88	1988	only	-	May	23	11:56:45s 0:03:15 -
159
+Rule	sol88	1988	only	-	May	24	11:56:50s 0:03:10 -
160
+Rule	sol88	1988	only	-	May	25	11:56:55s 0:03:05 -
161
+Rule	sol88	1988	only	-	May	26	11:57:00s 0:03:00 -
162
+Rule	sol88	1988	only	-	May	27	11:57:05s 0:02:55 -
163
+Rule	sol88	1988	only	-	May	28	11:57:15s 0:02:45 -
164
+Rule	sol88	1988	only	-	May	29	11:57:20s 0:02:40 -
165
+Rule	sol88	1988	only	-	May	30	11:57:30s 0:02:30 -
166
+Rule	sol88	1988	only	-	May	31	11:57:40s 0:02:20 -
167
+Rule	sol88	1988	only	-	Jun	1	11:57:50s 0:02:10 -
168
+Rule	sol88	1988	only	-	Jun	2	11:57:55s 0:02:05 -
169
+Rule	sol88	1988	only	-	Jun	3	11:58:05s 0:01:55 -
170
+Rule	sol88	1988	only	-	Jun	4	11:58:15s 0:01:45 -
171
+Rule	sol88	1988	only	-	Jun	5	11:58:30s 0:01:30 -
172
+Rule	sol88	1988	only	-	Jun	6	11:58:40s 0:01:20 -
173
+Rule	sol88	1988	only	-	Jun	7	11:58:50s 0:01:10 -
174
+Rule	sol88	1988	only	-	Jun	8	11:59:00s 0:01:00 -
175
+Rule	sol88	1988	only	-	Jun	9	11:59:15s 0:00:45 -
176
+Rule	sol88	1988	only	-	Jun	10	11:59:25s 0:00:35 -
177
+Rule	sol88	1988	only	-	Jun	11	11:59:35s 0:00:25 -
178
+Rule	sol88	1988	only	-	Jun	12	11:59:50s 0:00:10 -
179
+Rule	sol88	1988	only	-	Jun	13	12:00:00s 0:00:00 -
180
+Rule	sol88	1988	only	-	Jun	14	12:00:15s -0:00:15 -
181
+Rule	sol88	1988	only	-	Jun	15	12:00:25s -0:00:25 -
182
+Rule	sol88	1988	only	-	Jun	16	12:00:40s -0:00:40 -
183
+Rule	sol88	1988	only	-	Jun	17	12:00:55s -0:00:55 -
184
+Rule	sol88	1988	only	-	Jun	18	12:01:05s -0:01:05 -
185
+Rule	sol88	1988	only	-	Jun	19	12:01:20s -0:01:20 -
186
+Rule	sol88	1988	only	-	Jun	20	12:01:30s -0:01:30 -
187
+Rule	sol88	1988	only	-	Jun	21	12:01:45s -0:01:45 -
188
+Rule	sol88	1988	only	-	Jun	22	12:02:00s -0:02:00 -
189
+Rule	sol88	1988	only	-	Jun	23	12:02:10s -0:02:10 -
190
+Rule	sol88	1988	only	-	Jun	24	12:02:25s -0:02:25 -
191
+Rule	sol88	1988	only	-	Jun	25	12:02:35s -0:02:35 -
192
+Rule	sol88	1988	only	-	Jun	26	12:02:50s -0:02:50 -
193
+Rule	sol88	1988	only	-	Jun	27	12:03:00s -0:03:00 -
194
+Rule	sol88	1988	only	-	Jun	28	12:03:15s -0:03:15 -
195
+Rule	sol88	1988	only	-	Jun	29	12:03:25s -0:03:25 -
196
+Rule	sol88	1988	only	-	Jun	30	12:03:40s -0:03:40 -
197
+Rule	sol88	1988	only	-	Jul	1	12:03:50s -0:03:50 -
198
+Rule	sol88	1988	only	-	Jul	2	12:04:00s -0:04:00 -
199
+Rule	sol88	1988	only	-	Jul	3	12:04:10s -0:04:10 -
200
+Rule	sol88	1988	only	-	Jul	4	12:04:25s -0:04:25 -
201
+Rule	sol88	1988	only	-	Jul	5	12:04:35s -0:04:35 -
202
+Rule	sol88	1988	only	-	Jul	6	12:04:45s -0:04:45 -
203
+Rule	sol88	1988	only	-	Jul	7	12:04:55s -0:04:55 -
204
+Rule	sol88	1988	only	-	Jul	8	12:05:05s -0:05:05 -
205
+Rule	sol88	1988	only	-	Jul	9	12:05:10s -0:05:10 -
206
+Rule	sol88	1988	only	-	Jul	10	12:05:20s -0:05:20 -
207
+Rule	sol88	1988	only	-	Jul	11	12:05:30s -0:05:30 -
208
+Rule	sol88	1988	only	-	Jul	12	12:05:35s -0:05:35 -
209
+Rule	sol88	1988	only	-	Jul	13	12:05:45s -0:05:45 -
210
+Rule	sol88	1988	only	-	Jul	14	12:05:50s -0:05:50 -
211
+Rule	sol88	1988	only	-	Jul	15	12:05:55s -0:05:55 -
212
+Rule	sol88	1988	only	-	Jul	16	12:06:00s -0:06:00 -
213
+Rule	sol88	1988	only	-	Jul	17	12:06:05s -0:06:05 -
214
+Rule	sol88	1988	only	-	Jul	18	12:06:10s -0:06:10 -
215
+Rule	sol88	1988	only	-	Jul	19	12:06:15s -0:06:15 -
216
+Rule	sol88	1988	only	-	Jul	20	12:06:20s -0:06:20 -
217
+Rule	sol88	1988	only	-	Jul	21	12:06:25s -0:06:25 -
218
+Rule	sol88	1988	only	-	Jul	22	12:06:25s -0:06:25 -
219
+Rule	sol88	1988	only	-	Jul	23	12:06:25s -0:06:25 -
220
+Rule	sol88	1988	only	-	Jul	24	12:06:30s -0:06:30 -
221
+Rule	sol88	1988	only	-	Jul	25	12:06:30s -0:06:30 -
222
+Rule	sol88	1988	only	-	Jul	26	12:06:30s -0:06:30 -
223
+Rule	sol88	1988	only	-	Jul	27	12:06:30s -0:06:30 -
224
+Rule	sol88	1988	only	-	Jul	28	12:06:30s -0:06:30 -
225
+Rule	sol88	1988	only	-	Jul	29	12:06:25s -0:06:25 -
226
+Rule	sol88	1988	only	-	Jul	30	12:06:25s -0:06:25 -
227
+Rule	sol88	1988	only	-	Jul	31	12:06:20s -0:06:20 -
228
+Rule	sol88	1988	only	-	Aug	1	12:06:15s -0:06:15 -
229
+Rule	sol88	1988	only	-	Aug	2	12:06:15s -0:06:15 -
230
+Rule	sol88	1988	only	-	Aug	3	12:06:10s -0:06:10 -
231
+Rule	sol88	1988	only	-	Aug	4	12:06:05s -0:06:05 -
232
+Rule	sol88	1988	only	-	Aug	5	12:05:55s -0:05:55 -
233
+Rule	sol88	1988	only	-	Aug	6	12:05:50s -0:05:50 -
234
+Rule	sol88	1988	only	-	Aug	7	12:05:45s -0:05:45 -
235
+Rule	sol88	1988	only	-	Aug	8	12:05:35s -0:05:35 -
236
+Rule	sol88	1988	only	-	Aug	9	12:05:25s -0:05:25 -
237
+Rule	sol88	1988	only	-	Aug	10	12:05:20s -0:05:20 -
238
+Rule	sol88	1988	only	-	Aug	11	12:05:10s -0:05:10 -
239
+Rule	sol88	1988	only	-	Aug	12	12:05:00s -0:05:00 -
240
+Rule	sol88	1988	only	-	Aug	13	12:04:50s -0:04:50 -
241
+Rule	sol88	1988	only	-	Aug	14	12:04:35s -0:04:35 -
242
+Rule	sol88	1988	only	-	Aug	15	12:04:25s -0:04:25 -
243
+Rule	sol88	1988	only	-	Aug	16	12:04:15s -0:04:15 -
244
+Rule	sol88	1988	only	-	Aug	17	12:04:00s -0:04:00 -
245
+Rule	sol88	1988	only	-	Aug	18	12:03:50s -0:03:50 -
246
+Rule	sol88	1988	only	-	Aug	19	12:03:35s -0:03:35 -
247
+Rule	sol88	1988	only	-	Aug	20	12:03:20s -0:03:20 -
248
+Rule	sol88	1988	only	-	Aug	21	12:03:05s -0:03:05 -
249
+Rule	sol88	1988	only	-	Aug	22	12:02:50s -0:02:50 -
250
+Rule	sol88	1988	only	-	Aug	23	12:02:35s -0:02:35 -
251
+Rule	sol88	1988	only	-	Aug	24	12:02:20s -0:02:20 -
252
+Rule	sol88	1988	only	-	Aug	25	12:02:00s -0:02:00 -
253
+Rule	sol88	1988	only	-	Aug	26	12:01:45s -0:01:45 -
254
+Rule	sol88	1988	only	-	Aug	27	12:01:30s -0:01:30 -
255
+Rule	sol88	1988	only	-	Aug	28	12:01:10s -0:01:10 -
256
+Rule	sol88	1988	only	-	Aug	29	12:00:50s -0:00:50 -
257
+Rule	sol88	1988	only	-	Aug	30	12:00:35s -0:00:35 -
258
+Rule	sol88	1988	only	-	Aug	31	12:00:15s -0:00:15 -
259
+Rule	sol88	1988	only	-	Sep	1	11:59:55s 0:00:05 -
260
+Rule	sol88	1988	only	-	Sep	2	11:59:35s 0:00:25 -
261
+Rule	sol88	1988	only	-	Sep	3	11:59:20s 0:00:40 -
262
+Rule	sol88	1988	only	-	Sep	4	11:59:00s 0:01:00 -
263
+Rule	sol88	1988	only	-	Sep	5	11:58:40s 0:01:20 -
264
+Rule	sol88	1988	only	-	Sep	6	11:58:20s 0:01:40 -
265
+Rule	sol88	1988	only	-	Sep	7	11:58:00s 0:02:00 -
266
+Rule	sol88	1988	only	-	Sep	8	11:57:35s 0:02:25 -
267
+Rule	sol88	1988	only	-	Sep	9	11:57:15s 0:02:45 -
268
+Rule	sol88	1988	only	-	Sep	10	11:56:55s 0:03:05 -
269
+Rule	sol88	1988	only	-	Sep	11	11:56:35s 0:03:25 -
270
+Rule	sol88	1988	only	-	Sep	12	11:56:15s 0:03:45 -
271
+Rule	sol88	1988	only	-	Sep	13	11:55:50s 0:04:10 -
272
+Rule	sol88	1988	only	-	Sep	14	11:55:30s 0:04:30 -
273
+Rule	sol88	1988	only	-	Sep	15	11:55:10s 0:04:50 -
274
+Rule	sol88	1988	only	-	Sep	16	11:54:50s 0:05:10 -
275
+Rule	sol88	1988	only	-	Sep	17	11:54:25s 0:05:35 -
276
+Rule	sol88	1988	only	-	Sep	18	11:54:05s 0:05:55 -
277
+Rule	sol88	1988	only	-	Sep	19	11:53:45s 0:06:15 -
278
+Rule	sol88	1988	only	-	Sep	20	11:53:25s 0:06:35 -
279
+Rule	sol88	1988	only	-	Sep	21	11:53:00s 0:07:00 -
280
+Rule	sol88	1988	only	-	Sep	22	11:52:40s 0:07:20 -
281
+Rule	sol88	1988	only	-	Sep	23	11:52:20s 0:07:40 -
282
+Rule	sol88	1988	only	-	Sep	24	11:52:00s 0:08:00 -
283
+Rule	sol88	1988	only	-	Sep	25	11:51:40s 0:08:20 -
284
+Rule	sol88	1988	only	-	Sep	26	11:51:15s 0:08:45 -
285
+Rule	sol88	1988	only	-	Sep	27	11:50:55s 0:09:05 -
286
+Rule	sol88	1988	only	-	Sep	28	11:50:35s 0:09:25 -
287
+Rule	sol88	1988	only	-	Sep	29	11:50:15s 0:09:45 -
288
+Rule	sol88	1988	only	-	Sep	30	11:49:55s 0:10:05 -
289
+Rule	sol88	1988	only	-	Oct	1	11:49:35s 0:10:25 -
290
+Rule	sol88	1988	only	-	Oct	2	11:49:20s 0:10:40 -
291
+Rule	sol88	1988	only	-	Oct	3	11:49:00s 0:11:00 -
292
+Rule	sol88	1988	only	-	Oct	4	11:48:40s 0:11:20 -
293
+Rule	sol88	1988	only	-	Oct	5	11:48:25s 0:11:35 -
294
+Rule	sol88	1988	only	-	Oct	6	11:48:05s 0:11:55 -
295
+Rule	sol88	1988	only	-	Oct	7	11:47:50s 0:12:10 -
296
+Rule	sol88	1988	only	-	Oct	8	11:47:30s 0:12:30 -
297
+Rule	sol88	1988	only	-	Oct	9	11:47:15s 0:12:45 -
298
+Rule	sol88	1988	only	-	Oct	10	11:47:00s 0:13:00 -
299
+Rule	sol88	1988	only	-	Oct	11	11:46:45s 0:13:15 -
300
+Rule	sol88	1988	only	-	Oct	12	11:46:30s 0:13:30 -
301
+Rule	sol88	1988	only	-	Oct	13	11:46:15s 0:13:45 -
302
+Rule	sol88	1988	only	-	Oct	14	11:46:00s 0:14:00 -
303
+Rule	sol88	1988	only	-	Oct	15	11:45:45s 0:14:15 -
304
+Rule	sol88	1988	only	-	Oct	16	11:45:35s 0:14:25 -
305
+Rule	sol88	1988	only	-	Oct	17	11:45:20s 0:14:40 -
306
+Rule	sol88	1988	only	-	Oct	18	11:45:10s 0:14:50 -
307
+Rule	sol88	1988	only	-	Oct	19	11:45:00s 0:15:00 -
308
+Rule	sol88	1988	only	-	Oct	20	11:44:45s 0:15:15 -
309
+Rule	sol88	1988	only	-	Oct	21	11:44:40s 0:15:20 -
310
+Rule	sol88	1988	only	-	Oct	22	11:44:30s 0:15:30 -
311
+Rule	sol88	1988	only	-	Oct	23	11:44:20s 0:15:40 -
312
+Rule	sol88	1988	only	-	Oct	24	11:44:10s 0:15:50 -
313
+Rule	sol88	1988	only	-	Oct	25	11:44:05s 0:15:55 -
314
+Rule	sol88	1988	only	-	Oct	26	11:44:00s 0:16:00 -
315
+Rule	sol88	1988	only	-	Oct	27	11:43:55s 0:16:05 -
316
+Rule	sol88	1988	only	-	Oct	28	11:43:50s 0:16:10 -
317
+Rule	sol88	1988	only	-	Oct	29	11:43:45s 0:16:15 -
318
+Rule	sol88	1988	only	-	Oct	30	11:43:40s 0:16:20 -
319
+Rule	sol88	1988	only	-	Oct	31	11:43:40s 0:16:20 -
320
+Rule	sol88	1988	only	-	Nov	1	11:43:35s 0:16:25 -
321
+Rule	sol88	1988	only	-	Nov	2	11:43:35s 0:16:25 -
322
+Rule	sol88	1988	only	-	Nov	3	11:43:35s 0:16:25 -
323
+Rule	sol88	1988	only	-	Nov	4	11:43:35s 0:16:25 -
324
+Rule	sol88	1988	only	-	Nov	5	11:43:40s 0:16:20 -
325
+Rule	sol88	1988	only	-	Nov	6	11:43:40s 0:16:20 -
326
+Rule	sol88	1988	only	-	Nov	7	11:43:45s 0:16:15 -
327
+Rule	sol88	1988	only	-	Nov	8	11:43:45s 0:16:15 -
328
+Rule	sol88	1988	only	-	Nov	9	11:43:50s 0:16:10 -
329
+Rule	sol88	1988	only	-	Nov	10	11:44:00s 0:16:00 -
330
+Rule	sol88	1988	only	-	Nov	11	11:44:05s 0:15:55 -
331
+Rule	sol88	1988	only	-	Nov	12	11:44:10s 0:15:50 -
332
+Rule	sol88	1988	only	-	Nov	13	11:44:20s 0:15:40 -
333
+Rule	sol88	1988	only	-	Nov	14	11:44:30s 0:15:30 -
334
+Rule	sol88	1988	only	-	Nov	15	11:44:40s 0:15:20 -
335
+Rule	sol88	1988	only	-	Nov	16	11:44:50s 0:15:10 -
336
+Rule	sol88	1988	only	-	Nov	17	11:45:00s 0:15:00 -
337
+Rule	sol88	1988	only	-	Nov	18	11:45:15s 0:14:45 -
338
+Rule	sol88	1988	only	-	Nov	19	11:45:25s 0:14:35 -
339
+Rule	sol88	1988	only	-	Nov	20	11:45:40s 0:14:20 -
340
+Rule	sol88	1988	only	-	Nov	21	11:45:55s 0:14:05 -
341
+Rule	sol88	1988	only	-	Nov	22	11:46:10s 0:13:50 -
342
+Rule	sol88	1988	only	-	Nov	23	11:46:30s 0:13:30 -
343
+Rule	sol88	1988	only	-	Nov	24	11:46:45s 0:13:15 -
344
+Rule	sol88	1988	only	-	Nov	25	11:47:05s 0:12:55 -
345
+Rule	sol88	1988	only	-	Nov	26	11:47:20s 0:12:40 -
346
+Rule	sol88	1988	only	-	Nov	27	11:47:40s 0:12:20 -
347
+Rule	sol88	1988	only	-	Nov	28	11:48:00s 0:12:00 -
348
+Rule	sol88	1988	only	-	Nov	29	11:48:25s 0:11:35 -
349
+Rule	sol88	1988	only	-	Nov	30	11:48:45s 0:11:15 -
350
+Rule	sol88	1988	only	-	Dec	1	11:49:05s 0:10:55 -
351
+Rule	sol88	1988	only	-	Dec	2	11:49:30s 0:10:30 -
352
+Rule	sol88	1988	only	-	Dec	3	11:49:55s 0:10:05 -
353
+Rule	sol88	1988	only	-	Dec	4	11:50:15s 0:09:45 -
354
+Rule	sol88	1988	only	-	Dec	5	11:50:40s 0:09:20 -
355
+Rule	sol88	1988	only	-	Dec	6	11:51:05s 0:08:55 -
356
+Rule	sol88	1988	only	-	Dec	7	11:51:35s 0:08:25 -
357
+Rule	sol88	1988	only	-	Dec	8	11:52:00s 0:08:00 -
358
+Rule	sol88	1988	only	-	Dec	9	11:52:25s 0:07:35 -
359
+Rule	sol88	1988	only	-	Dec	10	11:52:55s 0:07:05 -
360
+Rule	sol88	1988	only	-	Dec	11	11:53:20s 0:06:40 -
361
+Rule	sol88	1988	only	-	Dec	12	11:53:50s 0:06:10 -
362
+Rule	sol88	1988	only	-	Dec	13	11:54:15s 0:05:45 -
363
+Rule	sol88	1988	only	-	Dec	14	11:54:45s 0:05:15 -
364
+Rule	sol88	1988	only	-	Dec	15	11:55:15s 0:04:45 -
365
+Rule	sol88	1988	only	-	Dec	16	11:55:45s 0:04:15 -
366
+Rule	sol88	1988	only	-	Dec	17	11:56:15s 0:03:45 -
367
+Rule	sol88	1988	only	-	Dec	18	11:56:40s 0:03:20 -
368
+Rule	sol88	1988	only	-	Dec	19	11:57:10s 0:02:50 -
369
+Rule	sol88	1988	only	-	Dec	20	11:57:40s 0:02:20 -
370
+Rule	sol88	1988	only	-	Dec	21	11:58:10s 0:01:50 -
371
+Rule	sol88	1988	only	-	Dec	22	11:58:40s 0:01:20 -
372
+Rule	sol88	1988	only	-	Dec	23	11:59:10s 0:00:50 -
373
+Rule	sol88	1988	only	-	Dec	24	11:59:40s 0:00:20 -
374
+Rule	sol88	1988	only	-	Dec	25	12:00:10s -0:00:10 -
375
+Rule	sol88	1988	only	-	Dec	26	12:00:40s -0:00:40 -
376
+Rule	sol88	1988	only	-	Dec	27	12:01:10s -0:01:10 -
377
+Rule	sol88	1988	only	-	Dec	28	12:01:40s -0:01:40 -
378
+Rule	sol88	1988	only	-	Dec	29	12:02:10s -0:02:10 -
379
+Rule	sol88	1988	only	-	Dec	30	12:02:35s -0:02:35 -
380
+Rule	sol88	1988	only	-	Dec	31	12:03:05s -0:03:05 -
381
+
382
+# Riyadh is at about 46 degrees 46 minutes East:  3 hrs, 7 mins, 4 secs
383
+# Before and after 1988, we'll operate on local mean solar time.
384
+
385
+# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
386
+Zone	Asia/Riyadh88	3:07:04	-		zzz	1988
387
+			3:07:04	sol88		zzz	1989
388
+			3:07:04	-		zzz
389
+# For backward compatibility...
390
+Link	Asia/Riyadh88	Mideast/Riyadh88
... ...
@@ -0,0 +1,395 @@
1
+# <pre>
2
+# This file is in the public domain, so clarified as of
3
+# 2009-05-17 by Arthur David Olson.
4
+
5
+# Apparent noon times below are for Riyadh; they're a bit off for other places.
6
+# Times were computed using a formula provided by the U. S. Naval Observatory:
7
+#	eqt = -105.8 * sin(l) + 596.2 * sin(2 * l) + 4.4 * sin(3 * l)
8
+#		-12.7 * sin(4 * l) - 429.0 * cos(l) - 2.1 * cos (2 * l)
9
+#		+ 19.3 * cos(3 * l);
10
+# where l is the "mean longitude of the Sun" given by
11
+#	l = 279.642 degrees + 0.985647 * d
12
+# and d is the interval in days from January 0, 0 hours Universal Time
13
+# (equaling the day of the year plus the fraction of a day from zero hours).
14
+# The accuracy of the formula is plus or minus three seconds.
15
+#
16
+# Rounding to the nearest five seconds results in fewer than
17
+# 256 different "time types"--a limit that's faced because time types are
18
+# stored on disk as unsigned chars.
19
+
20
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
21
+Rule	sol89	1989	only	-	Jan	1	12:03:35s -0:03:35 -
22
+Rule	sol89	1989	only	-	Jan	2	12:04:05s -0:04:05 -
23
+Rule	sol89	1989	only	-	Jan	3	12:04:30s -0:04:30 -
24
+Rule	sol89	1989	only	-	Jan	4	12:05:00s -0:05:00 -
25
+Rule	sol89	1989	only	-	Jan	5	12:05:25s -0:05:25 -
26
+Rule	sol89	1989	only	-	Jan	6	12:05:50s -0:05:50 -
27
+Rule	sol89	1989	only	-	Jan	7	12:06:15s -0:06:15 -
28
+Rule	sol89	1989	only	-	Jan	8	12:06:45s -0:06:45 -
29
+Rule	sol89	1989	only	-	Jan	9	12:07:10s -0:07:10 -
30
+Rule	sol89	1989	only	-	Jan	10	12:07:35s -0:07:35 -
31
+Rule	sol89	1989	only	-	Jan	11	12:07:55s -0:07:55 -
32
+Rule	sol89	1989	only	-	Jan	12	12:08:20s -0:08:20 -
33
+Rule	sol89	1989	only	-	Jan	13	12:08:45s -0:08:45 -
34
+Rule	sol89	1989	only	-	Jan	14	12:09:05s -0:09:05 -
35
+Rule	sol89	1989	only	-	Jan	15	12:09:25s -0:09:25 -
36
+Rule	sol89	1989	only	-	Jan	16	12:09:45s -0:09:45 -
37
+Rule	sol89	1989	only	-	Jan	17	12:10:05s -0:10:05 -
38
+Rule	sol89	1989	only	-	Jan	18	12:10:25s -0:10:25 -
39
+Rule	sol89	1989	only	-	Jan	19	12:10:45s -0:10:45 -
40
+Rule	sol89	1989	only	-	Jan	20	12:11:05s -0:11:05 -
41
+Rule	sol89	1989	only	-	Jan	21	12:11:20s -0:11:20 -
42
+Rule	sol89	1989	only	-	Jan	22	12:11:35s -0:11:35 -
43
+Rule	sol89	1989	only	-	Jan	23	12:11:55s -0:11:55 -
44
+Rule	sol89	1989	only	-	Jan	24	12:12:10s -0:12:10 -
45
+Rule	sol89	1989	only	-	Jan	25	12:12:20s -0:12:20 -
46
+Rule	sol89	1989	only	-	Jan	26	12:12:35s -0:12:35 -
47
+Rule	sol89	1989	only	-	Jan	27	12:12:50s -0:12:50 -
48
+Rule	sol89	1989	only	-	Jan	28	12:13:00s -0:13:00 -
49
+Rule	sol89	1989	only	-	Jan	29	12:13:10s -0:13:10 -
50
+Rule	sol89	1989	only	-	Jan	30	12:13:20s -0:13:20 -
51
+Rule	sol89	1989	only	-	Jan	31	12:13:30s -0:13:30 -
52
+Rule	sol89	1989	only	-	Feb	1	12:13:40s -0:13:40 -
53
+Rule	sol89	1989	only	-	Feb	2	12:13:45s -0:13:45 -
54
+Rule	sol89	1989	only	-	Feb	3	12:13:55s -0:13:55 -
55
+Rule	sol89	1989	only	-	Feb	4	12:14:00s -0:14:00 -
56
+Rule	sol89	1989	only	-	Feb	5	12:14:05s -0:14:05 -
57
+Rule	sol89	1989	only	-	Feb	6	12:14:10s -0:14:10 -
58
+Rule	sol89	1989	only	-	Feb	7	12:14:10s -0:14:10 -
59
+Rule	sol89	1989	only	-	Feb	8	12:14:15s -0:14:15 -
60
+Rule	sol89	1989	only	-	Feb	9	12:14:15s -0:14:15 -
61
+Rule	sol89	1989	only	-	Feb	10	12:14:20s -0:14:20 -
62
+Rule	sol89	1989	only	-	Feb	11	12:14:20s -0:14:20 -
63
+Rule	sol89	1989	only	-	Feb	12	12:14:20s -0:14:20 -
64
+Rule	sol89	1989	only	-	Feb	13	12:14:15s -0:14:15 -
65
+Rule	sol89	1989	only	-	Feb	14	12:14:15s -0:14:15 -
66
+Rule	sol89	1989	only	-	Feb	15	12:14:10s -0:14:10 -
67
+Rule	sol89	1989	only	-	Feb	16	12:14:10s -0:14:10 -
68
+Rule	sol89	1989	only	-	Feb	17	12:14:05s -0:14:05 -
69
+Rule	sol89	1989	only	-	Feb	18	12:14:00s -0:14:00 -
70
+Rule	sol89	1989	only	-	Feb	19	12:13:55s -0:13:55 -
71
+Rule	sol89	1989	only	-	Feb	20	12:13:50s -0:13:50 -
72
+Rule	sol89	1989	only	-	Feb	21	12:13:40s -0:13:40 -
73
+Rule	sol89	1989	only	-	Feb	22	12:13:35s -0:13:35 -
74
+Rule	sol89	1989	only	-	Feb	23	12:13:25s -0:13:25 -
75
+Rule	sol89	1989	only	-	Feb	24	12:13:15s -0:13:15 -
76
+Rule	sol89	1989	only	-	Feb	25	12:13:05s -0:13:05 -
77
+Rule	sol89	1989	only	-	Feb	26	12:12:55s -0:12:55 -
78
+Rule	sol89	1989	only	-	Feb	27	12:12:45s -0:12:45 -
79
+Rule	sol89	1989	only	-	Feb	28	12:12:35s -0:12:35 -
80
+Rule	sol89	1989	only	-	Mar	1	12:12:25s -0:12:25 -
81
+Rule	sol89	1989	only	-	Mar	2	12:12:10s -0:12:10 -
82
+Rule	sol89	1989	only	-	Mar	3	12:12:00s -0:12:00 -
83
+Rule	sol89	1989	only	-	Mar	4	12:11:45s -0:11:45 -
84
+Rule	sol89	1989	only	-	Mar	5	12:11:35s -0:11:35 -
85
+Rule	sol89	1989	only	-	Mar	6	12:11:20s -0:11:20 -
86
+Rule	sol89	1989	only	-	Mar	7	12:11:05s -0:11:05 -
87
+Rule	sol89	1989	only	-	Mar	8	12:10:50s -0:10:50 -
88
+Rule	sol89	1989	only	-	Mar	9	12:10:35s -0:10:35 -
89
+Rule	sol89	1989	only	-	Mar	10	12:10:20s -0:10:20 -
90
+Rule	sol89	1989	only	-	Mar	11	12:10:05s -0:10:05 -
91
+Rule	sol89	1989	only	-	Mar	12	12:09:50s -0:09:50 -
92
+Rule	sol89	1989	only	-	Mar	13	12:09:30s -0:09:30 -
93
+Rule	sol89	1989	only	-	Mar	14	12:09:15s -0:09:15 -
94
+Rule	sol89	1989	only	-	Mar	15	12:09:00s -0:09:00 -
95
+Rule	sol89	1989	only	-	Mar	16	12:08:40s -0:08:40 -
96
+Rule	sol89	1989	only	-	Mar	17	12:08:25s -0:08:25 -
97
+Rule	sol89	1989	only	-	Mar	18	12:08:05s -0:08:05 -
98
+Rule	sol89	1989	only	-	Mar	19	12:07:50s -0:07:50 -
99
+Rule	sol89	1989	only	-	Mar	20	12:07:30s -0:07:30 -
100
+Rule	sol89	1989	only	-	Mar	21	12:07:15s -0:07:15 -
101
+Rule	sol89	1989	only	-	Mar	22	12:06:55s -0:06:55 -
102
+Rule	sol89	1989	only	-	Mar	23	12:06:35s -0:06:35 -
103
+Rule	sol89	1989	only	-	Mar	24	12:06:20s -0:06:20 -
104
+Rule	sol89	1989	only	-	Mar	25	12:06:00s -0:06:00 -
105
+Rule	sol89	1989	only	-	Mar	26	12:05:40s -0:05:40 -
106
+Rule	sol89	1989	only	-	Mar	27	12:05:25s -0:05:25 -
107
+Rule	sol89	1989	only	-	Mar	28	12:05:05s -0:05:05 -
108
+Rule	sol89	1989	only	-	Mar	29	12:04:50s -0:04:50 -
109
+Rule	sol89	1989	only	-	Mar	30	12:04:30s -0:04:30 -
110
+Rule	sol89	1989	only	-	Mar	31	12:04:10s -0:04:10 -
111
+Rule	sol89	1989	only	-	Apr	1	12:03:55s -0:03:55 -
112
+Rule	sol89	1989	only	-	Apr	2	12:03:35s -0:03:35 -
113
+Rule	sol89	1989	only	-	Apr	3	12:03:20s -0:03:20 -
114
+Rule	sol89	1989	only	-	Apr	4	12:03:00s -0:03:00 -
115
+Rule	sol89	1989	only	-	Apr	5	12:02:45s -0:02:45 -
116
+Rule	sol89	1989	only	-	Apr	6	12:02:25s -0:02:25 -
117
+Rule	sol89	1989	only	-	Apr	7	12:02:10s -0:02:10 -
118
+Rule	sol89	1989	only	-	Apr	8	12:01:50s -0:01:50 -
119
+Rule	sol89	1989	only	-	Apr	9	12:01:35s -0:01:35 -
120
+Rule	sol89	1989	only	-	Apr	10	12:01:20s -0:01:20 -
121
+Rule	sol89	1989	only	-	Apr	11	12:01:05s -0:01:05 -
122
+Rule	sol89	1989	only	-	Apr	12	12:00:50s -0:00:50 -
123
+Rule	sol89	1989	only	-	Apr	13	12:00:35s -0:00:35 -
124
+Rule	sol89	1989	only	-	Apr	14	12:00:20s -0:00:20 -
125
+Rule	sol89	1989	only	-	Apr	15	12:00:05s -0:00:05 -
126
+Rule	sol89	1989	only	-	Apr	16	11:59:50s 0:00:10 -
127
+Rule	sol89	1989	only	-	Apr	17	11:59:35s 0:00:25 -
128
+Rule	sol89	1989	only	-	Apr	18	11:59:20s 0:00:40 -
129
+Rule	sol89	1989	only	-	Apr	19	11:59:10s 0:00:50 -
130
+Rule	sol89	1989	only	-	Apr	20	11:58:55s 0:01:05 -
131
+Rule	sol89	1989	only	-	Apr	21	11:58:45s 0:01:15 -
132
+Rule	sol89	1989	only	-	Apr	22	11:58:30s 0:01:30 -
133
+Rule	sol89	1989	only	-	Apr	23	11:58:20s 0:01:40 -
134
+Rule	sol89	1989	only	-	Apr	24	11:58:10s 0:01:50 -
135
+Rule	sol89	1989	only	-	Apr	25	11:58:00s 0:02:00 -
136
+Rule	sol89	1989	only	-	Apr	26	11:57:50s 0:02:10 -
137
+Rule	sol89	1989	only	-	Apr	27	11:57:40s 0:02:20 -
138
+Rule	sol89	1989	only	-	Apr	28	11:57:30s 0:02:30 -
139
+Rule	sol89	1989	only	-	Apr	29	11:57:20s 0:02:40 -
140
+Rule	sol89	1989	only	-	Apr	30	11:57:15s 0:02:45 -
141
+Rule	sol89	1989	only	-	May	1	11:57:05s 0:02:55 -
142
+Rule	sol89	1989	only	-	May	2	11:57:00s 0:03:00 -
143
+Rule	sol89	1989	only	-	May	3	11:56:50s 0:03:10 -
144
+Rule	sol89	1989	only	-	May	4	11:56:45s 0:03:15 -
145
+Rule	sol89	1989	only	-	May	5	11:56:40s 0:03:20 -
146
+Rule	sol89	1989	only	-	May	6	11:56:35s 0:03:25 -
147
+Rule	sol89	1989	only	-	May	7	11:56:30s 0:03:30 -
148
+Rule	sol89	1989	only	-	May	8	11:56:30s 0:03:30 -
149
+Rule	sol89	1989	only	-	May	9	11:56:25s 0:03:35 -
150
+Rule	sol89	1989	only	-	May	10	11:56:25s 0:03:35 -
151
+Rule	sol89	1989	only	-	May	11	11:56:20s 0:03:40 -
152
+Rule	sol89	1989	only	-	May	12	11:56:20s 0:03:40 -
153
+Rule	sol89	1989	only	-	May	13	11:56:20s 0:03:40 -
154
+Rule	sol89	1989	only	-	May	14	11:56:20s 0:03:40 -
155
+Rule	sol89	1989	only	-	May	15	11:56:20s 0:03:40 -
156
+Rule	sol89	1989	only	-	May	16	11:56:20s 0:03:40 -
157
+Rule	sol89	1989	only	-	May	17	11:56:20s 0:03:40 -
158
+Rule	sol89	1989	only	-	May	18	11:56:25s 0:03:35 -
159
+Rule	sol89	1989	only	-	May	19	11:56:25s 0:03:35 -
160
+Rule	sol89	1989	only	-	May	20	11:56:30s 0:03:30 -
161
+Rule	sol89	1989	only	-	May	21	11:56:35s 0:03:25 -
162
+Rule	sol89	1989	only	-	May	22	11:56:35s 0:03:25 -
163
+Rule	sol89	1989	only	-	May	23	11:56:40s 0:03:20 -
164
+Rule	sol89	1989	only	-	May	24	11:56:45s 0:03:15 -
165
+Rule	sol89	1989	only	-	May	25	11:56:55s 0:03:05 -
166
+Rule	sol89	1989	only	-	May	26	11:57:00s 0:03:00 -
167
+Rule	sol89	1989	only	-	May	27	11:57:05s 0:02:55 -
168
+Rule	sol89	1989	only	-	May	28	11:57:15s 0:02:45 -
169
+Rule	sol89	1989	only	-	May	29	11:57:20s 0:02:40 -
170
+Rule	sol89	1989	only	-	May	30	11:57:30s 0:02:30 -
171
+Rule	sol89	1989	only	-	May	31	11:57:35s 0:02:25 -
172
+Rule	sol89	1989	only	-	Jun	1	11:57:45s 0:02:15 -
173
+Rule	sol89	1989	only	-	Jun	2	11:57:55s 0:02:05 -
174
+Rule	sol89	1989	only	-	Jun	3	11:58:05s 0:01:55 -
175
+Rule	sol89	1989	only	-	Jun	4	11:58:15s 0:01:45 -
176
+Rule	sol89	1989	only	-	Jun	5	11:58:25s 0:01:35 -
177
+Rule	sol89	1989	only	-	Jun	6	11:58:35s 0:01:25 -
178
+Rule	sol89	1989	only	-	Jun	7	11:58:45s 0:01:15 -
179
+Rule	sol89	1989	only	-	Jun	8	11:59:00s 0:01:00 -
180
+Rule	sol89	1989	only	-	Jun	9	11:59:10s 0:00:50 -
181
+Rule	sol89	1989	only	-	Jun	10	11:59:20s 0:00:40 -
182
+Rule	sol89	1989	only	-	Jun	11	11:59:35s 0:00:25 -
183
+Rule	sol89	1989	only	-	Jun	12	11:59:45s 0:00:15 -
184
+Rule	sol89	1989	only	-	Jun	13	12:00:00s 0:00:00 -
185
+Rule	sol89	1989	only	-	Jun	14	12:00:10s -0:00:10 -
186
+Rule	sol89	1989	only	-	Jun	15	12:00:25s -0:00:25 -
187
+Rule	sol89	1989	only	-	Jun	16	12:00:35s -0:00:35 -
188
+Rule	sol89	1989	only	-	Jun	17	12:00:50s -0:00:50 -
189
+Rule	sol89	1989	only	-	Jun	18	12:01:05s -0:01:05 -
190
+Rule	sol89	1989	only	-	Jun	19	12:01:15s -0:01:15 -
191
+Rule	sol89	1989	only	-	Jun	20	12:01:30s -0:01:30 -
192
+Rule	sol89	1989	only	-	Jun	21	12:01:40s -0:01:40 -
193
+Rule	sol89	1989	only	-	Jun	22	12:01:55s -0:01:55 -
194
+Rule	sol89	1989	only	-	Jun	23	12:02:10s -0:02:10 -
195
+Rule	sol89	1989	only	-	Jun	24	12:02:20s -0:02:20 -
196
+Rule	sol89	1989	only	-	Jun	25	12:02:35s -0:02:35 -
197
+Rule	sol89	1989	only	-	Jun	26	12:02:45s -0:02:45 -
198
+Rule	sol89	1989	only	-	Jun	27	12:03:00s -0:03:00 -
199
+Rule	sol89	1989	only	-	Jun	28	12:03:10s -0:03:10 -
200
+Rule	sol89	1989	only	-	Jun	29	12:03:25s -0:03:25 -
201
+Rule	sol89	1989	only	-	Jun	30	12:03:35s -0:03:35 -
202
+Rule	sol89	1989	only	-	Jul	1	12:03:45s -0:03:45 -
203
+Rule	sol89	1989	only	-	Jul	2	12:04:00s -0:04:00 -
204
+Rule	sol89	1989	only	-	Jul	3	12:04:10s -0:04:10 -
205
+Rule	sol89	1989	only	-	Jul	4	12:04:20s -0:04:20 -
206
+Rule	sol89	1989	only	-	Jul	5	12:04:30s -0:04:30 -
207
+Rule	sol89	1989	only	-	Jul	6	12:04:40s -0:04:40 -
208
+Rule	sol89	1989	only	-	Jul	7	12:04:50s -0:04:50 -
209
+Rule	sol89	1989	only	-	Jul	8	12:05:00s -0:05:00 -
210
+Rule	sol89	1989	only	-	Jul	9	12:05:10s -0:05:10 -
211
+Rule	sol89	1989	only	-	Jul	10	12:05:20s -0:05:20 -
212
+Rule	sol89	1989	only	-	Jul	11	12:05:25s -0:05:25 -
213
+Rule	sol89	1989	only	-	Jul	12	12:05:35s -0:05:35 -
214
+Rule	sol89	1989	only	-	Jul	13	12:05:40s -0:05:40 -
215
+Rule	sol89	1989	only	-	Jul	14	12:05:50s -0:05:50 -
216
+Rule	sol89	1989	only	-	Jul	15	12:05:55s -0:05:55 -
217
+Rule	sol89	1989	only	-	Jul	16	12:06:00s -0:06:00 -
218
+Rule	sol89	1989	only	-	Jul	17	12:06:05s -0:06:05 -
219
+Rule	sol89	1989	only	-	Jul	18	12:06:10s -0:06:10 -
220
+Rule	sol89	1989	only	-	Jul	19	12:06:15s -0:06:15 -
221
+Rule	sol89	1989	only	-	Jul	20	12:06:20s -0:06:20 -
222
+Rule	sol89	1989	only	-	Jul	21	12:06:20s -0:06:20 -
223
+Rule	sol89	1989	only	-	Jul	22	12:06:25s -0:06:25 -
224
+Rule	sol89	1989	only	-	Jul	23	12:06:25s -0:06:25 -
225
+Rule	sol89	1989	only	-	Jul	24	12:06:30s -0:06:30 -
226
+Rule	sol89	1989	only	-	Jul	25	12:06:30s -0:06:30 -
227
+Rule	sol89	1989	only	-	Jul	26	12:06:30s -0:06:30 -
228
+Rule	sol89	1989	only	-	Jul	27	12:06:30s -0:06:30 -
229
+Rule	sol89	1989	only	-	Jul	28	12:06:30s -0:06:30 -
230
+Rule	sol89	1989	only	-	Jul	29	12:06:25s -0:06:25 -
231
+Rule	sol89	1989	only	-	Jul	30	12:06:25s -0:06:25 -
232
+Rule	sol89	1989	only	-	Jul	31	12:06:20s -0:06:20 -
233
+Rule	sol89	1989	only	-	Aug	1	12:06:20s -0:06:20 -
234
+Rule	sol89	1989	only	-	Aug	2	12:06:15s -0:06:15 -
235
+Rule	sol89	1989	only	-	Aug	3	12:06:10s -0:06:10 -
236
+Rule	sol89	1989	only	-	Aug	4	12:06:05s -0:06:05 -
237
+Rule	sol89	1989	only	-	Aug	5	12:06:00s -0:06:00 -
238
+Rule	sol89	1989	only	-	Aug	6	12:05:50s -0:05:50 -
239
+Rule	sol89	1989	only	-	Aug	7	12:05:45s -0:05:45 -
240
+Rule	sol89	1989	only	-	Aug	8	12:05:35s -0:05:35 -
241
+Rule	sol89	1989	only	-	Aug	9	12:05:30s -0:05:30 -
242
+Rule	sol89	1989	only	-	Aug	10	12:05:20s -0:05:20 -
243
+Rule	sol89	1989	only	-	Aug	11	12:05:10s -0:05:10 -
244
+Rule	sol89	1989	only	-	Aug	12	12:05:00s -0:05:00 -
245
+Rule	sol89	1989	only	-	Aug	13	12:04:50s -0:04:50 -
246
+Rule	sol89	1989	only	-	Aug	14	12:04:40s -0:04:40 -
247
+Rule	sol89	1989	only	-	Aug	15	12:04:30s -0:04:30 -
248
+Rule	sol89	1989	only	-	Aug	16	12:04:15s -0:04:15 -
249
+Rule	sol89	1989	only	-	Aug	17	12:04:05s -0:04:05 -
250
+Rule	sol89	1989	only	-	Aug	18	12:03:50s -0:03:50 -
251
+Rule	sol89	1989	only	-	Aug	19	12:03:35s -0:03:35 -
252
+Rule	sol89	1989	only	-	Aug	20	12:03:25s -0:03:25 -
253
+Rule	sol89	1989	only	-	Aug	21	12:03:10s -0:03:10 -
254
+Rule	sol89	1989	only	-	Aug	22	12:02:55s -0:02:55 -
255
+Rule	sol89	1989	only	-	Aug	23	12:02:40s -0:02:40 -
256
+Rule	sol89	1989	only	-	Aug	24	12:02:20s -0:02:20 -
257
+Rule	sol89	1989	only	-	Aug	25	12:02:05s -0:02:05 -
258
+Rule	sol89	1989	only	-	Aug	26	12:01:50s -0:01:50 -
259
+Rule	sol89	1989	only	-	Aug	27	12:01:30s -0:01:30 -
260
+Rule	sol89	1989	only	-	Aug	28	12:01:15s -0:01:15 -
261
+Rule	sol89	1989	only	-	Aug	29	12:00:55s -0:00:55 -
262
+Rule	sol89	1989	only	-	Aug	30	12:00:40s -0:00:40 -
263
+Rule	sol89	1989	only	-	Aug	31	12:00:20s -0:00:20 -
264
+Rule	sol89	1989	only	-	Sep	1	12:00:00s 0:00:00 -
265
+Rule	sol89	1989	only	-	Sep	2	11:59:45s 0:00:15 -
266
+Rule	sol89	1989	only	-	Sep	3	11:59:25s 0:00:35 -
267
+Rule	sol89	1989	only	-	Sep	4	11:59:05s 0:00:55 -
268
+Rule	sol89	1989	only	-	Sep	5	11:58:45s 0:01:15 -
269
+Rule	sol89	1989	only	-	Sep	6	11:58:25s 0:01:35 -
270
+Rule	sol89	1989	only	-	Sep	7	11:58:05s 0:01:55 -
271
+Rule	sol89	1989	only	-	Sep	8	11:57:45s 0:02:15 -
272
+Rule	sol89	1989	only	-	Sep	9	11:57:20s 0:02:40 -
273
+Rule	sol89	1989	only	-	Sep	10	11:57:00s 0:03:00 -
274
+Rule	sol89	1989	only	-	Sep	11	11:56:40s 0:03:20 -
275
+Rule	sol89	1989	only	-	Sep	12	11:56:20s 0:03:40 -
276
+Rule	sol89	1989	only	-	Sep	13	11:56:00s 0:04:00 -
277
+Rule	sol89	1989	only	-	Sep	14	11:55:35s 0:04:25 -
278
+Rule	sol89	1989	only	-	Sep	15	11:55:15s 0:04:45 -
279
+Rule	sol89	1989	only	-	Sep	16	11:54:55s 0:05:05 -
280
+Rule	sol89	1989	only	-	Sep	17	11:54:35s 0:05:25 -
281
+Rule	sol89	1989	only	-	Sep	18	11:54:10s 0:05:50 -
282
+Rule	sol89	1989	only	-	Sep	19	11:53:50s 0:06:10 -
283
+Rule	sol89	1989	only	-	Sep	20	11:53:30s 0:06:30 -
284
+Rule	sol89	1989	only	-	Sep	21	11:53:10s 0:06:50 -
285
+Rule	sol89	1989	only	-	Sep	22	11:52:45s 0:07:15 -
286
+Rule	sol89	1989	only	-	Sep	23	11:52:25s 0:07:35 -
287
+Rule	sol89	1989	only	-	Sep	24	11:52:05s 0:07:55 -
288
+Rule	sol89	1989	only	-	Sep	25	11:51:45s 0:08:15 -
289
+Rule	sol89	1989	only	-	Sep	26	11:51:25s 0:08:35 -
290
+Rule	sol89	1989	only	-	Sep	27	11:51:05s 0:08:55 -
291
+Rule	sol89	1989	only	-	Sep	28	11:50:40s 0:09:20 -
292
+Rule	sol89	1989	only	-	Sep	29	11:50:20s 0:09:40 -
293
+Rule	sol89	1989	only	-	Sep	30	11:50:00s 0:10:00 -
294
+Rule	sol89	1989	only	-	Oct	1	11:49:45s 0:10:15 -
295
+Rule	sol89	1989	only	-	Oct	2	11:49:25s 0:10:35 -
296
+Rule	sol89	1989	only	-	Oct	3	11:49:05s 0:10:55 -
297
+Rule	sol89	1989	only	-	Oct	4	11:48:45s 0:11:15 -
298
+Rule	sol89	1989	only	-	Oct	5	11:48:30s 0:11:30 -
299
+Rule	sol89	1989	only	-	Oct	6	11:48:10s 0:11:50 -
300
+Rule	sol89	1989	only	-	Oct	7	11:47:50s 0:12:10 -
301
+Rule	sol89	1989	only	-	Oct	8	11:47:35s 0:12:25 -
302
+Rule	sol89	1989	only	-	Oct	9	11:47:20s 0:12:40 -
303
+Rule	sol89	1989	only	-	Oct	10	11:47:00s 0:13:00 -
304
+Rule	sol89	1989	only	-	Oct	11	11:46:45s 0:13:15 -
305
+Rule	sol89	1989	only	-	Oct	12	11:46:30s 0:13:30 -
306
+Rule	sol89	1989	only	-	Oct	13	11:46:15s 0:13:45 -
307
+Rule	sol89	1989	only	-	Oct	14	11:46:00s 0:14:00 -
308
+Rule	sol89	1989	only	-	Oct	15	11:45:50s 0:14:10 -
309
+Rule	sol89	1989	only	-	Oct	16	11:45:35s 0:14:25 -
310
+Rule	sol89	1989	only	-	Oct	17	11:45:20s 0:14:40 -
311
+Rule	sol89	1989	only	-	Oct	18	11:45:10s 0:14:50 -
312
+Rule	sol89	1989	only	-	Oct	19	11:45:00s 0:15:00 -
313
+Rule	sol89	1989	only	-	Oct	20	11:44:50s 0:15:10 -
314
+Rule	sol89	1989	only	-	Oct	21	11:44:40s 0:15:20 -
315
+Rule	sol89	1989	only	-	Oct	22	11:44:30s 0:15:30 -
316
+Rule	sol89	1989	only	-	Oct	23	11:44:20s 0:15:40 -
317
+Rule	sol89	1989	only	-	Oct	24	11:44:10s 0:15:50 -
318
+Rule	sol89	1989	only	-	Oct	25	11:44:05s 0:15:55 -
319
+Rule	sol89	1989	only	-	Oct	26	11:44:00s 0:16:00 -
320
+Rule	sol89	1989	only	-	Oct	27	11:43:50s 0:16:10 -
321
+Rule	sol89	1989	only	-	Oct	28	11:43:45s 0:16:15 -
322
+Rule	sol89	1989	only	-	Oct	29	11:43:40s 0:16:20 -
323
+Rule	sol89	1989	only	-	Oct	30	11:43:40s 0:16:20 -
324
+Rule	sol89	1989	only	-	Oct	31	11:43:35s 0:16:25 -
325
+Rule	sol89	1989	only	-	Nov	1	11:43:35s 0:16:25 -
326
+Rule	sol89	1989	only	-	Nov	2	11:43:35s 0:16:25 -
327
+Rule	sol89	1989	only	-	Nov	3	11:43:30s 0:16:30 -
328
+Rule	sol89	1989	only	-	Nov	4	11:43:35s 0:16:25 -
329
+Rule	sol89	1989	only	-	Nov	5	11:43:35s 0:16:25 -
330
+Rule	sol89	1989	only	-	Nov	6	11:43:35s 0:16:25 -
331
+Rule	sol89	1989	only	-	Nov	7	11:43:40s 0:16:20 -
332
+Rule	sol89	1989	only	-	Nov	8	11:43:45s 0:16:15 -
333
+Rule	sol89	1989	only	-	Nov	9	11:43:50s 0:16:10 -
334
+Rule	sol89	1989	only	-	Nov	10	11:43:55s 0:16:05 -
335
+Rule	sol89	1989	only	-	Nov	11	11:44:00s 0:16:00 -
336
+Rule	sol89	1989	only	-	Nov	12	11:44:05s 0:15:55 -
337
+Rule	sol89	1989	only	-	Nov	13	11:44:15s 0:15:45 -
338
+Rule	sol89	1989	only	-	Nov	14	11:44:25s 0:15:35 -
339
+Rule	sol89	1989	only	-	Nov	15	11:44:35s 0:15:25 -
340
+Rule	sol89	1989	only	-	Nov	16	11:44:45s 0:15:15 -
341
+Rule	sol89	1989	only	-	Nov	17	11:44:55s 0:15:05 -
342
+Rule	sol89	1989	only	-	Nov	18	11:45:10s 0:14:50 -
343
+Rule	sol89	1989	only	-	Nov	19	11:45:20s 0:14:40 -
344
+Rule	sol89	1989	only	-	Nov	20	11:45:35s 0:14:25 -
345
+Rule	sol89	1989	only	-	Nov	21	11:45:50s 0:14:10 -
346
+Rule	sol89	1989	only	-	Nov	22	11:46:05s 0:13:55 -
347
+Rule	sol89	1989	only	-	Nov	23	11:46:25s 0:13:35 -
348
+Rule	sol89	1989	only	-	Nov	24	11:46:40s 0:13:20 -
349
+Rule	sol89	1989	only	-	Nov	25	11:47:00s 0:13:00 -
350
+Rule	sol89	1989	only	-	Nov	26	11:47:20s 0:12:40 -
351
+Rule	sol89	1989	only	-	Nov	27	11:47:35s 0:12:25 -
352
+Rule	sol89	1989	only	-	Nov	28	11:47:55s 0:12:05 -
353
+Rule	sol89	1989	only	-	Nov	29	11:48:20s 0:11:40 -
354
+Rule	sol89	1989	only	-	Nov	30	11:48:40s 0:11:20 -
355
+Rule	sol89	1989	only	-	Dec	1	11:49:00s 0:11:00 -
356
+Rule	sol89	1989	only	-	Dec	2	11:49:25s 0:10:35 -
357
+Rule	sol89	1989	only	-	Dec	3	11:49:50s 0:10:10 -
358
+Rule	sol89	1989	only	-	Dec	4	11:50:15s 0:09:45 -
359
+Rule	sol89	1989	only	-	Dec	5	11:50:35s 0:09:25 -
360
+Rule	sol89	1989	only	-	Dec	6	11:51:00s 0:09:00 -
361
+Rule	sol89	1989	only	-	Dec	7	11:51:30s 0:08:30 -
362
+Rule	sol89	1989	only	-	Dec	8	11:51:55s 0:08:05 -
363
+Rule	sol89	1989	only	-	Dec	9	11:52:20s 0:07:40 -
364
+Rule	sol89	1989	only	-	Dec	10	11:52:50s 0:07:10 -
365
+Rule	sol89	1989	only	-	Dec	11	11:53:15s 0:06:45 -
366
+Rule	sol89	1989	only	-	Dec	12	11:53:45s 0:06:15 -
367
+Rule	sol89	1989	only	-	Dec	13	11:54:10s 0:05:50 -
368
+Rule	sol89	1989	only	-	Dec	14	11:54:40s 0:05:20 -
369
+Rule	sol89	1989	only	-	Dec	15	11:55:10s 0:04:50 -
370
+Rule	sol89	1989	only	-	Dec	16	11:55:40s 0:04:20 -
371
+Rule	sol89	1989	only	-	Dec	17	11:56:05s 0:03:55 -
372
+Rule	sol89	1989	only	-	Dec	18	11:56:35s 0:03:25 -
373
+Rule	sol89	1989	only	-	Dec	19	11:57:05s 0:02:55 -
374
+Rule	sol89	1989	only	-	Dec	20	11:57:35s 0:02:25 -
375
+Rule	sol89	1989	only	-	Dec	21	11:58:05s 0:01:55 -
376
+Rule	sol89	1989	only	-	Dec	22	11:58:35s 0:01:25 -
377
+Rule	sol89	1989	only	-	Dec	23	11:59:05s 0:00:55 -
378
+Rule	sol89	1989	only	-	Dec	24	11:59:35s 0:00:25 -
379
+Rule	sol89	1989	only	-	Dec	25	12:00:05s -0:00:05 -
380
+Rule	sol89	1989	only	-	Dec	26	12:00:35s -0:00:35 -
381
+Rule	sol89	1989	only	-	Dec	27	12:01:05s -0:01:05 -
382
+Rule	sol89	1989	only	-	Dec	28	12:01:35s -0:01:35 -
383
+Rule	sol89	1989	only	-	Dec	29	12:02:00s -0:02:00 -
384
+Rule	sol89	1989	only	-	Dec	30	12:02:30s -0:02:30 -
385
+Rule	sol89	1989	only	-	Dec	31	12:03:00s -0:03:00 -
386
+
387
+# Riyadh is at about 46 degrees 46 minutes East:  3 hrs, 7 mins, 4 secs
388
+# Before and after 1989, we'll operate on local mean solar time.
389
+
390
+# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
391
+Zone	Asia/Riyadh89	3:07:04	-		zzz	1989
392
+			3:07:04	sol89		zzz	1990
393
+			3:07:04	-		zzz
394
+# For backward compatibility...
395
+Link	Asia/Riyadh89	Mideast/Riyadh89
... ...
@@ -0,0 +1,1711 @@
1
+# <pre>
2
+# This file is in the public domain, so clarified as of
3
+# 2009-05-17 by Arthur David Olson.
4
+
5
+# This data is by no means authoritative; if you think you know better,
6
+# go ahead and edit the file (and please send any changes to
7
+# tz@iana.org for general use in the future).
8
+
9
+# From Paul Eggert (2006-03-22):
10
+# A good source for time zone historical data outside the U.S. is
11
+# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
12
+# San Diego: ACS Publications, Inc. (2003).
13
+#
14
+# Gwillim Law writes that a good source
15
+# for recent time zone data is the International Air Transport
16
+# Association's Standard Schedules Information Manual (IATA SSIM),
17
+# published semiannually.  Law sent in several helpful summaries
18
+# of the IATA's data after 1990.
19
+#
20
+# Except where otherwise noted, Shanks & Pottenger is the source for
21
+# entries through 1990, and IATA SSIM is the source for entries afterwards.
22
+#
23
+# Earlier editions of these tables used the North American style (e.g. ARST and
24
+# ARDT for Argentine Standard and Daylight Time), but the following quote
25
+# suggests that it's better to use European style (e.g. ART and ARST).
26
+#	I suggest the use of _Summer time_ instead of the more cumbersome
27
+#	_daylight-saving time_.  _Summer time_ seems to be in general use
28
+#	in Europe and South America.
29
+#	-- E O Cutler, _New York Times_ (1937-02-14), quoted in
30
+#	H L Mencken, _The American Language: Supplement I_ (1960), p 466
31
+#
32
+# Earlier editions of these tables also used the North American style
33
+# for time zones in Brazil, but this was incorrect, as Brazilians say
34
+# "summer time".  Reinaldo Goulart, a Sao Paulo businessman active in
35
+# the railroad sector, writes (1999-07-06):
36
+#	The subject of time zones is currently a matter of discussion/debate in
37
+#	Brazil.  Let's say that "the Brasilia time" is considered the
38
+#	"official time" because Brasilia is the capital city.
39
+#	The other three time zones are called "Brasilia time "minus one" or
40
+#	"plus one" or "plus two".  As far as I know there is no such
41
+#	name/designation as "Eastern Time" or "Central Time".
42
+# So I invented the following (English-language) abbreviations for now.
43
+# Corrections are welcome!
44
+#		std	dst
45
+#	-2:00	FNT	FNST	Fernando de Noronha
46
+#	-3:00	BRT	BRST	Brasilia
47
+#	-4:00	AMT	AMST	Amazon
48
+#	-5:00	ACT	ACST	Acre
49
+
50
+###############################################################################
51
+
52
+###############################################################################
53
+
54
+# Argentina
55
+
56
+# From Bob Devine (1988-01-28):
57
+# Argentina: first Sunday in October to first Sunday in April since 1976.
58
+# Double Summer time from 1969 to 1974.  Switches at midnight.
59
+
60
+# From U. S. Naval Observatory (1988-01-199):
61
+# ARGENTINA           3 H BEHIND   UTC
62
+
63
+# From Hernan G. Otero (1995-06-26):
64
+# I am sending modifications to the Argentine time zone table...
65
+# AR was chosen because they are the ISO letters that represent Argentina.
66
+
67
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
68
+Rule	Arg	1930	only	-	Dec	 1	0:00	1:00	S
69
+Rule	Arg	1931	only	-	Apr	 1	0:00	0	-
70
+Rule	Arg	1931	only	-	Oct	15	0:00	1:00	S
71
+Rule	Arg	1932	1940	-	Mar	 1	0:00	0	-
72
+Rule	Arg	1932	1939	-	Nov	 1	0:00	1:00	S
73
+Rule	Arg	1940	only	-	Jul	 1	0:00	1:00	S
74
+Rule	Arg	1941	only	-	Jun	15	0:00	0	-
75
+Rule	Arg	1941	only	-	Oct	15	0:00	1:00	S
76
+Rule	Arg	1943	only	-	Aug	 1	0:00	0	-
77
+Rule	Arg	1943	only	-	Oct	15	0:00	1:00	S
78
+Rule	Arg	1946	only	-	Mar	 1	0:00	0	-
79
+Rule	Arg	1946	only	-	Oct	 1	0:00	1:00	S
80
+Rule	Arg	1963	only	-	Oct	 1	0:00	0	-
81
+Rule	Arg	1963	only	-	Dec	15	0:00	1:00	S
82
+Rule	Arg	1964	1966	-	Mar	 1	0:00	0	-
83
+Rule	Arg	1964	1966	-	Oct	15	0:00	1:00	S
84
+Rule	Arg	1967	only	-	Apr	 2	0:00	0	-
85
+Rule	Arg	1967	1968	-	Oct	Sun>=1	0:00	1:00	S
86
+Rule	Arg	1968	1969	-	Apr	Sun>=1	0:00	0	-
87
+Rule	Arg	1974	only	-	Jan	23	0:00	1:00	S
88
+Rule	Arg	1974	only	-	May	 1	0:00	0	-
89
+Rule	Arg	1988	only	-	Dec	 1	0:00	1:00	S
90
+#
91
+# From Hernan G. Otero (1995-06-26):
92
+# These corrections were contributed by InterSoft Argentina S.A.,
93
+# obtaining the data from the:
94
+# Talleres de Hidrografia Naval Argentina
95
+# (Argentine Naval Hydrography Institute)
96
+Rule	Arg	1989	1993	-	Mar	Sun>=1	0:00	0	-
97
+Rule	Arg	1989	1992	-	Oct	Sun>=15	0:00	1:00	S
98
+#
99
+# From Hernan G. Otero (1995-06-26):
100
+# From this moment on, the law that mandated the daylight saving
101
+# time corrections was derogated and no more modifications
102
+# to the time zones (for daylight saving) are now made.
103
+#
104
+# From Rives McDow (2000-01-10):
105
+# On October 3, 1999, 0:00 local, Argentina implemented daylight savings time,
106
+# which did not result in the switch of a time zone, as they stayed 9 hours
107
+# from the International Date Line.
108
+Rule	Arg	1999	only	-	Oct	Sun>=1	0:00	1:00	S
109
+# From Paul Eggert (2007-12-28):
110
+# DST was set to expire on March 5, not March 3, but since it was converted
111
+# to standard time on March 3 it's more convenient for us to pretend that
112
+# it ended on March 3.
113
+Rule	Arg	2000	only	-	Mar	3	0:00	0	-
114
+#
115
+# From Peter Gradelski via Steffen Thorsen (2000-03-01):
116
+# We just checked with our Sao Paulo office and they say the government of
117
+# Argentina decided not to become one of the countries that go on or off DST.
118
+# So Buenos Aires should be -3 hours from GMT at all times.
119
+#
120
+# From Fabian L. Arce Jofre (2000-04-04):
121
+# The law that claimed DST for Argentina was derogated by President Fernando
122
+# de la Rua on March 2, 2000, because it would make people spend more energy
123
+# in the winter time, rather than less.  The change took effect on March 3.
124
+#
125
+# From Mariano Absatz (2001-06-06):
126
+# one of the major newspapers here in Argentina said that the 1999
127
+# Timezone Law (which never was effectively applied) will (would?) be
128
+# in effect.... The article is at
129
+# http://ar.clarin.com/diario/2001-06-06/e-01701.htm
130
+# ... The Law itself is "Ley No 25155", sanctioned on 1999-08-25, enacted
131
+# 1999-09-17, and published 1999-09-21.  The official publication is at:
132
+# http://www.boletin.jus.gov.ar/BON/Primera/1999/09-Septiembre/21/PDF/BO21-09-99LEG.PDF
133
+# Regretfully, you have to subscribe (and pay) for the on-line version....
134
+#
135
+# (2001-06-12):
136
+# the timezone for Argentina will not change next Sunday.
137
+# Apparently it will do so on Sunday 24th....
138
+# http://ar.clarin.com/diario/2001-06-12/s-03501.htm
139
+#
140
+# (2001-06-25):
141
+# Last Friday (yes, the last working day before the date of the change), the
142
+# Senate annulled the 1999 law that introduced the changes later postponed.
143
+# http://www.clarin.com.ar/diario/2001-06-22/s-03601.htm
144
+# It remains the vote of the Deputies..., but it will be the same....
145
+# This kind of things had always been done this way in Argentina.
146
+# We are still -03:00 all year round in all of the country.
147
+#
148
+# From Steffen Thorsen (2007-12-21):
149
+# A user (Leonardo Chaim) reported that Argentina will adopt DST....
150
+# all of the country (all Zone-entries) are affected.  News reports like
151
+# http://www.lanacion.com.ar/opinion/nota.asp?nota_id=973037 indicate
152
+# that Argentina will use DST next year as well, from October to
153
+# March, although exact rules are not given.
154
+#
155
+# From Jesper Norgaard Welen (2007-12-26)
156
+# The last hurdle of Argentina DST is over, the proposal was approved in
157
+# the lower chamber too (Deputados) with a vote 192 for and 2 against.
158
+# By the way thanks to Mariano Absatz and Daniel Mario Vega for the link to
159
+# the original scanned proposal, where the dates and the zero hours are
160
+# clear and unambiguous...This is the article about final approval:
161
+# <a href="http://www.lanacion.com.ar/politica/nota.asp?nota_id=973996">
162
+# http://www.lanacion.com.ar/politica/nota.asp?nota_id=973996
163
+# </a>
164
+#
165
+# From Paul Eggert (2007-12-22):
166
+# For dates after mid-2008, the following rules are my guesses and
167
+# are quite possibly wrong, but are more likely than no DST at all.
168
+
169
+# From Alexander Krivenyshev (2008-09-05):
170
+# As per message from Carlos Alberto Fonseca Arauz (Nicaragua),
171
+# Argentina will start DST on Sunday October 19, 2008.
172
+#
173
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_argentina03.html">
174
+# http://www.worldtimezone.com/dst_news/dst_news_argentina03.html
175
+# </a>
176
+# OR
177
+# <a href="http://www.impulsobaires.com.ar/nota.php?id=57832 (in spanish)">
178
+# http://www.impulsobaires.com.ar/nota.php?id=57832 (in spanish)
179
+# </a>
180
+
181
+# From Rodrigo Severo (2008-10-06):
182
+# Here is some info available at a Gentoo bug related to TZ on Argentina's DST:
183
+# ...
184
+# ------- Comment #1 from [jmdocile]  2008-10-06 16:28 0000 -------
185
+# Hi, there is a problem with timezone-data-2008e and maybe with
186
+# timezone-data-2008f
187
+# Argentinian law [Number] 25.155 is no longer valid.
188
+# <a href="http://www.infoleg.gov.ar/infolegInternet/anexos/60000-64999/60036/norma.htm">
189
+# http://www.infoleg.gov.ar/infolegInternet/anexos/60000-64999/60036/norma.htm
190
+# </a>
191
+# The new one is law [Number] 26.350
192
+# <a href="http://www.infoleg.gov.ar/infolegInternet/anexos/135000-139999/136191/norma.htm">
193
+# http://www.infoleg.gov.ar/infolegInternet/anexos/135000-139999/136191/norma.htm
194
+# </a>
195
+# So there is no summer time in Argentina for now.
196
+
197
+# From Mariano Absatz (2008-10-20):
198
+# Decree 1693/2008 applies Law 26.350 for the summer 2008/2009 establishing DST in Argentina
199
+# From 2008-10-19 until 2009-03-15
200
+# <a href="http://www.boletinoficial.gov.ar/Bora.Portal/CustomControls/PdfContent.aspx?fp=16102008&pi=3&pf=4&s=0&sec=01">
201
+# http://www.boletinoficial.gov.ar/Bora.Portal/CustomControls/PdfContent.aspx?fp=16102008&pi=3&pf=4&s=0&sec=01
202
+# </a>
203
+#
204
+# Decree 1705/2008 excepting 12 Provinces from applying DST in the summer 2008/2009:
205
+# Catamarca, La Rioja, Mendoza, Salta, San Juan, San Luis, La Pampa, Neuquen, Rio Negro, Chubut, Santa Cruz
206
+# and Tierra del Fuego
207
+# <a href="http://www.boletinoficial.gov.ar/Bora.Portal/CustomControls/PdfContent.aspx?fp=17102008&pi=1&pf=1&s=0&sec=01">
208
+# http://www.boletinoficial.gov.ar/Bora.Portal/CustomControls/PdfContent.aspx?fp=17102008&pi=1&pf=1&s=0&sec=01
209
+# </a>
210
+#
211
+# Press release 235 dated Saturday October 18th, from the Government of the Province of Jujuy saying
212
+# it will not apply DST either (even when it was not included in Decree 1705/2008)
213
+# <a href="http://www.jujuy.gov.ar/index2/partes_prensa/18_10_08/235-181008.doc">
214
+# http://www.jujuy.gov.ar/index2/partes_prensa/18_10_08/235-181008.doc
215
+# </a>
216
+
217
+# From fullinet (2009-10-18):
218
+# As announced in
219
+# <a hef="http://www.argentina.gob.ar/argentina/portal/paginas.dhtml?pagina=356">
220
+# http://www.argentina.gob.ar/argentina/portal/paginas.dhtml?pagina=356
221
+# </a>
222
+# (an official .gob.ar) under title: "Sin Cambio de Hora" (english: "No hour change")
223
+#
224
+# "Por el momento, el Gobierno Nacional resolvio no modificar la hora
225
+# oficial, decision que estaba en estudio para su implementacion el
226
+# domingo 18 de octubre. Desde el Ministerio de Planificacion se anuncio
227
+# que la Argentina hoy, en estas condiciones meteorologicas, no necesita
228
+# la modificacion del huso horario, ya que 2009 nos encuentra con
229
+# crecimiento en la produccion y distribucion energetica."
230
+
231
+Rule	Arg	2007	only	-	Dec	30	0:00	1:00	S
232
+Rule	Arg	2008	2009	-	Mar	Sun>=15	0:00	0	-
233
+Rule	Arg	2008	only	-	Oct	Sun>=15	0:00	1:00	S
234
+
235
+# From Mariano Absatz (2004-05-21):
236
+# Today it was officially published that the Province of Mendoza is changing
237
+# its timezone this winter... starting tomorrow night....
238
+# http://www.gobernac.mendoza.gov.ar/boletin/pdf/20040521-27158-normas.pdf
239
+# From Paul Eggert (2004-05-24):
240
+# It's Law No. 7,210.  This change is due to a public power emergency, so for
241
+# now we'll assume it's for this year only.
242
+#
243
+# From Paul Eggert (2006-03-22):
244
+# <a href="http://www.spicasc.net/horvera.html">
245
+# Hora de verano para la Republica Argentina (2003-06-08)
246
+# </a> says that standard time in Argentina from 1894-10-31
247
+# to 1920-05-01 was -4:16:48.25.  Go with this more-precise value
248
+# over Shanks & Pottenger.
249
+#
250
+# From Mariano Absatz (2004-06-05):
251
+# These media articles from a major newspaper mostly cover the current state:
252
+# http://www.lanacion.com.ar/04/05/27/de_604825.asp
253
+# http://www.lanacion.com.ar/04/05/28/de_605203.asp
254
+#
255
+# The following eight (8) provinces pulled clocks back to UTC-04:00 at
256
+# midnight Monday May 31st. (that is, the night between 05/31 and 06/01).
257
+# Apparently, all nine provinces would go back to UTC-03:00 at the same
258
+# time in October 17th.
259
+#
260
+# Catamarca, Chubut, La Rioja, San Juan, San Luis, Santa Cruz,
261
+# Tierra del Fuego, Tucuman.
262
+#
263
+# From Mariano Absatz (2004-06-14):
264
+# ... this weekend, the Province of Tucuman decided it'd go back to UTC-03:00
265
+# yesterday midnight (that is, at 24:00 Saturday 12th), since the people's
266
+# annoyance with the change is much higher than the power savings obtained....
267
+#
268
+# From Gwillim Law (2004-06-14):
269
+# http://www.lanacion.com.ar/04/06/10/de_609078.asp ...
270
+#     "The time change in Tierra del Fuego was a conflicted decision from
271
+#   the start.  The government had decreed that the measure would take
272
+#   effect on June 1, but a normative error forced the new time to begin
273
+#   three days earlier, from a Saturday to a Sunday....
274
+# Our understanding was that the change was originally scheduled to take place
275
+# on June 1 at 00:00 in Chubut, Santa Cruz, Tierra del Fuego (and some other
276
+# provinces).  Sunday was May 30, only two days earlier.  So the article
277
+# contains a contradiction.  I would give more credence to the Saturday/Sunday
278
+# date than the "three days earlier" phrase, and conclude that Tierra del
279
+# Fuego set its clocks back at 2004-05-30 00:00.
280
+#
281
+# From Steffen Thorsen (2004-10-05):
282
+# The previous law 7210 which changed the province of Mendoza's time zone
283
+# back in May have been modified slightly in a new law 7277, which set the
284
+# new end date to 2004-09-26 (original date was 2004-10-17).
285
+# http://www.gobernac.mendoza.gov.ar/boletin/pdf/20040924-27244-normas.pdf
286
+#
287
+# From Mariano Absatz (2004-10-05):
288
+# San Juan changed from UTC-03:00 to UTC-04:00 at midnight between
289
+# Sunday, May 30th and Monday, May 31st.  It changed back to UTC-03:00
290
+# at midnight between Saturday, July 24th and Sunday, July 25th....
291
+# http://www.sanjuan.gov.ar/prensa/archivo/000329.html
292
+# http://www.sanjuan.gov.ar/prensa/archivo/000426.html
293
+# http://www.sanjuan.gov.ar/prensa/archivo/000441.html
294
+
295
+# From Alex Krivenyshev (2008-01-17):
296
+# Here are articles that Argentina Province San Luis is planning to end DST
297
+# as earlier as upcoming Monday January 21, 2008 or February 2008:
298
+#
299
+# Provincia argentina retrasa reloj y marca diferencia con resto del pais
300
+# (Argentine Province delayed clock and mark difference with the rest of the
301
+# country)
302
+# <a href="http://cl.invertia.com/noticias/noticia.aspx?idNoticia=200801171849_EFE_ET4373&idtel">
303
+# http://cl.invertia.com/noticias/noticia.aspx?idNoticia=200801171849_EFE_ET4373&idtel
304
+# </a>
305
+#
306
+# Es inminente que en San Luis atrasen una hora los relojes
307
+# (It is imminent in San Luis clocks one hour delay)
308
+# <a href="http://www.lagaceta.com.ar/vernotae.asp?id_nota=253414">
309
+# http://www.lagaceta.com.ar/vernotae.asp?id_nota=253414
310
+# </a>
311
+#
312
+# <a href="http://www.worldtimezone.net/dst_news/dst_news_argentina02.html">
313
+# http://www.worldtimezone.net/dst_news/dst_news_argentina02.html
314
+# </a>
315
+
316
+# From Jesper Norgaard Welen (2008-01-18):
317
+# The page of the San Luis provincial government
318
+# <a href="http://www.sanluis.gov.ar/notas.asp?idCanal=0&id=22812">
319
+# http://www.sanluis.gov.ar/notas.asp?idCanal=0&id=22812
320
+# </a>
321
+# confirms what Alex Krivenyshev has earlier sent to the tz
322
+# emailing list about that San Luis plans to return to standard
323
+# time much earlier than the rest of the country. It also
324
+# confirms that upon request the provinces San Juan and Mendoza
325
+# refused to follow San Luis in this change.
326
+#
327
+# The change is supposed to take place Monday the 21.st at 0:00
328
+# hours. As far as I understand it if this goes ahead, we need
329
+# a new timezone for San Luis (although there are also documented
330
+# independent changes in the southamerica file of San Luis in
331
+# 1990 and 1991 which has not been confirmed).
332
+
333
+# From Jesper Norgaard Welen (2008-01-25):
334
+# Unfortunately the below page has become defunct, about the San Luis
335
+# time change. Perhaps because it now is part of a group of pages "Most
336
+# important pages of 2008."
337
+#
338
+# You can use
339
+# <a href="http://www.sanluis.gov.ar/notas.asp?idCanal=8141&id=22834">
340
+# http://www.sanluis.gov.ar/notas.asp?idCanal=8141&id=22834
341
+# </a>
342
+# instead it seems. Or use "Buscador" from the main page of the San Luis
343
+# government, and fill in "huso" and click OK, and you will get 3 pages
344
+# from which the first one is identical to the above.
345
+
346
+# From Mariano Absatz (2008-01-28):
347
+# I can confirm that the Province of San Luis (and so far only that
348
+# province) decided to go back to UTC-3 effective midnight Jan 20th 2008
349
+# (that is, Monday 21st at 0:00 is the time the clocks were delayed back
350
+# 1 hour), and they intend to keep UTC-3 as their timezone all year round
351
+# (that is, unless they change their mind any minute now).
352
+#
353
+# So we'll have to add yet another city to 'southamerica' (I think San
354
+# Luis city is the mos populated city in the Province, so it'd be
355
+# America/Argentina/San_Luis... of course I can't remember if San Luis's
356
+# history of particular changes goes along with Mendoza or San Juan :-(
357
+# (I only remember not being able to collect hard facts about San Luis
358
+# back in 2004, when these provinces changed to UTC-4 for a few days, I
359
+# mailed them personally and never got an answer).
360
+
361
+# From Paul Eggert (2008-06-30):
362
+# Unless otherwise specified, data are from Shanks & Pottenger through 1992,
363
+# from the IATA otherwise.  As noted below, Shanks & Pottenger say that
364
+# America/Cordoba split into 6 subregions during 1991/1992, one of which
365
+# was America/San_Luis, but we haven't verified this yet so for now we'll
366
+# keep America/Cordoba a single region rather than splitting it into the
367
+# other 5 subregions.
368
+
369
+# From Mariano Absatz (2009-03-13):
370
+# Yesterday (with our usual 2-day notice) the Province of San Luis
371
+# decided that next Sunday instead of "staying" @utc-03:00 they will go
372
+# to utc-04:00 until the second Saturday in October...
373
+#
374
+# The press release is at
375
+# <a href="http://www.sanluis.gov.ar/SL/Paginas/NoticiaDetalle.asp?TemaId=1&InfoPrensaId=3102">
376
+# http://www.sanluis.gov.ar/SL/Paginas/NoticiaDetalle.asp?TemaId=1&InfoPrensaId=3102
377
+# </a>
378
+# (I couldn't find the decree, but
379
+# <a href="http://www.sanluis.gov.ar">
380
+# www.sanluis.gov.ar
381
+# <a/>
382
+# is the official page for the Province Government).
383
+#
384
+# There's also a note in only one of the major national papers (La Naci�n) at
385
+# <a href="http://www.lanacion.com.ar/nota.asp?nota_id=1107912">
386
+# http://www.lanacion.com.ar/nota.asp?nota_id=1107912
387
+# </a>
388
+#
389
+# The press release says:
390
+#  (...) anunci� que el pr�ximo domingo a las 00:00 los puntanos deber�n
391
+# atrasar una hora sus relojes.
392
+#
393
+# A partir de entonces, San Luis establecer� el huso horario propio de
394
+# la Provincia. De esta manera, durante el periodo del calendario anual
395
+# 2009, el cambio horario quedar� comprendido entre las 00:00 del tercer
396
+# domingo de marzo y las 24:00 del segundo s�bado de octubre.
397
+# Quick&dirty translation
398
+# (...) announced that next Sunday, at 00:00, Puntanos (the San Luis
399
+# inhabitants) will have to turn back one hour their clocks
400
+#
401
+# Since then, San Luis will establish its own Province timezone. Thus,
402
+# during 2009, this timezone change will run from 00:00 the third Sunday
403
+# in March until 24:00 of the second Saturday in October.
404
+
405
+# From Mariano Absatz (2009-10-16):
406
+# ...the Province of San Luis is a case in itself.
407
+#
408
+# The Law at
409
+# <a href="http://www.diputadossanluis.gov.ar/diputadosasp/paginas/verNorma.asp?NormaID=276>"
410
+# http://www.diputadossanluis.gov.ar/diputadosasp/paginas/verNorma.asp?NormaID=276
411
+# </a>
412
+# is ambiguous because establishes a calendar from the 2nd Sunday in
413
+# October at 0:00 thru the 2nd Saturday in March at 24:00 and the
414
+# complement of that starting on the 2nd Sunday of March at 0:00 and
415
+# ending on the 2nd Saturday of March at 24:00.
416
+#
417
+# This clearly breaks every time the 1st of March or October is a Sunday.
418
+#
419
+# IMHO, the "spirit of the Law" is to make the changes at 0:00 on the 2nd
420
+# Sunday of October and March.
421
+#
422
+# The problem is that the changes in the rest of the Provinces that did
423
+# change in 2007/2008, were made according to the Federal Law and Decrees
424
+# that did so on the 3rd Sunday of October and March.
425
+#
426
+# In fact, San Luis actually switched from UTC-4 to UTC-3 last Sunday
427
+# (October 11th) at 0:00.
428
+#
429
+# So I guess a new set of rules, besides "Arg", must be made and the last
430
+# America/Argentina/San_Luis entries should change to use these...
431
+#
432
+# I'm enclosing a patch that does what I say... regretfully, the San Luis
433
+# timezone must be called "WART/WARST" even when most of the time (like,
434
+# right now) WARST == ART... that is, since last Sunday, all the country
435
+# is using UTC-3, but in my patch, San Luis calls it "WARST" and the rest
436
+# of the country calls it "ART".
437
+# ...
438
+
439
+# From Alexander Krivenyshev (2010-04-09):
440
+# According to news reports from El Diario de la Republica Province San
441
+# Luis, Argentina (standard time UTC-04) will keep Daylight Saving Time
442
+# after April 11, 2010--will continue to have same time as rest of
443
+# Argentina (UTC-3) (no DST).
444
+#
445
+# Confirmaron la pr&oacute;rroga del huso horario de verano (Spanish)
446
+# <a href="http://www.eldiariodelarepublica.com/index.php?option=com_content&task=view&id=29383&Itemid=9">
447
+# http://www.eldiariodelarepublica.com/index.php?option=com_content&task=view&id=29383&Itemid=9
448
+# </a>
449
+# or (some English translation):
450
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_argentina08.html">
451
+# http://www.worldtimezone.com/dst_news/dst_news_argentina08.html
452
+# </a>
453
+
454
+# From Mariano Absatz (2010-04-12):
455
+# yes...I can confirm this...and given that San Luis keeps calling
456
+# UTC-03:00 "summer time", we should't just let San Luis go back to "Arg"
457
+# rules...San Luis is still using "Western ARgentina Time" and it got
458
+# stuck on Summer daylight savings time even though the summer is over.
459
+
460
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
461
+#
462
+# Buenos Aires (BA), Capital Federal (CF),
463
+Zone America/Argentina/Buenos_Aires -3:53:48 - LMT 1894 Oct 31
464
+			-4:16:48 -	CMT	1920 May # Cordoba Mean Time
465
+			-4:00	-	ART	1930 Dec
466
+			-4:00	Arg	AR%sT	1969 Oct  5
467
+			-3:00	Arg	AR%sT	1999 Oct  3
468
+			-4:00	Arg	AR%sT	2000 Mar  3
469
+			-3:00	Arg	AR%sT
470
+#
471
+# Cordoba (CB), Santa Fe (SF), Entre Rios (ER), Corrientes (CN), Misiones (MN),
472
+# Chaco (CC), Formosa (FM), Santiago del Estero (SE)
473
+#
474
+# Shanks & Pottenger also make the following claims, which we haven't verified:
475
+# - Formosa switched to -3:00 on 1991-01-07.
476
+# - Misiones switched to -3:00 on 1990-12-29.
477
+# - Chaco switched to -3:00 on 1991-01-04.
478
+# - Santiago del Estero switched to -4:00 on 1991-04-01,
479
+#   then to -3:00 on 1991-04-26.
480
+#
481
+Zone America/Argentina/Cordoba -4:16:48 - LMT	1894 Oct 31
482
+			-4:16:48 -	CMT	1920 May
483
+			-4:00	-	ART	1930 Dec
484
+			-4:00	Arg	AR%sT	1969 Oct  5
485
+			-3:00	Arg	AR%sT	1991 Mar  3
486
+			-4:00	-	WART	1991 Oct 20
487
+			-3:00	Arg	AR%sT	1999 Oct  3
488
+			-4:00	Arg	AR%sT	2000 Mar  3
489
+			-3:00	Arg	AR%sT
490
+#
491
+# Salta (SA), La Pampa (LP), Neuquen (NQ), Rio Negro (RN)
492
+Zone America/Argentina/Salta -4:21:40 - LMT	1894 Oct 31
493
+			-4:16:48 -	CMT	1920 May
494
+			-4:00	-	ART	1930 Dec
495
+			-4:00	Arg	AR%sT	1969 Oct  5
496
+			-3:00	Arg	AR%sT	1991 Mar  3
497
+			-4:00	-	WART	1991 Oct 20
498
+			-3:00	Arg	AR%sT	1999 Oct  3
499
+			-4:00	Arg	AR%sT	2000 Mar  3
500
+			-3:00	Arg	AR%sT	2008 Oct 18
501
+			-3:00	-	ART
502
+#
503
+# Tucuman (TM)
504
+Zone America/Argentina/Tucuman -4:20:52 - LMT	1894 Oct 31
505
+			-4:16:48 -	CMT	1920 May
506
+			-4:00	-	ART	1930 Dec
507
+			-4:00	Arg	AR%sT	1969 Oct  5
508
+			-3:00	Arg	AR%sT	1991 Mar  3
509
+			-4:00	-	WART	1991 Oct 20
510
+			-3:00	Arg	AR%sT	1999 Oct  3
511
+			-4:00	Arg	AR%sT	2000 Mar  3
512
+			-3:00	-	ART	2004 Jun  1
513
+			-4:00	-	WART	2004 Jun 13
514
+			-3:00	Arg	AR%sT
515
+#
516
+# La Rioja (LR)
517
+Zone America/Argentina/La_Rioja -4:27:24 - LMT	1894 Oct 31
518
+			-4:16:48 -	CMT	1920 May
519
+			-4:00	-	ART	1930 Dec
520
+			-4:00	Arg	AR%sT	1969 Oct  5
521
+			-3:00	Arg	AR%sT	1991 Mar  1
522
+			-4:00	-	WART	1991 May  7
523
+			-3:00	Arg	AR%sT	1999 Oct  3
524
+			-4:00	Arg	AR%sT	2000 Mar  3
525
+			-3:00	-	ART	2004 Jun  1
526
+			-4:00	-	WART	2004 Jun 20
527
+			-3:00	Arg	AR%sT	2008 Oct 18
528
+			-3:00	-	ART
529
+#
530
+# San Juan (SJ)
531
+Zone America/Argentina/San_Juan -4:34:04 - LMT	1894 Oct 31
532
+			-4:16:48 -	CMT	1920 May
533
+			-4:00	-	ART	1930 Dec
534
+			-4:00	Arg	AR%sT	1969 Oct  5
535
+			-3:00	Arg	AR%sT	1991 Mar  1
536
+			-4:00	-	WART	1991 May  7
537
+			-3:00	Arg	AR%sT	1999 Oct  3
538
+			-4:00	Arg	AR%sT	2000 Mar  3
539
+			-3:00	-	ART	2004 May 31
540
+			-4:00	-	WART	2004 Jul 25
541
+			-3:00	Arg	AR%sT	2008 Oct 18
542
+			-3:00	-	ART
543
+#
544
+# Jujuy (JY)
545
+Zone America/Argentina/Jujuy -4:21:12 -	LMT	1894 Oct 31
546
+			-4:16:48 -	CMT	1920 May
547
+			-4:00	-	ART	1930 Dec
548
+			-4:00	Arg	AR%sT	1969 Oct  5
549
+			-3:00	Arg	AR%sT	1990 Mar  4
550
+			-4:00	-	WART	1990 Oct 28
551
+			-4:00	1:00	WARST	1991 Mar 17
552
+			-4:00	-	WART	1991 Oct  6
553
+			-3:00	1:00	ARST	1992
554
+			-3:00	Arg	AR%sT	1999 Oct  3
555
+			-4:00	Arg	AR%sT	2000 Mar  3
556
+			-3:00	Arg	AR%sT	2008 Oct 18
557
+			-3:00	-	ART
558
+#
559
+# Catamarca (CT), Chubut (CH)
560
+Zone America/Argentina/Catamarca -4:23:08 - LMT	1894 Oct 31
561
+			-4:16:48 -	CMT	1920 May
562
+			-4:00	-	ART	1930 Dec
563
+			-4:00	Arg	AR%sT	1969 Oct  5
564
+			-3:00	Arg	AR%sT	1991 Mar  3
565
+			-4:00	-	WART	1991 Oct 20
566
+			-3:00	Arg	AR%sT	1999 Oct  3
567
+			-4:00	Arg	AR%sT	2000 Mar  3
568
+			-3:00	-	ART	2004 Jun  1
569
+			-4:00	-	WART	2004 Jun 20
570
+			-3:00	Arg	AR%sT	2008 Oct 18
571
+			-3:00	-	ART
572
+#
573
+# Mendoza (MZ)
574
+Zone America/Argentina/Mendoza -4:35:16 - LMT	1894 Oct 31
575
+			-4:16:48 -	CMT	1920 May
576
+			-4:00	-	ART	1930 Dec
577
+			-4:00	Arg	AR%sT	1969 Oct  5
578
+			-3:00	Arg	AR%sT	1990 Mar  4
579
+			-4:00	-	WART	1990 Oct 15
580
+			-4:00	1:00	WARST	1991 Mar  1
581
+			-4:00	-	WART	1991 Oct 15
582
+			-4:00	1:00	WARST	1992 Mar  1
583
+			-4:00	-	WART	1992 Oct 18
584
+			-3:00	Arg	AR%sT	1999 Oct  3
585
+			-4:00	Arg	AR%sT	2000 Mar  3
586
+			-3:00	-	ART	2004 May 23
587
+			-4:00	-	WART	2004 Sep 26
588
+			-3:00	Arg	AR%sT	2008 Oct 18
589
+			-3:00	-	ART
590
+#
591
+# San Luis (SL)
592
+
593
+Rule	SanLuis	2008	2009	-	Mar	Sun>=8	0:00	0	-
594
+Rule	SanLuis	2007	2009	-	Oct	Sun>=8	0:00	1:00	S
595
+
596
+Zone America/Argentina/San_Luis -4:25:24 - LMT	1894 Oct 31
597
+			-4:16:48 -	CMT	1920 May
598
+			-4:00	-	ART	1930 Dec
599
+			-4:00	Arg	AR%sT	1969 Oct  5
600
+			-3:00	Arg	AR%sT	1990
601
+			-3:00	1:00	ARST	1990 Mar 14
602
+			-4:00	-	WART	1990 Oct 15
603
+			-4:00	1:00	WARST	1991 Mar  1
604
+			-4:00	-	WART	1991 Jun  1
605
+			-3:00	-	ART	1999 Oct  3
606
+			-4:00	1:00	WARST	2000 Mar  3
607
+			-3:00	-	ART	2004 May 31
608
+			-4:00	-	WART	2004 Jul 25
609
+			-3:00	Arg	AR%sT	2008 Jan 21
610
+			-4:00	SanLuis	WAR%sT
611
+#
612
+# Santa Cruz (SC)
613
+Zone America/Argentina/Rio_Gallegos -4:36:52 - LMT 1894 Oct 31
614
+			-4:16:48 -	CMT	1920 May # Cordoba Mean Time
615
+			-4:00	-	ART	1930 Dec
616
+			-4:00	Arg	AR%sT	1969 Oct  5
617
+			-3:00	Arg	AR%sT	1999 Oct  3
618
+			-4:00	Arg	AR%sT	2000 Mar  3
619
+			-3:00	-	ART	2004 Jun  1
620
+			-4:00	-	WART	2004 Jun 20
621
+			-3:00	Arg	AR%sT	2008 Oct 18
622
+			-3:00	-	ART
623
+#
624
+# Tierra del Fuego, Antartida e Islas del Atlantico Sur (TF)
625
+Zone America/Argentina/Ushuaia -4:33:12 - LMT 1894 Oct 31
626
+			-4:16:48 -	CMT	1920 May # Cordoba Mean Time
627
+			-4:00	-	ART	1930 Dec
628
+			-4:00	Arg	AR%sT	1969 Oct  5
629
+			-3:00	Arg	AR%sT	1999 Oct  3
630
+			-4:00	Arg	AR%sT	2000 Mar  3
631
+			-3:00	-	ART	2004 May 30
632
+			-4:00	-	WART	2004 Jun 20
633
+			-3:00	Arg	AR%sT	2008 Oct 18
634
+			-3:00	-	ART
635
+
636
+# Aruba
637
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
638
+Zone	America/Aruba	-4:40:24 -	LMT	1912 Feb 12	# Oranjestad
639
+			-4:30	-	ANT	1965 # Netherlands Antilles Time
640
+			-4:00	-	AST
641
+
642
+# Bolivia
643
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
644
+Zone	America/La_Paz	-4:32:36 -	LMT	1890
645
+			-4:32:36 -	CMT	1931 Oct 15 # Calamarca MT
646
+			-4:32:36 1:00	BOST	1932 Mar 21 # Bolivia ST
647
+			-4:00	-	BOT	# Bolivia Time
648
+
649
+# Brazil
650
+
651
+# From Paul Eggert (1993-11-18):
652
+# The mayor of Rio recently attempted to change the time zone rules
653
+# just in his city, in order to leave more summer time for the tourist trade.
654
+# The rule change lasted only part of the day;
655
+# the federal government refused to follow the city's rules, and business
656
+# was in a chaos, so the mayor backed down that afternoon.
657
+
658
+# From IATA SSIM (1996-02):
659
+# _Only_ the following states in BR1 observe DST: Rio Grande do Sul (RS),
660
+# Santa Catarina (SC), Parana (PR), Sao Paulo (SP), Rio de Janeiro (RJ),
661
+# Espirito Santo (ES), Minas Gerais (MG), Bahia (BA), Goias (GO),
662
+# Distrito Federal (DF), Tocantins (TO), Sergipe [SE] and Alagoas [AL].
663
+# [The last three states are new to this issue of the IATA SSIM.]
664
+
665
+# From Gwillim Law (1996-10-07):
666
+# Geography, history (Tocantins was part of Goias until 1989), and other
667
+# sources of time zone information lead me to believe that AL, SE, and TO were
668
+# always in BR1, and so the only change was whether or not they observed DST....
669
+# The earliest issue of the SSIM I have is 2/91.  Each issue from then until
670
+# 9/95 says that DST is observed only in the ten states I quoted from 9/95,
671
+# along with Mato Grosso (MT) and Mato Grosso do Sul (MS), which are in BR2
672
+# (UTC-4)....  The other two time zones given for Brazil are BR3, which is
673
+# UTC-5, no DST, and applies only in the state of Acre (AC); and BR4, which is
674
+# UTC-2, and applies to Fernando de Noronha (formerly FN, but I believe it's
675
+# become part of the state of Pernambuco).  The boundary between BR1 and BR2
676
+# has never been clearly stated.  They've simply been called East and West.
677
+# However, some conclusions can be drawn from another IATA manual: the Airline
678
+# Coding Directory, which lists close to 400 airports in Brazil.  For each
679
+# airport it gives a time zone which is coded to the SSIM.  From that
680
+# information, I'm led to conclude that the states of Amapa (AP), Ceara (CE),
681
+# Maranhao (MA), Paraiba (PR), Pernambuco (PE), Piaui (PI), and Rio Grande do
682
+# Norte (RN), and the eastern part of Para (PA) are all in BR1 without DST.
683
+
684
+# From Marcos Tadeu (1998-09-27):
685
+# <a href="http://pcdsh01.on.br/verao1.html">
686
+# Brazilian official page
687
+# </a>
688
+
689
+# From Jesper Norgaard (2000-11-03):
690
+# [For an official list of which regions in Brazil use which time zones, see:]
691
+# http://pcdsh01.on.br/Fusbr.htm
692
+# http://pcdsh01.on.br/Fusbrhv.htm
693
+
694
+# From Celso Doria via David Madeo (2002-10-09):
695
+# The reason for the delay this year has to do with elections in Brazil.
696
+#
697
+# Unlike in the United States, elections in Brazil are 100% computerized and
698
+# the results are known almost immediately.  Yesterday, it was the first
699
+# round of the elections when 115 million Brazilians voted for President,
700
+# Governor, Senators, Federal Deputies, and State Deputies.  Nobody is
701
+# counting (or re-counting) votes anymore and we know there will be a second
702
+# round for the Presidency and also for some Governors.  The 2nd round will
703
+# take place on October 27th.
704
+#
705
+# The reason why the DST will only begin November 3rd is that the thousands
706
+# of electoral machines used cannot have their time changed, and since the
707
+# Constitution says the elections must begin at 8:00 AM and end at 5:00 PM,
708
+# the Government decided to postpone DST, instead of changing the Constitution
709
+# (maybe, for the next elections, it will be possible to change the clock)...
710
+
711
+# From Rodrigo Severo (2004-10-04):
712
+# It's just the biannual change made necessary by the much hyped, supposedly
713
+# modern Brazilian eletronic voting machines which, apparently, can't deal
714
+# with a time change between the first and the second rounds of the elections.
715
+
716
+# From Steffen Thorsen (2007-09-20):
717
+# Brazil will start DST on 2007-10-14 00:00 and end on 2008-02-17 00:00:
718
+# http://www.mme.gov.br/site/news/detail.do;jsessionid=BBA06811AFCAAC28F0285210913513DA?newsId=13975
719
+
720
+# From Paul Schulze (2008-06-24):
721
+# ...by law number 11.662 of April 24, 2008 (published in the "Diario
722
+# Oficial da Uniao"...) in Brazil there are changes in the timezones,
723
+# effective today (00:00am at June 24, 2008) as follows:
724
+#
725
+# a) The timezone UTC+5 is e[x]tinguished, with all the Acre state and the
726
+# part of the Amazonas state that had this timezone now being put to the
727
+# timezone UTC+4
728
+# b) The whole Para state now is put at timezone UTC+3, instead of just
729
+# part of it, as was before.
730
+#
731
+# This change follows a proposal of senator Tiao Viana of Acre state, that
732
+# proposed it due to concerns about open television channels displaying
733
+# programs inappropriate to youths in the states that had the timezone
734
+# UTC+5 too early in the night. In the occasion, some more corrections
735
+# were proposed, trying to unify the timezones of any given state. This
736
+# change modifies timezone rules defined in decree 2.784 of 18 June,
737
+# 1913.
738
+
739
+# From Rodrigo Severo (2008-06-24):
740
+# Just correcting the URL:
741
+# <a href="https://www.in.gov.br/imprensa/visualiza/index.jsp?jornal=do&secao=1&pagina=1&data=25/04/2008">
742
+# https://www.in.gov.br/imprensa/visualiza/index.jsp?jornal=do&secao=1&pagina=1&data=25/04/2008
743
+# </a>
744
+#
745
+# As a result of the above Decree I believe the America/Rio_Branco
746
+# timezone shall be modified from UTC-5 to UTC-4 and a new timezone shall
747
+# be created to represent the...west side of the Para State. I
748
+# suggest this new timezone be called Santarem as the most
749
+# important/populated city in the affected area.
750
+#
751
+# This new timezone would be the same as the Rio_Branco timezone up to
752
+# the 2008/06/24 change which would be to UTC-3 instead of UTC-4.
753
+
754
+# From Alex Krivenyshev (2008-06-24):
755
+# This is a quick reference page for New and Old Brazil Time Zones map.
756
+# <a href="http://www.worldtimezone.com/brazil-time-new-old.php">
757
+# http://www.worldtimezone.com/brazil-time-new-old.php
758
+# </a>
759
+#
760
+# - 4 time zones replaced by 3 time zones-eliminating time zone UTC- 05
761
+# (state Acre and the part of the Amazonas will be UTC/GMT- 04) - western
762
+# part of Par state is moving to one timezone UTC- 03 (from UTC -04).
763
+
764
+# From Paul Eggert (2002-10-10):
765
+# The official decrees referenced below are mostly taken from
766
+# <a href="http://pcdsh01.on.br/DecHV.html">
767
+# Decretos sobre o Horario de Verao no Brasil
768
+# </a>.
769
+
770
+# From Steffen Thorsen (2008-08-29):
771
+# As announced by the government and many newspapers in Brazil late
772
+# yesterday, Brazil will start DST on 2008-10-19 (need to change rule) and
773
+# it will end on 2009-02-15 (current rule for Brazil is fine). Based on
774
+# past years experience with the elections, there was a good chance that
775
+# the start was postponed to November, but it did not happen this year.
776
+#
777
+# It has not yet been posted to http://pcdsh01.on.br/DecHV.html
778
+#
779
+# An official page about it:
780
+# <a href="http://www.mme.gov.br/site/news/detail.do?newsId=16722">
781
+# http://www.mme.gov.br/site/news/detail.do?newsId=16722
782
+# </a>
783
+# Note that this link does not always work directly, but must be accessed
784
+# by going to
785
+# <a href="http://www.mme.gov.br/first">
786
+# http://www.mme.gov.br/first
787
+# </a>
788
+#
789
+# One example link that works directly:
790
+# <a href="http://jornale.com.br/index.php?option=com_content&task=view&id=13530&Itemid=54">
791
+# http://jornale.com.br/index.php?option=com_content&task=view&id=13530&Itemid=54
792
+# (Portuguese)
793
+# </a>
794
+#
795
+# We have a written a short article about it as well:
796
+# <a href="http://www.timeanddate.com/news/time/brazil-dst-2008-2009.html">
797
+# http://www.timeanddate.com/news/time/brazil-dst-2008-2009.html
798
+# </a>
799
+#
800
+# From Alexander Krivenyshev (2011-10-04):
801
+# State Bahia will return to Daylight savings time this year after 8 years off.
802
+# The announcement was made by Governor Jaques Wagner in an interview to a
803
+# television station in Salvador.
804
+
805
+# In Portuguese:
806
+# <a href="http://g1.globo.com/bahia/noticia/2011/10/governador-jaques-wagner-confirma-horario-de-verao-na-bahia.html">
807
+# http://g1.globo.com/bahia/noticia/2011/10/governador-jaques-wagner-confirma-horario-de-verao-na-bahia.html
808
+# </a> and
809
+# <a href="http://noticias.terra.com.br/brasil/noticias/0,,OI5390887-EI8139,00-Bahia+volta+a+ter+horario+de+verao+apos+oito+anos.html">
810
+# http://noticias.terra.com.br/brasil/noticias/0,,OI5390887-EI8139,00-Bahia+volta+a+ter+horario+de+verao+apos+oito+anos.html
811
+# </a>
812
+
813
+# From Guilherme Bernardes Rodrigues (2011-10-07):
814
+# There is news in the media, however there is still no decree about it.
815
+# I just send a e-mail to Zulmira Brand�o at
816
+# <a href="http://pcdsh01.on.br/">http://pcdsh01.on.br/</a> the
817
+# oficial agency about time in Brazil, and she confirmed that the old rule is
818
+# still in force.
819
+
820
+# From Guilherme Bernardes Rodrigues (2011-10-14)
821
+# It's official, the President signed a decree that includes Bahia in summer
822
+# time.
823
+#	 [ and in a second message (same day): ]
824
+# I found the decree.
825
+#
826
+# DECRETO No- 7.584, DE 13 DE OUTUBRO DE 2011
827
+# Link :
828
+# <a href="http://www.in.gov.br/visualiza/index.jsp?data=13/10/2011&jornal=1000&pagina=6&totalArquivos=6">
829
+# http://www.in.gov.br/visualiza/index.jsp?data=13/10/2011&jornal=1000&pagina=6&totalArquivos=6
830
+# </a>
831
+
832
+# From Kelley Cook (2012-10-16):
833
+# The governor of state of Bahia in Brazil announced on Thursday that
834
+# due to public pressure, he is reversing the DST policy they implemented
835
+# last year and will not be going to Summer Time on October 21st....
836
+# http://www.correio24horas.com.br/r/artigo/apos-pressoes-wagner-suspende-horario-de-verao-na-bahia
837
+
838
+# From Rodrigo Severo (2012-10-16):
839
+# Tocantins state will have DST.
840
+# http://noticias.terra.com.br/brasil/noticias/0,,OI6232536-EI306.html
841
+
842
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
843
+# Decree <a href="http://pcdsh01.on.br/HV20466.htm">20,466</a> (1931-10-01)
844
+# Decree <a href="http://pcdsh01.on.br/HV21896.htm">21,896</a> (1932-01-10)
845
+Rule	Brazil	1931	only	-	Oct	 3	11:00	1:00	S
846
+Rule	Brazil	1932	1933	-	Apr	 1	 0:00	0	-
847
+Rule	Brazil	1932	only	-	Oct	 3	 0:00	1:00	S
848
+# Decree <a href="http://pcdsh01.on.br/HV23195.htm">23,195</a> (1933-10-10)
849
+# revoked DST.
850
+# Decree <a href="http://pcdsh01.on.br/HV27496.htm">27,496</a> (1949-11-24)
851
+# Decree <a href="http://pcdsh01.on.br/HV27998.htm">27,998</a> (1950-04-13)
852
+Rule	Brazil	1949	1952	-	Dec	 1	 0:00	1:00	S
853
+Rule	Brazil	1950	only	-	Apr	16	 1:00	0	-
854
+Rule	Brazil	1951	1952	-	Apr	 1	 0:00	0	-
855
+# Decree <a href="http://pcdsh01.on.br/HV32308.htm">32,308</a> (1953-02-24)
856
+Rule	Brazil	1953	only	-	Mar	 1	 0:00	0	-
857
+# Decree <a href="http://pcdsh01.on.br/HV34724.htm">34,724</a> (1953-11-30)
858
+# revoked DST.
859
+# Decree <a href="http://pcdsh01.on.br/HV52700.htm">52,700</a> (1963-10-18)
860
+# established DST from 1963-10-23 00:00 to 1964-02-29 00:00
861
+# in SP, RJ, GB, MG, ES, due to the prolongation of the drought.
862
+# Decree <a href="http://pcdsh01.on.br/HV53071.htm">53,071</a> (1963-12-03)
863
+# extended the above decree to all of the national territory on 12-09.
864
+Rule	Brazil	1963	only	-	Dec	 9	 0:00	1:00	S
865
+# Decree <a href="http://pcdsh01.on.br/HV53604.htm">53,604</a> (1964-02-25)
866
+# extended summer time by one day to 1964-03-01 00:00 (start of school).
867
+Rule	Brazil	1964	only	-	Mar	 1	 0:00	0	-
868
+# Decree <a href="http://pcdsh01.on.br/HV55639.htm">55,639</a> (1965-01-27)
869
+Rule	Brazil	1965	only	-	Jan	31	 0:00	1:00	S
870
+Rule	Brazil	1965	only	-	Mar	31	 0:00	0	-
871
+# Decree <a href="http://pcdsh01.on.br/HV57303.htm">57,303</a> (1965-11-22)
872
+Rule	Brazil	1965	only	-	Dec	 1	 0:00	1:00	S
873
+# Decree <a href="http://pcdsh01.on.br/HV57843.htm">57,843</a> (1966-02-18)
874
+Rule	Brazil	1966	1968	-	Mar	 1	 0:00	0	-
875
+Rule	Brazil	1966	1967	-	Nov	 1	 0:00	1:00	S
876
+# Decree <a href="http://pcdsh01.on.br/HV63429.htm">63,429</a> (1968-10-15)
877
+# revoked DST.
878
+# Decree <a href="http://pcdsh01.on.br/HV91698.htm">91,698</a> (1985-09-27)
879
+Rule	Brazil	1985	only	-	Nov	 2	 0:00	1:00	S
880
+# Decree 92,310 (1986-01-21)
881
+# Decree 92,463 (1986-03-13)
882
+Rule	Brazil	1986	only	-	Mar	15	 0:00	0	-
883
+# Decree 93,316 (1986-10-01)
884
+Rule	Brazil	1986	only	-	Oct	25	 0:00	1:00	S
885
+Rule	Brazil	1987	only	-	Feb	14	 0:00	0	-
886
+# Decree <a href="http://pcdsh01.on.br/HV94922.htm">94,922</a> (1987-09-22)
887
+Rule	Brazil	1987	only	-	Oct	25	 0:00	1:00	S
888
+Rule	Brazil	1988	only	-	Feb	 7	 0:00	0	-
889
+# Decree <a href="http://pcdsh01.on.br/HV96676.htm">96,676</a> (1988-09-12)
890
+# except for the states of AC, AM, PA, RR, RO, and AP (then a territory)
891
+Rule	Brazil	1988	only	-	Oct	16	 0:00	1:00	S
892
+Rule	Brazil	1989	only	-	Jan	29	 0:00	0	-
893
+# Decree <a href="http://pcdsh01.on.br/HV98077.htm">98,077</a> (1989-08-21)
894
+# with the same exceptions
895
+Rule	Brazil	1989	only	-	Oct	15	 0:00	1:00	S
896
+Rule	Brazil	1990	only	-	Feb	11	 0:00	0	-
897
+# Decree <a href="http://pcdsh01.on.br/HV99530.htm">99,530</a> (1990-09-17)
898
+# adopted by RS, SC, PR, SP, RJ, ES, MG, GO, MS, DF.
899
+# Decree 99,629 (1990-10-19) adds BA, MT.
900
+Rule	Brazil	1990	only	-	Oct	21	 0:00	1:00	S
901
+Rule	Brazil	1991	only	-	Feb	17	 0:00	0	-
902
+# <a href="http://pcdsh01.on.br/HV1991.htm">Unnumbered decree</a> (1991-09-25)
903
+# adopted by RS, SC, PR, SP, RJ, ES, MG, BA, GO, MT, MS, DF.
904
+Rule	Brazil	1991	only	-	Oct	20	 0:00	1:00	S
905
+Rule	Brazil	1992	only	-	Feb	 9	 0:00	0	-
906
+# <a href="http://pcdsh01.on.br/HV1992.htm">Unnumbered decree</a> (1992-10-16)
907
+# adopted by same states.
908
+Rule	Brazil	1992	only	-	Oct	25	 0:00	1:00	S
909
+Rule	Brazil	1993	only	-	Jan	31	 0:00	0	-
910
+# Decree <a href="http://pcdsh01.on.br/HV942.htm">942</a> (1993-09-28)
911
+# adopted by same states, plus AM.
912
+# Decree <a href="http://pcdsh01.on.br/HV1252.htm">1,252</a> (1994-09-22;
913
+# web page corrected 2004-01-07) adopted by same states, minus AM.
914
+# Decree <a href="http://pcdsh01.on.br/HV1636.htm">1,636</a> (1995-09-14)
915
+# adopted by same states, plus MT and TO.
916
+# Decree <a href="http://pcdsh01.on.br/HV1674.htm">1,674</a> (1995-10-13)
917
+# adds AL, SE.
918
+Rule	Brazil	1993	1995	-	Oct	Sun>=11	 0:00	1:00	S
919
+Rule	Brazil	1994	1995	-	Feb	Sun>=15	 0:00	0	-
920
+Rule	Brazil	1996	only	-	Feb	11	 0:00	0	-
921
+# Decree <a href="http://pcdsh01.on.br/HV2000.htm">2,000</a> (1996-09-04)
922
+# adopted by same states, minus AL, SE.
923
+Rule	Brazil	1996	only	-	Oct	 6	 0:00	1:00	S
924
+Rule	Brazil	1997	only	-	Feb	16	 0:00	0	-
925
+# From Daniel C. Sobral (1998-02-12):
926
+# In 1997, the DS began on October 6. The stated reason was that
927
+# because international television networks ignored Brazil's policy on DS,
928
+# they bought the wrong times on satellite for coverage of Pope's visit.
929
+# This year, the ending date of DS was postponed to March 1
930
+# to help dealing with the shortages of electric power.
931
+#
932
+# Decree 2,317 (1997-09-04), adopted by same states.
933
+Rule	Brazil	1997	only	-	Oct	 6	 0:00	1:00	S
934
+# Decree <a href="http://pcdsh01.on.br/figuras/HV2495.JPG">2,495</a>
935
+# (1998-02-10)
936
+Rule	Brazil	1998	only	-	Mar	 1	 0:00	0	-
937
+# Decree <a href="http://pcdsh01.on.br/figuras/Hv98.jpg">2,780</a> (1998-09-11)
938
+# adopted by the same states as before.
939
+Rule	Brazil	1998	only	-	Oct	11	 0:00	1:00	S
940
+Rule	Brazil	1999	only	-	Feb	21	 0:00	0	-
941
+# Decree <a href="http://pcdsh01.on.br/figuras/HV3150.gif">3,150</a>
942
+# (1999-08-23) adopted by same states.
943
+# Decree <a href="http://pcdsh01.on.br/DecHV99.gif">3,188</a> (1999-09-30)
944
+# adds SE, AL, PB, PE, RN, CE, PI, MA and RR.
945
+Rule	Brazil	1999	only	-	Oct	 3	 0:00	1:00	S
946
+Rule	Brazil	2000	only	-	Feb	27	 0:00	0	-
947
+# Decree <a href="http://pcdsh01.on.br/DEC3592.htm">3,592</a> (2000-09-06)
948
+# adopted by the same states as before.
949
+# Decree <a href="http://pcdsh01.on.br/Dec3630.jpg">3,630</a> (2000-10-13)
950
+# repeals DST in PE and RR, effective 2000-10-15 00:00.
951
+# Decree <a href="http://pcdsh01.on.br/Dec3632.jpg">3,632</a> (2000-10-17)
952
+# repeals DST in SE, AL, PB, RN, CE, PI and MA, effective 2000-10-22 00:00.
953
+# Decree <a href="http://pcdsh01.on.br/figuras/HV3916.gif">3,916</a>
954
+# (2001-09-13) reestablishes DST in AL, CE, MA, PB, PE, PI, RN, SE.
955
+Rule	Brazil	2000	2001	-	Oct	Sun>=8	 0:00	1:00	S
956
+Rule	Brazil	2001	2006	-	Feb	Sun>=15	 0:00	0	-
957
+# Decree 4,399 (2002-10-01) repeals DST in AL, CE, MA, PB, PE, PI, RN, SE.
958
+# <a href="http://www.presidencia.gov.br/CCIVIL/decreto/2002/D4399.htm">4,399</a>
959
+Rule	Brazil	2002	only	-	Nov	 3	 0:00	1:00	S
960
+# Decree 4,844 (2003-09-24; corrected 2003-09-26) repeals DST in BA, MT, TO.
961
+# <a href="http://www.presidencia.gov.br/CCIVIL/decreto/2003/D4844.htm">4,844</a>
962
+Rule	Brazil	2003	only	-	Oct	19	 0:00	1:00	S
963
+# Decree 5,223 (2004-10-01) reestablishes DST in MT.
964
+# <a href="http://www.planalto.gov.br/ccivil_03/_Ato2004-2006/2004/Decreto/D5223.htm">5,223</a>
965
+Rule	Brazil	2004	only	-	Nov	 2	 0:00	1:00	S
966
+# Decree <a href="http://pcdsh01.on.br/DecHV5539.gif">5,539</a> (2005-09-19),
967
+# adopted by the same states as before.
968
+Rule	Brazil	2005	only	-	Oct	16	 0:00	1:00	S
969
+# Decree <a href="http://pcdsh01.on.br/DecHV5920.gif">5,920</a> (2006-10-03),
970
+# adopted by the same states as before.
971
+Rule	Brazil	2006	only	-	Nov	 5	 0:00	1:00	S
972
+Rule	Brazil	2007	only	-	Feb	25	 0:00	0	-
973
+# Decree <a href="http://pcdsh01.on.br/DecHV6212.gif">6,212</a> (2007-09-26),
974
+# adopted by the same states as before.
975
+Rule	Brazil	2007	only	-	Oct	Sun>=8	 0:00	1:00	S
976
+# From Frederico A. C. Neves (2008-09-10):
977
+# Acording to this decree
978
+# <a href="http://www.planalto.gov.br/ccivil_03/_Ato2007-2010/2008/Decreto/D6558.htm">
979
+# http://www.planalto.gov.br/ccivil_03/_Ato2007-2010/2008/Decreto/D6558.htm
980
+# </a>
981
+# [t]he DST period in Brazil now on will be from the 3rd Oct Sunday to the
982
+# 3rd Feb Sunday. There is an exception on the return date when this is
983
+# the Carnival Sunday then the return date will be the next Sunday...
984
+Rule	Brazil	2008	max	-	Oct	Sun>=15	0:00	1:00	S
985
+Rule	Brazil	2008	2011	-	Feb	Sun>=15	0:00	0	-
986
+Rule	Brazil	2012	only	-	Feb	Sun>=22	0:00	0	-
987
+Rule	Brazil	2013	2014	-	Feb	Sun>=15	0:00	0	-
988
+Rule	Brazil	2015	only	-	Feb	Sun>=22	0:00	0	-
989
+Rule	Brazil	2016	2022	-	Feb	Sun>=15	0:00	0	-
990
+Rule	Brazil	2023	only	-	Feb	Sun>=22	0:00	0	-
991
+Rule	Brazil	2024	2025	-	Feb	Sun>=15	0:00	0	-
992
+Rule	Brazil	2026	only	-	Feb	Sun>=22	0:00	0	-
993
+Rule	Brazil	2027	2033	-	Feb	Sun>=15	0:00	0	-
994
+Rule	Brazil	2034	only	-	Feb	Sun>=22	0:00	0	-
995
+Rule	Brazil	2035	2036	-	Feb	Sun>=15	0:00	0	-
996
+Rule	Brazil	2037	only	-	Feb	Sun>=22	0:00	0	-
997
+# From Arthur David Olson (2008-09-29):
998
+# The next is wrong in some years but is better than nothing.
999
+Rule	Brazil	2038	max	-	Feb	Sun>=15	0:00	0	-
1000
+
1001
+# The latest ruleset listed above says that the following states observe DST:
1002
+# DF, ES, GO, MG, MS, MT, PR, RJ, RS, SC, SP.
1003
+
1004
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1005
+#
1006
+# Fernando de Noronha (administratively part of PE)
1007
+Zone America/Noronha	-2:09:40 -	LMT	1914
1008
+			-2:00	Brazil	FN%sT	1990 Sep 17
1009
+			-2:00	-	FNT	1999 Sep 30
1010
+			-2:00	Brazil	FN%sT	2000 Oct 15
1011
+			-2:00	-	FNT	2001 Sep 13
1012
+			-2:00	Brazil	FN%sT	2002 Oct  1
1013
+			-2:00	-	FNT
1014
+# Other Atlantic islands have no permanent settlement.
1015
+# These include Trindade and Martin Vaz (administratively part of ES),
1016
+# Atol das Rocas (RN), and Penedos de Sao Pedro e Sao Paulo (PE).
1017
+# Fernando de Noronha was a separate territory from 1942-09-02 to 1989-01-01;
1018
+# it also included the Penedos.
1019
+#
1020
+# Amapa (AP), east Para (PA)
1021
+# East Para includes Belem, Maraba, Serra Norte, and Sao Felix do Xingu.
1022
+# The division between east and west Para is the river Xingu.
1023
+# In the north a very small part from the river Javary (now Jari I guess,
1024
+# the border with Amapa) to the Amazon, then to the Xingu.
1025
+Zone America/Belem	-3:13:56 -	LMT	1914
1026
+			-3:00	Brazil	BR%sT	1988 Sep 12
1027
+			-3:00	-	BRT
1028
+#
1029
+# west Para (PA)
1030
+# West Para includes Altamira, Oribidos, Prainha, Oriximina, and Santarem.
1031
+Zone America/Santarem	-3:38:48 -	LMT	1914
1032
+			-4:00	Brazil	AM%sT	1988 Sep 12
1033
+			-4:00	-	AMT	2008 Jun 24 00:00
1034
+			-3:00	-	BRT
1035
+#
1036
+# Maranhao (MA), Piaui (PI), Ceara (CE), Rio Grande do Norte (RN),
1037
+# Paraiba (PB)
1038
+Zone America/Fortaleza	-2:34:00 -	LMT	1914
1039
+			-3:00	Brazil	BR%sT	1990 Sep 17
1040
+			-3:00	-	BRT	1999 Sep 30
1041
+			-3:00	Brazil	BR%sT	2000 Oct 22
1042
+			-3:00	-	BRT	2001 Sep 13
1043
+			-3:00	Brazil	BR%sT	2002 Oct  1
1044
+			-3:00	-	BRT
1045
+#
1046
+# Pernambuco (PE) (except Atlantic islands)
1047
+Zone America/Recife	-2:19:36 -	LMT	1914
1048
+			-3:00	Brazil	BR%sT	1990 Sep 17
1049
+			-3:00	-	BRT	1999 Sep 30
1050
+			-3:00	Brazil	BR%sT	2000 Oct 15
1051
+			-3:00	-	BRT	2001 Sep 13
1052
+			-3:00	Brazil	BR%sT	2002 Oct  1
1053
+			-3:00	-	BRT
1054
+#
1055
+# Tocantins (TO)
1056
+Zone America/Araguaina	-3:12:48 -	LMT	1914
1057
+			-3:00	Brazil	BR%sT	1990 Sep 17
1058
+			-3:00	-	BRT	1995 Sep 14
1059
+			-3:00	Brazil	BR%sT	2003 Sep 24
1060
+			-3:00	-	BRT	2012 Oct 21
1061
+			-3:00	Brazil	BR%sT
1062
+#
1063
+# Alagoas (AL), Sergipe (SE)
1064
+Zone America/Maceio	-2:22:52 -	LMT	1914
1065
+			-3:00	Brazil	BR%sT	1990 Sep 17
1066
+			-3:00	-	BRT	1995 Oct 13
1067
+			-3:00	Brazil	BR%sT	1996 Sep  4
1068
+			-3:00	-	BRT	1999 Sep 30
1069
+			-3:00	Brazil	BR%sT	2000 Oct 22
1070
+			-3:00	-	BRT	2001 Sep 13
1071
+			-3:00	Brazil	BR%sT	2002 Oct  1
1072
+			-3:00	-	BRT
1073
+#
1074
+# Bahia (BA)
1075
+# There are too many Salvadors elsewhere, so use America/Bahia instead
1076
+# of America/Salvador.
1077
+Zone America/Bahia	-2:34:04 -	LMT	1914
1078
+			-3:00	Brazil	BR%sT	2003 Sep 24
1079
+			-3:00	-	BRT	2011 Oct 16
1080
+			-3:00	Brazil	BR%sT	2012 Oct 21
1081
+			-3:00	-	BRT
1082
+#
1083
+# Goias (GO), Distrito Federal (DF), Minas Gerais (MG),
1084
+# Espirito Santo (ES), Rio de Janeiro (RJ), Sao Paulo (SP), Parana (PR),
1085
+# Santa Catarina (SC), Rio Grande do Sul (RS)
1086
+Zone America/Sao_Paulo	-3:06:28 -	LMT	1914
1087
+			-3:00	Brazil	BR%sT	1963 Oct 23 00:00
1088
+			-3:00	1:00	BRST	1964
1089
+			-3:00	Brazil	BR%sT
1090
+#
1091
+# Mato Grosso do Sul (MS)
1092
+Zone America/Campo_Grande -3:38:28 -	LMT	1914
1093
+			-4:00	Brazil	AM%sT
1094
+#
1095
+# Mato Grosso (MT)
1096
+Zone America/Cuiaba	-3:44:20 -	LMT	1914
1097
+			-4:00	Brazil	AM%sT	2003 Sep 24
1098
+			-4:00	-	AMT	2004 Oct  1
1099
+			-4:00	Brazil	AM%sT
1100
+#
1101
+# Rondonia (RO)
1102
+Zone America/Porto_Velho -4:15:36 -	LMT	1914
1103
+			-4:00	Brazil	AM%sT	1988 Sep 12
1104
+			-4:00	-	AMT
1105
+#
1106
+# Roraima (RR)
1107
+Zone America/Boa_Vista	-4:02:40 -	LMT	1914
1108
+			-4:00	Brazil	AM%sT	1988 Sep 12
1109
+			-4:00	-	AMT	1999 Sep 30
1110
+			-4:00	Brazil	AM%sT	2000 Oct 15
1111
+			-4:00	-	AMT
1112
+#
1113
+# east Amazonas (AM): Boca do Acre, Jutai, Manaus, Floriano Peixoto
1114
+# The great circle line from Tabatinga to Porto Acre divides
1115
+# east from west Amazonas.
1116
+Zone America/Manaus	-4:00:04 -	LMT	1914
1117
+			-4:00	Brazil	AM%sT	1988 Sep 12
1118
+			-4:00	-	AMT	1993 Sep 28
1119
+			-4:00	Brazil	AM%sT	1994 Sep 22
1120
+			-4:00	-	AMT
1121
+#
1122
+# west Amazonas (AM): Atalaia do Norte, Boca do Maoco, Benjamin Constant,
1123
+#	Eirunepe, Envira, Ipixuna
1124
+Zone America/Eirunepe	-4:39:28 -	LMT	1914
1125
+			-5:00	Brazil	AC%sT	1988 Sep 12
1126
+			-5:00	-	ACT	1993 Sep 28
1127
+			-5:00	Brazil	AC%sT	1994 Sep 22
1128
+			-5:00	-	ACT	2008 Jun 24 00:00
1129
+			-4:00	-	AMT
1130
+#
1131
+# Acre (AC)
1132
+Zone America/Rio_Branco	-4:31:12 -	LMT	1914
1133
+			-5:00	Brazil	AC%sT	1988 Sep 12
1134
+			-5:00	-	ACT	2008 Jun 24 00:00
1135
+			-4:00	-	AMT
1136
+
1137
+# Chile
1138
+
1139
+# From Eduardo Krell (1995-10-19):
1140
+# The law says to switch to DST at midnight [24:00] on the second SATURDAY
1141
+# of October....  The law is the same for March and October.
1142
+# (1998-09-29):
1143
+# Because of the drought this year, the government decided to go into
1144
+# DST earlier (saturday 9/26 at 24:00). This is a one-time change only ...
1145
+# (unless there's another dry season next year, I guess).
1146
+
1147
+# From Julio I. Pacheco Troncoso (1999-03-18):
1148
+# Because of the same drought, the government decided to end DST later,
1149
+# on April 3, (one-time change).
1150
+
1151
+# From Oscar van Vlijmen (2006-10-08):
1152
+# http://www.horaoficial.cl/cambio.htm
1153
+
1154
+# From Jesper Norgaard Welen (2006-10-08):
1155
+# I think that there are some obvious mistakes in the suggested link
1156
+# from Oscar van Vlijmen,... for instance entry 66 says that GMT-4
1157
+# ended 1990-09-12 while entry 67 only begins GMT-3 at 1990-09-15
1158
+# (they should have been 1990-09-15 and 1990-09-16 respectively), but
1159
+# anyhow it clears up some doubts too.
1160
+
1161
+# From Paul Eggert (2006-12-27):
1162
+# The following data for Chile and America/Santiago are from
1163
+# <http://www.horaoficial.cl/horaof.htm> (2006-09-20), transcribed by
1164
+# Jesper Norgaard Welen.  The data for Pacific/Easter are from Shanks
1165
+# & Pottenger, except with DST transitions after 1932 cloned from
1166
+# America/Santiago.  The pre-1980 Pacific/Easter data are dubious,
1167
+# but we have no other source.
1168
+
1169
+# From German Poo-Caaman~o (2008-03-03):
1170
+# Due to drought, Chile extends Daylight Time in three weeks.  This
1171
+# is one-time change (Saturday 3/29 at 24:00 for America/Santiago
1172
+# and Saturday 3/29 at 22:00 for Pacific/Easter)
1173
+# The Supreme Decree is located at
1174
+# <a href="http://www.shoa.cl/servicios/supremo316.pdf">
1175
+# http://www.shoa.cl/servicios/supremo316.pdf
1176
+# </a>
1177
+# and the instructions for 2008 are located in:
1178
+# <a href="http://www.horaoficial.cl/cambio.htm">
1179
+# http://www.horaoficial.cl/cambio.htm
1180
+# </a>.
1181
+
1182
+# From Jose Miguel Garrido (2008-03-05):
1183
+# ...
1184
+# You could see the announces of the change on
1185
+# <a href="http://www.shoa.cl/noticias/2008/04hora/hora.htm">
1186
+# http://www.shoa.cl/noticias/2008/04hora/hora.htm
1187
+# </a>.
1188
+
1189
+# From Angel Chiang (2010-03-04):
1190
+# Subject: DST in Chile exceptionally extended to 3 April due to earthquake
1191
+# <a href="http://www.gobiernodechile.cl/viewNoticia.aspx?idArticulo=30098">
1192
+# http://www.gobiernodechile.cl/viewNoticia.aspx?idArticulo=30098
1193
+# </a>
1194
+# (in Spanish, last paragraph).
1195
+#
1196
+# This is breaking news. There should be more information available later.
1197
+
1198
+# From Arthur Daivd Olson (2010-03-06):
1199
+# Angel Chiang's message confirmed by Julio Pacheco; Julio provided a patch.
1200
+
1201
+# From Glenn Eychaner (2011-03-02): [geychaner@mac.com]
1202
+# It appears that the Chilean government has decided to postpone the
1203
+# change from summer time to winter time again, by three weeks to April
1204
+# 2nd:
1205
+# <a href="http://www.emol.com/noticias/nacional/detalle/detallenoticias.asp?idnoticia=467651">
1206
+# http://www.emol.com/noticias/nacional/detalle/detallenoticias.asp?idnoticia=467651
1207
+# </a>
1208
+#
1209
+# This is not yet reflected in the offical "cambio de hora" site, but
1210
+# probably will be soon:
1211
+# <a href="http://www.horaoficial.cl/cambio.htm">
1212
+# http://www.horaoficial.cl/cambio.htm
1213
+# </a>
1214
+
1215
+# From Arthur David Olson (2011-03-02):
1216
+# The emol.com article mentions a water shortage as the cause of the
1217
+# postponement, which may mean that it's not a permanent change.
1218
+
1219
+# From Glenn Eychaner (2011-03-28):
1220
+# The article:
1221
+# <a href="http://diario.elmercurio.com/2011/03/28/_portada/_portada/noticias/7565897A-CA86-49E6-9E03-660B21A4883E.htm?id=3D{7565897A-CA86-49E6-9E03-660B21A4883E}">
1222
+# http://diario.elmercurio.com/2011/03/28/_portada/_portada/noticias/7565897A-CA86-49E6-9E03-660B21A4883E.htm?id=3D{7565897A-CA86-49E6-9E03-660B21A4883E}
1223
+# </a>
1224
+#
1225
+# In English:
1226
+# Chile's clocks will go back an hour this year on the 7th of May instead
1227
+# of this Saturday. They will go forward again the 3rd Saturday in
1228
+# August, not in October as they have since 1968. This is a pilot plan
1229
+# which will be reevaluated in 2012.
1230
+
1231
+# From Mauricio Parada (2012-02-22), translated by Glenn Eychaner (2012-02-23):
1232
+# As stated in the website of the Chilean Energy Ministry
1233
+# http://www.minenergia.cl/ministerio/noticias/generales/gobierno-anuncia-fechas-de-cambio-de.html
1234
+# The Chilean Government has decided to postpone the entrance into winter time
1235
+# (to leave DST) from March 11 2012 to April 28th 2012. The decision has not
1236
+# been yet formalized but it will within the next days.
1237
+# Quote from the website communication:
1238
+#
1239
+# 6. For the year 2012, the dates of entry into winter time will be as follows:
1240
+# a. Saturday April 28, 2012, clocks should go back 60 minutes; that is, at
1241
+# 23:59:59, instead of passing to 0:00, the time should be adjusted to be 23:00
1242
+# of the same day.
1243
+# b. Saturday, September 1, 2012, clocks should go forward 60 minutes; that is,
1244
+# at 23:59:59, instead of passing to 0:00, the time should be adjusted to be
1245
+# 01:00 on September 2.
1246
+#
1247
+# Note that...this is yet another "temporary" change that will be reevaluated
1248
+# AGAIN in 2013.
1249
+
1250
+# NOTE: ChileAQ rules for Antarctic bases are stored separately in the
1251
+# 'antarctica' file.
1252
+
1253
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1254
+Rule	Chile	1927	1932	-	Sep	 1	0:00	1:00	S
1255
+Rule	Chile	1928	1932	-	Apr	 1	0:00	0	-
1256
+Rule	Chile	1942	only	-	Jun	 1	4:00u	0	-
1257
+Rule	Chile	1942	only	-	Aug	 1	5:00u	1:00	S
1258
+Rule	Chile	1946	only	-	Jul	15	4:00u	1:00	S
1259
+Rule	Chile	1946	only	-	Sep	 1	3:00u	0:00	-
1260
+Rule	Chile	1947	only	-	Apr	 1	4:00u	0	-
1261
+Rule	Chile	1968	only	-	Nov	 3	4:00u	1:00	S
1262
+Rule	Chile	1969	only	-	Mar	30	3:00u	0	-
1263
+Rule	Chile	1969	only	-	Nov	23	4:00u	1:00	S
1264
+Rule	Chile	1970	only	-	Mar	29	3:00u	0	-
1265
+Rule	Chile	1971	only	-	Mar	14	3:00u	0	-
1266
+Rule	Chile	1970	1972	-	Oct	Sun>=9	4:00u	1:00	S
1267
+Rule	Chile	1972	1986	-	Mar	Sun>=9	3:00u	0	-
1268
+Rule	Chile	1973	only	-	Sep	30	4:00u	1:00	S
1269
+Rule	Chile	1974	1987	-	Oct	Sun>=9	4:00u	1:00	S
1270
+Rule	Chile	1987	only	-	Apr	12	3:00u	0	-
1271
+Rule	Chile	1988	1989	-	Mar	Sun>=9	3:00u	0	-
1272
+Rule	Chile	1988	only	-	Oct	Sun>=1	4:00u	1:00	S
1273
+Rule	Chile	1989	only	-	Oct	Sun>=9	4:00u	1:00	S
1274
+Rule	Chile	1990	only	-	Mar	18	3:00u	0	-
1275
+Rule	Chile	1990	only	-	Sep	16	4:00u	1:00	S
1276
+Rule	Chile	1991	1996	-	Mar	Sun>=9	3:00u	0	-
1277
+Rule	Chile	1991	1997	-	Oct	Sun>=9	4:00u	1:00	S
1278
+Rule	Chile	1997	only	-	Mar	30	3:00u	0	-
1279
+Rule	Chile	1998	only	-	Mar	Sun>=9	3:00u	0	-
1280
+Rule	Chile	1998	only	-	Sep	27	4:00u	1:00	S
1281
+Rule	Chile	1999	only	-	Apr	 4	3:00u	0	-
1282
+Rule	Chile	1999	2010	-	Oct	Sun>=9	4:00u	1:00	S
1283
+Rule	Chile	2000	2007	-	Mar	Sun>=9	3:00u	0	-
1284
+# N.B.: the end of March 29 in Chile is March 30 in Universal time,
1285
+# which is used below in specifying the transition.
1286
+Rule	Chile	2008	only	-	Mar	30	3:00u	0	-
1287
+Rule	Chile	2009	only	-	Mar	Sun>=9	3:00u	0	-
1288
+Rule	Chile	2010	only	-	Apr	Sun>=1	3:00u	0	-
1289
+Rule	Chile	2011	only	-	May	Sun>=2	3:00u	0	-
1290
+Rule	Chile	2011	only	-	Aug	Sun>=16	4:00u	1:00	S
1291
+Rule	Chile	2012	only	-	Apr	Sun>=23	3:00u	0	-
1292
+Rule	Chile	2012	only	-	Sep	Sun>=2	4:00u	1:00	S
1293
+Rule	Chile	2013	max	-	Mar	Sun>=9	3:00u	0	-
1294
+Rule	Chile	2013	max	-	Oct	Sun>=9	4:00u	1:00	S
1295
+# IATA SSIM anomalies: (1992-02) says 1992-03-14;
1296
+# (1996-09) says 1998-03-08.  Ignore these.
1297
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1298
+Zone America/Santiago	-4:42:46 -	LMT	1890
1299
+			-4:42:46 -	SMT	1910 	    # Santiago Mean Time
1300
+			-5:00	-	CLT	1916 Jul  1 # Chile Time
1301
+			-4:42:46 -	SMT	1918 Sep  1 # Santiago Mean Time
1302
+			-4:00	-	CLT	1919 Jul  1 # Chile Time
1303
+			-4:42:46 -	SMT	1927 Sep  1 # Santiago Mean Time
1304
+			-5:00	Chile	CL%sT	1947 May 22 # Chile Time
1305
+			-4:00	Chile	CL%sT
1306
+Zone Pacific/Easter	-7:17:44 -	LMT	1890
1307
+			-7:17:28 -	EMT	1932 Sep    # Easter Mean Time
1308
+			-7:00	Chile	EAS%sT	1982 Mar 13 21:00 # Easter I Time
1309
+			-6:00	Chile	EAS%sT
1310
+#
1311
+# Sala y Gomez Island is like Pacific/Easter.
1312
+# Other Chilean locations, including Juan Fernandez Is, San Ambrosio,
1313
+# San Felix, and Antarctic bases, are like America/Santiago.
1314
+
1315
+# Colombia
1316
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1317
+Rule	CO	1992	only	-	May	 3	0:00	1:00	S
1318
+Rule	CO	1993	only	-	Apr	 4	0:00	0	-
1319
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1320
+Zone	America/Bogota	-4:56:20 -	LMT	1884 Mar 13
1321
+			-4:56:20 -	BMT	1914 Nov 23 # Bogota Mean Time
1322
+			-5:00	CO	CO%sT	# Colombia Time
1323
+# Malpelo, Providencia, San Andres
1324
+# no information; probably like America/Bogota
1325
+
1326
+# Curacao
1327
+#
1328
+# From Paul Eggert (2006-03-22):
1329
+# Shanks & Pottenger say that The Bottom and Philipsburg have been at
1330
+# -4:00 since standard time was introduced on 1912-03-02; and that
1331
+# Kralendijk and Rincon used Kralendijk Mean Time (-4:33:08) from
1332
+# 1912-02-02 to 1965-01-01.  The former is dubious, since S&P also say
1333
+# Saba Island has been like Curacao.
1334
+# This all predates our 1970 cutoff, though.
1335
+#
1336
+# By July 2007 Curacao and St Maarten are planned to become
1337
+# associated states within the Netherlands, much like Aruba;
1338
+# Bonaire, Saba and St Eustatius would become directly part of the
1339
+# Netherlands as Kingdom Islands.  This won't affect their time zones
1340
+# though, as far as we know.
1341
+#
1342
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1343
+Zone	America/Curacao	-4:35:44 -	LMT	1912 Feb 12	# Willemstad
1344
+			-4:30	-	ANT	1965 # Netherlands Antilles Time
1345
+			-4:00	-	AST
1346
+
1347
+# From Arthur David Olson (2011-06-15):
1348
+# At least for now, use links for places with new iso3166 codes.
1349
+# The name "Lower Prince's Quarter" is both longer than fourteen charaters
1350
+# and contains an apostrophe; use "Lower_Princes" below.
1351
+
1352
+Link	America/Curacao	America/Lower_Princes # Sint Maarten
1353
+Link	America/Curacao	America/Kralendijk # Bonaire, Sint Estatius and Saba
1354
+
1355
+# Ecuador
1356
+#
1357
+# From Paul Eggert (2007-03-04):
1358
+# Apparently Ecuador had a failed experiment with DST in 1992.
1359
+# <http://midena.gov.ec/content/view/1261/208/> (2007-02-27) and
1360
+# <http://www.hoy.com.ec/NoticiaNue.asp?row_id=249856> (2006-11-06) both
1361
+# talk about "hora Sixto".  Leave this alone for now, as we have no data.
1362
+#
1363
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1364
+Zone America/Guayaquil	-5:19:20 -	LMT	1890
1365
+			-5:14:00 -	QMT	1931 # Quito Mean Time
1366
+			-5:00	-	ECT	     # Ecuador Time
1367
+Zone Pacific/Galapagos	-5:58:24 -	LMT	1931 # Puerto Baquerizo Moreno
1368
+			-5:00	-	ECT	1986
1369
+			-6:00	-	GALT	     # Galapagos Time
1370
+
1371
+# Falklands
1372
+
1373
+# From Paul Eggert (2006-03-22):
1374
+# Between 1990 and 2000 inclusive, Shanks & Pottenger and the IATA agree except
1375
+# the IATA gives 1996-09-08.  Go with Shanks & Pottenger.
1376
+
1377
+# From Falkland Islands Government Office, London (2001-01-22)
1378
+# via Jesper Norgaard:
1379
+# ... the clocks revert back to Local Mean Time at 2 am on Sunday 15
1380
+# April 2001 and advance one hour to summer time at 2 am on Sunday 2
1381
+# September.  It is anticipated that the clocks will revert back at 2
1382
+# am on Sunday 21 April 2002 and advance to summer time at 2 am on
1383
+# Sunday 1 September.
1384
+
1385
+# From Rives McDow (2001-02-13):
1386
+#
1387
+# I have communicated several times with people there, and the last
1388
+# time I had communications that was helpful was in 1998.  Here is
1389
+# what was said then:
1390
+#
1391
+# "The general rule was that Stanley used daylight saving and the Camp
1392
+# did not. However for various reasons many people in the Camp have
1393
+# started to use daylight saving (known locally as 'Stanley Time')
1394
+# There is no rule as to who uses daylight saving - it is a matter of
1395
+# personal choice and so it is impossible to draw a map showing who
1396
+# uses it and who does not. Any list would be out of date as soon as
1397
+# it was produced. This year daylight saving ended on April 18/19th
1398
+# and started again on September 12/13th.  I do not know what the rule
1399
+# is, but can find out if you like.  We do not change at the same time
1400
+# as UK or Chile."
1401
+#
1402
+# I did have in my notes that the rule was "Second Saturday in Sep at
1403
+# 0:00 until third Saturday in Apr at 0:00".  I think that this does
1404
+# not agree in some cases with Shanks; is this true?
1405
+#
1406
+# Also, there is no mention in the list that some areas in the
1407
+# Falklands do not use DST.  I have found in my communications there
1408
+# that these areas are on the western half of East Falkland and all of
1409
+# West Falkland.  Stanley is the only place that consistently observes
1410
+# DST.  Again, as in other places in the world, the farmers don't like
1411
+# it.  West Falkland is almost entirely sheep farmers.
1412
+#
1413
+# I know one lady there that keeps a list of which farm keeps DST and
1414
+# which doesn't each year.  She runs a shop in Stanley, and says that
1415
+# the list changes each year.  She uses it to communicate to her
1416
+# customers, catching them when they are home for lunch or dinner.
1417
+
1418
+# From Paul Eggert (2001-03-05):
1419
+# For now, we'll just record the time in Stanley, since we have no
1420
+# better info.
1421
+
1422
+# From Steffen Thorsen (2011-04-01):
1423
+# The Falkland Islands will not turn back clocks this winter, but stay on
1424
+# daylight saving time.
1425
+#
1426
+# One source:
1427
+# <a href="http://www.falklandnews.com/public/story.cfm?get=5914&source=3">
1428
+# http://www.falklandnews.com/public/story.cfm?get=5914&source=3
1429
+# </a>
1430
+#
1431
+# We have gotten this confirmed by a clerk of the legislative assembly:
1432
+# Normally the clocks revert to Local Mean Time (UTC/GMT -4 hours) on the
1433
+# third Sunday of April at 0200hrs and advance to Summer Time (UTC/GMT -3
1434
+# hours) on the first Sunday of September at 0200hrs.
1435
+#
1436
+# IMPORTANT NOTE: During 2011, on a trial basis, the Falkland Islands
1437
+# will not revert to local mean time, but clocks will remain on Summer
1438
+# time (UTC/GMT - 3 hours) throughout the whole of 2011.  Any long term
1439
+# change to local time following the trial period will be notified.
1440
+#
1441
+# From Andrew Newman (2012-02-24)
1442
+# A letter from Justin McPhee, Chief Executive,
1443
+# Cable & Wireless Falkland Islands (dated 2012-02-22)
1444
+# states...
1445
+#   The current Atlantic/Stanley entry under South America expects the
1446
+#   clocks to go back to standard Falklands Time (FKT) on the 15th April.
1447
+#   The database entry states that in 2011 Stanley was staying on fixed
1448
+#   summer time on a trial basis only.  FIG need to contact IANA and/or
1449
+#   the maintainers of the database to inform them we're adopting
1450
+#   the same policy this year and suggest recommendations for future years.
1451
+#
1452
+# For now we will assume permanent summer time for the Falklands
1453
+# until advised differently (to apply for 2012 and beyond, after the 2011
1454
+# experiment was apparently successful.)
1455
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1456
+Rule	Falk	1937	1938	-	Sep	lastSun	0:00	1:00	S
1457
+Rule	Falk	1938	1942	-	Mar	Sun>=19	0:00	0	-
1458
+Rule	Falk	1939	only	-	Oct	1	0:00	1:00	S
1459
+Rule	Falk	1940	1942	-	Sep	lastSun	0:00	1:00	S
1460
+Rule	Falk	1943	only	-	Jan	1	0:00	0	-
1461
+Rule	Falk	1983	only	-	Sep	lastSun	0:00	1:00	S
1462
+Rule	Falk	1984	1985	-	Apr	lastSun	0:00	0	-
1463
+Rule	Falk	1984	only	-	Sep	16	0:00	1:00	S
1464
+Rule	Falk	1985	2000	-	Sep	Sun>=9	0:00	1:00	S
1465
+Rule	Falk	1986	2000	-	Apr	Sun>=16	0:00	0	-
1466
+Rule	Falk	2001	2010	-	Apr	Sun>=15	2:00	0	-
1467
+Rule	Falk	2001	2010	-	Sep	Sun>=1	2:00	1:00	S
1468
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1469
+Zone Atlantic/Stanley	-3:51:24 -	LMT	1890
1470
+			-3:51:24 -	SMT	1912 Mar 12  # Stanley Mean Time
1471
+			-4:00	Falk	FK%sT	1983 May     # Falkland Is Time
1472
+			-3:00	Falk	FK%sT	1985 Sep 15
1473
+			-4:00	Falk	FK%sT	2010 Sep 5 02:00
1474
+			-3:00	-	FKST
1475
+
1476
+# French Guiana
1477
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1478
+Zone America/Cayenne	-3:29:20 -	LMT	1911 Jul
1479
+			-4:00	-	GFT	1967 Oct # French Guiana Time
1480
+			-3:00	-	GFT
1481
+
1482
+# Guyana
1483
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1484
+Zone	America/Guyana	-3:52:40 -	LMT	1915 Mar	# Georgetown
1485
+			-3:45	-	GBGT	1966 May 26 # Br Guiana Time
1486
+			-3:45	-	GYT	1975 Jul 31 # Guyana Time
1487
+			-3:00	-	GYT	1991
1488
+# IATA SSIM (1996-06) says -4:00.  Assume a 1991 switch.
1489
+			-4:00	-	GYT
1490
+
1491
+# Paraguay
1492
+# From Paul Eggert (2006-03-22):
1493
+# Shanks & Pottenger say that spring transitions are from 01:00 -> 02:00,
1494
+# and autumn transitions are from 00:00 -> 23:00.  Go with pre-1999
1495
+# editions of Shanks, and with the IATA, who say transitions occur at 00:00.
1496
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1497
+Rule	Para	1975	1988	-	Oct	 1	0:00	1:00	S
1498
+Rule	Para	1975	1978	-	Mar	 1	0:00	0	-
1499
+Rule	Para	1979	1991	-	Apr	 1	0:00	0	-
1500
+Rule	Para	1989	only	-	Oct	22	0:00	1:00	S
1501
+Rule	Para	1990	only	-	Oct	 1	0:00	1:00	S
1502
+Rule	Para	1991	only	-	Oct	 6	0:00	1:00	S
1503
+Rule	Para	1992	only	-	Mar	 1	0:00	0	-
1504
+Rule	Para	1992	only	-	Oct	 5	0:00	1:00	S
1505
+Rule	Para	1993	only	-	Mar	31	0:00	0	-
1506
+Rule	Para	1993	1995	-	Oct	 1	0:00	1:00	S
1507
+Rule	Para	1994	1995	-	Feb	lastSun	0:00	0	-
1508
+Rule	Para	1996	only	-	Mar	 1	0:00	0	-
1509
+# IATA SSIM (2000-02) says 1999-10-10; ignore this for now.
1510
+# From Steffen Thorsen (2000-10-02):
1511
+# I have three independent reports that Paraguay changed to DST this Sunday
1512
+# (10-01).
1513
+#
1514
+# Translated by Gwillim Law (2001-02-27) from
1515
+# <a href="http://www.diarionoticias.com.py/011000/nacional/naciona1.htm">
1516
+# Noticias, a daily paper in Asuncion, Paraguay (2000-10-01)
1517
+# </a>:
1518
+# Starting at 0:00 today, the clock will be set forward 60 minutes, in
1519
+# fulfillment of Decree No. 7,273 of the Executive Power....  The time change
1520
+# system has been operating for several years.  Formerly there was a separate
1521
+# decree each year; the new law has the same effect, but permanently.  Every
1522
+# year, the time will change on the first Sunday of October; likewise, the
1523
+# clock will be set back on the first Sunday of March.
1524
+#
1525
+Rule	Para	1996	2001	-	Oct	Sun>=1	0:00	1:00	S
1526
+# IATA SSIM (1997-09) says Mar 1; go with Shanks & Pottenger.
1527
+Rule	Para	1997	only	-	Feb	lastSun	0:00	0	-
1528
+# Shanks & Pottenger say 1999-02-28; IATA SSIM (1999-02) says 1999-02-27, but
1529
+# (1999-09) reports no date; go with above sources and Gerd Knops (2001-02-27).
1530
+Rule	Para	1998	2001	-	Mar	Sun>=1	0:00	0	-
1531
+# From Rives McDow (2002-02-28):
1532
+# A decree was issued in Paraguay (no. 16350) on 2002-02-26 that changed the
1533
+# dst method to be from the first Sunday in September to the first Sunday in
1534
+# April.
1535
+Rule	Para	2002	2004	-	Apr	Sun>=1	0:00	0	-
1536
+Rule	Para	2002	2003	-	Sep	Sun>=1	0:00	1:00	S
1537
+#
1538
+# From Jesper Norgaard Welen (2005-01-02):
1539
+# There are several sources that claim that Paraguay made
1540
+# a timezone rule change in autumn 2004.
1541
+# From Steffen Thorsen (2005-01-05):
1542
+# Decree 1,867 (2004-03-05)
1543
+# From Carlos Raul Perasso via Jesper Norgaard Welen (2006-10-13)
1544
+# <http://www.presidencia.gov.py/decretos/D1867.pdf>
1545
+Rule	Para	2004	2009	-	Oct	Sun>=15	0:00	1:00	S
1546
+Rule	Para	2005	2009	-	Mar	Sun>=8	0:00	0	-
1547
+# From Carlos Raul Perasso (2010-02-18):
1548
+# By decree number 3958 issued yesterday (
1549
+# <a href="http://www.presidencia.gov.py/v1/wp-content/uploads/2010/02/decreto3958.pdf">
1550
+# http://www.presidencia.gov.py/v1/wp-content/uploads/2010/02/decreto3958.pdf
1551
+# </a>
1552
+# )
1553
+# Paraguay changes its DST schedule, postponing the March rule to April and
1554
+# modifying the October date. The decree reads:
1555
+# ...
1556
+# Art. 1. It is hereby established that from the second Sunday of the month of
1557
+# April of this year (2010), the official time is to be set back 60 minutes,
1558
+# and that on the first Sunday of the month of October, it is to be set
1559
+# forward 60 minutes, in all the territory of the Paraguayan Republic.
1560
+# ...
1561
+Rule	Para	2010	max	-	Oct	Sun>=1	0:00	1:00	S
1562
+Rule	Para	2010	max	-	Apr	Sun>=8	0:00	0	-
1563
+
1564
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1565
+Zone America/Asuncion	-3:50:40 -	LMT	1890
1566
+			-3:50:40 -	AMT	1931 Oct 10 # Asuncion Mean Time
1567
+			-4:00	-	PYT	1972 Oct # Paraguay Time
1568
+			-3:00	-	PYT	1974 Apr
1569
+			-4:00	Para	PY%sT
1570
+
1571
+# Peru
1572
+#
1573
+# <a href="news:xrGmb.39935$gA1.13896113@news4.srv.hcvlny.cv.net">
1574
+# From Evelyn C. Leeper via Mark Brader (2003-10-26):</a>
1575
+# When we were in Peru in 1985-1986, they apparently switched over
1576
+# sometime between December 29 and January 3 while we were on the Amazon.
1577
+#
1578
+# From Paul Eggert (2006-03-22):
1579
+# Shanks & Pottenger don't have this transition.  Assume 1986 was like 1987.
1580
+
1581
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1582
+Rule	Peru	1938	only	-	Jan	 1	0:00	1:00	S
1583
+Rule	Peru	1938	only	-	Apr	 1	0:00	0	-
1584
+Rule	Peru	1938	1939	-	Sep	lastSun	0:00	1:00	S
1585
+Rule	Peru	1939	1940	-	Mar	Sun>=24	0:00	0	-
1586
+Rule	Peru	1986	1987	-	Jan	 1	0:00	1:00	S
1587
+Rule	Peru	1986	1987	-	Apr	 1	0:00	0	-
1588
+Rule	Peru	1990	only	-	Jan	 1	0:00	1:00	S
1589
+Rule	Peru	1990	only	-	Apr	 1	0:00	0	-
1590
+# IATA is ambiguous for 1993/1995; go with Shanks & Pottenger.
1591
+Rule	Peru	1994	only	-	Jan	 1	0:00	1:00	S
1592
+Rule	Peru	1994	only	-	Apr	 1	0:00	0	-
1593
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1594
+Zone	America/Lima	-5:08:12 -	LMT	1890
1595
+			-5:08:36 -	LMT	1908 Jul 28 # Lima Mean Time?
1596
+			-5:00	Peru	PE%sT	# Peru Time
1597
+
1598
+# South Georgia
1599
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1600
+Zone Atlantic/South_Georgia -2:26:08 -	LMT	1890		# Grytviken
1601
+			-2:00	-	GST	# South Georgia Time
1602
+
1603
+# South Sandwich Is
1604
+# uninhabited; scientific personnel have wintered
1605
+
1606
+# Suriname
1607
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1608
+Zone America/Paramaribo	-3:40:40 -	LMT	1911
1609
+			-3:40:52 -	PMT	1935     # Paramaribo Mean Time
1610
+			-3:40:36 -	PMT	1945 Oct # The capital moved?
1611
+			-3:30	-	NEGT	1975 Nov 20 # Dutch Guiana Time
1612
+			-3:30	-	SRT	1984 Oct # Suriname Time
1613
+			-3:00	-	SRT
1614
+
1615
+# Trinidad and Tobago
1616
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1617
+Zone America/Port_of_Spain -4:06:04 -	LMT	1912 Mar 2
1618
+			-4:00	-	AST
1619
+
1620
+# Uruguay
1621
+# From Paul Eggert (1993-11-18):
1622
+# Uruguay wins the prize for the strangest peacetime manipulation of the rules.
1623
+# From Shanks & Pottenger:
1624
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
1625
+# Whitman gives 1923 Oct 1; go with Shanks & Pottenger.
1626
+Rule	Uruguay	1923	only	-	Oct	 2	 0:00	0:30	HS
1627
+Rule	Uruguay	1924	1926	-	Apr	 1	 0:00	0	-
1628
+Rule	Uruguay	1924	1925	-	Oct	 1	 0:00	0:30	HS
1629
+Rule	Uruguay	1933	1935	-	Oct	lastSun	 0:00	0:30	HS
1630
+# Shanks & Pottenger give 1935 Apr 1 0:00 & 1936 Mar 30 0:00; go with Whitman.
1631
+Rule	Uruguay	1934	1936	-	Mar	Sat>=25	23:30s	0	-
1632
+Rule	Uruguay	1936	only	-	Nov	 1	 0:00	0:30	HS
1633
+Rule	Uruguay	1937	1941	-	Mar	lastSun	 0:00	0	-
1634
+# Whitman gives 1937 Oct 3; go with Shanks & Pottenger.
1635
+Rule	Uruguay	1937	1940	-	Oct	lastSun	 0:00	0:30	HS
1636
+# Whitman gives 1941 Oct 24 - 1942 Mar 27, 1942 Dec 14 - 1943 Apr 13,
1637
+# and 1943 Apr 13 ``to present time''; go with Shanks & Pottenger.
1638
+Rule	Uruguay	1941	only	-	Aug	 1	 0:00	0:30	HS
1639
+Rule	Uruguay	1942	only	-	Jan	 1	 0:00	0	-
1640
+Rule	Uruguay	1942	only	-	Dec	14	 0:00	1:00	S
1641
+Rule	Uruguay	1943	only	-	Mar	14	 0:00	0	-
1642
+Rule	Uruguay	1959	only	-	May	24	 0:00	1:00	S
1643
+Rule	Uruguay	1959	only	-	Nov	15	 0:00	0	-
1644
+Rule	Uruguay	1960	only	-	Jan	17	 0:00	1:00	S
1645
+Rule	Uruguay	1960	only	-	Mar	 6	 0:00	0	-
1646
+Rule	Uruguay	1965	1967	-	Apr	Sun>=1	 0:00	1:00	S
1647
+Rule	Uruguay	1965	only	-	Sep	26	 0:00	0	-
1648
+Rule	Uruguay	1966	1967	-	Oct	31	 0:00	0	-
1649
+Rule	Uruguay	1968	1970	-	May	27	 0:00	0:30	HS
1650
+Rule	Uruguay	1968	1970	-	Dec	 2	 0:00	0	-
1651
+Rule	Uruguay	1972	only	-	Apr	24	 0:00	1:00	S
1652
+Rule	Uruguay	1972	only	-	Aug	15	 0:00	0	-
1653
+Rule	Uruguay	1974	only	-	Mar	10	 0:00	0:30	HS
1654
+Rule	Uruguay	1974	only	-	Dec	22	 0:00	1:00	S
1655
+Rule	Uruguay	1976	only	-	Oct	 1	 0:00	0	-
1656
+Rule	Uruguay	1977	only	-	Dec	 4	 0:00	1:00	S
1657
+Rule	Uruguay	1978	only	-	Apr	 1	 0:00	0	-
1658
+Rule	Uruguay	1979	only	-	Oct	 1	 0:00	1:00	S
1659
+Rule	Uruguay	1980	only	-	May	 1	 0:00	0	-
1660
+Rule	Uruguay	1987	only	-	Dec	14	 0:00	1:00	S
1661
+Rule	Uruguay	1988	only	-	Mar	14	 0:00	0	-
1662
+Rule	Uruguay	1988	only	-	Dec	11	 0:00	1:00	S
1663
+Rule	Uruguay	1989	only	-	Mar	12	 0:00	0	-
1664
+Rule	Uruguay	1989	only	-	Oct	29	 0:00	1:00	S
1665
+# Shanks & Pottenger say no DST was observed in 1990/1 and 1991/2,
1666
+# and that 1992/3's DST was from 10-25 to 03-01.  Go with IATA.
1667
+Rule	Uruguay	1990	1992	-	Mar	Sun>=1	 0:00	0	-
1668
+Rule	Uruguay	1990	1991	-	Oct	Sun>=21	 0:00	1:00	S
1669
+Rule	Uruguay	1992	only	-	Oct	18	 0:00	1:00	S
1670
+Rule	Uruguay	1993	only	-	Feb	28	 0:00	0	-
1671
+# From Eduardo Cota (2004-09-20):
1672
+# The uruguayan government has decreed a change in the local time....
1673
+# http://www.presidencia.gub.uy/decretos/2004091502.htm
1674
+Rule	Uruguay	2004	only	-	Sep	19	 0:00	1:00	S
1675
+# From Steffen Thorsen (2005-03-11):
1676
+# Uruguay's DST was scheduled to end on Sunday, 2005-03-13, but in order to
1677
+# save energy ... it was postponed two weeks....
1678
+# http://www.presidencia.gub.uy/_Web/noticias/2005/03/2005031005.htm
1679
+Rule	Uruguay	2005	only	-	Mar	27	 2:00	0	-
1680
+# From Eduardo Cota (2005-09-27):
1681
+# http://www.presidencia.gub.uy/_Web/decretos/2005/09/CM%20119_09%2009%202005_00001.PDF
1682
+# This means that from 2005-10-09 at 02:00 local time, until 2006-03-12 at
1683
+# 02:00 local time, official time in Uruguay will be at GMT -2.
1684
+Rule	Uruguay	2005	only	-	Oct	 9	 2:00	1:00	S
1685
+Rule	Uruguay	2006	only	-	Mar	12	 2:00	0	-
1686
+# From Jesper Norgaard Welen (2006-09-06):
1687
+# http://www.presidencia.gub.uy/_web/decretos/2006/09/CM%20210_08%2006%202006_00001.PDF
1688
+Rule	Uruguay	2006	max	-	Oct	Sun>=1	 2:00	1:00	S
1689
+Rule	Uruguay	2007	max	-	Mar	Sun>=8	 2:00	0	-
1690
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1691
+Zone America/Montevideo	-3:44:44 -	LMT	1898 Jun 28
1692
+			-3:44:44 -	MMT	1920 May  1	# Montevideo MT
1693
+			-3:30	Uruguay	UY%sT	1942 Dec 14	# Uruguay Time
1694
+			-3:00	Uruguay	UY%sT
1695
+
1696
+# Venezuela
1697
+#
1698
+# From John Stainforth (2007-11-28):
1699
+# ... the change for Venezuela originally expected for 2007-12-31 has
1700
+# been brought forward to 2007-12-09.  The official announcement was
1701
+# published today in the "Gaceta Oficial de la Republica Bolivariana
1702
+# de Venezuela, numero 38.819" (official document for all laws or
1703
+# resolution publication)
1704
+# http://www.globovision.com/news.php?nid=72208
1705
+
1706
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
1707
+Zone	America/Caracas	-4:27:44 -	LMT	1890
1708
+			-4:27:40 -	CMT	1912 Feb 12 # Caracas Mean Time?
1709
+			-4:30	-	VET	1965	     # Venezuela Time
1710
+			-4:00	-	VET	2007 Dec  9 03:00
1711
+			-4:30	-	VET
... ...
@@ -0,0 +1,38 @@
1
+# <pre>
2
+# This file is in the public domain, so clarified as of
3
+# 2009-05-17 by Arthur David Olson.
4
+
5
+# Old rules, should the need arise.
6
+# No attempt is made to handle Newfoundland, since it cannot be expressed
7
+# using the System V "TZ" scheme (half-hour offset), or anything outside
8
+# North America (no support for non-standard DST start/end dates), nor
9
+# the changes in the DST rules in the US after 1976 (which occurred after
10
+# the old rules were written).
11
+#
12
+# If you need the old rules, uncomment ## lines.
13
+# Compile this *without* leap second correction for true conformance.
14
+
15
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
16
+Rule	SystemV	min	1973	-	Apr	lastSun	2:00	1:00	D
17
+Rule	SystemV	min	1973	-	Oct	lastSun	2:00	0	S
18
+Rule	SystemV	1974	only	-	Jan	6	2:00	1:00	D
19
+Rule	SystemV	1974	only	-	Nov	lastSun	2:00	0	S
20
+Rule	SystemV	1975	only	-	Feb	23	2:00	1:00	D
21
+Rule	SystemV	1975	only	-	Oct	lastSun	2:00	0	S
22
+Rule	SystemV	1976	max	-	Apr	lastSun	2:00	1:00	D
23
+Rule	SystemV	1976	max	-	Oct	lastSun	2:00	0	S
24
+
25
+# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
26
+## Zone	SystemV/AST4ADT	-4:00	SystemV		A%sT
27
+## Zone	SystemV/EST5EDT	-5:00	SystemV		E%sT
28
+## Zone	SystemV/CST6CDT	-6:00	SystemV		C%sT
29
+## Zone	SystemV/MST7MDT	-7:00	SystemV		M%sT
30
+## Zone	SystemV/PST8PDT	-8:00	SystemV		P%sT
31
+## Zone	SystemV/YST9YDT	-9:00	SystemV		Y%sT
32
+## Zone	SystemV/AST4	-4:00	-		AST
33
+## Zone	SystemV/EST5	-5:00	-		EST
34
+## Zone	SystemV/CST6	-6:00	-		CST
35
+## Zone	SystemV/MST7	-7:00	-		MST
36
+## Zone	SystemV/PST8	-8:00	-		PST
37
+## Zone	SystemV/YST9	-9:00	-		YST
38
+## Zone	SystemV/HST10	-10:00	-		HST
... ...
@@ -0,0 +1,38 @@
1
+#! /bin/sh
2
+
3
+: 'This file is in the public domain, so clarified as of'
4
+: '2006-07-17 by Arthur David Olson.'
5
+
6
+case $#-$1 in
7
+	2-|2-0*|2-*[!0-9]*)
8
+		echo "$0: wild year - $1" >&2
9
+		exit 1 ;;
10
+esac
11
+
12
+case $#-$2 in
13
+	2-even)
14
+		case $1 in
15
+			*[24680])			exit 0 ;;
16
+			*)				exit 1 ;;
17
+		esac ;;
18
+	2-nonpres|2-nonuspres)
19
+		case $1 in
20
+			*[02468][048]|*[13579][26])	exit 1 ;;
21
+			*)				exit 0 ;;
22
+		esac ;;
23
+	2-odd)
24
+		case $1 in
25
+			*[13579])			exit 0 ;;
26
+			*)				exit 1 ;;
27
+		esac ;;
28
+	2-uspres)
29
+		case $1 in
30
+			*[02468][048]|*[13579][26])	exit 0 ;;
31
+			*)				exit 1 ;;
32
+		esac ;;
33
+	2-*)
34
+		echo "$0: wild type - $2" >&2 ;;
35
+esac
36
+
37
+echo "$0: usage is $0 year even|odd|uspres|nonpres|nonuspres" >&2
38
+exit 1
... ...
@@ -0,0 +1,441 @@
1
+# <pre>
2
+# This file is in the public domain, so clarified as of
3
+# 2009-05-17 by Arthur David Olson.
4
+#
5
+# TZ zone descriptions
6
+#
7
+# From Paul Eggert (1996-08-05):
8
+#
9
+# This file contains a table with the following columns:
10
+# 1.  ISO 3166 2-character country code.  See the file `iso3166.tab'.
11
+# 2.  Latitude and longitude of the zone's principal location
12
+#     in ISO 6709 sign-degrees-minutes-seconds format,
13
+#     either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS,
14
+#     first latitude (+ is north), then longitude (+ is east).
15
+# 3.  Zone name used in value of TZ environment variable.
16
+# 4.  Comments; present if and only if the country has multiple rows.
17
+#
18
+# Columns are separated by a single tab.
19
+# The table is sorted first by country, then an order within the country that
20
+# (1) makes some geographical sense, and
21
+# (2) puts the most populous zones first, where that does not contradict (1).
22
+#
23
+# Lines beginning with `#' are comments.
24
+#
25
+#country-
26
+#code	coordinates	TZ			comments
27
+AD	+4230+00131	Europe/Andorra
28
+AE	+2518+05518	Asia/Dubai
29
+AF	+3431+06912	Asia/Kabul
30
+AG	+1703-06148	America/Antigua
31
+AI	+1812-06304	America/Anguilla
32
+AL	+4120+01950	Europe/Tirane
33
+AM	+4011+04430	Asia/Yerevan
34
+AO	-0848+01314	Africa/Luanda
35
+AQ	-7750+16636	Antarctica/McMurdo	McMurdo Station, Ross Island
36
+AQ	-9000+00000	Antarctica/South_Pole	Amundsen-Scott Station, South Pole
37
+AQ	-6734-06808	Antarctica/Rothera	Rothera Station, Adelaide Island
38
+AQ	-6448-06406	Antarctica/Palmer	Palmer Station, Anvers Island
39
+AQ	-6736+06253	Antarctica/Mawson	Mawson Station, Holme Bay
40
+AQ	-6835+07758	Antarctica/Davis	Davis Station, Vestfold Hills
41
+AQ	-6617+11031	Antarctica/Casey	Casey Station, Bailey Peninsula
42
+AQ	-7824+10654	Antarctica/Vostok	Vostok Station, Lake Vostok
43
+AQ	-6640+14001	Antarctica/DumontDUrville	Dumont-d'Urville Station, Terre Adelie
44
+AQ	-690022+0393524	Antarctica/Syowa	Syowa Station, E Ongul I
45
+AQ	-5430+15857	Antarctica/Macquarie	Macquarie Island Station, Macquarie Island
46
+AR	-3436-05827	America/Argentina/Buenos_Aires	Buenos Aires (BA, CF)
47
+AR	-3124-06411	America/Argentina/Cordoba	most locations (CB, CC, CN, ER, FM, MN, SE, SF)
48
+AR	-2447-06525	America/Argentina/Salta	(SA, LP, NQ, RN)
49
+AR	-2411-06518	America/Argentina/Jujuy	Jujuy (JY)
50
+AR	-2649-06513	America/Argentina/Tucuman	Tucuman (TM)
51
+AR	-2828-06547	America/Argentina/Catamarca	Catamarca (CT), Chubut (CH)
52
+AR	-2926-06651	America/Argentina/La_Rioja	La Rioja (LR)
53
+AR	-3132-06831	America/Argentina/San_Juan	San Juan (SJ)
54
+AR	-3253-06849	America/Argentina/Mendoza	Mendoza (MZ)
55
+AR	-3319-06621	America/Argentina/San_Luis	San Luis (SL)
56
+AR	-5138-06913	America/Argentina/Rio_Gallegos	Santa Cruz (SC)
57
+AR	-5448-06818	America/Argentina/Ushuaia	Tierra del Fuego (TF)
58
+AS	-1416-17042	Pacific/Pago_Pago
59
+AT	+4813+01620	Europe/Vienna
60
+AU	-3133+15905	Australia/Lord_Howe	Lord Howe Island
61
+AU	-4253+14719	Australia/Hobart	Tasmania - most locations
62
+AU	-3956+14352	Australia/Currie	Tasmania - King Island
63
+AU	-3749+14458	Australia/Melbourne	Victoria
64
+AU	-3352+15113	Australia/Sydney	New South Wales - most locations
65
+AU	-3157+14127	Australia/Broken_Hill	New South Wales - Yancowinna
66
+AU	-2728+15302	Australia/Brisbane	Queensland - most locations
67
+AU	-2016+14900	Australia/Lindeman	Queensland - Holiday Islands
68
+AU	-3455+13835	Australia/Adelaide	South Australia
69
+AU	-1228+13050	Australia/Darwin	Northern Territory
70
+AU	-3157+11551	Australia/Perth	Western Australia - most locations
71
+AU	-3143+12852	Australia/Eucla	Western Australia - Eucla area
72
+AW	+1230-06958	America/Aruba
73
+AX	+6006+01957	Europe/Mariehamn
74
+AZ	+4023+04951	Asia/Baku
75
+BA	+4352+01825	Europe/Sarajevo
76
+BB	+1306-05937	America/Barbados
77
+BD	+2343+09025	Asia/Dhaka
78
+BE	+5050+00420	Europe/Brussels
79
+BF	+1222-00131	Africa/Ouagadougou
80
+BG	+4241+02319	Europe/Sofia
81
+BH	+2623+05035	Asia/Bahrain
82
+BI	-0323+02922	Africa/Bujumbura
83
+BJ	+0629+00237	Africa/Porto-Novo
84
+BL	+1753-06251	America/St_Barthelemy
85
+BM	+3217-06446	Atlantic/Bermuda
86
+BN	+0456+11455	Asia/Brunei
87
+BO	-1630-06809	America/La_Paz
88
+BQ	+120903-0681636	America/Kralendijk
89
+BR	-0351-03225	America/Noronha	Atlantic islands
90
+BR	-0127-04829	America/Belem	Amapa, E Para
91
+BR	-0343-03830	America/Fortaleza	NE Brazil (MA, PI, CE, RN, PB)
92
+BR	-0803-03454	America/Recife	Pernambuco
93
+BR	-0712-04812	America/Araguaina	Tocantins
94
+BR	-0940-03543	America/Maceio	Alagoas, Sergipe
95
+BR	-1259-03831	America/Bahia	Bahia
96
+BR	-2332-04637	America/Sao_Paulo	S & SE Brazil (GO, DF, MG, ES, RJ, SP, PR, SC, RS)
97
+BR	-2027-05437	America/Campo_Grande	Mato Grosso do Sul
98
+BR	-1535-05605	America/Cuiaba	Mato Grosso
99
+BR	-0226-05452	America/Santarem	W Para
100
+BR	-0846-06354	America/Porto_Velho	Rondonia
101
+BR	+0249-06040	America/Boa_Vista	Roraima
102
+BR	-0308-06001	America/Manaus	E Amazonas
103
+BR	-0640-06952	America/Eirunepe	W Amazonas
104
+BR	-0958-06748	America/Rio_Branco	Acre
105
+BS	+2505-07721	America/Nassau
106
+BT	+2728+08939	Asia/Thimphu
107
+BW	-2439+02555	Africa/Gaborone
108
+BY	+5354+02734	Europe/Minsk
109
+BZ	+1730-08812	America/Belize
110
+CA	+4734-05243	America/St_Johns	Newfoundland Time, including SE Labrador
111
+CA	+4439-06336	America/Halifax	Atlantic Time - Nova Scotia (most places), PEI
112
+CA	+4612-05957	America/Glace_Bay	Atlantic Time - Nova Scotia - places that did not observe DST 1966-1971
113
+CA	+4606-06447	America/Moncton	Atlantic Time - New Brunswick
114
+CA	+5320-06025	America/Goose_Bay	Atlantic Time - Labrador - most locations
115
+CA	+5125-05707	America/Blanc-Sablon	Atlantic Standard Time - Quebec - Lower North Shore
116
+CA	+4531-07334	America/Montreal	Eastern Time - Quebec - most locations
117
+CA	+4339-07923	America/Toronto	Eastern Time - Ontario - most locations
118
+CA	+4901-08816	America/Nipigon	Eastern Time - Ontario & Quebec - places that did not observe DST 1967-1973
119
+CA	+4823-08915	America/Thunder_Bay	Eastern Time - Thunder Bay, Ontario
120
+CA	+6344-06828	America/Iqaluit	Eastern Time - east Nunavut - most locations
121
+CA	+6608-06544	America/Pangnirtung	Eastern Time - Pangnirtung, Nunavut
122
+CA	+744144-0944945	America/Resolute	Central Standard Time - Resolute, Nunavut
123
+CA	+484531-0913718	America/Atikokan	Eastern Standard Time - Atikokan, Ontario and Southampton I, Nunavut
124
+CA	+624900-0920459	America/Rankin_Inlet	Central Time - central Nunavut
125
+CA	+4953-09709	America/Winnipeg	Central Time - Manitoba & west Ontario
126
+CA	+4843-09434	America/Rainy_River	Central Time - Rainy River & Fort Frances, Ontario
127
+CA	+5024-10439	America/Regina	Central Standard Time - Saskatchewan - most locations
128
+CA	+5017-10750	America/Swift_Current	Central Standard Time - Saskatchewan - midwest
129
+CA	+5333-11328	America/Edmonton	Mountain Time - Alberta, east British Columbia & west Saskatchewan
130
+CA	+690650-1050310	America/Cambridge_Bay	Mountain Time - west Nunavut
131
+CA	+6227-11421	America/Yellowknife	Mountain Time - central Northwest Territories
132
+CA	+682059-1334300	America/Inuvik	Mountain Time - west Northwest Territories
133
+CA	+4906-11631	America/Creston	Mountain Standard Time - Creston, British Columbia
134
+CA	+5946-12014	America/Dawson_Creek	Mountain Standard Time - Dawson Creek & Fort Saint John, British Columbia
135
+CA	+4916-12307	America/Vancouver	Pacific Time - west British Columbia
136
+CA	+6043-13503	America/Whitehorse	Pacific Time - south Yukon
137
+CA	+6404-13925	America/Dawson	Pacific Time - north Yukon
138
+CC	-1210+09655	Indian/Cocos
139
+CD	-0418+01518	Africa/Kinshasa	west Dem. Rep. of Congo
140
+CD	-1140+02728	Africa/Lubumbashi	east Dem. Rep. of Congo
141
+CF	+0422+01835	Africa/Bangui
142
+CG	-0416+01517	Africa/Brazzaville
143
+CH	+4723+00832	Europe/Zurich
144
+CI	+0519-00402	Africa/Abidjan
145
+CK	-2114-15946	Pacific/Rarotonga
146
+CL	-3327-07040	America/Santiago	most locations
147
+CL	-2709-10926	Pacific/Easter	Easter Island & Sala y Gomez
148
+CM	+0403+00942	Africa/Douala
149
+CN	+3114+12128	Asia/Shanghai	east China - Beijing, Guangdong, Shanghai, etc.
150
+CN	+4545+12641	Asia/Harbin	Heilongjiang (except Mohe), Jilin
151
+CN	+2934+10635	Asia/Chongqing	central China - Sichuan, Yunnan, Guangxi, Shaanxi, Guizhou, etc.
152
+CN	+4348+08735	Asia/Urumqi	most of Tibet & Xinjiang
153
+CN	+3929+07559	Asia/Kashgar	west Tibet & Xinjiang
154
+CO	+0436-07405	America/Bogota
155
+CR	+0956-08405	America/Costa_Rica
156
+CU	+2308-08222	America/Havana
157
+CV	+1455-02331	Atlantic/Cape_Verde
158
+CW	+1211-06900	America/Curacao
159
+CX	-1025+10543	Indian/Christmas
160
+CY	+3510+03322	Asia/Nicosia
161
+CZ	+5005+01426	Europe/Prague
162
+DE	+5230+01322	Europe/Berlin
163
+DJ	+1136+04309	Africa/Djibouti
164
+DK	+5540+01235	Europe/Copenhagen
165
+DM	+1518-06124	America/Dominica
166
+DO	+1828-06954	America/Santo_Domingo
167
+DZ	+3647+00303	Africa/Algiers
168
+EC	-0210-07950	America/Guayaquil	mainland
169
+EC	-0054-08936	Pacific/Galapagos	Galapagos Islands
170
+EE	+5925+02445	Europe/Tallinn
171
+EG	+3003+03115	Africa/Cairo
172
+EH	+2709-01312	Africa/El_Aaiun
173
+ER	+1520+03853	Africa/Asmara
174
+ES	+4024-00341	Europe/Madrid	mainland
175
+ES	+3553-00519	Africa/Ceuta	Ceuta & Melilla
176
+ES	+2806-01524	Atlantic/Canary	Canary Islands
177
+ET	+0902+03842	Africa/Addis_Ababa
178
+FI	+6010+02458	Europe/Helsinki
179
+FJ	-1808+17825	Pacific/Fiji
180
+FK	-5142-05751	Atlantic/Stanley
181
+FM	+0725+15147	Pacific/Chuuk	Chuuk (Truk) and Yap
182
+FM	+0658+15813	Pacific/Pohnpei	Pohnpei (Ponape)
183
+FM	+0519+16259	Pacific/Kosrae	Kosrae
184
+FO	+6201-00646	Atlantic/Faroe
185
+FR	+4852+00220	Europe/Paris
186
+GA	+0023+00927	Africa/Libreville
187
+GB	+513030-0000731	Europe/London
188
+GD	+1203-06145	America/Grenada
189
+GE	+4143+04449	Asia/Tbilisi
190
+GF	+0456-05220	America/Cayenne
191
+GG	+4927-00232	Europe/Guernsey
192
+GH	+0533-00013	Africa/Accra
193
+GI	+3608-00521	Europe/Gibraltar
194
+GL	+6411-05144	America/Godthab	most locations
195
+GL	+7646-01840	America/Danmarkshavn	east coast, north of Scoresbysund
196
+GL	+7029-02158	America/Scoresbysund	Scoresbysund / Ittoqqortoormiit
197
+GL	+7634-06847	America/Thule	Thule / Pituffik
198
+GM	+1328-01639	Africa/Banjul
199
+GN	+0931-01343	Africa/Conakry
200
+GP	+1614-06132	America/Guadeloupe
201
+GQ	+0345+00847	Africa/Malabo
202
+GR	+3758+02343	Europe/Athens
203
+GS	-5416-03632	Atlantic/South_Georgia
204
+GT	+1438-09031	America/Guatemala
205
+GU	+1328+14445	Pacific/Guam
206
+GW	+1151-01535	Africa/Bissau
207
+GY	+0648-05810	America/Guyana
208
+HK	+2217+11409	Asia/Hong_Kong
209
+HN	+1406-08713	America/Tegucigalpa
210
+HR	+4548+01558	Europe/Zagreb
211
+HT	+1832-07220	America/Port-au-Prince
212
+HU	+4730+01905	Europe/Budapest
213
+ID	-0610+10648	Asia/Jakarta	Java & Sumatra
214
+ID	-0002+10920	Asia/Pontianak	west & central Borneo
215
+ID	-0507+11924	Asia/Makassar	east & south Borneo, Sulawesi (Celebes), Bali, Nusa Tengarra, west Timor
216
+ID	-0232+14042	Asia/Jayapura	west New Guinea (Irian Jaya) & Malukus (Moluccas)
217
+IE	+5320-00615	Europe/Dublin
218
+IL	+3146+03514	Asia/Jerusalem
219
+IM	+5409-00428	Europe/Isle_of_Man
220
+IN	+2232+08822	Asia/Kolkata
221
+IO	-0720+07225	Indian/Chagos
222
+IQ	+3321+04425	Asia/Baghdad
223
+IR	+3540+05126	Asia/Tehran
224
+IS	+6409-02151	Atlantic/Reykjavik
225
+IT	+4154+01229	Europe/Rome
226
+JE	+4912-00207	Europe/Jersey
227
+JM	+1800-07648	America/Jamaica
228
+JO	+3157+03556	Asia/Amman
229
+JP	+353916+1394441	Asia/Tokyo
230
+KE	-0117+03649	Africa/Nairobi
231
+KG	+4254+07436	Asia/Bishkek
232
+KH	+1133+10455	Asia/Phnom_Penh
233
+KI	+0125+17300	Pacific/Tarawa	Gilbert Islands
234
+KI	-0308-17105	Pacific/Enderbury	Phoenix Islands
235
+KI	+0152-15720	Pacific/Kiritimati	Line Islands
236
+KM	-1141+04316	Indian/Comoro
237
+KN	+1718-06243	America/St_Kitts
238
+KP	+3901+12545	Asia/Pyongyang
239
+KR	+3733+12658	Asia/Seoul
240
+KW	+2920+04759	Asia/Kuwait
241
+KY	+1918-08123	America/Cayman
242
+KZ	+4315+07657	Asia/Almaty	most locations
243
+KZ	+4448+06528	Asia/Qyzylorda	Qyzylorda (Kyzylorda, Kzyl-Orda)
244
+KZ	+5017+05710	Asia/Aqtobe	Aqtobe (Aktobe)
245
+KZ	+4431+05016	Asia/Aqtau	Atyrau (Atirau, Gur'yev), Mangghystau (Mankistau)
246
+KZ	+5113+05121	Asia/Oral	West Kazakhstan
247
+LA	+1758+10236	Asia/Vientiane
248
+LB	+3353+03530	Asia/Beirut
249
+LC	+1401-06100	America/St_Lucia
250
+LI	+4709+00931	Europe/Vaduz
251
+LK	+0656+07951	Asia/Colombo
252
+LR	+0618-01047	Africa/Monrovia
253
+LS	-2928+02730	Africa/Maseru
254
+LT	+5441+02519	Europe/Vilnius
255
+LU	+4936+00609	Europe/Luxembourg
256
+LV	+5657+02406	Europe/Riga
257
+LY	+3254+01311	Africa/Tripoli
258
+MA	+3339-00735	Africa/Casablanca
259
+MC	+4342+00723	Europe/Monaco
260
+MD	+4700+02850	Europe/Chisinau
261
+ME	+4226+01916	Europe/Podgorica
262
+MF	+1804-06305	America/Marigot
263
+MG	-1855+04731	Indian/Antananarivo
264
+MH	+0709+17112	Pacific/Majuro	most locations
265
+MH	+0905+16720	Pacific/Kwajalein	Kwajalein
266
+MK	+4159+02126	Europe/Skopje
267
+ML	+1239-00800	Africa/Bamako
268
+MM	+1647+09610	Asia/Rangoon
269
+MN	+4755+10653	Asia/Ulaanbaatar	most locations
270
+MN	+4801+09139	Asia/Hovd	Bayan-Olgiy, Govi-Altai, Hovd, Uvs, Zavkhan
271
+MN	+4804+11430	Asia/Choibalsan	Dornod, Sukhbaatar
272
+MO	+2214+11335	Asia/Macau
273
+MP	+1512+14545	Pacific/Saipan
274
+MQ	+1436-06105	America/Martinique
275
+MR	+1806-01557	Africa/Nouakchott
276
+MS	+1643-06213	America/Montserrat
277
+MT	+3554+01431	Europe/Malta
278
+MU	-2010+05730	Indian/Mauritius
279
+MV	+0410+07330	Indian/Maldives
280
+MW	-1547+03500	Africa/Blantyre
281
+MX	+1924-09909	America/Mexico_City	Central Time - most locations
282
+MX	+2105-08646	America/Cancun	Central Time - Quintana Roo
283
+MX	+2058-08937	America/Merida	Central Time - Campeche, Yucatan
284
+MX	+2540-10019	America/Monterrey	Mexican Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas away from US border
285
+MX	+2550-09730	America/Matamoros	US Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas near US border
286
+MX	+2313-10625	America/Mazatlan	Mountain Time - S Baja, Nayarit, Sinaloa
287
+MX	+2838-10605	America/Chihuahua	Mexican Mountain Time - Chihuahua away from US border
288
+MX	+2934-10425	America/Ojinaga	US Mountain Time - Chihuahua near US border
289
+MX	+2904-11058	America/Hermosillo	Mountain Standard Time - Sonora
290
+MX	+3232-11701	America/Tijuana	US Pacific Time - Baja California near US border
291
+MX	+3018-11452	America/Santa_Isabel	Mexican Pacific Time - Baja California away from US border
292
+MX	+2048-10515	America/Bahia_Banderas	Mexican Central Time - Bahia de Banderas
293
+MY	+0310+10142	Asia/Kuala_Lumpur	peninsular Malaysia
294
+MY	+0133+11020	Asia/Kuching	Sabah & Sarawak
295
+MZ	-2558+03235	Africa/Maputo
296
+NA	-2234+01706	Africa/Windhoek
297
+NC	-2216+16627	Pacific/Noumea
298
+NE	+1331+00207	Africa/Niamey
299
+NF	-2903+16758	Pacific/Norfolk
300
+NG	+0627+00324	Africa/Lagos
301
+NI	+1209-08617	America/Managua
302
+NL	+5222+00454	Europe/Amsterdam
303
+NO	+5955+01045	Europe/Oslo
304
+NP	+2743+08519	Asia/Kathmandu
305
+NR	-0031+16655	Pacific/Nauru
306
+NU	-1901-16955	Pacific/Niue
307
+NZ	-3652+17446	Pacific/Auckland	most locations
308
+NZ	-4357-17633	Pacific/Chatham	Chatham Islands
309
+OM	+2336+05835	Asia/Muscat
310
+PA	+0858-07932	America/Panama
311
+PE	-1203-07703	America/Lima
312
+PF	-1732-14934	Pacific/Tahiti	Society Islands
313
+PF	-0900-13930	Pacific/Marquesas	Marquesas Islands
314
+PF	-2308-13457	Pacific/Gambier	Gambier Islands
315
+PG	-0930+14710	Pacific/Port_Moresby
316
+PH	+1435+12100	Asia/Manila
317
+PK	+2452+06703	Asia/Karachi
318
+PL	+5215+02100	Europe/Warsaw
319
+PM	+4703-05620	America/Miquelon
320
+PN	-2504-13005	Pacific/Pitcairn
321
+PR	+182806-0660622	America/Puerto_Rico
322
+PS	+3130+03428	Asia/Gaza	Gaza Strip
323
+PS	+313200+0350542	Asia/Hebron	West Bank
324
+PT	+3843-00908	Europe/Lisbon	mainland
325
+PT	+3238-01654	Atlantic/Madeira	Madeira Islands
326
+PT	+3744-02540	Atlantic/Azores	Azores
327
+PW	+0720+13429	Pacific/Palau
328
+PY	-2516-05740	America/Asuncion
329
+QA	+2517+05132	Asia/Qatar
330
+RE	-2052+05528	Indian/Reunion
331
+RO	+4426+02606	Europe/Bucharest
332
+RS	+4450+02030	Europe/Belgrade
333
+RU	+5443+02030	Europe/Kaliningrad	Moscow-01 - Kaliningrad
334
+RU	+5545+03735	Europe/Moscow	Moscow+00 - west Russia
335
+RU	+4844+04425	Europe/Volgograd	Moscow+00 - Caspian Sea
336
+RU	+5312+05009	Europe/Samara	Moscow+00 - Samara, Udmurtia
337
+RU	+5651+06036	Asia/Yekaterinburg	Moscow+02 - Urals
338
+RU	+5500+07324	Asia/Omsk	Moscow+03 - west Siberia
339
+RU	+5502+08255	Asia/Novosibirsk	Moscow+03 - Novosibirsk
340
+RU	+5345+08707	Asia/Novokuznetsk	Moscow+03 - Novokuznetsk
341
+RU	+5601+09250	Asia/Krasnoyarsk	Moscow+04 - Yenisei River
342
+RU	+5216+10420	Asia/Irkutsk	Moscow+05 - Lake Baikal
343
+RU	+6200+12940	Asia/Yakutsk	Moscow+06 - Lena River
344
+RU	+4310+13156	Asia/Vladivostok	Moscow+07 - Amur River
345
+RU	+4658+14242	Asia/Sakhalin	Moscow+07 - Sakhalin Island
346
+RU	+5934+15048	Asia/Magadan	Moscow+08 - Magadan
347
+RU	+5301+15839	Asia/Kamchatka	Moscow+08 - Kamchatka
348
+RU	+6445+17729	Asia/Anadyr	Moscow+08 - Bering Sea
349
+RW	-0157+03004	Africa/Kigali
350
+SA	+2438+04643	Asia/Riyadh
351
+SB	-0932+16012	Pacific/Guadalcanal
352
+SC	-0440+05528	Indian/Mahe
353
+SD	+1536+03232	Africa/Khartoum
354
+SE	+5920+01803	Europe/Stockholm
355
+SG	+0117+10351	Asia/Singapore
356
+SH	-1555-00542	Atlantic/St_Helena
357
+SI	+4603+01431	Europe/Ljubljana
358
+SJ	+7800+01600	Arctic/Longyearbyen
359
+SK	+4809+01707	Europe/Bratislava
360
+SL	+0830-01315	Africa/Freetown
361
+SM	+4355+01228	Europe/San_Marino
362
+SN	+1440-01726	Africa/Dakar
363
+SO	+0204+04522	Africa/Mogadishu
364
+SR	+0550-05510	America/Paramaribo
365
+SS	+0451+03136	Africa/Juba
366
+ST	+0020+00644	Africa/Sao_Tome
367
+SV	+1342-08912	America/El_Salvador
368
+SX	+180305-0630250	America/Lower_Princes
369
+SY	+3330+03618	Asia/Damascus
370
+SZ	-2618+03106	Africa/Mbabane
371
+TC	+2128-07108	America/Grand_Turk
372
+TD	+1207+01503	Africa/Ndjamena
373
+TF	-492110+0701303	Indian/Kerguelen
374
+TG	+0608+00113	Africa/Lome
375
+TH	+1345+10031	Asia/Bangkok
376
+TJ	+3835+06848	Asia/Dushanbe
377
+TK	-0922-17114	Pacific/Fakaofo
378
+TL	-0833+12535	Asia/Dili
379
+TM	+3757+05823	Asia/Ashgabat
380
+TN	+3648+01011	Africa/Tunis
381
+TO	-2110-17510	Pacific/Tongatapu
382
+TR	+4101+02858	Europe/Istanbul
383
+TT	+1039-06131	America/Port_of_Spain
384
+TV	-0831+17913	Pacific/Funafuti
385
+TW	+2503+12130	Asia/Taipei
386
+TZ	-0648+03917	Africa/Dar_es_Salaam
387
+UA	+5026+03031	Europe/Kiev	most locations
388
+UA	+4837+02218	Europe/Uzhgorod	Ruthenia
389
+UA	+4750+03510	Europe/Zaporozhye	Zaporozh'ye, E Lugansk / Zaporizhia, E Luhansk
390
+UA	+4457+03406	Europe/Simferopol	central Crimea
391
+UG	+0019+03225	Africa/Kampala
392
+UM	+1645-16931	Pacific/Johnston	Johnston Atoll
393
+UM	+2813-17722	Pacific/Midway	Midway Islands
394
+UM	+1917+16637	Pacific/Wake	Wake Island
395
+US	+404251-0740023	America/New_York	Eastern Time
396
+US	+421953-0830245	America/Detroit	Eastern Time - Michigan - most locations
397
+US	+381515-0854534	America/Kentucky/Louisville	Eastern Time - Kentucky - Louisville area
398
+US	+364947-0845057	America/Kentucky/Monticello	Eastern Time - Kentucky - Wayne County
399
+US	+394606-0860929	America/Indiana/Indianapolis	Eastern Time - Indiana - most locations
400
+US	+384038-0873143	America/Indiana/Vincennes	Eastern Time - Indiana - Daviess, Dubois, Knox & Martin Counties
401
+US	+410305-0863611	America/Indiana/Winamac	Eastern Time - Indiana - Pulaski County
402
+US	+382232-0862041	America/Indiana/Marengo	Eastern Time - Indiana - Crawford County
403
+US	+382931-0871643	America/Indiana/Petersburg	Eastern Time - Indiana - Pike County
404
+US	+384452-0850402	America/Indiana/Vevay	Eastern Time - Indiana - Switzerland County
405
+US	+415100-0873900	America/Chicago	Central Time
406
+US	+375711-0864541	America/Indiana/Tell_City	Central Time - Indiana - Perry County
407
+US	+411745-0863730	America/Indiana/Knox	Central Time - Indiana - Starke County
408
+US	+450628-0873651	America/Menominee	Central Time - Michigan - Dickinson, Gogebic, Iron & Menominee Counties
409
+US	+470659-1011757	America/North_Dakota/Center	Central Time - North Dakota - Oliver County
410
+US	+465042-1012439	America/North_Dakota/New_Salem	Central Time - North Dakota - Morton County (except Mandan area)
411
+US	+471551-1014640	America/North_Dakota/Beulah	Central Time - North Dakota - Mercer County
412
+US	+394421-1045903	America/Denver	Mountain Time
413
+US	+433649-1161209	America/Boise	Mountain Time - south Idaho & east Oregon
414
+US	+364708-1084111	America/Shiprock	Mountain Time - Navajo
415
+US	+332654-1120424	America/Phoenix	Mountain Standard Time - Arizona
416
+US	+340308-1181434	America/Los_Angeles	Pacific Time
417
+US	+611305-1495401	America/Anchorage	Alaska Time
418
+US	+581807-1342511	America/Juneau	Alaska Time - Alaska panhandle
419
+US	+571035-1351807	America/Sitka	Alaska Time - southeast Alaska panhandle
420
+US	+593249-1394338	America/Yakutat	Alaska Time - Alaska panhandle neck
421
+US	+643004-1652423	America/Nome	Alaska Time - west Alaska
422
+US	+515248-1763929	America/Adak	Aleutian Islands
423
+US	+550737-1313435	America/Metlakatla	Metlakatla Time - Annette Island
424
+US	+211825-1575130	Pacific/Honolulu	Hawaii
425
+UY	-3453-05611	America/Montevideo
426
+UZ	+3940+06648	Asia/Samarkand	west Uzbekistan
427
+UZ	+4120+06918	Asia/Tashkent	east Uzbekistan
428
+VA	+415408+0122711	Europe/Vatican
429
+VC	+1309-06114	America/St_Vincent
430
+VE	+1030-06656	America/Caracas
431
+VG	+1827-06437	America/Tortola
432
+VI	+1821-06456	America/St_Thomas
433
+VN	+1045+10640	Asia/Ho_Chi_Minh
434
+VU	-1740+16825	Pacific/Efate
435
+WF	-1318-17610	Pacific/Wallis
436
+WS	-1350-17144	Pacific/Apia
437
+YE	+1245+04512	Asia/Aden
438
+YT	-1247+04514	Indian/Mayotte
439
+ZA	-2615+02800	Africa/Johannesburg
440
+ZM	-1525+02817	Africa/Lusaka
441
+ZW	-1750+03103	Africa/Harare
... ...
@@ -0,0 +1,137 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Time Axes</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.time.js"></script>
11
+	<script type="text/javascript">
12
+
13
+	$(function() {
14
+
15
+		var d = [[-373597200000, 315.71], [-370918800000, 317.45], [-368326800000, 317.50], [-363056400000, 315.86], [-360378000000, 314.93], [-357699600000, 313.19], [-352429200000, 313.34], [-349837200000, 314.67], [-347158800000, 315.58], [-344480400000, 316.47], [-342061200000, 316.65], [-339382800000, 317.71], [-336790800000, 318.29], [-334112400000, 318.16], [-331520400000, 316.55], [-328842000000, 314.80], [-326163600000, 313.84], [-323571600000, 313.34], [-320893200000, 314.81], [-318301200000, 315.59], [-315622800000, 316.43], [-312944400000, 316.97], [-310438800000, 317.58], [-307760400000, 319.03], [-305168400000, 320.03], [-302490000000, 319.59], [-299898000000, 318.18], [-297219600000, 315.91], [-294541200000, 314.16], [-291949200000, 313.83], [-289270800000, 315.00], [-286678800000, 316.19], [-284000400000, 316.89], [-281322000000, 317.70], [-278902800000, 318.54], [-276224400000, 319.48], [-273632400000, 320.58], [-270954000000, 319.78], [-268362000000, 318.58], [-265683600000, 316.79], [-263005200000, 314.99], [-260413200000, 315.31], [-257734800000, 316.10], [-255142800000, 317.01], [-252464400000, 317.94], [-249786000000, 318.56], [-247366800000, 319.69], [-244688400000, 320.58], [-242096400000, 321.01], [-239418000000, 320.61], [-236826000000, 319.61], [-234147600000, 317.40], [-231469200000, 316.26], [-228877200000, 315.42], [-226198800000, 316.69], [-223606800000, 317.69], [-220928400000, 318.74], [-218250000000, 319.08], [-215830800000, 319.86], [-213152400000, 321.39], [-210560400000, 322.24], [-207882000000, 321.47], [-205290000000, 319.74], [-202611600000, 317.77], [-199933200000, 316.21], [-197341200000, 315.99], [-194662800000, 317.07], [-192070800000, 318.36], [-189392400000, 319.57], [-178938000000, 322.23], [-176259600000, 321.89], [-173667600000, 320.44], [-170989200000, 318.70], [-168310800000, 316.70], [-165718800000, 316.87], [-163040400000, 317.68], [-160448400000, 318.71], [-157770000000, 319.44], [-155091600000, 320.44], [-152672400000, 320.89], [-149994000000, 322.13], [-147402000000, 322.16], [-144723600000, 321.87], [-142131600000, 321.21], [-139453200000, 318.87], [-136774800000, 317.81], [-134182800000, 317.30], [-131504400000, 318.87], [-128912400000, 319.42], [-126234000000, 320.62], [-123555600000, 321.59], [-121136400000, 322.39], [-118458000000, 323.70], [-115866000000, 324.07], [-113187600000, 323.75], [-110595600000, 322.40], [-107917200000, 320.37], [-105238800000, 318.64], [-102646800000, 318.10], [-99968400000, 319.79], [-97376400000, 321.03], [-94698000000, 322.33], [-92019600000, 322.50], [-89600400000, 323.04], [-86922000000, 324.42], [-84330000000, 325.00], [-81651600000, 324.09], [-79059600000, 322.55], [-76381200000, 320.92], [-73702800000, 319.26], [-71110800000, 319.39], [-68432400000, 320.72], [-65840400000, 321.96], [-63162000000, 322.57], [-60483600000, 323.15], [-57978000000, 323.89], [-55299600000, 325.02], [-52707600000, 325.57], [-50029200000, 325.36], [-47437200000, 324.14], [-44758800000, 322.11], [-42080400000, 320.33], [-39488400000, 320.25], [-36810000000, 321.32], [-34218000000, 322.90], [-31539600000, 324.00], [-28861200000, 324.42], [-26442000000, 325.64], [-23763600000, 326.66], [-21171600000, 327.38], [-18493200000, 326.70], [-15901200000, 325.89], [-13222800000, 323.67], [-10544400000, 322.38], [-7952400000, 321.78], [-5274000000, 322.85], [-2682000000, 324.12], [-3600000, 325.06], [2674800000, 325.98], [5094000000, 326.93], [7772400000, 328.13], [10364400000, 328.07], [13042800000, 327.66], [15634800000, 326.35], [18313200000, 324.69], [20991600000, 323.10], [23583600000, 323.07], [26262000000, 324.01], [28854000000, 325.13], [31532400000, 326.17], [34210800000, 326.68], [36630000000, 327.18], [39308400000, 327.78], [41900400000, 328.92], [44578800000, 328.57], [47170800000, 327.37], [49849200000, 325.43], [52527600000, 323.36], [55119600000, 323.56], [57798000000, 324.80], [60390000000, 326.01], [63068400000, 326.77], [65746800000, 327.63], [68252400000, 327.75], [70930800000, 329.72], [73522800000, 330.07], [76201200000, 329.09], [78793200000, 328.05], [81471600000, 326.32], [84150000000, 324.84], [86742000000, 325.20], [89420400000, 326.50], [92012400000, 327.55], [94690800000, 328.54], [97369200000, 329.56], [99788400000, 330.30], [102466800000, 331.50], [105058800000, 332.48], [107737200000, 332.07], [110329200000, 330.87], [113007600000, 329.31], [115686000000, 327.51], [118278000000, 327.18], [120956400000, 328.16], [123548400000, 328.64], [126226800000, 329.35], [128905200000, 330.71], [131324400000, 331.48], [134002800000, 332.65], [136594800000, 333.16], [139273200000, 332.06], [141865200000, 330.99], [144543600000, 329.17], [147222000000, 327.41], [149814000000, 327.20], [152492400000, 328.33], [155084400000, 329.50], [157762800000, 330.68], [160441200000, 331.41], [162860400000, 331.85], [165538800000, 333.29], [168130800000, 333.91], [170809200000, 333.40], [173401200000, 331.78], [176079600000, 329.88], [178758000000, 328.57], [181350000000, 328.46], [184028400000, 329.26], [189298800000, 331.71], [191977200000, 332.76], [194482800000, 333.48], [197161200000, 334.78], [199753200000, 334.78], [202431600000, 334.17], [205023600000, 332.78], [207702000000, 330.64], [210380400000, 328.95], [212972400000, 328.77], [215650800000, 330.23], [218242800000, 331.69], [220921200000, 332.70], [223599600000, 333.24], [226018800000, 334.96], [228697200000, 336.04], [231289200000, 336.82], [233967600000, 336.13], [236559600000, 334.73], [239238000000, 332.52], [241916400000, 331.19], [244508400000, 331.19], [247186800000, 332.35], [249778800000, 333.47], [252457200000, 335.11], [255135600000, 335.26], [257554800000, 336.60], [260233200000, 337.77], [262825200000, 338.00], [265503600000, 337.99], [268095600000, 336.48], [270774000000, 334.37], [273452400000, 332.27], [276044400000, 332.41], [278722800000, 333.76], [281314800000, 334.83], [283993200000, 336.21], [286671600000, 336.64], [289090800000, 338.12], [291769200000, 339.02], [294361200000, 339.02], [297039600000, 339.20], [299631600000, 337.58], [302310000000, 335.55], [304988400000, 333.89], [307580400000, 334.14], [310258800000, 335.26], [312850800000, 336.71], [315529200000, 337.81], [318207600000, 338.29], [320713200000, 340.04], [323391600000, 340.86], [325980000000, 341.47], [328658400000, 341.26], [331250400000, 339.29], [333928800000, 337.60], [336607200000, 336.12], [339202800000, 336.08], [341881200000, 337.22], [344473200000, 338.34], [347151600000, 339.36], [349830000000, 340.51], [352249200000, 341.57], [354924000000, 342.56], [357516000000, 343.01], [360194400000, 342.47], [362786400000, 340.71], [365464800000, 338.52], [368143200000, 336.96], [370738800000, 337.13], [373417200000, 338.58], [376009200000, 339.89], [378687600000, 340.93], [381366000000, 341.69], [383785200000, 342.69], [389052000000, 344.30], [391730400000, 343.43], [394322400000, 341.88], [397000800000, 339.89], [399679200000, 337.95], [402274800000, 338.10], [404953200000, 339.27], [407545200000, 340.67], [410223600000, 341.42], [412902000000, 342.68], [415321200000, 343.46], [417996000000, 345.10], [420588000000, 345.76], [423266400000, 345.36], [425858400000, 343.91], [428536800000, 342.05], [431215200000, 340.00], [433810800000, 340.12], [436489200000, 341.33], [439081200000, 342.94], [441759600000, 343.87], [444438000000, 344.60], [446943600000, 345.20], [452210400000, 347.36], [454888800000, 346.74], [457480800000, 345.41], [460159200000, 343.01], [462837600000, 341.23], [465433200000, 341.52], [468111600000, 342.86], [470703600000, 344.41], [473382000000, 345.09], [476060400000, 345.89], [478479600000, 347.49], [481154400000, 348.00], [483746400000, 348.75], [486424800000, 348.19], [489016800000, 346.54], [491695200000, 344.63], [494373600000, 343.03], [496969200000, 342.92], [499647600000, 344.24], [502239600000, 345.62], [504918000000, 346.43], [507596400000, 346.94], [510015600000, 347.88], [512690400000, 349.57], [515282400000, 350.35], [517960800000, 349.72], [520552800000, 347.78], [523231200000, 345.86], [525909600000, 344.84], [528505200000, 344.32], [531183600000, 345.67], [533775600000, 346.88], [536454000000, 348.19], [539132400000, 348.55], [541551600000, 349.52], [544226400000, 351.12], [546818400000, 351.84], [549496800000, 351.49], [552088800000, 349.82], [554767200000, 347.63], [557445600000, 346.38], [560041200000, 346.49], [562719600000, 347.75], [565311600000, 349.03], [567990000000, 350.20], [570668400000, 351.61], [573174000000, 352.22], [575848800000, 353.53], [578440800000, 354.14], [581119200000, 353.62], [583711200000, 352.53], [586389600000, 350.41], [589068000000, 348.84], [591663600000, 348.94], [594342000000, 350.04], [596934000000, 351.29], [599612400000, 352.72], [602290800000, 353.10], [604710000000, 353.65], [607384800000, 355.43], [609976800000, 355.70], [612655200000, 355.11], [615247200000, 353.79], [617925600000, 351.42], [620604000000, 349.81], [623199600000, 350.11], [625878000000, 351.26], [628470000000, 352.63], [631148400000, 353.64], [633826800000, 354.72], [636246000000, 355.49], [638920800000, 356.09], [641512800000, 357.08], [644191200000, 356.11], [646783200000, 354.70], [649461600000, 352.68], [652140000000, 351.05], [654735600000, 351.36], [657414000000, 352.81], [660006000000, 354.22], [662684400000, 354.85], [665362800000, 355.66], [667782000000, 357.04], [670456800000, 358.40], [673048800000, 359.00], [675727200000, 357.99], [678319200000, 356.00], [680997600000, 353.78], [683676000000, 352.20], [686271600000, 352.22], [688950000000, 353.70], [691542000000, 354.98], [694220400000, 356.09], [696898800000, 356.85], [699404400000, 357.73], [702079200000, 358.91], [704671200000, 359.45], [707349600000, 359.19], [709941600000, 356.72], [712620000000, 354.79], [715298400000, 352.79], [717894000000, 353.20], [720572400000, 354.15], [723164400000, 355.39], [725842800000, 356.77], [728521200000, 357.17], [730940400000, 358.26], [733615200000, 359.16], [736207200000, 360.07], [738885600000, 359.41], [741477600000, 357.44], [744156000000, 355.30], [746834400000, 353.87], [749430000000, 354.04], [752108400000, 355.27], [754700400000, 356.70], [757378800000, 358.00], [760057200000, 358.81], [762476400000, 359.68], [765151200000, 361.13], [767743200000, 361.48], [770421600000, 360.60], [773013600000, 359.20], [775692000000, 357.23], [778370400000, 355.42], [780966000000, 355.89], [783644400000, 357.41], [786236400000, 358.74], [788914800000, 359.73], [791593200000, 360.61], [794012400000, 361.58], [796687200000, 363.05], [799279200000, 363.62], [801957600000, 363.03], [804549600000, 361.55], [807228000000, 358.94], [809906400000, 357.93], [812502000000, 357.80], [815180400000, 359.22], [817772400000, 360.44], [820450800000, 361.83], [823129200000, 362.95], [825634800000, 363.91], [828309600000, 364.28], [830901600000, 364.94], [833580000000, 364.70], [836172000000, 363.31], [838850400000, 361.15], [841528800000, 359.40], [844120800000, 359.34], [846802800000, 360.62], [849394800000, 361.96], [852073200000, 362.81], [854751600000, 363.87], [857170800000, 364.25], [859845600000, 366.02], [862437600000, 366.46], [865116000000, 365.32], [867708000000, 364.07], [870386400000, 361.95], [873064800000, 360.06], [875656800000, 360.49], [878338800000, 362.19], [880930800000, 364.12], [883609200000, 364.99], [886287600000, 365.82], [888706800000, 366.95], [891381600000, 368.42], [893973600000, 369.33], [896652000000, 368.78], [899244000000, 367.59], [901922400000, 365.84], [904600800000, 363.83], [907192800000, 364.18], [909874800000, 365.34], [912466800000, 366.93], [915145200000, 367.94], [917823600000, 368.82], [920242800000, 369.46], [922917600000, 370.77], [925509600000, 370.66], [928188000000, 370.10], [930780000000, 369.08], [933458400000, 366.66], [936136800000, 364.60], [938728800000, 365.17], [941410800000, 366.51], [944002800000, 367.89], [946681200000, 369.04], [949359600000, 369.35], [951865200000, 370.38], [954540000000, 371.63], [957132000000, 371.32], [959810400000, 371.53], [962402400000, 369.75], [965080800000, 368.23], [967759200000, 366.87], [970351200000, 366.94], [973033200000, 368.27], [975625200000, 369.64], [978303600000, 370.46], [980982000000, 371.44], [983401200000, 372.37], [986076000000, 373.33], [988668000000, 373.77], [991346400000, 373.09], [993938400000, 371.51], [996616800000, 369.55], [999295200000, 368.12], [1001887200000, 368.38], [1004569200000, 369.66], [1007161200000, 371.11], [1009839600000, 372.36], [1012518000000, 373.09], [1014937200000, 373.81], [1017612000000, 374.93], [1020204000000, 375.58], [1022882400000, 375.44], [1025474400000, 373.86], [1028152800000, 371.77], [1030831200000, 370.73], [1033423200000, 370.50], [1036105200000, 372.18], [1038697200000, 373.70], [1041375600000, 374.92], [1044054000000, 375.62], [1046473200000, 376.51], [1049148000000, 377.75], [1051740000000, 378.54], [1054418400000, 378.20], [1057010400000, 376.68], [1059688800000, 374.43], [1062367200000, 373.11], [1064959200000, 373.10], [1067641200000, 374.77], [1070233200000, 375.97], [1072911600000, 377.03], [1075590000000, 377.87], [1078095600000, 378.88], [1080770400000, 380.42], [1083362400000, 380.62], [1086040800000, 379.70], [1088632800000, 377.43], [1091311200000, 376.32], [1093989600000, 374.19], [1096581600000, 374.47], [1099263600000, 376.15], [1101855600000, 377.51], [1104534000000, 378.43], [1107212400000, 379.70], [1109631600000, 380.92], [1112306400000, 382.18], [1114898400000, 382.45], [1117576800000, 382.14], [1120168800000, 380.60], [1122847200000, 378.64], [1125525600000, 376.73], [1128117600000, 376.84], [1130799600000, 378.29], [1133391600000, 380.06], [1136070000000, 381.40], [1138748400000, 382.20], [1141167600000, 382.66], [1143842400000, 384.69], [1146434400000, 384.94], [1149112800000, 384.01], [1151704800000, 382.14], [1154383200000, 380.31], [1157061600000, 378.81], [1159653600000, 379.03], [1162335600000, 380.17], [1164927600000, 381.85], [1167606000000, 382.94], [1170284400000, 383.86], [1172703600000, 384.49], [1175378400000, 386.37], [1177970400000, 386.54], [1180648800000, 385.98], [1183240800000, 384.36], [1185919200000, 381.85], [1188597600000, 380.74], [1191189600000, 381.15], [1193871600000, 382.38], [1196463600000, 383.94], [1199142000000, 385.44]]; 
16
+
17
+		$.plot("#placeholder", [d], {
18
+			xaxis: { mode: "time" }
19
+		});
20
+
21
+		$("#whole").click(function () {
22
+			$.plot("#placeholder", [d], {
23
+				xaxis: { mode: "time" }
24
+			});
25
+		});
26
+
27
+		$("#nineties").click(function () {
28
+			$.plot("#placeholder", [d], {
29
+				xaxis: {
30
+					mode: "time",
31
+					min: (new Date(1990, 0, 1)).getTime(),
32
+					max: (new Date(2000, 0, 1)).getTime()
33
+				}
34
+			});
35
+		});
36
+
37
+		$("#latenineties").click(function () {
38
+			$.plot("#placeholder", [d], {
39
+				xaxis: {
40
+					mode: "time",
41
+					minTickSize: [1, "year"],
42
+					min: (new Date(1996, 0, 1)).getTime(),
43
+					max: (new Date(2000, 0, 1)).getTime()
44
+				}
45
+			});
46
+		});
47
+
48
+		$("#ninetyninequarters").click(function () {
49
+			$.plot("#placeholder", [d], {
50
+				xaxis: {
51
+					mode: "time",
52
+					minTickSize: [1, "quarter"],
53
+					min: (new Date(1999, 0, 1)).getTime(),
54
+					max: (new Date(2000, 0, 1)).getTime()
55
+				}
56
+			});
57
+		});
58
+
59
+		$("#ninetynine").click(function () {
60
+			$.plot("#placeholder", [d], {
61
+				xaxis: {
62
+					mode: "time",
63
+					minTickSize: [1, "month"],
64
+					min: (new Date(1999, 0, 1)).getTime(),
65
+					max: (new Date(2000, 0, 1)).getTime()
66
+				}
67
+			});
68
+		});
69
+
70
+		$("#lastweekninetynine").click(function () {
71
+			$.plot("#placeholder", [d], {
72
+				xaxis: {
73
+					mode: "time",
74
+					minTickSize: [1, "day"],
75
+					min: (new Date(1999, 11, 25)).getTime(),
76
+					max: (new Date(2000, 0, 1)).getTime(),
77
+					timeformat: "%a"
78
+				}
79
+			});
80
+		});
81
+
82
+		$("#lastdayninetynine").click(function () {
83
+			$.plot("#placeholder", [d], {
84
+				xaxis: {
85
+					mode: "time",
86
+					minTickSize: [1, "hour"],
87
+					min: (new Date(1999, 11, 31)).getTime(),
88
+					max: (new Date(2000, 0, 1)).getTime(),
89
+					twelveHourClock: true
90
+				}
91
+			});
92
+		});
93
+
94
+		// Add the Flot version string to the footer
95
+
96
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
97
+	});
98
+
99
+	</script>
100
+</head>
101
+<body>
102
+
103
+	<div id="header">
104
+		<h2>Time Axes</h2>
105
+	</div>
106
+
107
+	<div id="content">
108
+
109
+		<div class="demo-container">
110
+			<div id="placeholder" class="demo-placeholder"></div>
111
+		</div>
112
+
113
+		<p>Monthly mean atmospheric CO<sub>2</sub> in PPM at Mauna Loa, Hawaii (source: <a href="http://www.esrl.noaa.gov/gmd/ccgg/trends/">NOAA/ESRL</a>).</p>
114
+
115
+		<p>If you tell Flot that an axis represents time, the data will be interpreted as timestamps and the ticks adjusted and formatted accordingly.</p>
116
+
117
+		<p>Zoom to: <button id="whole">Whole period</button>
118
+		<button id="nineties">1990-2000</button>
119
+		<button id="latenineties">1996-2000</button></p>
120
+
121
+		<p>Zoom to: <button id="ninetyninequarters">1999 by quarter</button>
122
+		<button id="ninetynine">1999 by month</button>
123
+		<button id="lastweekninetynine">Last week of 1999</button>
124
+		<button id="lastdayninetynine">Dec. 31, 1999</button></p>
125
+
126
+		<p>The timestamps must be specified as Javascript timestamps, as milliseconds since January 1, 1970 00:00. This is like Unix timestamps, but in milliseconds instead of seconds (remember to multiply with 1000!).</p>
127
+
128
+		<p>As an extra caveat, the timestamps are interpreted according to UTC and, by default, displayed as such. You can set the axis "timezone" option to "browser" to display the timestamps in the user's timezone, or, if you use timezoneJS, you can specify a time zone.</p>
129
+
130
+	</div>
131
+
132
+	<div id="footer">
133
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
134
+	</div>
135
+
136
+</body>
137
+</html>
... ...
@@ -0,0 +1,91 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Basic Options</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script type="text/javascript">
11
+
12
+	$(function () {
13
+
14
+		var d1 = [];
15
+		for (var i = 0; i < Math.PI * 2; i += 0.25) {
16
+			d1.push([i, Math.sin(i)]);
17
+		}
18
+
19
+		var d2 = [];
20
+		for (var i = 0; i < Math.PI * 2; i += 0.25) {
21
+			d2.push([i, Math.cos(i)]);
22
+		}
23
+
24
+		var d3 = [];
25
+		for (var i = 0; i < Math.PI * 2; i += 0.1) {
26
+			d3.push([i, Math.tan(i)]);
27
+		}
28
+
29
+		$.plot("#placeholder", [
30
+			{ label: "sin(x)", data: d1 },
31
+			{ label: "cos(x)", data: d2 },
32
+			{ label: "tan(x)", data: d3 }
33
+		], {
34
+			series: {
35
+				lines: { show: true },
36
+				points: { show: true }
37
+			},
38
+			xaxis: {
39
+				ticks: [
40
+					0, [ Math.PI/2, "\u03c0/2" ], [ Math.PI, "\u03c0" ],
41
+					[ Math.PI * 3/2, "3\u03c0/2" ], [ Math.PI * 2, "2\u03c0" ]
42
+				]
43
+			},
44
+			yaxis: {
45
+				ticks: 10,
46
+				min: -2,
47
+				max: 2,
48
+				tickDecimals: 3
49
+			},
50
+			grid: {
51
+				backgroundColor: { colors: [ "#fff", "#eee" ] },
52
+				borderWidth: {
53
+					top: 1,
54
+					right: 1,
55
+					bottom: 2,
56
+					left: 2
57
+				}
58
+			}
59
+		});
60
+
61
+		// Add the Flot version string to the footer
62
+
63
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
64
+	});
65
+
66
+	</script>
67
+</head>
68
+<body>
69
+
70
+	<div id="header">
71
+		<h2>Basic Options</h2>
72
+	</div>
73
+
74
+	<div id="content">
75
+
76
+		<div class="demo-container">
77
+			<div id="placeholder" class="demo-placeholder"></div>
78
+		</div>
79
+
80
+		<p>There are plenty of options you can set to control the precise looks of your plot. You can control the ticks on the axes, the legend, the graph type, etc.</p>
81
+
82
+		<p>Flot goes to great lengths to provide sensible defaults so that you don't have to customize much for a good-looking result.</p>
83
+
84
+	</div>
85
+
86
+	<div id="footer">
87
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
88
+	</div>
89
+
90
+</body>
91
+</html>
... ...
@@ -0,0 +1,57 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Basic Usage</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script type="text/javascript">
11
+
12
+	$(function() {
13
+
14
+		var d1 = [];
15
+		for (var i = 0; i < 14; i += 0.5) {
16
+			d1.push([i, Math.sin(i)]);
17
+		}
18
+
19
+		var d2 = [[0, 3], [4, 8], [8, 5], [9, 13]];
20
+
21
+		// A null signifies separate line segments
22
+
23
+		var d3 = [[0, 12], [7, 12], null, [7, 2.5], [12, 2.5]];
24
+
25
+		$.plot("#placeholder", [ d1, d2, d3 ]);
26
+
27
+		// Add the Flot version string to the footer
28
+
29
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
30
+	});
31
+
32
+	</script>
33
+</head>
34
+<body>
35
+
36
+	<div id="header">
37
+		<h2>Basic Usage</h2>
38
+	</div>
39
+
40
+	<div id="content">
41
+
42
+		<div class="demo-container">
43
+			<div id="placeholder" class="demo-placeholder"></div>
44
+		</div>
45
+
46
+		<p>You don't have to do much to get an attractive plot.  Create a placeholder, make sure it has dimensions (so Flot knows at what size to draw the plot), then call the plot function with your data.</p>
47
+
48
+		<p>The axes are automatically scaled.</p>
49
+
50
+	</div>
51
+
52
+	<div id="footer">
53
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
54
+	</div>
55
+
56
+</body>
57
+</html>
... ...
@@ -0,0 +1,75 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Canvas text</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.time.js"></script>
11
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.canvas.js"></script>
12
+	<script type="text/javascript">
13
+
14
+	$(function() {
15
+
16
+		var oilPrices = [[1167692400000,61.05], [1167778800000,58.32], [1167865200000,57.35], [1167951600000,56.31], [1168210800000,55.55], [1168297200000,55.64], [1168383600000,54.02], [1168470000000,51.88], [1168556400000,52.99], [1168815600000,52.99], [1168902000000,51.21], [1168988400000,52.24], [1169074800000,50.48], [1169161200000,51.99], [1169420400000,51.13], [1169506800000,55.04], [1169593200000,55.37], [1169679600000,54.23], [1169766000000,55.42], [1170025200000,54.01], [1170111600000,56.97], [1170198000000,58.14], [1170284400000,58.14], [1170370800000,59.02], [1170630000000,58.74], [1170716400000,58.88], [1170802800000,57.71], [1170889200000,59.71], [1170975600000,59.89], [1171234800000,57.81], [1171321200000,59.06], [1171407600000,58.00], [1171494000000,57.99], [1171580400000,59.39], [1171839600000,59.39], [1171926000000,58.07], [1172012400000,60.07], [1172098800000,61.14], [1172444400000,61.39], [1172530800000,61.46], [1172617200000,61.79], [1172703600000,62.00], [1172790000000,60.07], [1173135600000,60.69], [1173222000000,61.82], [1173308400000,60.05], [1173654000000,58.91], [1173740400000,57.93], [1173826800000,58.16], [1173913200000,57.55], [1173999600000,57.11], [1174258800000,56.59], [1174345200000,59.61], [1174518000000,61.69], [1174604400000,62.28], [1174860000000,62.91], [1174946400000,62.93], [1175032800000,64.03], [1175119200000,66.03], [1175205600000,65.87], [1175464800000,64.64], [1175637600000,64.38], [1175724000000,64.28], [1175810400000,64.28], [1176069600000,61.51], [1176156000000,61.89], [1176242400000,62.01], [1176328800000,63.85], [1176415200000,63.63], [1176674400000,63.61], [1176760800000,63.10], [1176847200000,63.13], [1176933600000,61.83], [1177020000000,63.38], [1177279200000,64.58], [1177452000000,65.84], [1177538400000,65.06], [1177624800000,66.46], [1177884000000,64.40], [1178056800000,63.68], [1178143200000,63.19], [1178229600000,61.93], [1178488800000,61.47], [1178575200000,61.55], [1178748000000,61.81], [1178834400000,62.37], [1179093600000,62.46], [1179180000000,63.17], [1179266400000,62.55], [1179352800000,64.94], [1179698400000,66.27], [1179784800000,65.50], [1179871200000,65.77], [1179957600000,64.18], [1180044000000,65.20], [1180389600000,63.15], [1180476000000,63.49], [1180562400000,65.08], [1180908000000,66.30], [1180994400000,65.96], [1181167200000,66.93], [1181253600000,65.98], [1181599200000,65.35], [1181685600000,66.26], [1181858400000,68.00], [1182117600000,69.09], [1182204000000,69.10], [1182290400000,68.19], [1182376800000,68.19], [1182463200000,69.14], [1182722400000,68.19], [1182808800000,67.77], [1182895200000,68.97], [1182981600000,69.57], [1183068000000,70.68], [1183327200000,71.09], [1183413600000,70.92], [1183586400000,71.81], [1183672800000,72.81], [1183932000000,72.19], [1184018400000,72.56], [1184191200000,72.50], [1184277600000,74.15], [1184623200000,75.05], [1184796000000,75.92], [1184882400000,75.57], [1185141600000,74.89], [1185228000000,73.56], [1185314400000,75.57], [1185400800000,74.95], [1185487200000,76.83], [1185832800000,78.21], [1185919200000,76.53], [1186005600000,76.86], [1186092000000,76.00], [1186437600000,71.59], [1186696800000,71.47], [1186956000000,71.62], [1187042400000,71.00], [1187301600000,71.98], [1187560800000,71.12], [1187647200000,69.47], [1187733600000,69.26], [1187820000000,69.83], [1187906400000,71.09], [1188165600000,71.73], [1188338400000,73.36], [1188511200000,74.04], [1188856800000,76.30], [1189116000000,77.49], [1189461600000,78.23], [1189548000000,79.91], [1189634400000,80.09], [1189720800000,79.10], [1189980000000,80.57], [1190066400000,81.93], [1190239200000,83.32], [1190325600000,81.62], [1190584800000,80.95], [1190671200000,79.53], [1190757600000,80.30], [1190844000000,82.88], [1190930400000,81.66], [1191189600000,80.24], [1191276000000,80.05], [1191362400000,79.94], [1191448800000,81.44], [1191535200000,81.22], [1191794400000,79.02], [1191880800000,80.26], [1191967200000,80.30], [1192053600000,83.08], [1192140000000,83.69], [1192399200000,86.13], [1192485600000,87.61], [1192572000000,87.40], [1192658400000,89.47], [1192744800000,88.60], [1193004000000,87.56], [1193090400000,87.56], [1193176800000,87.10], [1193263200000,91.86], [1193612400000,93.53], [1193698800000,94.53], [1193871600000,95.93], [1194217200000,93.98], [1194303600000,96.37], [1194476400000,95.46], [1194562800000,96.32], [1195081200000,93.43], [1195167600000,95.10], [1195426800000,94.64], [1195513200000,95.10], [1196031600000,97.70], [1196118000000,94.42], [1196204400000,90.62], [1196290800000,91.01], [1196377200000,88.71], [1196636400000,88.32], [1196809200000,90.23], [1196982000000,88.28], [1197241200000,87.86], [1197327600000,90.02], [1197414000000,92.25], [1197586800000,90.63], [1197846000000,90.63], [1197932400000,90.49], [1198018800000,91.24], [1198105200000,91.06], [1198191600000,90.49], [1198710000000,96.62], [1198796400000,96.00], [1199142000000,99.62], [1199314800000,99.18], [1199401200000,95.09], [1199660400000,96.33], [1199833200000,95.67], [1200351600000,91.90], [1200438000000,90.84], [1200524400000,90.13], [1200610800000,90.57], [1200956400000,89.21], [1201042800000,86.99], [1201129200000,89.85], [1201474800000,90.99], [1201561200000,91.64], [1201647600000,92.33], [1201734000000,91.75], [1202079600000,90.02], [1202166000000,88.41], [1202252400000,87.14], [1202338800000,88.11], [1202425200000,91.77], [1202770800000,92.78], [1202857200000,93.27], [1202943600000,95.46], [1203030000000,95.46], [1203289200000,101.74], [1203462000000,98.81], [1203894000000,100.88], [1204066800000,99.64], [1204153200000,102.59], [1204239600000,101.84], [1204498800000,99.52], [1204585200000,99.52], [1204671600000,104.52], [1204758000000,105.47], [1204844400000,105.15], [1205103600000,108.75], [1205276400000,109.92], [1205362800000,110.33], [1205449200000,110.21], [1205708400000,105.68], [1205967600000,101.84], [1206313200000,100.86], [1206399600000,101.22], [1206486000000,105.90], [1206572400000,107.58], [1206658800000,105.62], [1206914400000,101.58], [1207000800000,100.98], [1207173600000,103.83], [1207260000000,106.23], [1207605600000,108.50], [1207778400000,110.11], [1207864800000,110.14], [1208210400000,113.79], [1208296800000,114.93], [1208383200000,114.86], [1208728800000,117.48], [1208815200000,118.30], [1208988000000,116.06], [1209074400000,118.52], [1209333600000,118.75], [1209420000000,113.46], [1209592800000,112.52], [1210024800000,121.84], [1210111200000,123.53], [1210197600000,123.69], [1210543200000,124.23], [1210629600000,125.80], [1210716000000,126.29], [1211148000000,127.05], [1211320800000,129.07], [1211493600000,132.19], [1211839200000,128.85], [1212357600000,127.76], [1212703200000,138.54], [1212962400000,136.80], [1213135200000,136.38], [1213308000000,134.86], [1213653600000,134.01], [1213740000000,136.68], [1213912800000,135.65], [1214172000000,134.62], [1214258400000,134.62], [1214344800000,134.62], [1214431200000,139.64], [1214517600000,140.21], [1214776800000,140.00], [1214863200000,140.97], [1214949600000,143.57], [1215036000000,145.29], [1215381600000,141.37], [1215468000000,136.04], [1215727200000,146.40], [1215986400000,145.18], [1216072800000,138.74], [1216159200000,134.60], [1216245600000,129.29], [1216332000000,130.65], [1216677600000,127.95], [1216850400000,127.95], [1217282400000,122.19], [1217455200000,124.08], [1217541600000,125.10], [1217800800000,121.41], [1217887200000,119.17], [1217973600000,118.58], [1218060000000,120.02], [1218405600000,114.45], [1218492000000,113.01], [1218578400000,116.00], [1218751200000,113.77], [1219010400000,112.87], [1219096800000,114.53], [1219269600000,114.98], [1219356000000,114.98], [1219701600000,116.27], [1219788000000,118.15], [1219874400000,115.59], [1219960800000,115.46], [1220306400000,109.71], [1220392800000,109.35], [1220565600000,106.23], [1220824800000,106.34]];
17
+
18
+		var exchangeRates = [[1167606000000,0.7580], [1167692400000,0.7580], [1167778800000,0.75470], [1167865200000,0.75490], [1167951600000,0.76130], [1168038000000,0.76550], [1168124400000,0.76930], [1168210800000,0.76940], [1168297200000,0.76880], [1168383600000,0.76780], [1168470000000,0.77080], [1168556400000,0.77270], [1168642800000,0.77490], [1168729200000,0.77410], [1168815600000,0.77410], [1168902000000,0.77320], [1168988400000,0.77270], [1169074800000,0.77370], [1169161200000,0.77240], [1169247600000,0.77120], [1169334000000,0.7720], [1169420400000,0.77210], [1169506800000,0.77170], [1169593200000,0.77040], [1169679600000,0.7690], [1169766000000,0.77110], [1169852400000,0.7740], [1169938800000,0.77450], [1170025200000,0.77450], [1170111600000,0.7740], [1170198000000,0.77160], [1170284400000,0.77130], [1170370800000,0.76780], [1170457200000,0.76880], [1170543600000,0.77180], [1170630000000,0.77180], [1170716400000,0.77280], [1170802800000,0.77290], [1170889200000,0.76980], [1170975600000,0.76850], [1171062000000,0.76810], [1171148400000,0.7690], [1171234800000,0.7690], [1171321200000,0.76980], [1171407600000,0.76990], [1171494000000,0.76510], [1171580400000,0.76130], [1171666800000,0.76160], [1171753200000,0.76140], [1171839600000,0.76140], [1171926000000,0.76070], [1172012400000,0.76020], [1172098800000,0.76110], [1172185200000,0.76220], [1172271600000,0.76150], [1172358000000,0.75980], [1172444400000,0.75980], [1172530800000,0.75920], [1172617200000,0.75730], [1172703600000,0.75660], [1172790000000,0.75670], [1172876400000,0.75910], [1172962800000,0.75820], [1173049200000,0.75850], [1173135600000,0.76130], [1173222000000,0.76310], [1173308400000,0.76150], [1173394800000,0.760], [1173481200000,0.76130], [1173567600000,0.76270], [1173654000000,0.76270], [1173740400000,0.76080], [1173826800000,0.75830], [1173913200000,0.75750], [1173999600000,0.75620], [1174086000000,0.7520], [1174172400000,0.75120], [1174258800000,0.75120], [1174345200000,0.75170], [1174431600000,0.7520], [1174518000000,0.75110], [1174604400000,0.7480], [1174690800000,0.75090], [1174777200000,0.75310], [1174860000000,0.75310], [1174946400000,0.75270], [1175032800000,0.74980], [1175119200000,0.74930], [1175205600000,0.75040], [1175292000000,0.750], [1175378400000,0.74910], [1175464800000,0.74910], [1175551200000,0.74850], [1175637600000,0.74840], [1175724000000,0.74920], [1175810400000,0.74710], [1175896800000,0.74590], [1175983200000,0.74770], [1176069600000,0.74770], [1176156000000,0.74830], [1176242400000,0.74580], [1176328800000,0.74480], [1176415200000,0.7430], [1176501600000,0.73990], [1176588000000,0.73950], [1176674400000,0.73950], [1176760800000,0.73780], [1176847200000,0.73820], [1176933600000,0.73620], [1177020000000,0.73550], [1177106400000,0.73480], [1177192800000,0.73610], [1177279200000,0.73610], [1177365600000,0.73650], [1177452000000,0.73620], [1177538400000,0.73310], [1177624800000,0.73390], [1177711200000,0.73440], [1177797600000,0.73270], [1177884000000,0.73270], [1177970400000,0.73360], [1178056800000,0.73330], [1178143200000,0.73590], [1178229600000,0.73590], [1178316000000,0.73720], [1178402400000,0.7360], [1178488800000,0.7360], [1178575200000,0.7350], [1178661600000,0.73650], [1178748000000,0.73840], [1178834400000,0.73950], [1178920800000,0.74130], [1179007200000,0.73970], [1179093600000,0.73960], [1179180000000,0.73850], [1179266400000,0.73780], [1179352800000,0.73660], [1179439200000,0.740], [1179525600000,0.74110], [1179612000000,0.74060], [1179698400000,0.74050], [1179784800000,0.74140], [1179871200000,0.74310], [1179957600000,0.74310], [1180044000000,0.74380], [1180130400000,0.74430], [1180216800000,0.74430], [1180303200000,0.74430], [1180389600000,0.74340], [1180476000000,0.74290], [1180562400000,0.74420], [1180648800000,0.7440], [1180735200000,0.74390], [1180821600000,0.74370], [1180908000000,0.74370], [1180994400000,0.74290], [1181080800000,0.74030], [1181167200000,0.73990], [1181253600000,0.74180], [1181340000000,0.74680], [1181426400000,0.7480], [1181512800000,0.7480], [1181599200000,0.7490], [1181685600000,0.74940], [1181772000000,0.75220], [1181858400000,0.75150], [1181944800000,0.75020], [1182031200000,0.74720], [1182117600000,0.74720], [1182204000000,0.74620], [1182290400000,0.74550], [1182376800000,0.74490], [1182463200000,0.74670], [1182549600000,0.74580], [1182636000000,0.74270], [1182722400000,0.74270], [1182808800000,0.7430], [1182895200000,0.74290], [1182981600000,0.7440], [1183068000000,0.7430], [1183154400000,0.74220], [1183240800000,0.73880], [1183327200000,0.73880], [1183413600000,0.73690], [1183500000000,0.73450], [1183586400000,0.73450], [1183672800000,0.73450], [1183759200000,0.73520], [1183845600000,0.73410], [1183932000000,0.73410], [1184018400000,0.7340], [1184104800000,0.73240], [1184191200000,0.72720], [1184277600000,0.72640], [1184364000000,0.72550], [1184450400000,0.72580], [1184536800000,0.72580], [1184623200000,0.72560], [1184709600000,0.72570], [1184796000000,0.72470], [1184882400000,0.72430], [1184968800000,0.72440], [1185055200000,0.72350], [1185141600000,0.72350], [1185228000000,0.72350], [1185314400000,0.72350], [1185400800000,0.72620], [1185487200000,0.72880], [1185573600000,0.73010], [1185660000000,0.73370], [1185746400000,0.73370], [1185832800000,0.73240], [1185919200000,0.72970], [1186005600000,0.73170], [1186092000000,0.73150], [1186178400000,0.72880], [1186264800000,0.72630], [1186351200000,0.72630], [1186437600000,0.72420], [1186524000000,0.72530], [1186610400000,0.72640], [1186696800000,0.7270], [1186783200000,0.73120], [1186869600000,0.73050], [1186956000000,0.73050], [1187042400000,0.73180], [1187128800000,0.73580], [1187215200000,0.74090], [1187301600000,0.74540], [1187388000000,0.74370], [1187474400000,0.74240], [1187560800000,0.74240], [1187647200000,0.74150], [1187733600000,0.74190], [1187820000000,0.74140], [1187906400000,0.73770], [1187992800000,0.73550], [1188079200000,0.73150], [1188165600000,0.73150], [1188252000000,0.7320], [1188338400000,0.73320], [1188424800000,0.73460], [1188511200000,0.73280], [1188597600000,0.73230], [1188684000000,0.7340], [1188770400000,0.7340], [1188856800000,0.73360], [1188943200000,0.73510], [1189029600000,0.73460], [1189116000000,0.73210], [1189202400000,0.72940], [1189288800000,0.72660], [1189375200000,0.72660], [1189461600000,0.72540], [1189548000000,0.72420], [1189634400000,0.72130], [1189720800000,0.71970], [1189807200000,0.72090], [1189893600000,0.7210], [1189980000000,0.7210], [1190066400000,0.7210], [1190152800000,0.72090], [1190239200000,0.71590], [1190325600000,0.71330], [1190412000000,0.71050], [1190498400000,0.70990], [1190584800000,0.70990], [1190671200000,0.70930], [1190757600000,0.70930], [1190844000000,0.70760], [1190930400000,0.7070], [1191016800000,0.70490], [1191103200000,0.70120], [1191189600000,0.70110], [1191276000000,0.70190], [1191362400000,0.70460], [1191448800000,0.70630], [1191535200000,0.70890], [1191621600000,0.70770], [1191708000000,0.70770], [1191794400000,0.70770], [1191880800000,0.70910], [1191967200000,0.71180], [1192053600000,0.70790], [1192140000000,0.70530], [1192226400000,0.7050], [1192312800000,0.70550], [1192399200000,0.70550], [1192485600000,0.70450], [1192572000000,0.70510], [1192658400000,0.70510], [1192744800000,0.70170], [1192831200000,0.70], [1192917600000,0.69950], [1193004000000,0.69940], [1193090400000,0.70140], [1193176800000,0.70360], [1193263200000,0.70210], [1193349600000,0.70020], [1193436000000,0.69670], [1193522400000,0.6950], [1193612400000,0.6950], [1193698800000,0.69390], [1193785200000,0.6940], [1193871600000,0.69220], [1193958000000,0.69190], [1194044400000,0.69140], [1194130800000,0.68940], [1194217200000,0.68910], [1194303600000,0.69040], [1194390000000,0.6890], [1194476400000,0.68340], [1194562800000,0.68230], [1194649200000,0.68070], [1194735600000,0.68150], [1194822000000,0.68150], [1194908400000,0.68470], [1194994800000,0.68590], [1195081200000,0.68220], [1195167600000,0.68270], [1195254000000,0.68370], [1195340400000,0.68230], [1195426800000,0.68220], [1195513200000,0.68220], [1195599600000,0.67920], [1195686000000,0.67460], [1195772400000,0.67350], [1195858800000,0.67310], [1195945200000,0.67420], [1196031600000,0.67440], [1196118000000,0.67390], [1196204400000,0.67310], [1196290800000,0.67610], [1196377200000,0.67610], [1196463600000,0.67850], [1196550000000,0.68180], [1196636400000,0.68360], [1196722800000,0.68230], [1196809200000,0.68050], [1196895600000,0.67930], [1196982000000,0.68490], [1197068400000,0.68330], [1197154800000,0.68250], [1197241200000,0.68250], [1197327600000,0.68160], [1197414000000,0.67990], [1197500400000,0.68130], [1197586800000,0.68090], [1197673200000,0.68680], [1197759600000,0.69330], [1197846000000,0.69330], [1197932400000,0.69450], [1198018800000,0.69440], [1198105200000,0.69460], [1198191600000,0.69640], [1198278000000,0.69650], [1198364400000,0.69560], [1198450800000,0.69560], [1198537200000,0.6950], [1198623600000,0.69480], [1198710000000,0.69280], [1198796400000,0.68870], [1198882800000,0.68240], [1198969200000,0.67940], [1199055600000,0.67940], [1199142000000,0.68030], [1199228400000,0.68550], [1199314800000,0.68240], [1199401200000,0.67910], [1199487600000,0.67830], [1199574000000,0.67850], [1199660400000,0.67850], [1199746800000,0.67970], [1199833200000,0.680], [1199919600000,0.68030], [1200006000000,0.68050], [1200092400000,0.6760], [1200178800000,0.6770], [1200265200000,0.6770], [1200351600000,0.67360], [1200438000000,0.67260], [1200524400000,0.67640], [1200610800000,0.68210], [1200697200000,0.68310], [1200783600000,0.68420], [1200870000000,0.68420], [1200956400000,0.68870], [1201042800000,0.69030], [1201129200000,0.68480], [1201215600000,0.68240], [1201302000000,0.67880], [1201388400000,0.68140], [1201474800000,0.68140], [1201561200000,0.67970], [1201647600000,0.67690], [1201734000000,0.67650], [1201820400000,0.67330], [1201906800000,0.67290], [1201993200000,0.67580], [1202079600000,0.67580], [1202166000000,0.6750], [1202252400000,0.6780], [1202338800000,0.68330], [1202425200000,0.68560], [1202511600000,0.69030], [1202598000000,0.68960], [1202684400000,0.68960], [1202770800000,0.68820], [1202857200000,0.68790], [1202943600000,0.68620], [1203030000000,0.68520], [1203116400000,0.68230], [1203202800000,0.68130], [1203289200000,0.68130], [1203375600000,0.68220], [1203462000000,0.68020], [1203548400000,0.68020], [1203634800000,0.67840], [1203721200000,0.67480], [1203807600000,0.67470], [1203894000000,0.67470], [1203980400000,0.67480], [1204066800000,0.67330], [1204153200000,0.6650], [1204239600000,0.66110], [1204326000000,0.65830], [1204412400000,0.6590], [1204498800000,0.6590], [1204585200000,0.65810], [1204671600000,0.65780], [1204758000000,0.65740], [1204844400000,0.65320], [1204930800000,0.65020], [1205017200000,0.65140], [1205103600000,0.65140], [1205190000000,0.65070], [1205276400000,0.6510], [1205362800000,0.64890], [1205449200000,0.64240], [1205535600000,0.64060], [1205622000000,0.63820], [1205708400000,0.63820], [1205794800000,0.63410], [1205881200000,0.63440], [1205967600000,0.63780], [1206054000000,0.64390], [1206140400000,0.64780], [1206226800000,0.64810], [1206313200000,0.64810], [1206399600000,0.64940], [1206486000000,0.64380], [1206572400000,0.63770], [1206658800000,0.63290], [1206745200000,0.63360], [1206831600000,0.63330], [1206914400000,0.63330], [1207000800000,0.6330], [1207087200000,0.63710], [1207173600000,0.64030], [1207260000000,0.63960], [1207346400000,0.63640], [1207432800000,0.63560], [1207519200000,0.63560], [1207605600000,0.63680], [1207692000000,0.63570], [1207778400000,0.63540], [1207864800000,0.6320], [1207951200000,0.63320], [1208037600000,0.63280], [1208124000000,0.63310], [1208210400000,0.63420], [1208296800000,0.63210], [1208383200000,0.63020], [1208469600000,0.62780], [1208556000000,0.63080], [1208642400000,0.63240], [1208728800000,0.63240], [1208815200000,0.63070], [1208901600000,0.62770], [1208988000000,0.62690], [1209074400000,0.63350], [1209160800000,0.63920], [1209247200000,0.640], [1209333600000,0.64010], [1209420000000,0.63960], [1209506400000,0.64070], [1209592800000,0.64230], [1209679200000,0.64290], [1209765600000,0.64720], [1209852000000,0.64850], [1209938400000,0.64860], [1210024800000,0.64670], [1210111200000,0.64440], [1210197600000,0.64670], [1210284000000,0.65090], [1210370400000,0.64780], [1210456800000,0.64610], [1210543200000,0.64610], [1210629600000,0.64680], [1210716000000,0.64490], [1210802400000,0.6470], [1210888800000,0.64610], [1210975200000,0.64520], [1211061600000,0.64220], [1211148000000,0.64220], [1211234400000,0.64250], [1211320800000,0.64140], [1211407200000,0.63660], [1211493600000,0.63460], [1211580000000,0.6350], [1211666400000,0.63460], [1211752800000,0.63460], [1211839200000,0.63430], [1211925600000,0.63460], [1212012000000,0.63790], [1212098400000,0.64160], [1212184800000,0.64420], [1212271200000,0.64310], [1212357600000,0.64310], [1212444000000,0.64350], [1212530400000,0.6440], [1212616800000,0.64730], [1212703200000,0.64690], [1212789600000,0.63860], [1212876000000,0.63560], [1212962400000,0.6340], [1213048800000,0.63460], [1213135200000,0.6430], [1213221600000,0.64520], [1213308000000,0.64670], [1213394400000,0.65060], [1213480800000,0.65040], [1213567200000,0.65030], [1213653600000,0.64810], [1213740000000,0.64510], [1213826400000,0.6450], [1213912800000,0.64410], [1213999200000,0.64140], [1214085600000,0.64090], [1214172000000,0.64090], [1214258400000,0.64280], [1214344800000,0.64310], [1214431200000,0.64180], [1214517600000,0.63710], [1214604000000,0.63490], [1214690400000,0.63330], [1214776800000,0.63340], [1214863200000,0.63380], [1214949600000,0.63420], [1215036000000,0.6320], [1215122400000,0.63180], [1215208800000,0.6370], [1215295200000,0.63680], [1215381600000,0.63680], [1215468000000,0.63830], [1215554400000,0.63710], [1215640800000,0.63710], [1215727200000,0.63550], [1215813600000,0.6320], [1215900000000,0.62770], [1215986400000,0.62760], [1216072800000,0.62910], [1216159200000,0.62740], [1216245600000,0.62930], [1216332000000,0.63110], [1216418400000,0.6310], [1216504800000,0.63120], [1216591200000,0.63120], [1216677600000,0.63040], [1216764000000,0.62940], [1216850400000,0.63480], [1216936800000,0.63780], [1217023200000,0.63680], [1217109600000,0.63680], [1217196000000,0.63680], [1217282400000,0.6360], [1217368800000,0.6370], [1217455200000,0.64180], [1217541600000,0.64110], [1217628000000,0.64350], [1217714400000,0.64270], [1217800800000,0.64270], [1217887200000,0.64190], [1217973600000,0.64460], [1218060000000,0.64680], [1218146400000,0.64870], [1218232800000,0.65940], [1218319200000,0.66660], [1218405600000,0.66660], [1218492000000,0.66780], [1218578400000,0.67120], [1218664800000,0.67050], [1218751200000,0.67180], [1218837600000,0.67840], [1218924000000,0.68110], [1219010400000,0.68110], [1219096800000,0.67940], [1219183200000,0.68040], [1219269600000,0.67810], [1219356000000,0.67560], [1219442400000,0.67350], [1219528800000,0.67630], [1219615200000,0.67620], [1219701600000,0.67770], [1219788000000,0.68150], [1219874400000,0.68020], [1219960800000,0.6780], [1220047200000,0.67960], [1220133600000,0.68170], [1220220000000,0.68170], [1220306400000,0.68320], [1220392800000,0.68770], [1220479200000,0.69120], [1220565600000,0.69140], [1220652000000,0.70090], [1220738400000,0.70120], [1220824800000,0.7010], [1220911200000,0.70050]];
19
+
20
+		var data = [
21
+			{ data: oilPrices, label: "Oil price ($)" },
22
+			{ data: exchangeRates, label: "USD/EUR exchange rate", yaxis: 2 }
23
+		];
24
+
25
+		var options = {
26
+			canvas: true,
27
+			xaxes: [ { mode: "time" } ],
28
+			yaxes: [ { min: 0 }, {
29
+				position: "right",
30
+				alignTicksWithAxis: 1,
31
+				tickFormatter: function(value, axis) {
32
+					return value.toFixed(axis.tickDecimals) + "€";
33
+				}
34
+			} ],
35
+			legend: { position: "sw" }
36
+		}
37
+
38
+		$.plot("#placeholder", data, options);
39
+
40
+		$("input").change(function () {
41
+			options.canvas = $(this).is(":checked");
42
+			$.plot("#placeholder", data, options);
43
+		});
44
+
45
+		// Add the Flot version string to the footer
46
+
47
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
48
+	});
49
+
50
+	</script>
51
+</head>
52
+<body>
53
+
54
+	<div id="header">
55
+		<h2>Canvas text</h2>
56
+	</div>
57
+
58
+	<div id="content">
59
+
60
+		<div class="demo-container">
61
+			<div id="placeholder" class="demo-placeholder"></div>
62
+		</div>
63
+
64
+		<p>This example uses the same dataset (raw oil price in US $/barrel of crude oil vs. the exchange rate from US $ to €) as the multiple-axes example, but uses the canvas plugin to render axis tick labels using canvas text.</p>
65
+
66
+		<p><input type="checkbox" checked="checked">Enable canvas text</input></p>
67
+
68
+	</div>
69
+
70
+	<div id="footer">
71
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
72
+	</div>
73
+
74
+</body>
75
+</html>
... ...
@@ -0,0 +1,64 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Categories</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.categories.js"></script>
11
+	<script type="text/javascript">
12
+
13
+	$(function() {
14
+
15
+		var data = [ ["January", 10], ["February", 8], ["March", 4], ["April", 13], ["May", 17], ["June", 9] ];
16
+
17
+		$.plot("#placeholder", [ data ], {
18
+			series: {
19
+				bars: {
20
+					show: true,
21
+					barWidth: 0.6,
22
+					align: "center"
23
+				}
24
+			},
25
+			xaxis: {
26
+				mode: "categories",
27
+				tickLength: 0
28
+			}
29
+		});
30
+
31
+		// Add the Flot version string to the footer
32
+
33
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
34
+	});
35
+
36
+	</script>
37
+</head>
38
+<body>
39
+
40
+	<div id="header">
41
+		<h2>Categories</h2>
42
+	</div>
43
+
44
+	<div id="content">
45
+
46
+		<div class="demo-container">
47
+			<div id="placeholder" class="demo-placeholder"></div>
48
+		</div>
49
+
50
+		<p>With the categories plugin you can plot categories/textual data easily.</p>
51
+
52
+	</div>
53
+
54
+	<div id="footer">
55
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
56
+	</div>
57
+
58
+</body>
59
+</html>
60
+
61
+
62
+
63
+
64
+
... ...
@@ -0,0 +1,97 @@
1
+* {	padding: 0; margin: 0; vertical-align: top; }
2
+
3
+body {
4
+	background: url(background.png) repeat-x;
5
+	font: 18px/1.5em "proxima-nova", Helvetica, Arial, sans-serif;
6
+}
7
+
8
+a {	color: #069; }
9
+a:hover { color: #28b; }
10
+
11
+h2 {
12
+	margin-top: 15px;
13
+	font: normal 32px "omnes-pro", Helvetica, Arial, sans-serif;
14
+}
15
+
16
+h3 {
17
+	margin-left: 30px;
18
+	font: normal 26px "omnes-pro", Helvetica, Arial, sans-serif;
19
+	color: #666;
20
+}
21
+
22
+p {
23
+	margin-top: 10px;
24
+}
25
+
26
+button {
27
+	font-size: 18px;
28
+	padding: 1px 7px;
29
+}
30
+
31
+input {
32
+	font-size: 18px;
33
+}
34
+
35
+input[type=checkbox] {
36
+	margin: 7px;
37
+}
38
+
39
+#header {
40
+	position: relative;
41
+	width: 900px;
42
+	margin: auto;
43
+}
44
+
45
+#header h2 {
46
+	margin-left: 10px;
47
+	vertical-align: middle;
48
+	font-size: 42px;
49
+	font-weight: bold;
50
+	text-decoration: none;
51
+	color: #000;
52
+}
53
+
54
+#content {
55
+	width: 880px;
56
+	margin: 0 auto;
57
+	padding: 10px;
58
+}
59
+
60
+#footer {
61
+	margin-top: 25px;
62
+	margin-bottom: 10px;
63
+	text-align: center;
64
+	font-size: 12px;
65
+	color: #999;
66
+}
67
+
68
+.demo-container {
69
+	box-sizing: border-box;
70
+	width: 850px;
71
+	height: 450px;
72
+	padding: 20px 15px 15px 15px;
73
+	margin: 15px auto 30px auto;
74
+	border: 1px solid #ddd;
75
+	background: #fff;
76
+	background: linear-gradient(#f6f6f6 0, #fff 50px);
77
+	background: -o-linear-gradient(#f6f6f6 0, #fff 50px);
78
+	background: -ms-linear-gradient(#f6f6f6 0, #fff 50px);
79
+	background: -moz-linear-gradient(#f6f6f6 0, #fff 50px);
80
+	background: -webkit-linear-gradient(#f6f6f6 0, #fff 50px);
81
+	box-shadow: 0 3px 10px rgba(0,0,0,0.15);
82
+	-o-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
83
+	-ms-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
84
+	-moz-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
85
+	-webkit-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
86
+}
87
+
88
+.demo-placeholder {
89
+	width: 100%;
90
+	height: 100%;
91
+	font-size: 14px;
92
+	line-height: 1.2em;
93
+}
94
+
95
+.legend table {
96
+	border-spacing: 5px;
97
+}
0 98
\ No newline at end of file
... ...
@@ -0,0 +1,69 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Image Plots</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.image.js"></script>
11
+	<script type="text/javascript">
12
+
13
+	$(function() {
14
+
15
+		var data = [[["hs-2004-27-a-large-web.jpg", -10, -10, 10, 10]]];
16
+
17
+		var options = {
18
+			series: {
19
+				images: {
20
+					show: true
21
+				}
22
+			},
23
+			xaxis: {
24
+				min: -8,
25
+				max: 4
26
+			},
27
+			yaxis: {
28
+				min: -8,
29
+				max: 4
30
+			}
31
+		};
32
+
33
+		$.plot.image.loadDataImages(data, options, function () {
34
+			$.plot("#placeholder", data, options);
35
+		});
36
+
37
+		// Add the Flot version string to the footer
38
+
39
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
40
+	});
41
+
42
+	</script>
43
+</head>
44
+<body>
45
+
46
+	<div id="header">
47
+		<h2>Image Plots</h2>
48
+	</div>
49
+
50
+	<div id="content">
51
+
52
+		<div class="demo-container" style="width:600px;height:600px;">
53
+			<div id="placeholder" class="demo-placeholder"></div>
54
+		</div>
55
+
56
+		<p>The Cat's Eye Nebula (<a href="http://hubblesite.org/gallery/album/nebula/pr2004027a/">picture from Hubble</a>).</p>
57
+
58
+		<p>With the image plugin, you can plot static images against a set of axes. This is for useful for adding ticks to complex prerendered visualizations. Instead of inputting data points, you specify the images and where their two opposite corners are supposed to be in plot space.</p>
59
+
60
+		<p>Images represent a little further complication because you need to make sure they are loaded before you can use them (Flot skips incomplete images). The plugin comes with a couple of helpers for doing that.</p>
61
+
62
+	</div>
63
+
64
+	<div id="footer">
65
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
66
+	</div>
67
+
68
+</body>
69
+</html>
... ...
@@ -0,0 +1,80 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples</title>
6
+	<link href="examples.css" rel="stylesheet" type="text/css">
7
+	<style>
8
+
9
+	h3 {
10
+		margin-top: 30px;
11
+		margin-bottom: 5px;
12
+	}
13
+
14
+	</style>
15
+	<script language="javascript" type="text/javascript" src="../jquery.js"></script>
16
+	<script language="javascript" type="text/javascript" src="../jquery.flot.js"></script>
17
+	<script type="text/javascript">
18
+
19
+	$(function() {
20
+
21
+		// Add the Flot version string to the footer
22
+
23
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
24
+	});
25
+
26
+	</script>
27
+</head>
28
+<body>
29
+
30
+	<div id="header">
31
+		<h2>Flot Examples</h2>
32
+	</div>
33
+
34
+	<div id="content">
35
+
36
+		<p>Here are some examples for <a href="http://www.flotcharts.org">Flot</a>, the Javascript charting library for jQuery:</p>
37
+
38
+		<h3>Basic Usage</h3>
39
+
40
+		<ul>
41
+			<li><a href="basic-usage/index.html">Basic example</a></li>
42
+			<li><a href="series-types/index.html">Different graph types</a> and <a href="categories/index.html">simple categories/textual data</a></li>
43
+			<li><a href="basic-options/index.html">Setting various options</a> and <a href="annotating/index.html">annotating a chart</a></li>
44
+			<li><a href="ajax/index.html">Updating graphs with AJAX</a> and <a href="realtime/index.html">real-time updates</a></li>
45
+		</ul>
46
+
47
+		<h3>Interactivity</h3>
48
+
49
+		<ul>
50
+			<li><a href="series-toggle/index.html">Turning series on/off</a></li>
51
+			<li><a href="selection/index.html">Rectangular selection support and zooming</a> and <a href="zooming/index.html">zooming with overview</a> (both with selection plugin)</li>
52
+			<li><a href="interacting/index.html">Interacting with the data points</a></li>
53
+			<li><a href="navigate/index.html">Panning and zooming</a> (with navigation plugin)</li>
54
+			<li><a href="resize/index.html">Automatically redraw when window is resized</a> (with resize plugin)</li>
55
+		</ul>
56
+
57
+		<h3>Additional Features</h3>
58
+
59
+		<ul>
60
+			<li><a href="symbols/index.html">Using other symbols than circles for points</a> (with symbol plugin)</li>
61
+			<li><a href="axes-time/index.html">Plotting time series</a>, <a href="visitors/index.html">visitors per day with zooming and weekends</a> (with selection plugin) and <a href="axes-time-zones/index.html">time zone support</a></li>
62
+			<li><a href="axes-multiple/index.html">Multiple axes</a> and <a href="axes-interacting/index.html">interacting with the axes</a></li>
63
+			<li><a href="threshold/index.html">Thresholding the data</a> (with threshold plugin)</li>
64
+			<li><a href="stacking/index.html">Stacked charts</a> (with stacking plugin)</li>
65
+			<li><a href="percentiles/index.html">Using filled areas to plot percentiles</a> (with fillbetween plugin)</li>
66
+			<li><a href="tracking/index.html">Tracking curves with crosshair</a> (with crosshair plugin)</li>
67
+			<li><a href="image/index.html">Plotting prerendered images</a> (with image plugin)</li>
68
+			<li><a href="series-errorbars/index.html">Plotting error bars</a> (with errorbars plugin)</li>
69
+			<li><a href="series-pie/index.html">Pie charts</a> (with pie plugin)</li>
70
+			<li><a href="canvas/index.html">Rendering text with canvas instead of HTML</a> (with canvas plugin)</li>
71
+		</ul>
72
+
73
+	</div>
74
+
75
+	<div id="footer">
76
+		Copyright &copy; 2007 - 2013 IOLA and Ole Laursen
77
+	</div>
78
+
79
+</body>
80
+</html>
... ...
@@ -0,0 +1,118 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Interactivity</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script type="text/javascript">
11
+
12
+	$(function() {
13
+
14
+		var sin = [],
15
+			cos = [];
16
+
17
+		for (var i = 0; i < 14; i += 0.5) {
18
+			sin.push([i, Math.sin(i)]);
19
+			cos.push([i, Math.cos(i)]);
20
+		}
21
+
22
+		var plot = $.plot("#placeholder", [
23
+			{ data: sin, label: "sin(x)"},
24
+			{ data: cos, label: "cos(x)"}
25
+		], {
26
+			series: {
27
+				lines: {
28
+					show: true
29
+				},
30
+				points: {
31
+					show: true
32
+				}
33
+			},
34
+			grid: {
35
+				hoverable: true,
36
+				clickable: true
37
+			},
38
+			yaxis: {
39
+				min: -1.2,
40
+				max: 1.2
41
+			}
42
+		});
43
+
44
+		$("<div id='tooltip'></div>").css({
45
+			position: "absolute",
46
+			display: "none",
47
+			border: "1px solid #fdd",
48
+			padding: "2px",
49
+			"background-color": "#fee",
50
+			opacity: 0.80
51
+		}).appendTo("body");
52
+
53
+		$("#placeholder").bind("plothover", function (event, pos, item) {
54
+
55
+			if ($("#enablePosition:checked").length > 0) {
56
+				var str = "(" + pos.x.toFixed(2) + ", " + pos.y.toFixed(2) + ")";
57
+				$("#hoverdata").text(str);
58
+			}
59
+
60
+			if ($("#enableTooltip:checked").length > 0) {
61
+				if (item) {
62
+					var x = item.datapoint[0].toFixed(2),
63
+						y = item.datapoint[1].toFixed(2);
64
+
65
+					$("#tooltip").html(item.series.label + " of " + x + " = " + y)
66
+						.css({top: item.pageY+5, left: item.pageX+5})
67
+						.fadeIn(200);
68
+				} else {
69
+					$("#tooltip").hide();
70
+				}
71
+			}
72
+		});
73
+
74
+		$("#placeholder").bind("plotclick", function (event, pos, item) {
75
+			if (item) {
76
+				$("#clickdata").text(" - click point " + item.dataIndex + " in " + item.series.label);
77
+				plot.highlight(item.series, item.datapoint);
78
+			}
79
+		});
80
+
81
+		// Add the Flot version string to the footer
82
+
83
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
84
+	});
85
+
86
+	</script>
87
+</head>
88
+<body>
89
+	<div id="header">
90
+		<h2>Interactivity</h2>
91
+	</div>
92
+
93
+	<div id="content">
94
+
95
+		<div class="demo-container">
96
+			<div id="placeholder" class="demo-placeholder"></div>
97
+		</div>
98
+
99
+		<p>One of the goals of Flot is to support user interactions. Try pointing and clicking on the points.</p>
100
+
101
+		<p>
102
+			<label><input id="enablePosition" type="checkbox" checked="checked"></input>Show mouse position</label>
103
+			<span id="hoverdata"></span>
104
+			<span id="clickdata"></span>
105
+		</p>
106
+
107
+		<p>A tooltip is easy to build with a bit of jQuery code and the data returned from the plot.</p>
108
+
109
+		<p><label><input id="enableTooltip" type="checkbox" checked="checked"></input>Enable tooltip</label></p>
110
+
111
+	</div>
112
+
113
+	<div id="footer">
114
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
115
+	</div>
116
+
117
+</body>
118
+</html>
... ...
@@ -0,0 +1,153 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Navigation</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<style type="text/css">
8
+
9
+	#placeholder .button {
10
+		position: absolute;
11
+		cursor: pointer;
12
+	}
13
+
14
+	#placeholder div.button {
15
+		font-size: smaller;
16
+		color: #999;
17
+		background-color: #eee;
18
+		padding: 2px;
19
+	}
20
+	.message {
21
+		padding-left: 50px;
22
+		font-size: smaller;
23
+	}
24
+
25
+	</style>
26
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
27
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
28
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
29
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.navigate.js"></script>
30
+	<script type="text/javascript">
31
+
32
+	$(function() {
33
+
34
+		// generate data set from a parametric function with a fractal look
35
+
36
+		function sumf(f, t, m) {
37
+			var res = 0;
38
+			for (var i = 1; i < m; ++i) {
39
+				res += f(i * i * t) / (i * i);
40
+			}
41
+			return res;
42
+		}
43
+
44
+		var d1 = [];
45
+		for (var t = 0; t <= 2 * Math.PI; t += 0.01) {
46
+			d1.push([sumf(Math.cos, t, 10), sumf(Math.sin, t, 10)]);
47
+		}
48
+
49
+		var data = [ d1 ],
50
+			placeholder = $("#placeholder");
51
+
52
+		var plot = $.plot(placeholder, data, {
53
+			series: {
54
+				lines: {
55
+					show: true
56
+				},
57
+				shadowSize: 0
58
+			},
59
+			xaxis: {
60
+				zoomRange: [0.1, 10],
61
+				panRange: [-10, 10]
62
+			},
63
+			yaxis: {
64
+				zoomRange: [0.1, 10],
65
+				panRange: [-10, 10]
66
+			},
67
+			zoom: {
68
+				interactive: true
69
+			},
70
+			pan: {
71
+				interactive: true
72
+			}
73
+		});
74
+
75
+		// show pan/zoom messages to illustrate events 
76
+
77
+		placeholder.bind("plotpan", function (event, plot) {
78
+			var axes = plot.getAxes();
79
+			$(".message").html("Panning to x: "  + axes.xaxis.min.toFixed(2)
80
+			+ " &ndash; " + axes.xaxis.max.toFixed(2)
81
+			+ " and y: " + axes.yaxis.min.toFixed(2)
82
+			+ " &ndash; " + axes.yaxis.max.toFixed(2));
83
+		});
84
+
85
+		placeholder.bind("plotzoom", function (event, plot) {
86
+			var axes = plot.getAxes();
87
+			$(".message").html("Zooming to x: "  + axes.xaxis.min.toFixed(2)
88
+			+ " &ndash; " + axes.xaxis.max.toFixed(2)
89
+			+ " and y: " + axes.yaxis.min.toFixed(2)
90
+			+ " &ndash; " + axes.yaxis.max.toFixed(2));
91
+		});
92
+
93
+		// add zoom out button 
94
+
95
+		$("<div class='button' style='right:20px;top:20px'>zoom out</div>")
96
+			.appendTo(placeholder)
97
+			.click(function (event) {
98
+				event.preventDefault();
99
+				plot.zoomOut();
100
+			});
101
+
102
+		// and add panning buttons
103
+
104
+		// little helper for taking the repetitive work out of placing
105
+		// panning arrows
106
+
107
+		function addArrow(dir, right, top, offset) {
108
+			$("<img class='button' src='arrow-" + dir + ".gif' style='right:" + right + "px;top:" + top + "px'>")
109
+				.appendTo(placeholder)
110
+				.click(function (e) {
111
+					e.preventDefault();
112
+					plot.pan(offset);
113
+				});
114
+		}
115
+
116
+		addArrow("left", 55, 60, { left: -100 });
117
+		addArrow("right", 25, 60, { left: 100 });
118
+		addArrow("up", 40, 45, { top: -100 });
119
+		addArrow("down", 40, 75, { top: 100 });
120
+
121
+		// Add the Flot version string to the footer
122
+
123
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
124
+	});
125
+
126
+	</script>
127
+</head>
128
+<body>
129
+
130
+	<div id="header">
131
+		<h2>Navigation</h2>
132
+	</div>
133
+
134
+	<div id="content">
135
+
136
+		<div class="demo-container">
137
+			<div id="placeholder" class="demo-placeholder"></div>
138
+		</div>
139
+
140
+		<p class="message"></p>
141
+
142
+		<p>With the navigate plugin it is easy to add panning and zooming. Drag to pan, double click to zoom (or use the mouse scrollwheel).</p>
143
+
144
+		<p>The plugin fires events (useful for synchronizing several plots) and adds a couple of public methods so you can easily build a little user interface around it, like the little buttons at the top right in the plot.</p>
145
+
146
+	</div>
147
+
148
+	<div id="footer">
149
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
150
+	</div>
151
+
152
+</body>
153
+</html>
... ...
@@ -0,0 +1,79 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Percentiles</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.fillbetween.js"></script>
11
+	<script type="text/javascript">
12
+
13
+	$(function() {
14
+
15
+		var males = {"15%": [[2, 88.0], [3, 93.3], [4, 102.0], [5, 108.5], [6, 115.7], [7, 115.6], [8, 124.6], [9, 130.3], [10, 134.3], [11, 141.4], [12, 146.5], [13, 151.7], [14, 159.9], [15, 165.4], [16, 167.8], [17, 168.7], [18, 169.5], [19, 168.0]], "90%": [[2, 96.8], [3, 105.2], [4, 113.9], [5, 120.8], [6, 127.0], [7, 133.1], [8, 139.1], [9, 143.9], [10, 151.3], [11, 161.1], [12, 164.8], [13, 173.5], [14, 179.0], [15, 182.0], [16, 186.9], [17, 185.2], [18, 186.3], [19, 186.6]], "25%": [[2, 89.2], [3, 94.9], [4, 104.4], [5, 111.4], [6, 117.5], [7, 120.2], [8, 127.1], [9, 132.9], [10, 136.8], [11, 144.4], [12, 149.5], [13, 154.1], [14, 163.1], [15, 169.2], [16, 170.4], [17, 171.2], [18, 172.4], [19, 170.8]], "10%": [[2, 86.9], [3, 92.6], [4, 99.9], [5, 107.0], [6, 114.0], [7, 113.5], [8, 123.6], [9, 129.2], [10, 133.0], [11, 140.6], [12, 145.2], [13, 149.7], [14, 158.4], [15, 163.5], [16, 166.9], [17, 167.5], [18, 167.1], [19, 165.3]], "mean": [[2, 91.9], [3, 98.5], [4, 107.1], [5, 114.4], [6, 120.6], [7, 124.7], [8, 131.1], [9, 136.8], [10, 142.3], [11, 150.0], [12, 154.7], [13, 161.9], [14, 168.7], [15, 173.6], [16, 175.9], [17, 176.6], [18, 176.8], [19, 176.7]], "75%": [[2, 94.5], [3, 102.1], [4, 110.8], [5, 117.9], [6, 124.0], [7, 129.3], [8, 134.6], [9, 141.4], [10, 147.0], [11, 156.1], [12, 160.3], [13, 168.3], [14, 174.7], [15, 178.0], [16, 180.2], [17, 181.7], [18, 181.3], [19, 182.5]], "85%": [[2, 96.2], [3, 103.8], [4, 111.8], [5, 119.6], [6, 125.6], [7, 131.5], [8, 138.0], [9, 143.3], [10, 149.3], [11, 159.8], [12, 162.5], [13, 171.3], [14, 177.5], [15, 180.2], [16, 183.8], [17, 183.4], [18, 183.5], [19, 185.5]], "50%": [[2, 91.9], [3, 98.2], [4, 106.8], [5, 114.6], [6, 120.8], [7, 125.2], [8, 130.3], [9, 137.1], [10, 141.5], [11, 149.4], [12, 153.9], [13, 162.2], [14, 169.0], [15, 174.8], [16, 176.0], [17, 176.8], [18, 176.4], [19, 177.4]]};
16
+
17
+		var females = {"15%": [[2, 84.8], [3, 93.7], [4, 100.6], [5, 105.8], [6, 113.3], [7, 119.3], [8, 124.3], [9, 131.4], [10, 136.9], [11, 143.8], [12, 149.4], [13, 151.2], [14, 152.3], [15, 155.9], [16, 154.7], [17, 157.0], [18, 156.1], [19, 155.4]], "90%": [[2, 95.6], [3, 104.1], [4, 111.9], [5, 119.6], [6, 127.6], [7, 133.1], [8, 138.7], [9, 147.1], [10, 152.8], [11, 161.3], [12, 166.6], [13, 167.9], [14, 169.3], [15, 170.1], [16, 172.4], [17, 169.2], [18, 171.1], [19, 172.4]], "25%": [[2, 87.2], [3, 95.9], [4, 101.9], [5, 107.4], [6, 114.8], [7, 121.4], [8, 126.8], [9, 133.4], [10, 138.6], [11, 146.2], [12, 152.0], [13, 153.8], [14, 155.7], [15, 158.4], [16, 157.0], [17, 158.5], [18, 158.4], [19, 158.1]], "10%": [[2, 84.0], [3, 91.9], [4, 99.2], [5, 105.2], [6, 112.7], [7, 118.0], [8, 123.3], [9, 130.2], [10, 135.0], [11, 141.1], [12, 148.3], [13, 150.0], [14, 150.7], [15, 154.3], [16, 153.6], [17, 155.6], [18, 154.7], [19, 153.1]], "mean": [[2, 90.2], [3, 98.3], [4, 105.2], [5, 112.2], [6, 119.0], [7, 125.8], [8, 131.3], [9, 138.6], [10, 144.2], [11, 151.3], [12, 156.7], [13, 158.6], [14, 160.5], [15, 162.1], [16, 162.9], [17, 162.2], [18, 163.0], [19, 163.1]], "75%": [[2, 93.2], [3, 101.5], [4, 107.9], [5, 116.6], [6, 122.8], [7, 129.3], [8, 135.2], [9, 143.7], [10, 148.7], [11, 156.9], [12, 160.8], [13, 163.0], [14, 165.0], [15, 165.8], [16, 168.7], [17, 166.2], [18, 167.6], [19, 168.0]], "85%": [[2, 94.5], [3, 102.8], [4, 110.4], [5, 119.0], [6, 125.7], [7, 131.5], [8, 137.9], [9, 146.0], [10, 151.3], [11, 159.9], [12, 164.0], [13, 166.5], [14, 167.5], [15, 168.5], [16, 171.5], [17, 168.0], [18, 169.8], [19, 170.3]], "50%": [[2, 90.2], [3, 98.1], [4, 105.2], [5, 111.7], [6, 118.2], [7, 125.6], [8, 130.5], [9, 138.3], [10, 143.7], [11, 151.4], [12, 156.7], [13, 157.7], [14, 161.0], [15, 162.0], [16, 162.8], [17, 162.2], [18, 162.8], [19, 163.3]]};
18
+
19
+		var dataset = [
20
+			{ label: "Female mean", data: females["mean"], lines: { show: true }, color: "rgb(255,50,50)" },
21
+			{ id: "f15%", data: females["15%"], lines: { show: true, lineWidth: 0, fill: false }, color: "rgb(255,50,50)" },
22
+			{ id: "f25%", data: females["25%"], lines: { show: true, lineWidth: 0, fill: 0.2 }, color: "rgb(255,50,50)", fillBetween: "f15%" },
23
+			{ id: "f50%", data: females["50%"], lines: { show: true, lineWidth: 0.5, fill: 0.4, shadowSize: 0 }, color: "rgb(255,50,50)", fillBetween: "f25%" },
24
+			{ id: "f75%", data: females["75%"], lines: { show: true, lineWidth: 0, fill: 0.4 }, color: "rgb(255,50,50)", fillBetween: "f50%" },
25
+			{ id: "f85%", data: females["85%"], lines: { show: true, lineWidth: 0, fill: 0.2 }, color: "rgb(255,50,50)", fillBetween: "f75%" },
26
+
27
+			{ label: "Male mean", data: males["mean"], lines: { show: true }, color: "rgb(50,50,255)" },
28
+			{ id: "m15%", data: males["15%"], lines: { show: true, lineWidth: 0, fill: false }, color: "rgb(50,50,255)" },
29
+			{ id: "m25%", data: males["25%"], lines: { show: true, lineWidth: 0, fill: 0.2 }, color: "rgb(50,50,255)", fillBetween: "m15%" },
30
+			{ id: "m50%", data: males["50%"], lines: { show: true, lineWidth: 0.5, fill: 0.4, shadowSize: 0 }, color: "rgb(50,50,255)", fillBetween: "m25%" },
31
+			{ id: "m75%", data: males["75%"], lines: { show: true, lineWidth: 0, fill: 0.4 }, color: "rgb(50,50,255)", fillBetween: "m50%" },
32
+			{ id: "m85%", data: males["85%"], lines: { show: true, lineWidth: 0, fill: 0.2 }, color: "rgb(50,50,255)", fillBetween: "m75%" }
33
+		];
34
+
35
+		$.plot($("#placeholder"), dataset, {
36
+			xaxis: {
37
+				tickDecimals: 0
38
+			},
39
+			yaxis: {
40
+				tickFormatter: function (v) {
41
+					return v + " cm";
42
+				}
43
+			},
44
+			legend: {
45
+				position: "se"
46
+			}
47
+		});
48
+
49
+		// Add the Flot version string to the footer
50
+
51
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
52
+	});
53
+
54
+	</script>
55
+</head>
56
+<body>
57
+
58
+	<div id="header">
59
+		<h2>Percentiles</h2>
60
+	</div>
61
+
62
+	<div id="content">
63
+
64
+		<div class="demo-container">
65
+			<div id="placeholder" class="demo-placeholder"></div>
66
+		</div>
67
+
68
+		<p>Height in centimeters of individuals from the US (2003-2006) as function of age in years (source: <a href="http://www.cdc.gov/nchs/data/nhsr/nhsr010.pdf">CDC</a>). The 15%-85%, 25%-75% and 50% percentiles are indicated.</p>
69
+
70
+		<p>For each point of a filled curve, you can specify an arbitrary bottom. As this example illustrates, this can be useful for plotting percentiles. If you have the data sets available without appropriate fill bottoms, you can use the fillbetween plugin to compute the data point bottoms automatically.</p>
71
+
72
+	</div>
73
+
74
+	<div id="footer">
75
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
76
+	</div>
77
+
78
+</body>
79
+</html>
... ...
@@ -0,0 +1,122 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Real-time updates</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script type="text/javascript">
11
+
12
+	$(function() {
13
+
14
+		// We use an inline data source in the example, usually data would
15
+		// be fetched from a server
16
+
17
+		var data = [],
18
+			totalPoints = 300;
19
+
20
+		function getRandomData() {
21
+
22
+			if (data.length > 0)
23
+				data = data.slice(1);
24
+
25
+			// Do a random walk
26
+
27
+			while (data.length < totalPoints) {
28
+
29
+				var prev = data.length > 0 ? data[data.length - 1] : 50,
30
+					y = prev + Math.random() * 10 - 5;
31
+
32
+				if (y < 0) {
33
+					y = 0;
34
+				} else if (y > 100) {
35
+					y = 100;
36
+				}
37
+
38
+				data.push(y);
39
+			}
40
+
41
+			// Zip the generated y values with the x values
42
+
43
+			var res = [];
44
+			for (var i = 0; i < data.length; ++i) {
45
+				res.push([i, data[i]])
46
+			}
47
+
48
+			return res;
49
+		}
50
+
51
+		// Set up the control widget
52
+
53
+		var updateInterval = 30;
54
+		$("#updateInterval").val(updateInterval).change(function () {
55
+			var v = $(this).val();
56
+			if (v && !isNaN(+v)) {
57
+				updateInterval = +v;
58
+				if (updateInterval < 1) {
59
+					updateInterval = 1;
60
+				} else if (updateInterval > 2000) {
61
+					updateInterval = 2000;
62
+				}
63
+				$(this).val("" + updateInterval);
64
+			}
65
+		});
66
+
67
+		var plot = $.plot("#placeholder", [ getRandomData() ], {
68
+			series: {
69
+				shadowSize: 0	// Drawing is faster without shadows
70
+			},
71
+			yaxis: {
72
+				min: 0,
73
+				max: 100
74
+			},
75
+			xaxis: {
76
+				show: false
77
+			}
78
+		});
79
+
80
+		function update() {
81
+
82
+			plot.setData([getRandomData()]);
83
+
84
+			// Since the axes don't change, we don't need to call plot.setupGrid()
85
+
86
+			plot.draw();
87
+			setTimeout(update, updateInterval);
88
+		}
89
+
90
+		update();
91
+
92
+		// Add the Flot version string to the footer
93
+
94
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
95
+	});
96
+
97
+	</script>
98
+</head>
99
+<body>
100
+
101
+	<div id="header">
102
+		<h2>Real-time updates</h2>
103
+	</div>
104
+
105
+	<div id="content">
106
+
107
+		<div class="demo-container">
108
+			<div id="placeholder" class="demo-placeholder"></div>
109
+		</div>
110
+
111
+		<p>You can update a chart periodically to get a real-time effect by using a timer to insert the new data in the plot and redraw it.</p>
112
+
113
+		<p>Time between updates: <input id="updateInterval" type="text" value="" style="text-align: right; width:5em"> milliseconds</p>
114
+
115
+	</div>
116
+
117
+	<div id="footer">
118
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
119
+	</div>
120
+
121
+</body>
122
+</html>
... ...
@@ -0,0 +1,76 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Resizing</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<link href="../shared/jquery-ui/jquery-ui.min.css" rel="stylesheet" type="text/css">
8
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
9
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
10
+	<script language="javascript" type="text/javascript" src="../shared/jquery-ui/jquery-ui.min.js"></script>
11
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
12
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.resize.js"></script>
13
+	<script type="text/javascript">
14
+
15
+	$(function() {
16
+
17
+		var d1 = [];
18
+		for (var i = 0; i < 14; i += 0.5) {
19
+			d1.push([i, Math.sin(i)]);
20
+		}
21
+
22
+		var d2 = [[0, 3], [4, 8], [8, 5], [9, 13]];
23
+		var d3 = [[0, 12], [7, 12], null, [7, 2.5], [12, 2.5]];
24
+
25
+		var placeholder = $("#placeholder");
26
+		var plot = $.plot(placeholder, [d1, d2, d3]);
27
+
28
+		// The plugin includes a jQuery plugin for adding resize events to any
29
+		// element.  Add a callback so we can display the placeholder size.
30
+
31
+		placeholder.resize(function () {
32
+			$(".message").text("Placeholder is now "
33
+				+ $(this).width() + "x" + $(this).height()
34
+				+ " pixels");
35
+		});
36
+
37
+		$(".demo-container").resizable({
38
+			maxWidth: 900,
39
+			maxHeight: 500,
40
+			minWidth: 450,
41
+			minHeight: 250
42
+		});
43
+
44
+		// Add the Flot version string to the footer
45
+
46
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
47
+	});
48
+
49
+	</script>
50
+</head>
51
+<body>
52
+
53
+	<div id="header">
54
+		<h2>Resizing</h2>
55
+	</div>
56
+
57
+	<div id="content">
58
+
59
+		<div class="demo-container">
60
+			<div id="placeholder" class="demo-placeholder"></div>
61
+		</div>
62
+
63
+		<p class="message"></p>
64
+
65
+		<p>Sometimes it makes more sense to just let the plot take up the available space. In that case, we need to redraw the plot each time the placeholder changes its size. If you include the resize plugin, this is handled automatically.</p>
66
+
67
+		<p>Drag the bottom and right sides of the plot to resize it.</p>
68
+
69
+	</div>
70
+
71
+	<div id="footer">
72
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
73
+	</div>
74
+
75
+</body>
76
+</html>
... ...
@@ -0,0 +1,152 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Selection</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.selection.js"></script>
11
+	<script type="text/javascript">
12
+
13
+	$(function() {
14
+
15
+		// Shim allowing us to get the state of the check-box on jQuery versions
16
+		// prior to 1.6, when prop was added.  The reason we don't just use attr
17
+		// is because it doesn't work in jQuery versions 1.9.x and later.
18
+
19
+		// TODO: Remove this once Flot's minimum supported jQuery reaches 1.6.
20
+		if (typeof $.fn.prop != 'function') {
21
+		    $.fn.prop = $.fn.attr;
22
+		}
23
+
24
+		var data = [{
25
+			label: "United States",
26
+			data: [[1990, 18.9], [1991, 18.7], [1992, 18.4], [1993, 19.3], [1994, 19.5], [1995, 19.3], [1996, 19.4], [1997, 20.2], [1998, 19.8], [1999, 19.9], [2000, 20.4], [2001, 20.1], [2002, 20.0], [2003, 19.8], [2004, 20.4]]
27
+		}, {
28
+			label: "Russia", 
29
+			data: [[1992, 13.4], [1993, 12.2], [1994, 10.6], [1995, 10.2], [1996, 10.1], [1997, 9.7], [1998, 9.5], [1999, 9.7], [2000, 9.9], [2001, 9.9], [2002, 9.9], [2003, 10.3], [2004, 10.5]]
30
+		}, {
31
+			label: "United Kingdom",
32
+			data: [[1990, 10.0], [1991, 11.3], [1992, 9.9], [1993, 9.6], [1994, 9.5], [1995, 9.5], [1996, 9.9], [1997, 9.3], [1998, 9.2], [1999, 9.2], [2000, 9.5], [2001, 9.6], [2002, 9.3], [2003, 9.4], [2004, 9.79]]
33
+		}, {
34
+			label: "Germany",
35
+			data: [[1990, 12.4], [1991, 11.2], [1992, 10.8], [1993, 10.5], [1994, 10.4], [1995, 10.2], [1996, 10.5], [1997, 10.2], [1998, 10.1], [1999, 9.6], [2000, 9.7], [2001, 10.0], [2002, 9.7], [2003, 9.8], [2004, 9.79]]
36
+		}, {
37
+			label: "Denmark",
38
+			data: [[1990, 9.7], [1991, 12.1], [1992, 10.3], [1993, 11.3], [1994, 11.7], [1995, 10.6], [1996, 12.8], [1997, 10.8], [1998, 10.3], [1999, 9.4], [2000, 8.7], [2001, 9.0], [2002, 8.9], [2003, 10.1], [2004, 9.80]]
39
+		}, {
40
+			label: "Sweden",
41
+			data: [[1990, 5.8], [1991, 6.0], [1992, 5.9], [1993, 5.5], [1994, 5.7], [1995, 5.3], [1996, 6.1], [1997, 5.4], [1998, 5.4], [1999, 5.1], [2000, 5.2], [2001, 5.4], [2002, 6.2], [2003, 5.9], [2004, 5.89]]
42
+		}, {
43
+			label: "Norway",
44
+			data: [[1990, 8.3], [1991, 8.3], [1992, 7.8], [1993, 8.3], [1994, 8.4], [1995, 5.9], [1996, 6.4], [1997, 6.7], [1998, 6.9], [1999, 7.6], [2000, 7.4], [2001, 8.1], [2002, 12.5], [2003, 9.9], [2004, 19.0]]
45
+		}];
46
+
47
+		var options = {
48
+			series: {
49
+				lines: {
50
+					show: true
51
+				},
52
+				points: {
53
+					show: true
54
+				}
55
+			},
56
+			legend: {
57
+				noColumns: 2
58
+			},
59
+			xaxis: {
60
+				tickDecimals: 0
61
+			},
62
+			yaxis: {
63
+				min: 0
64
+			},
65
+			selection: {
66
+				mode: "x"
67
+			}
68
+		};
69
+
70
+		var placeholder = $("#placeholder");
71
+
72
+		placeholder.bind("plotselected", function (event, ranges) {
73
+
74
+			$("#selection").text(ranges.xaxis.from.toFixed(1) + " to " + ranges.xaxis.to.toFixed(1));
75
+
76
+			var zoom = $("#zoom").prop("checked");
77
+
78
+			if (zoom) {
79
+				$.each(plot.getXAxes(), function(_, axis) {
80
+					var opts = axis.options;
81
+					opts.min = ranges.xaxis.from;
82
+					opts.max = ranges.xaxis.to;
83
+				});
84
+				plot.setupGrid();
85
+				plot.draw();
86
+				plot.clearSelection();
87
+			}
88
+		});
89
+
90
+		placeholder.bind("plotunselected", function (event) {
91
+			$("#selection").text("");
92
+		});
93
+
94
+		var plot = $.plot(placeholder, data, options);
95
+
96
+		$("#clearSelection").click(function () {
97
+			plot.clearSelection();
98
+		});
99
+
100
+		$("#setSelection").click(function () {
101
+			plot.setSelection({
102
+				xaxis: {
103
+					from: 1994,
104
+					to: 1995
105
+				}
106
+			});
107
+		});
108
+
109
+		// Add the Flot version string to the footer
110
+
111
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
112
+	});
113
+
114
+	</script>
115
+</head>
116
+<body>
117
+
118
+	<div id="header">
119
+		<h2>Selection</h2>
120
+	</div>
121
+
122
+	<div id="content">
123
+
124
+		<div class="demo-container">
125
+			<div id="placeholder" class="demo-placeholder"></div>
126
+		</div>
127
+
128
+		<p>1000 kg. CO<sub>2</sub> emissions per year per capita for various countries (source: <a href="http://en.wikipedia.org/wiki/List_of_countries_by_carbon_dioxide_emissions_per_capita">Wikipedia</a>).</p>
129
+
130
+		<p>Flot supports selections through the selection plugin. You can enable rectangular selection or one-dimensional selection if the user should only be able to select on one axis. Try left-click and drag on the plot above where selection on the x axis is enabled.</p>
131
+
132
+		<p>You selected: <span id="selection"></span></p>
133
+
134
+		<p>The plot command returns a plot object you can use to control the selection. Click the buttons below.</p>
135
+
136
+		<p>
137
+			<button id="clearSelection">Clear selection</button>
138
+			<button id="setSelection">Select year 1994</button>
139
+		</p>
140
+
141
+		<p>Selections are really useful for zooming. Just replot the chart with min and max values for the axes set to the values in the "plotselected" event triggered. Enable the checkbox below and select a region again.</p>
142
+
143
+		<p><label><input id="zoom" type="checkbox"></input>Zoom to selection.</label></p>
144
+
145
+	</div>
146
+
147
+	<div id="footer">
148
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
149
+	</div>
150
+
151
+</body>
152
+</html>
... ...
@@ -0,0 +1,150 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Error Bars</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.errorbars.js"></script>
11
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.navigate.js"></script>
12
+	<script type="text/javascript">
13
+
14
+	$(function() {
15
+
16
+		function drawArrow(ctx, x, y, radius){
17
+			ctx.beginPath();
18
+			ctx.moveTo(x + radius, y + radius);
19
+			ctx.lineTo(x, y);
20
+			ctx.lineTo(x - radius, y + radius);
21
+			ctx.stroke();
22
+		}
23
+
24
+		function drawSemiCircle(ctx, x, y, radius){
25
+			ctx.beginPath();
26
+			ctx.arc(x, y, radius, 0, Math.PI, false);
27
+			ctx.moveTo(x - radius, y);
28
+			ctx.lineTo(x + radius, y);
29
+			ctx.stroke();
30
+		}
31
+
32
+		var data1 = [
33
+			[1,1,.5,.1,.3],
34
+			[2,2,.3,.5,.2],
35
+			[3,3,.9,.5,.2],
36
+			[1.5,-.05,.5,.1,.3],
37
+			[3.15,1.,.5,.1,.3],
38
+			[2.5,-1.,.5,.1,.3]
39
+		];
40
+
41
+		var data1_points = {
42
+			show: true,
43
+			radius: 5,
44
+			fillColor: "blue", 
45
+			errorbars: "xy", 
46
+			xerr: {show: true, asymmetric: true, upperCap: "-", lowerCap: "-"}, 
47
+			yerr: {show: true, color: "red", upperCap: "-"}
48
+		};
49
+
50
+		var data2 = [
51
+			[.7,3,.2,.4],
52
+			[1.5,2.2,.3,.4],
53
+			[2.3,1,.5,.2]
54
+		];
55
+
56
+		var data2_points = {
57
+			show: true,
58
+			radius: 5,
59
+			errorbars: "y", 
60
+			yerr: {show:true, asymmetric:true, upperCap: drawArrow, lowerCap: drawSemiCircle}
61
+		};
62
+
63
+		var data3 = [
64
+			[1,2,.4],
65
+			[2,0.5,.3],
66
+			[2.7,2,.5]
67
+		];
68
+
69
+		var data3_points = {
70
+			//do not show points
71
+			radius: 0,
72
+			errorbars: "y", 
73
+			yerr: {show:true, upperCap: "-", lowerCap: "-", radius: 5}
74
+		};
75
+
76
+		var data4 = [
77
+			[1.3, 1],
78
+			[1.75, 2.5],
79
+			[2.5, 0.5]
80
+		];
81
+
82
+		var data4_errors = [0.1, 0.4, 0.2];
83
+		for (var i = 0; i < data4.length; i++) {
84
+			data4_errors[i] = data4[i].concat(data4_errors[i])
85
+		}
86
+
87
+		var data = [
88
+			{color: "blue", points: data1_points, data: data1, label: "data1"}, 
89
+			{color: "red",  points: data2_points, data: data2, label: "data2"},
90
+			{color: "green", lines: {show: true}, points: data3_points, data: data3, label: "data3"},
91
+			// bars with errors
92
+			{color: "orange", bars: {show: true, align: "center", barWidth: 0.25}, data: data4, label: "data4"},
93
+			{color: "orange", points: data3_points, data: data4_errors}
94
+		];
95
+
96
+		$.plot($("#placeholder"), data , {
97
+			legend: {
98
+				position: "sw",
99
+				show: true
100
+			},
101
+			series: {
102
+				lines: {
103
+					show: false
104
+				}
105
+			},
106
+			xaxis: {
107
+				min: 0.6,
108
+				max: 3.1
109
+			},
110
+			yaxis: {
111
+				min: 0,
112
+				max: 3.5
113
+			},
114
+			zoom: {
115
+				interactive: true
116
+			},
117
+			pan: {
118
+				interactive: true
119
+			}
120
+		});
121
+
122
+		// Add the Flot version string to the footer
123
+
124
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
125
+	});
126
+
127
+	</script>
128
+</head>
129
+<body>
130
+
131
+	<div id="header">
132
+		<h2>Error Bars</h2>
133
+	</div>
134
+
135
+	<div id="content">
136
+
137
+		<div class="demo-container">
138
+			<div id="placeholder" class="demo-placeholder"></div>
139
+		</div>
140
+
141
+		<p>With the errorbars plugin you can plot error bars to show standard deviation and other useful statistical properties.</p>
142
+
143
+	</div>
144
+
145
+	<div id="footer">
146
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
147
+	</div>
148
+
149
+</body>
150
+</html>
... ...
@@ -0,0 +1,818 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Pie Charts</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<style type="text/css">
8
+
9
+	.demo-container {
10
+		position: relative;
11
+		height: 400px;
12
+	}
13
+
14
+	#placeholder {
15
+		width: 550px;
16
+	}
17
+
18
+	#menu {
19
+		position: absolute;
20
+		top: 20px;
21
+		left: 625px;
22
+		bottom: 20px;
23
+		right: 20px;
24
+		width: 200px;
25
+	}
26
+
27
+	#menu button {
28
+		display: inline-block;
29
+		width: 200px;
30
+		padding: 3px 0 2px 0;
31
+		margin-bottom: 4px;
32
+		background: #eee;
33
+		border: 1px solid #999;
34
+		border-radius: 2px;
35
+		font-size: 16px;
36
+		-o-box-shadow: 0 1px 2px rgba(0,0,0,0.15);
37
+		-ms-box-shadow: 0 1px 2px rgba(0,0,0,0.15);
38
+		-moz-box-shadow: 0 1px 2px rgba(0,0,0,0.15);
39
+		-webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.15);
40
+		box-shadow: 0 1px 2px rgba(0,0,0,0.15);
41
+		cursor: pointer;
42
+	}
43
+
44
+	#description {
45
+		margin: 15px 10px 20px 10px;
46
+	}
47
+
48
+	#code {
49
+		display: block;
50
+		width: 870px;
51
+		padding: 15px;
52
+		margin: 10px auto;
53
+		border: 1px dashed #999;
54
+		background-color: #f8f8f8;
55
+		font-size: 16px;
56
+		line-height: 20px;
57
+		color: #666;
58
+	}
59
+
60
+	ul {
61
+		font-size: 10pt;
62
+	}
63
+
64
+	ul li {
65
+		margin-bottom: 0.5em;
66
+	}
67
+
68
+	ul.options li {
69
+		list-style: none;
70
+		margin-bottom: 1em;
71
+	}
72
+
73
+	ul li i {
74
+		color: #999;
75
+	}
76
+
77
+	</style>
78
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
79
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
80
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
81
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.pie.js"></script>
82
+	<script type="text/javascript">
83
+
84
+	$(function() {
85
+
86
+		// Example Data
87
+
88
+		//var data = [
89
+		//	{ label: "Series1",  data: 10},
90
+		//	{ label: "Series2",  data: 30},
91
+		//	{ label: "Series3",  data: 90},
92
+		//	{ label: "Series4",  data: 70},
93
+		//	{ label: "Series5",  data: 80},
94
+		//	{ label: "Series6",  data: 110}
95
+		//];
96
+
97
+		//var data = [
98
+		//	{ label: "Series1",  data: [[1,10]]},
99
+		//	{ label: "Series2",  data: [[1,30]]},
100
+		//	{ label: "Series3",  data: [[1,90]]},
101
+		//	{ label: "Series4",  data: [[1,70]]},
102
+		//	{ label: "Series5",  data: [[1,80]]},
103
+		//	{ label: "Series6",  data: [[1,0]]}
104
+		//];
105
+
106
+		//var data = [
107
+		//	{ label: "Series A",  data: 0.2063},
108
+		//	{ label: "Series B",  data: 38888}
109
+		//];
110
+
111
+		// Randomly Generated Data
112
+
113
+		var data = [],
114
+			series = Math.floor(Math.random() * 6) + 3;
115
+
116
+		for (var i = 0; i < series; i++) {
117
+			data[i] = {
118
+				label: "Series" + (i + 1),
119
+				data: Math.floor(Math.random() * 100) + 1
120
+			}
121
+		}
122
+
123
+		var placeholder = $("#placeholder");
124
+
125
+		$("#example-1").click(function() {
126
+
127
+			placeholder.unbind();
128
+
129
+			$("#title").text("Default pie chart");
130
+			$("#description").text("The default pie chart with no options set.");
131
+
132
+			$.plot(placeholder, data, {
133
+				series: {
134
+					pie: { 
135
+						show: true
136
+					}
137
+				}
138
+			});
139
+
140
+			setCode([
141
+				"$.plot('#placeholder', data, {",
142
+				"    series: {",
143
+				"        pie: {",
144
+				"            show: true",
145
+				"        }",
146
+				"    }",
147
+				"});"
148
+			]);
149
+		});
150
+
151
+		$("#example-2").click(function() {
152
+
153
+			placeholder.unbind();
154
+
155
+			$("#title").text("Default without legend");
156
+			$("#description").text("The default pie chart when the legend is disabled. Since the labels would normally be outside the container, the chart is resized to fit.");
157
+
158
+			$.plot(placeholder, data, {
159
+				series: {
160
+					pie: { 
161
+						show: true
162
+					}
163
+				},
164
+				legend: {
165
+					show: false
166
+				}
167
+			});
168
+
169
+			setCode([
170
+				"$.plot('#placeholder', data, {",
171
+				"    series: {",
172
+				"        pie: {",
173
+				"            show: true",
174
+				"        }",
175
+				"    },",
176
+				"    legend: {",
177
+				"        show: false",
178
+				"    }",
179
+				"});"
180
+			]);
181
+		});
182
+
183
+		$("#example-3").click(function() {
184
+
185
+			placeholder.unbind();
186
+
187
+			$("#title").text("Custom Label Formatter");
188
+			$("#description").text("Added a semi-transparent background to the labels and a custom labelFormatter function.");
189
+
190
+			$.plot(placeholder, data, {
191
+				series: {
192
+					pie: { 
193
+						show: true,
194
+						radius: 1,
195
+						label: {
196
+							show: true,
197
+							radius: 1,
198
+							formatter: labelFormatter,
199
+							background: {
200
+								opacity: 0.8
201
+							}
202
+						}
203
+					}
204
+				},
205
+				legend: {
206
+					show: false
207
+				}
208
+			});
209
+
210
+			setCode([
211
+				"$.plot('#placeholder', data, {",
212
+				"    series: {",
213
+				"        pie: {",
214
+				"            show: true,",
215
+				"            radius: 1,",
216
+				"            label: {",
217
+				"                show: true,",
218
+				"                radius: 1,",
219
+				"                formatter: labelFormatter,",
220
+				"                background: {",
221
+				"                    opacity: 0.8",
222
+				"                }",
223
+				"            }",
224
+				"        }",
225
+				"    },",
226
+				"    legend: {",
227
+				"        show: false",
228
+				"    }",
229
+				"});"
230
+			]);
231
+		});
232
+
233
+		$("#example-4").click(function() {
234
+
235
+			placeholder.unbind();
236
+
237
+			$("#title").text("Label Radius");
238
+			$("#description").text("Slightly more transparent label backgrounds and adjusted the radius values to place them within the pie.");
239
+
240
+			$.plot(placeholder, data, {
241
+				series: {
242
+					pie: { 
243
+						show: true,
244
+						radius: 1,
245
+						label: {
246
+							show: true,
247
+							radius: 3/4,
248
+							formatter: labelFormatter,
249
+							background: {
250
+								opacity: 0.5
251
+							}
252
+						}
253
+					}
254
+				},
255
+				legend: {
256
+					show: false
257
+				}
258
+			});
259
+
260
+			setCode([
261
+				"$.plot('#placeholder', data, {",
262
+				"    series: {",
263
+				"        pie: {",
264
+				"            show: true,",
265
+				"            radius: 1,",
266
+				"            label: {",
267
+				"                show: true,",
268
+				"                radius: 3/4,",
269
+				"                formatter: labelFormatter,",
270
+				"                background: {",
271
+				"                    opacity: 0.5",
272
+				"                }",
273
+				"            }",
274
+				"        }",
275
+				"    },",
276
+				"    legend: {",
277
+				"        show: false",
278
+				"    }",
279
+				"});"
280
+			]);
281
+		});
282
+
283
+		$("#example-5").click(function() {
284
+
285
+			placeholder.unbind();
286
+
287
+			$("#title").text("Label Styles #1");
288
+			$("#description").text("Semi-transparent, black-colored label background.");
289
+
290
+			$.plot(placeholder, data, {
291
+				series: {
292
+					pie: { 
293
+						show: true,
294
+						radius: 1,
295
+						label: {
296
+							show: true,
297
+							radius: 3/4,
298
+							formatter: labelFormatter,
299
+							background: { 
300
+								opacity: 0.5,
301
+								color: "#000"
302
+							}
303
+						}
304
+					}
305
+				},
306
+				legend: {
307
+					show: false
308
+				}
309
+			});
310
+
311
+			setCode([
312
+				"$.plot('#placeholder', data, {",
313
+				"    series: {",
314
+				"        pie: { ",
315
+				"            show: true,",
316
+				"            radius: 1,",
317
+				"            label: {",
318
+				"                show: true,",
319
+				"                radius: 3/4,",
320
+				"                formatter: labelFormatter,",
321
+				"                background: { ",
322
+				"                    opacity: 0.5,",
323
+				"                    color: '#000'",
324
+				"                }",
325
+				"            }",
326
+				"        }",
327
+				"    },",
328
+				"    legend: {",
329
+				"        show: false",
330
+				"    }",
331
+				"});"
332
+			]);
333
+		});
334
+
335
+		$("#example-6").click(function() {
336
+
337
+			placeholder.unbind();
338
+
339
+			$("#title").text("Label Styles #2");
340
+			$("#description").text("Semi-transparent, black-colored label background placed at pie edge.");
341
+
342
+			$.plot(placeholder, data, {
343
+				series: {
344
+					pie: { 
345
+						show: true,
346
+						radius: 3/4,
347
+						label: {
348
+							show: true,
349
+							radius: 3/4,
350
+							formatter: labelFormatter,
351
+							background: { 
352
+								opacity: 0.5,
353
+								color: "#000"
354
+							}
355
+						}
356
+					}
357
+				},
358
+				legend: {
359
+					show: false
360
+				}
361
+			});
362
+
363
+			setCode([
364
+				"$.plot('#placeholder', data, {",
365
+				"    series: {",
366
+				"        pie: {",
367
+				"            show: true,",
368
+				"            radius: 3/4,",
369
+				"            label: {",
370
+				"                show: true,",
371
+				"                radius: 3/4,",
372
+				"                formatter: labelFormatter,",
373
+				"                background: {",
374
+				"                    opacity: 0.5,",
375
+				"                    color: '#000'",
376
+				"                }",
377
+				"            }",
378
+				"        }",
379
+				"    },",
380
+				"    legend: {",
381
+				"        show: false",
382
+				"    }",
383
+				"});"
384
+			]);
385
+		});
386
+
387
+		$("#example-7").click(function() {
388
+
389
+			placeholder.unbind();
390
+
391
+			$("#title").text("Hidden Labels");
392
+			$("#description").text("Labels can be hidden if the slice is less than a given percentage of the pie (10% in this case).");
393
+
394
+			$.plot(placeholder, data, {
395
+				series: {
396
+					pie: { 
397
+						show: true,
398
+						radius: 1,
399
+						label: {
400
+							show: true,
401
+							radius: 2/3,
402
+							formatter: labelFormatter,
403
+							threshold: 0.1
404
+						}
405
+					}
406
+				},
407
+				legend: {
408
+					show: false
409
+				}
410
+			});
411
+
412
+			setCode([
413
+				"$.plot('#placeholder', data, {",
414
+				"    series: {",
415
+				"        pie: {",
416
+				"            show: true,",
417
+				"            radius: 1,",
418
+				"            label: {",
419
+				"                show: true,",
420
+				"                radius: 2/3,",
421
+				"                formatter: labelFormatter,",
422
+				"                threshold: 0.1",
423
+				"            }",
424
+				"        }",
425
+				"    },",
426
+				"    legend: {",
427
+				"        show: false",
428
+				"    }",
429
+				"});"
430
+			]);
431
+		});
432
+
433
+		$("#example-8").click(function() {
434
+
435
+			placeholder.unbind();
436
+
437
+			$("#title").text("Combined Slice");
438
+			$("#description").text("Multiple slices less than a given percentage (5% in this case) of the pie can be combined into a single, larger slice.");
439
+
440
+			$.plot(placeholder, data, {
441
+				series: {
442
+					pie: { 
443
+						show: true,
444
+						combine: {
445
+							color: "#999",
446
+							threshold: 0.05
447
+						}
448
+					}
449
+				},
450
+				legend: {
451
+					show: false
452
+				}
453
+			});
454
+
455
+			setCode([
456
+				"$.plot('#placeholder', data, {",
457
+				"    series: {",
458
+				"        pie: {",
459
+				"            show: true,",
460
+				"            combine: {",
461
+				"                color: '#999',",
462
+				"                threshold: 0.1",
463
+				"            }",
464
+				"        }",
465
+				"    },",
466
+				"    legend: {",
467
+				"        show: false",
468
+				"    }",
469
+				"});"
470
+			]);
471
+		});
472
+
473
+		$("#example-9").click(function() {
474
+
475
+			placeholder.unbind();
476
+
477
+			$("#title").text("Rectangular Pie");
478
+			$("#description").text("The radius can also be set to a specific size (even larger than the container itself).");
479
+
480
+			$.plot(placeholder, data, {
481
+				series: {
482
+					pie: { 
483
+						show: true,
484
+						radius: 500,
485
+						label: {
486
+							show: true,
487
+							formatter: labelFormatter,
488
+							threshold: 0.1
489
+						}
490
+					}
491
+				},
492
+				legend: {
493
+					show: false
494
+				}
495
+			});
496
+
497
+			setCode([
498
+				"$.plot('#placeholder', data, {",
499
+				"    series: {",
500
+				"        pie: {",
501
+				"            show: true,",
502
+				"            radius: 500,",
503
+				"            label: {",
504
+				"                show: true,",
505
+				"                formatter: labelFormatter,",
506
+				"                threshold: 0.1",
507
+				"            }",
508
+				"        }",
509
+				"    },",
510
+				"    legend: {",
511
+				"        show: false",
512
+				"    }",
513
+				"});"
514
+			]);
515
+		});
516
+
517
+		$("#example-10").click(function() {
518
+
519
+			placeholder.unbind();
520
+
521
+			$("#title").text("Tilted Pie");
522
+			$("#description").text("The pie can be tilted at an angle.");
523
+
524
+			$.plot(placeholder, data, {
525
+				series: {
526
+					pie: { 
527
+						show: true,
528
+						radius: 1,
529
+						tilt: 0.5,
530
+						label: {
531
+							show: true,
532
+							radius: 1,
533
+							formatter: labelFormatter,
534
+							background: {
535
+								opacity: 0.8
536
+							}
537
+						},
538
+						combine: {
539
+							color: "#999",
540
+							threshold: 0.1
541
+						}
542
+					}
543
+				},
544
+				legend: {
545
+					show: false
546
+				}
547
+			});
548
+
549
+			setCode([
550
+				"$.plot('#placeholder', data, {",
551
+				"    series: {",
552
+				"        pie: {",
553
+				"            show: true,",
554
+				"            radius: 1,",
555
+				"            tilt: 0.5,",
556
+				"            label: {",
557
+				"                show: true,",
558
+				"                radius: 1,",
559
+				"                formatter: labelFormatter,",
560
+				"                background: {",
561
+				"                    opacity: 0.8",
562
+				"                }",
563
+				"            },",
564
+				"            combine: {",
565
+				"                color: '#999',",
566
+				"                threshold: 0.1",
567
+				"            }",
568
+				"        }",
569
+				"    },",
570
+				"    legend: {",
571
+				"        show: false",
572
+				"    }",
573
+				"});",
574
+			]);
575
+		});
576
+
577
+		$("#example-11").click(function() {
578
+
579
+			placeholder.unbind();
580
+
581
+			$("#title").text("Donut Hole");
582
+			$("#description").text("A donut hole can be added.");
583
+
584
+			$.plot(placeholder, data, {
585
+				series: {
586
+					pie: { 
587
+						innerRadius: 0.5,
588
+						show: true
589
+					}
590
+				}
591
+			});
592
+
593
+			setCode([
594
+				"$.plot('#placeholder', data, {",
595
+				"    series: {",
596
+				"        pie: {",
597
+				"            innerRadius: 0.5,",
598
+				"            show: true",
599
+				"        }",
600
+				"    }",
601
+				"});"
602
+			]);
603
+		});
604
+
605
+		$("#example-12").click(function() {
606
+
607
+			placeholder.unbind();
608
+
609
+			$("#title").text("Interactivity");
610
+			$("#description").text("The pie can be made interactive with hover and click events.");
611
+
612
+			$.plot(placeholder, data, {
613
+				series: {
614
+					pie: { 
615
+						show: true
616
+					}
617
+				},
618
+				grid: {
619
+					hoverable: true,
620
+					clickable: true
621
+				}
622
+			});
623
+
624
+			setCode([
625
+				"$.plot('#placeholder', data, {",
626
+				"    series: {",
627
+				"        pie: {",
628
+				"            show: true",
629
+				"        }",
630
+				"    },",
631
+				"    grid: {",
632
+				"        hoverable: true,",
633
+				"        clickable: true",
634
+				"    }",
635
+				"});"
636
+			]);
637
+
638
+			placeholder.bind("plothover", function(event, pos, obj) {
639
+
640
+				if (!obj) {
641
+					return;
642
+				}
643
+
644
+				var percent = parseFloat(obj.series.percent).toFixed(2);
645
+				$("#hover").html("<span style='font-weight:bold; color:" + obj.series.color + "'>" + obj.series.label + " (" + percent + "%)</span>");
646
+			});
647
+
648
+			placeholder.bind("plotclick", function(event, pos, obj) {
649
+
650
+				if (!obj) {
651
+					return;
652
+				}
653
+
654
+				percent = parseFloat(obj.series.percent).toFixed(2);
655
+				alert(""  + obj.series.label + ": " + percent + "%");
656
+			});
657
+		});
658
+
659
+		// Show the initial default chart
660
+
661
+		$("#example-1").click();
662
+
663
+		// Add the Flot version string to the footer
664
+
665
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
666
+	});
667
+
668
+	// A custom label formatter used by several of the plots
669
+
670
+	function labelFormatter(label, series) {
671
+		return "<div style='font-size:8pt; text-align:center; padding:2px; color:white;'>" + label + "<br/>" + Math.round(series.percent) + "%</div>";
672
+	}
673
+
674
+	//
675
+
676
+	function setCode(lines) {
677
+		$("#code").text(lines.join("\n"));
678
+	}
679
+
680
+	</script>
681
+</head>
682
+<body>
683
+
684
+	<div id="header">
685
+		<h2>Pie Charts</h2>
686
+	</div>
687
+
688
+	<div id="content">
689
+
690
+		<h3 id="title"></h3>
691
+		<div class="demo-container">
692
+			<div id="placeholder" class="demo-placeholder"></div>
693
+			<div id="menu">
694
+				<button id="example-1">Default Options</button>
695
+				<button id="example-2">Without Legend</button>
696
+				<button id="example-3">Label Formatter</button>
697
+				<button id="example-4">Label Radius</button>
698
+				<button id="example-5">Label Styles #1</button>
699
+				<button id="example-6">Label Styles #2</button>
700
+				<button id="example-7">Hidden Labels</button>
701
+				<button id="example-8">Combined Slice</button>
702
+				<button id="example-9">Rectangular Pie</button>
703
+				<button id="example-10">Tilted Pie</button>
704
+				<button id="example-11">Donut Hole</button>
705
+				<button id="example-12">Interactivity</button>
706
+			</div>
707
+		</div>
708
+
709
+		<p id="description"></p>
710
+
711
+		<h3>Source Code</h3>
712
+		<pre><code id="code"></code></pre>
713
+
714
+		<br/>
715
+
716
+		<h2>Pie Options</h2>
717
+
718
+		<ul class="options">
719
+			<li style="border-bottom: 1px dotted #ccc;"><b>option:</b> <i>default value</i> - Description of option</li>
720
+			<li><b>show:</b> <i>false</i> - Enable the plugin and draw as a pie.</li>
721
+			<li><b>radius:</b> <i>'auto'</i> - Sets the radius of the pie. If value is between 0 and 1 (inclusive) then it will use that as a percentage of the available space (size of the container), otherwise it will use the value as a direct pixel length. If set to 'auto', it will be set to 1 if the legend is enabled and 3/4 if not.</li>
722
+			<li><b>innerRadius:</b> <i>0</i> - Sets the radius of the donut hole. If value is between 0 and 1 (inclusive) then it will use that as a percentage of the radius, otherwise it will use the value as a direct pixel length.</li>
723
+			<li><b>startAngle:</b> <i>3/2</i> - Factor of PI used for the starting angle (in radians) It can range between 0 and 2 (where 0 and 2 have the same result).</li>
724
+			<li><b>tilt:</b> <i>1</i> - Percentage of tilt ranging from 0 and 1, where 1 has no change (fully vertical) and 0 is completely flat (fully horizontal -- in which case nothing actually gets drawn).</li>
725
+			<li><b>shadow:</b> <ul>
726
+				<li><b>top:</b> <i>5</i> - Vertical distance in pixel of the tilted pie shadow.</li>
727
+				<li><b>left:</b> <i>15</i> - Horizontal distance in pixel of the tilted pie shadow.</li>
728
+				<li><b>alpha:</b> <i>0.02</i> - Alpha value of the tilted pie shadow.</li>
729
+			</ul>
730
+			<li><b>offset:</b> <ul>
731
+				<li><b>top:</b> <i>0</i> - Pixel distance to move the pie up and down (relative to the center).</li>
732
+				<li><b>left:</b> <i>'auto'</i> - Pixel distance to move the pie left and right (relative to the center).</li>
733
+			</ul>
734
+			<li><b>stroke:</b> <ul>
735
+				<li><b>color:</b> <i>'#FFF'</i> - Color of the border of each slice. Hexadecimal color definitions are prefered (other formats may or may not work).</li>
736
+				<li><b>width:</b> <i>1</i> - Pixel width of the border of each slice.</li>
737
+			</ul>
738
+			<li><b>label:</b> <ul>
739
+				<li><b>show:</b> <i>'auto'</i> - Enable/Disable the labels. This can be set to true, false, or 'auto'. When set to 'auto', it will be set to false if the legend is enabled and true if not.</li>
740
+				<li><b>radius:</b> <i>1</i> - Sets the radius at which to place the labels. If value is between 0 and 1 (inclusive) then it will use that as a percentage of the available space (size of the container), otherwise it will use the value as a direct pixel length.</li>
741
+				<li><b>threshold:</b> <i>0</i> - Hides the labels of any pie slice that is smaller than the specified percentage (ranging from 0 to 1) i.e. a value of '0.03' will hide all slices 3% or less of the total.</li>
742
+				<li><b>formatter:</b> <i>[function]</i> - This function specifies how the positioned labels should be formatted, and is applied after the legend's labelFormatter function. The labels can also still be styled using the class "pieLabel" (i.e. ".pieLabel" or "#graph1 .pieLabel").</li>
743
+				<li><b>radius:</b> <i>1</i> - Sets the radius at which to place the labels. If value is between 0 and 1 (inclusive) then it will use that as a percentage of the available space (size of the container), otherwise it will use the value as a direct pixel length.</li>
744
+				<li><b>background:</b> <ul>
745
+					<li><b>color:</b> <i>null</i> - Backgound color of the positioned labels. If null, the plugin will automatically use the color of the slice.</li>
746
+					<li><b>opacity:</b> <i>0</i> - Opacity of the background for the positioned labels. Acceptable values range from 0 to 1, where 0 is completely transparent and 1 is completely opaque.</li>
747
+				</ul>
748
+			</ul>
749
+			<li><b>combine:</b> <ul>
750
+				<li><b>threshold:</b> <i>0</i> - Combines all slices that are smaller than the specified percentage (ranging from 0 to 1) i.e. a value of '0.03' will combine all slices 3% or less into one slice).</li>
751
+				<li><b>color:</b> <i>null</i> - Backgound color of the positioned labels. If null, the plugin will automatically use the color of the first slice to be combined.</li>
752
+				<li><b>label:</b> <i>'Other'</i> - Label text for the combined slice.</li>
753
+			</ul>
754
+			<li><b>highlight:</b> <ul>
755
+				<li><b>opacity:</b> <i>0.5</i> - Opacity of the highlight overlay on top of the current pie slice. Currently this just uses a white overlay, but support for changing the color of the overlay will also be added at a later date.
756
+			</ul>
757
+		</ul>
758
+		
759
+		<h2>Changes/Features</h2>
760
+		<ul>
761
+			<li style="list-style: none;"><i>v1.0 - November 20th, 2009 - Brian Medendorp</i></li>
762
+			<li>The pie plug-in is now part of the Flot repository! This should make it a lot easier to deal with.</li>
763
+			<li>Added a new option (innerRadius) to add a "donut hole" to the center of the pie, based on comtributions from Anthony Aragues. I was a little reluctant to add this feature because it doesn't work very well with the shadow created for the tilted pie, but figured it was worthwhile for non-tilted pies. Also, excanvas apparently doesn't support compositing, so it will fall back to using the stroke color to fill in the center (but I recommend setting the stroke color to the background color anyway).</li>
764
+			<li>Changed the lineJoin for the border of the pie slices to use the 'round' option. This should make the center of the pie look better, particularly when there are numerous thin slices.</li>
765
+			<li>Included a bug fix submitted by btburnett3 to display a slightly smaller slice in the event that the slice is 100% and being rendered with Internet Explorer. I haven't experienced this bug myself, but it doesn't seem to hurt anything so I've included it.</li>
766
+			<li>The tilt value is now used when calculating the maximum radius of the pie in relation to the height of the container. This should prevent the pie from being smaller than it needed to in some cases, as well as reducing the amount of extra white space generated above and below the pie.</li>
767
+			<li><b>Hover and Click functionality are now availabe!</b><ul>
768
+				<li>Thanks to btburnett3 for the original hover functionality and Anthony Aragues for the modification that makes it compatable with excanvas, this was a huge help!</li>
769
+				<li>Added a new option (highlight opacity) to modify the highlight created when mousing over a slice. Currently this just uses a white overlay, but an option to change the hightlight color will be added when the appropriate functionality becomes available.
770
+				<li>I had a major setback that required me to practically rebuild the hover/click events from scratch one piece at a time (I discovered that it only worked with a single pie on a page at a time), but the end result ended up being virtually identical to the original, so I'm not quite sure what exactly made it work.</li>
771
+				<li><span style="color: red;">Warning:</span> There are some minor issues with using this functionality in conjuction with some of the other more advanced features (tilt and donut). When using a donut hole, the inner portion still triggers the events even though that portion of the pie is no longer visible. When tilted, the interactive portions still use the original, untilted version of the pie when determining mouse position (this is because the isPointInPath function apparently doesn't work with transformations), however hover and click both work this way, so the appropriate slice is still highlighted when clicking, and it isn't as noticable of a problem.</li>
772
+			</ul></li>
773
+			<li>Included a bug fix submitted by Xavi Ivars to fix array issues when other javascript libraries are included in addition to jQuery</li>
774
+			<br/>
775
+			<li style="list-style: none;"><i>v0.4 - July 1st, 2009 - Brian Medendorp</i></li>
776
+			<li>Each series will now be shown in the legend, even if it's value is zero. The series will not get a positioned label because it will overlap with the other labels present and often makes them unreadable.</li>
777
+			<li>Data can now be passed in using the standard Flot method using an array of datapoints, the pie plugin will simply use the first y-value that it finds for each series in this case. The plugin uses this datastructure internally, but you can still use the old method of passing in a single numerical value for each series (the plugin will convert it as necessary). This should make it easier to transition from other types of graphs (such as a stacked bar graph) to a pie.</li>
778
+			<li>The pie can now be tilted at an angle with a new "tilt" option. Acceptable values range from 0-1, where 1 has no change (fully vertical) and 0 is completely flat (fully horizontal -- in which case nothing actually gets drawn). If the plugin determines that it will fit within the canvas, a drop shadow will be drawn under the tilted pie (this also requires a tilt value of 0.8 or less).</li>
779
+			<br/>
780
+			<li style="list-style: none;"><i>v0.3.2 - June 25th, 2009 - Brian Medendorp</i></li>
781
+			<li>Fixed a bug that was causing the pie to be shifted too far left or right when the legend is showing in some cases.</li>
782
+			<br/>
783
+			<li style="list-style: none;"><i>v0.3.1 - June 24th, 2009 - Brian Medendorp</i></li>
784
+			<li>Fixed a bug that was causing nothing to be drawn and generating a javascript error if any of the data values were set to zero.</li>
785
+			<br/>
786
+			<li style="list-style: none;"><i>v0.3 - June 23rd, 2009 - Brian Medendorp</i></li>
787
+			<li>The legend now works without any modifications! Because of changes made to flot and the plugin system (thanks Ole Laursen!) I was able to simplify a number of things and am now able to use the legend without the direct access hack that was required in the previous version.</li>
788
+			<br/>
789
+			<li style="list-style: none;"><i>v0.2 - June 22nd, 2009 - Brian Medendorp</i></li>
790
+			<li>The legend now works but only if you make the necessary changes to jquery.flot.js. Because of this, I changed the default values for pie.radius and pie.label.show to new 'auto' settings that change the default behavior of the size and labels depending on whether the legend functionality is available or not.</li>
791
+			<br/>
792
+			<li style="list-style: none;"><i>v0.1 - June 18th, 2009 - Brian Medendorp</i></li>
793
+			<li>Rewrote the entire pie code into a flot plugin (since that is now an option), so it should be much easier to use and the code is cleaned up a bit. However, the (standard flot) legend is no longer available because the only way to prevent the grid lines from being displayed also prevents the legend from being displayed. Hopefully this can be fixed at a later date.</li>
794
+			<li>Restructured and combined some of the options. It should be much easier to deal with now.</li>
795
+			<li>Added the ability to change the starting point of the pie (still defaults to the top).</li>
796
+			<li>Modified the default options to show the labels to compensate for the lack of a legend.</li>
797
+			<li>Modified this page to use a random dataset. <span style="color: red">Note: you may need to refresh the page to see the effects of some of the examples.</span></li>
798
+			<br/>
799
+			<li style="list-style: none;"><i>May 21st, 2009 - Brian Medendorp</i></li>
800
+			<li>Merged original pie modifications by Sergey Nosenko into the latest SVN version <i>(as of May 15th, 2009)</i> so that it will work with ie8.</li>
801
+			<li>Pie graph will now be centered in the canvas unless moved because of the legend or manually via the options. Additionally it prevents the pie from being moved beyond the edge of the canvas.</li>
802
+			<li>Modified the code related to the labelFormatter option to apply flot's legend labelFormatter first. This is so that the labels will be consistent, but still provide extra formatting for the positioned labels (such as adding the percentage value).</li>
803
+			<li>Positioned labels now have their backgrounds applied as a seperate element (much like the legend background) so that the opacity value can be set independently from the label itself (foreground). Additionally, the background color defaults to that of the matching slice.</li>
804
+			<li>As long as the labelOffset and radiusLimit are not set to hard values, the pie will be shrunk if the labels will extend outside the edge of the canvas</li>
805
+			<li>Added new options "radiusLimitFactor" and "radiusLimit" which limits how large the (visual) radius of the pie is in relation to the full radius (as calculated from the canvas dimensions) or a hard-pixel value (respectively). This allows for pushing the labels "outside" the pie.</li>
806
+			<li>Added a new option "labelHidePercent" that does not show the positioned labels of slices smaller than the specified percentage. This is to help prevent a bunch of overlapping labels from small slices.</li>
807
+			<li>Added a new option "sliceCombinePercent" that combines all slices smaller than the specified percentage into one larger slice. This is to help make the pie more attractive when there are a number of tiny slices. The options "sliceCombineColor" and "sliceCombineLabel" have also been added to change the color and name of the new slice if desired.</li>
808
+			<li>Tested in Firefox (3.0.10, 3.5b4), Internet Explorer (6.0.2900, 7.0.5730, 8.0.6001), Chrome (1.0.154), Opera (9.64), and Safari (3.1.1, 4 beta 5528.16).
809
+		</ul>
810
+
811
+	</div>
812
+
813
+	<div id="footer">
814
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
815
+	</div>
816
+
817
+</body>
818
+</html>
... ...
@@ -0,0 +1,121 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Toggling Series</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script type="text/javascript">
11
+
12
+	$(function() {
13
+
14
+		var datasets = {
15
+			"usa": {
16
+				label: "USA",
17
+				data: [[1988, 483994], [1989, 479060], [1990, 457648], [1991, 401949], [1992, 424705], [1993, 402375], [1994, 377867], [1995, 357382], [1996, 337946], [1997, 336185], [1998, 328611], [1999, 329421], [2000, 342172], [2001, 344932], [2002, 387303], [2003, 440813], [2004, 480451], [2005, 504638], [2006, 528692]]
18
+			},        
19
+			"russia": {
20
+				label: "Russia",
21
+				data: [[1988, 218000], [1989, 203000], [1990, 171000], [1992, 42500], [1993, 37600], [1994, 36600], [1995, 21700], [1996, 19200], [1997, 21300], [1998, 13600], [1999, 14000], [2000, 19100], [2001, 21300], [2002, 23600], [2003, 25100], [2004, 26100], [2005, 31100], [2006, 34700]]
22
+			},
23
+			"uk": {
24
+				label: "UK",
25
+				data: [[1988, 62982], [1989, 62027], [1990, 60696], [1991, 62348], [1992, 58560], [1993, 56393], [1994, 54579], [1995, 50818], [1996, 50554], [1997, 48276], [1998, 47691], [1999, 47529], [2000, 47778], [2001, 48760], [2002, 50949], [2003, 57452], [2004, 60234], [2005, 60076], [2006, 59213]]
26
+			},
27
+			"germany": {
28
+				label: "Germany",
29
+				data: [[1988, 55627], [1989, 55475], [1990, 58464], [1991, 55134], [1992, 52436], [1993, 47139], [1994, 43962], [1995, 43238], [1996, 42395], [1997, 40854], [1998, 40993], [1999, 41822], [2000, 41147], [2001, 40474], [2002, 40604], [2003, 40044], [2004, 38816], [2005, 38060], [2006, 36984]]
30
+			},
31
+			"denmark": {
32
+				label: "Denmark",
33
+				data: [[1988, 3813], [1989, 3719], [1990, 3722], [1991, 3789], [1992, 3720], [1993, 3730], [1994, 3636], [1995, 3598], [1996, 3610], [1997, 3655], [1998, 3695], [1999, 3673], [2000, 3553], [2001, 3774], [2002, 3728], [2003, 3618], [2004, 3638], [2005, 3467], [2006, 3770]]
34
+			},
35
+			"sweden": {
36
+				label: "Sweden",
37
+				data: [[1988, 6402], [1989, 6474], [1990, 6605], [1991, 6209], [1992, 6035], [1993, 6020], [1994, 6000], [1995, 6018], [1996, 3958], [1997, 5780], [1998, 5954], [1999, 6178], [2000, 6411], [2001, 5993], [2002, 5833], [2003, 5791], [2004, 5450], [2005, 5521], [2006, 5271]]
38
+			},
39
+			"norway": {
40
+				label: "Norway",
41
+				data: [[1988, 4382], [1989, 4498], [1990, 4535], [1991, 4398], [1992, 4766], [1993, 4441], [1994, 4670], [1995, 4217], [1996, 4275], [1997, 4203], [1998, 4482], [1999, 4506], [2000, 4358], [2001, 4385], [2002, 5269], [2003, 5066], [2004, 5194], [2005, 4887], [2006, 4891]]
42
+			}
43
+		};
44
+
45
+		// hard-code color indices to prevent them from shifting as
46
+		// countries are turned on/off
47
+
48
+		var i = 0;
49
+		$.each(datasets, function(key, val) {
50
+			val.color = i;
51
+			++i;
52
+		});
53
+
54
+		// insert checkboxes 
55
+		var choiceContainer = $("#choices");
56
+		$.each(datasets, function(key, val) {
57
+			choiceContainer.append("<br/><input type='checkbox' name='" + key +
58
+				"' checked='checked' id='id" + key + "'></input>" +
59
+				"<label for='id" + key + "'>"
60
+				+ val.label + "</label>");
61
+		});
62
+
63
+		choiceContainer.find("input").click(plotAccordingToChoices);
64
+
65
+		function plotAccordingToChoices() {
66
+
67
+			var data = [];
68
+
69
+			choiceContainer.find("input:checked").each(function () {
70
+				var key = $(this).attr("name");
71
+				if (key && datasets[key]) {
72
+					data.push(datasets[key]);
73
+				}
74
+			});
75
+
76
+			if (data.length > 0) {
77
+				$.plot("#placeholder", data, {
78
+					yaxis: {
79
+						min: 0
80
+					},
81
+					xaxis: {
82
+						tickDecimals: 0
83
+					}
84
+				});
85
+			}
86
+		}
87
+
88
+		plotAccordingToChoices();
89
+
90
+		// Add the Flot version string to the footer
91
+
92
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
93
+	});
94
+
95
+	</script>
96
+</head>
97
+<body>
98
+
99
+	<div id="header">
100
+		<h2>Toggling Series</h2>
101
+	</div>
102
+
103
+	<div id="content">
104
+
105
+		<div class="demo-container">
106
+			<div id="placeholder" class="demo-placeholder" style="float:left; width:675px;"></div>
107
+			<p id="choices" style="float:right; width:135px;"></p>
108
+		</div>
109
+
110
+		<p>This example shows military budgets for various countries in constant (2005) million US dollars (source: <a href="http://www.sipri.org/">SIPRI</a>).</p>
111
+
112
+		<p>Since all data is available client-side, it's pretty easy to make the plot interactive. Try turning countries on and off with the checkboxes next to the plot.</p>
113
+
114
+	</div>
115
+
116
+	<div id="footer">
117
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
118
+	</div>
119
+
120
+</body>
121
+</html>
... ...
@@ -0,0 +1,90 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Series Types</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script type="text/javascript">
11
+
12
+	$(function() {
13
+
14
+		var d1 = [];
15
+		for (var i = 0; i < 14; i += 0.5) {
16
+			d1.push([i, Math.sin(i)]);
17
+		}
18
+
19
+		var d2 = [[0, 3], [4, 8], [8, 5], [9, 13]];
20
+
21
+		var d3 = [];
22
+		for (var i = 0; i < 14; i += 0.5) {
23
+			d3.push([i, Math.cos(i)]);
24
+		}
25
+
26
+		var d4 = [];
27
+		for (var i = 0; i < 14; i += 0.1) {
28
+			d4.push([i, Math.sqrt(i * 10)]);
29
+		}
30
+
31
+		var d5 = [];
32
+		for (var i = 0; i < 14; i += 0.5) {
33
+			d5.push([i, Math.sqrt(i)]);
34
+		}
35
+
36
+		var d6 = [];
37
+		for (var i = 0; i < 14; i += 0.5 + Math.random()) {
38
+			d6.push([i, Math.sqrt(2*i + Math.sin(i) + 5)]);
39
+		}
40
+
41
+		$.plot("#placeholder", [{
42
+			data: d1,
43
+			lines: { show: true, fill: true }
44
+		}, {
45
+			data: d2,
46
+			bars: { show: true }
47
+		}, {
48
+			data: d3,
49
+			points: { show: true }
50
+		}, {
51
+			data: d4,
52
+			lines: { show: true }
53
+		}, {
54
+			data: d5,
55
+			lines: { show: true },
56
+			points: { show: true }
57
+		}, {
58
+			data: d6,
59
+			lines: { show: true, steps: true }
60
+		}]);
61
+
62
+		// Add the Flot version string to the footer
63
+
64
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
65
+	});
66
+
67
+	</script>
68
+</head>
69
+<body>
70
+
71
+	<div id="header">
72
+		<h2>Series Types</h2>
73
+	</div>
74
+
75
+	<div id="content">
76
+
77
+		<div class="demo-container">
78
+			<div id="placeholder" class="demo-placeholder"></div>
79
+		</div>
80
+
81
+		<p>Flot supports lines, points, filled areas, bars and any combinations of these, in the same plot and even on the same data series.</p>
82
+
83
+	</div>
84
+
85
+	<div id="footer">
86
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
87
+	</div>
88
+
89
+</body>
90
+</html>
... ...
@@ -0,0 +1,6 @@
1
+/*! jQuery UI - v1.10.0 - 2013-01-26
2
+* http://jqueryui.com
3
+* Includes: jquery.ui.core.css, jquery.ui.resizable.css
4
+* Copyright (c) 2013 jQuery Foundation and other contributors Licensed MIT */
5
+
6
+.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}
0 7
\ No newline at end of file
... ...
@@ -0,0 +1,6 @@
1
+/*! jQuery UI - v1.10.0 - 2013-01-26
2
+* http://jqueryui.com
3
+* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.resizable.js
4
+* Copyright (c) 2013 jQuery Foundation and other contributors Licensed MIT */
5
+
6
+(function(e,t){function i(t,n){var r,i,o,u=t.nodeName.toLowerCase();return"area"===u?(r=t.parentNode,i=r.name,!t.href||!i||r.nodeName.toLowerCase()!=="map"?!1:(o=e("img[usemap=#"+i+"]")[0],!!o&&s(o))):(/input|select|textarea|button|object/.test(u)?!t.disabled:"a"===u?t.href||n:n)&&s(t)}function s(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return e.css(this,"visibility")==="hidden"}).length}var n=0,r=/^ui-id-\d+$/;e.ui=e.ui||{};if(e.ui.version)return;e.extend(e.ui,{version:"1.10.0",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({_focus:e.fn.focus,focus:function(t,n){return typeof t=="number"?this.each(function(){var r=this;setTimeout(function(){e(r).focus(),n&&n.call(r)},t)}):this._focus.apply(this,arguments)},scrollParent:function(){var t;return e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?t=this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):t=this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(n){if(n!==t)return this.css("zIndex",n);if(this.length){var r=e(this[0]),i,s;while(r.length&&r[0]!==document){i=r.css("position");if(i==="absolute"||i==="relative"||i==="fixed"){s=parseInt(r.css("zIndex"),10);if(!isNaN(s)&&s!==0)return s}r=r.parent()}}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++n)})},removeUniqueId:function(){return this.each(function(){r.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(n){return!!e.data(n,t)}}):function(t,n,r){return!!e.data(t,r[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var n=e.attr(t,"tabindex"),r=isNaN(n);return(r||n>=0)&&i(t,!r)}}),e("<a>").outerWidth(1).jquery||e.each(["Width","Height"],function(n,r){function u(t,n,r,s){return e.each(i,function(){n-=parseFloat(e.css(t,"padding"+this))||0,r&&(n-=parseFloat(e.css(t,"border"+this+"Width"))||0),s&&(n-=parseFloat(e.css(t,"margin"+this))||0)}),n}var i=r==="Width"?["Left","Right"]:["Top","Bottom"],s=r.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+r]=function(n){return n===t?o["inner"+r].call(this):this.each(function(){e(this).css(s,u(this,n)+"px")})},e.fn["outer"+r]=function(t,n){return typeof t!="number"?o["outer"+r].call(this,t):this.each(function(){e(this).css(s,u(this,t,!0,n)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}),e("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(n){return arguments.length?t.call(this,e.camelCase(n)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.support.selectstart="onselectstart"in document.createElement("div"),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,n,r){var i,s=e.ui[t].prototype;for(i in r)s.plugins[i]=s.plugins[i]||[],s.plugins[i].push([n,r[i]])},call:function(e,t,n){var r,i=e.plugins[t];if(!i||!e.element[0].parentNode||e.element[0].parentNode.nodeType===11)return;for(r=0;r<i.length;r++)e.options[i[r][0]]&&i[r][1].apply(e.element,n)}},hasScroll:function(t,n){if(e(t).css("overflow")==="hidden")return!1;var r=n&&n==="left"?"scrollLeft":"scrollTop",i=!1;return t[r]>0?!0:(t[r]=1,i=t[r]>0,t[r]=0,i)}})})(jQuery);(function(e,t){var n=0,r=Array.prototype.slice,i=e.cleanData;e.cleanData=function(t){for(var n=0,r;(r=t[n])!=null;n++)try{e(r).triggerHandler("remove")}catch(s){}i(t)},e.widget=function(t,n,r){var i,s,o,u,a={},f=t.split(".")[0];t=t.split(".")[1],i=f+"-"+t,r||(r=n,n=e.Widget),e.expr[":"][i.toLowerCase()]=function(t){return!!e.data(t,i)},e[f]=e[f]||{},s=e[f][t],o=e[f][t]=function(e,t){if(!this._createWidget)return new o(e,t);arguments.length&&this._createWidget(e,t)},e.extend(o,s,{version:r.version,_proto:e.extend({},r),_childConstructors:[]}),u=new n,u.options=e.widget.extend({},u.options),e.each(r,function(t,r){if(!e.isFunction(r)){a[t]=r;return}a[t]=function(){var e=function(){return n.prototype[t].apply(this,arguments)},i=function(e){return n.prototype[t].apply(this,e)};return function(){var t=this._super,n=this._superApply,s;return this._super=e,this._superApply=i,s=r.apply(this,arguments),this._super=t,this._superApply=n,s}}()}),o.prototype=e.widget.extend(u,{widgetEventPrefix:s?u.widgetEventPrefix:t},a,{constructor:o,namespace:f,widgetName:t,widgetFullName:i}),s?(e.each(s._childConstructors,function(t,n){var r=n.prototype;e.widget(r.namespace+"."+r.widgetName,o,n._proto)}),delete s._childConstructors):n._childConstructors.push(o),e.widget.bridge(t,o)},e.widget.extend=function(n){var i=r.call(arguments,1),s=0,o=i.length,u,a;for(;s<o;s++)for(u in i[s])a=i[s][u],i[s].hasOwnProperty(u)&&a!==t&&(e.isPlainObject(a)?n[u]=e.isPlainObject(n[u])?e.widget.extend({},n[u],a):e.widget.extend({},a):n[u]=a);return n},e.widget.bridge=function(n,i){var s=i.prototype.widgetFullName||n;e.fn[n]=function(o){var u=typeof o=="string",a=r.call(arguments,1),f=this;return o=!u&&a.length?e.widget.extend.apply(null,[o].concat(a)):o,u?this.each(function(){var r,i=e.data(this,s);if(!i)return e.error("cannot call methods on "+n+" prior to initialization; "+"attempted to call method '"+o+"'");if(!e.isFunction(i[o])||o.charAt(0)==="_")return e.error("no such method '"+o+"' for "+n+" widget instance");r=i[o].apply(i,a);if(r!==i&&r!==t)return f=r&&r.jquery?f.pushStack(r.get()):r,!1}):this.each(function(){var t=e.data(this,s);t?t.option(o||{})._init():e.data(this,s,new i(o,this))}),f}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(t,r){r=e(r||this.defaultElement||this)[0],this.element=e(r),this.uuid=n++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),r!==this&&(e.data(r,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===r&&this.destroy()}}),this.document=e(r.style?r.ownerDocument:r.document||r),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(n,r){var i=n,s,o,u;if(arguments.length===0)return e.widget.extend({},this.options);if(typeof n=="string"){i={},s=n.split("."),n=s.shift();if(s.length){o=i[n]=e.widget.extend({},this.options[n]);for(u=0;u<s.length-1;u++)o[s[u]]=o[s[u]]||{},o=o[s[u]];n=s.pop();if(r===t)return o[n]===t?null:o[n];o[n]=r}else{if(r===t)return this.options[n]===t?null:this.options[n];i[n]=r}}return this._setOptions(i),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,e==="disabled"&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!t).attr("aria-disabled",t),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(t,n,r){var i,s=this;typeof t!="boolean"&&(r=n,n=t,t=!1),r?(n=i=e(n),this.bindings=this.bindings.add(n)):(r=n,n=this.element,i=this.widget()),e.each(r,function(r,o){function u(){if(!t&&(s.options.disabled===!0||e(this).hasClass("ui-state-disabled")))return;return(typeof o=="string"?s[o]:o).apply(s,arguments)}typeof o!="string"&&(u.guid=o.guid=o.guid||u.guid||e.guid++);var a=r.match(/^(\w+)\s*(.*)$/),f=a[1]+s.eventNamespace,l=a[2];l?i.delegate(l,f,u):n.bind(f,u)})},_off:function(e,t){t=(t||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.unbind(t).undelegate(t)},_delay:function(e,t){function n(){return(typeof e=="string"?r[e]:e).apply(r,arguments)}var r=this;return setTimeout(n,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,n,r){var i,s,o=this.options[t];r=r||{},n=e.Event(n),n.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),n.target=this.element[0],s=n.originalEvent;if(s)for(i in s)i in n||(n[i]=s[i]);return this.element.trigger(n,r),!(e.isFunction(o)&&o.apply(this.element[0],[n].concat(r))===!1||n.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,n){e.Widget.prototype["_"+t]=function(r,i,s){typeof i=="string"&&(i={effect:i});var o,u=i?i===!0||typeof i=="number"?n:i.effect||n:t;i=i||{},typeof i=="number"&&(i={duration:i}),o=!e.isEmptyObject(i),i.complete=s,i.delay&&r.delay(i.delay),o&&e.effects&&e.effects.effect[u]?r[t](i):u!==t&&r[u]?r[u](i.duration,i.easing,s):r.queue(function(n){e(this)[t](),s&&s.call(r[0]),n()})}})})(jQuery);(function(e,t){var n=!1;e(document).mouseup(function(){n=!1}),e.widget("ui.mouse",{version:"1.10.0",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var t=this;this.element.bind("mousedown."+this.widgetName,function(e){return t._mouseDown(e)}).bind("click."+this.widgetName,function(n){if(!0===e.data(n.target,t.widgetName+".preventClickEvent"))return e.removeData(n.target,t.widgetName+".preventClickEvent"),n.stopImmediatePropagation(),!1}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(t){if(n)return;this._mouseStarted&&this._mouseUp(t),this._mouseDownEvent=t;var r=this,i=t.which===1,s=typeof this.options.cancel=="string"&&t.target.nodeName?e(t.target).closest(this.options.cancel).length:!1;if(!i||s||!this._mouseCapture(t))return!0;this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){r.mouseDelayMet=!0},this.options.delay));if(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)){this._mouseStarted=this._mouseStart(t)!==!1;if(!this._mouseStarted)return t.preventDefault(),!0}return!0===e.data(t.target,this.widgetName+".preventClickEvent")&&e.removeData(t.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(e){return r._mouseMove(e)},this._mouseUpDelegate=function(e){return r._mouseUp(e)},e(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),t.preventDefault(),n=!0,!0},_mouseMove:function(t){return e.ui.ie&&(!document.documentMode||document.documentMode<9)&&!t.button?this._mouseUp(t):this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted)},_mouseUp:function(t){return e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})})(jQuery);(function(e,t){function n(e){return parseInt(e,10)||0}function r(e){return!isNaN(parseInt(e,10))}e.widget("ui.resizable",e.ui.mouse,{version:"1.10.0",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_create:function(){var t,n,r,i,s,o=this,u=this.options;this.element.addClass("ui-resizable"),e.extend(this,{_aspectRatio:!!u.aspectRatio,aspectRatio:u.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:u.helper||u.ghost||u.animate?u.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(e("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.data("ui-resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=u.handles||(e(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se");if(this.handles.constructor===String){this.handles==="all"&&(this.handles="n,e,s,w,se,sw,ne,nw"),t=this.handles.split(","),this.handles={};for(n=0;n<t.length;n++)r=e.trim(t[n]),s="ui-resizable-"+r,i=e("<div class='ui-resizable-handle "+s+"'></div>"),i.css({zIndex:u.zIndex}),"se"===r&&i.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[r]=".ui-resizable-"+r,this.element.append(i)}this._renderAxis=function(t){var n,r,i,s;t=t||this.element;for(n in this.handles){this.handles[n].constructor===String&&(this.handles[n]=e(this.handles[n],this.element).show()),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)&&(r=e(this.handles[n],this.element),s=/sw|ne|nw|se|n|s/.test(n)?r.outerHeight():r.outerWidth(),i=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join(""),t.css(i,s),this._proportionallyResize());if(!e(this.handles[n]).length)continue}},this._renderAxis(this.element),this._handles=e(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){o.resizing||(this.className&&(i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),o.axis=i&&i[1]?i[1]:"se")}),u.autoHide&&(this._handles.hide(),e(this.element).addClass("ui-resizable-autohide").mouseenter(function(){if(u.disabled)return;e(this).removeClass("ui-resizable-autohide"),o._handles.show()}).mouseleave(function(){if(u.disabled)return;o.resizing||(e(this).addClass("ui-resizable-autohide"),o._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var t,n=function(t){e(t).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(n(this.element),t=this.element,this.originalElement.css({position:t.css("position"),width:t.outerWidth(),height:t.outerHeight(),top:t.css("top"),left:t.css("left")}).insertAfter(t),t.remove()),this.originalElement.css("resize",this.originalResizeStyle),n(this.originalElement),this},_mouseCapture:function(t){var n,r,i=!1;for(n in this.handles){r=e(this.handles[n])[0];if(r===t.target||e.contains(r,t.target))i=!0}return!this.options.disabled&&i},_mouseStart:function(t){var r,i,s,o=this.options,u=this.element.position(),a=this.element;return this.resizing=!0,/absolute/.test(a.css("position"))?a.css({position:"absolute",top:a.css("top"),left:a.css("left")}):a.is(".ui-draggable")&&a.css({position:"absolute",top:u.top,left:u.left}),this._renderProxy(),r=n(this.helper.css("left")),i=n(this.helper.css("top")),o.containment&&(r+=e(o.containment).scrollLeft()||0,i+=e(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:r,top:i},this.size=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.originalPosition={left:r,top:i},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio=typeof o.aspectRatio=="number"?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,s=e(".ui-resizable-"+this.axis).css("cursor"),e("body").css("cursor",s==="auto"?this.axis+"-resize":s),a.addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var n,r=this.helper,i={},s=this.originalMousePosition,o=this.axis,u=this.position.top,a=this.position.left,f=this.size.width,l=this.size.height,c=t.pageX-s.left||0,h=t.pageY-s.top||0,p=this._change[o];if(!p)return!1;n=p.apply(this,[t,c,h]),this._updateVirtualBoundaries(t.shiftKey);if(this._aspectRatio||t.shiftKey)n=this._updateRatio(n,t);return n=this._respectSize(n,t),this._updateCache(n),this._propagate("resize",t),this.position.top!==u&&(i.top=this.position.top+"px"),this.position.left!==a&&(i.left=this.position.left+"px"),this.size.width!==f&&(i.width=this.size.width+"px"),this.size.height!==l&&(i.height=this.size.height+"px"),r.css(i),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),e.isEmptyObject(i)||this._trigger("resize",t,this.ui()),!1},_mouseStop:function(t){this.resizing=!1;var n,r,i,s,o,u,a,f=this.options,l=this;return this._helper&&(n=this._proportionallyResizeElements,r=n.length&&/textarea/i.test(n[0].nodeName),i=r&&e.ui.hasScroll(n[0],"left")?0:l.sizeDiff.height,s=r?0:l.sizeDiff.width,o={width:l.helper.width()-s,height:l.helper.height()-i},u=parseInt(l.element.css("left"),10)+(l.position.left-l.originalPosition.left)||null,a=parseInt(l.element.css("top"),10)+(l.position.top-l.originalPosition.top)||null,f.animate||this.element.css(e.extend(o,{top:a,left:u})),l.helper.height(l.size.height),l.helper.width(l.size.width),this._helper&&!f.animate&&this._proportionallyResize()),e("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(e){var t,n,i,s,o,u=this.options;o={minWidth:r(u.minWidth)?u.minWidth:0,maxWidth:r(u.maxWidth)?u.maxWidth:Infinity,minHeight:r(u.minHeight)?u.minHeight:0,maxHeight:r(u.maxHeight)?u.maxHeight:Infinity};if(this._aspectRatio||e)t=o.minHeight*this.aspectRatio,i=o.minWidth/this.aspectRatio,n=o.maxHeight*this.aspectRatio,s=o.maxWidth/this.aspectRatio,t>o.minWidth&&(o.minWidth=t),i>o.minHeight&&(o.minHeight=i),n<o.maxWidth&&(o.maxWidth=n),s<o.maxHeight&&(o.maxHeight=s);this._vBoundaries=o},_updateCache:function(e){this.offset=this.helper.offset(),r(e.left)&&(this.position.left=e.left),r(e.top)&&(this.position.top=e.top),r(e.height)&&(this.size.height=e.height),r(e.width)&&(this.size.width=e.width)},_updateRatio:function(e){var t=this.position,n=this.size,i=this.axis;return r(e.height)?e.width=e.height*this.aspectRatio:r(e.width)&&(e.height=e.width/this.aspectRatio),i==="sw"&&(e.left=t.left+(n.width-e.width),e.top=null),i==="nw"&&(e.top=t.top+(n.height-e.height),e.left=t.left+(n.width-e.width)),e},_respectSize:function(e){var t=this._vBoundaries,n=this.axis,i=r(e.width)&&t.maxWidth&&t.maxWidth<e.width,s=r(e.height)&&t.maxHeight&&t.maxHeight<e.height,o=r(e.width)&&t.minWidth&&t.minWidth>e.width,u=r(e.height)&&t.minHeight&&t.minHeight>e.height,a=this.originalPosition.left+this.originalSize.width,f=this.position.top+this.size.height,l=/sw|nw|w/.test(n),c=/nw|ne|n/.test(n);return o&&(e.width=t.minWidth),u&&(e.height=t.minHeight),i&&(e.width=t.maxWidth),s&&(e.height=t.maxHeight),o&&l&&(e.left=a-t.minWidth),i&&l&&(e.left=a-t.maxWidth),u&&c&&(e.top=f-t.minHeight),s&&c&&(e.top=f-t.maxHeight),!e.width&&!e.height&&!e.left&&e.top?e.top=null:!e.width&&!e.height&&!e.top&&e.left&&(e.left=null),e},_proportionallyResize:function(){if(!this._proportionallyResizeElements.length)return;var e,t,n,r,i,s=this.helper||this.element;for(e=0;e<this._proportionallyResizeElements.length;e++){i=this._proportionallyResizeElements[e];if(!this.borderDif){this.borderDif=[],n=[i.css("borderTopWidth"),i.css("borderRightWidth"),i.css("borderBottomWidth"),i.css("borderLeftWidth")],r=[i.css("paddingTop"),i.css("paddingRight"),i.css("paddingBottom"),i.css("paddingLeft")];for(t=0;t<n.length;t++)this.borderDif[t]=(parseInt(n[t],10)||0)+(parseInt(r[t],10)||0)}i.css({height:s.height()-this.borderDif[0]-this.borderDif[2]||0,width:s.width()-this.borderDif[1]-this.borderDif[3]||0})}},_renderProxy:function(){var t=this.element,n=this.options;this.elementOffset=t.offset(),this._helper?(this.helper=this.helper||e("<div style='overflow:hidden;'></div>"),this.helper.addClass(this._helper).css({width:this.element.outerWidth()-1,height:this.element.outerHeight()-1,position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++n.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(e,t){return{width:this.originalSize.width+t}},w:function(e,t){var n=this.originalSize,r=this.originalPosition;return{left:r.left+t,width:n.width-t}},n:function(e,t,n){var r=this.originalSize,i=this.originalPosition;return{top:i.top+n,height:r.height-n}},s:function(e,t,n){return{height:this.originalSize.height+n}},se:function(t,n,r){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,n,r]))},sw:function(t,n,r){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,n,r]))},ne:function(t,n,r){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,n,r]))},nw:function(t,n,r){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,n,r]))}},_propagate:function(t,n){e.ui.plugin.call(this,t,[n,this.ui()]),t!=="resize"&&this._trigger(t,n,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),e.ui.plugin.add("resizable","animate",{stop:function(t){var n=e(this).data("ui-resizable"),r=n.options,i=n._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),o=s&&e.ui.hasScroll(i[0],"left")?0:n.sizeDiff.height,u=s?0:n.sizeDiff.width,a={width:n.size.width-u,height:n.size.height-o},f=parseInt(n.element.css("left"),10)+(n.position.left-n.originalPosition.left)||null,l=parseInt(n.element.css("top"),10)+(n.position.top-n.originalPosition.top)||null;n.element.animate(e.extend(a,l&&f?{top:l,left:f}:{}),{duration:r.animateDuration,easing:r.animateEasing,step:function(){var r={width:parseInt(n.element.css("width"),10),height:parseInt(n.element.css("height"),10),top:parseInt(n.element.css("top"),10),left:parseInt(n.element.css("left"),10)};i&&i.length&&e(i[0]).css({width:r.width,height:r.height}),n._updateCache(r),n._propagate("resize",t)}})}}),e.ui.plugin.add("resizable","containment",{start:function(){var t,r,i,s,o,u,a,f=e(this).data("ui-resizable"),l=f.options,c=f.element,h=l.containment,p=h instanceof e?h.get(0):/parent/.test(h)?c.parent().get(0):h;if(!p)return;f.containerElement=e(p),/document/.test(h)||h===document?(f.containerOffset={left:0,top:0},f.containerPosition={left:0,top:0},f.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}):(t=e(p),r=[],e(["Top","Right","Left","Bottom"]).each(function(e,i){r[e]=n(t.css("padding"+i))}),f.containerOffset=t.offset(),f.containerPosition=t.position(),f.containerSize={height:t.innerHeight()-r[3],width:t.innerWidth()-r[1]},i=f.containerOffset,s=f.containerSize.height,o=f.containerSize.width,u=e.ui.hasScroll(p,"left")?p.scrollWidth:o,a=e.ui.hasScroll(p)?p.scrollHeight:s,f.parentData={element:p,left:i.left,top:i.top,width:u,height:a})},resize:function(t){var n,r,i,s,o=e(this).data("ui-resizable"),u=o.options,a=o.containerOffset,f=o.position,l=o._aspectRatio||t.shiftKey,c={top:0,left:0},h=o.containerElement;h[0]!==document&&/static/.test(h.css("position"))&&(c=a),f.left<(o._helper?a.left:0)&&(o.size.width=o.size.width+(o._helper?o.position.left-a.left:o.position.left-c.left),l&&(o.size.height=o.size.width/o.aspectRatio),o.position.left=u.helper?a.left:0),f.top<(o._helper?a.top:0)&&(o.size.height=o.size.height+(o._helper?o.position.top-a.top:o.position.top),l&&(o.size.width=o.size.height*o.aspectRatio),o.position.top=o._helper?a.top:0),o.offset.left=o.parentData.left+o.position.left,o.offset.top=o.parentData.top+o.position.top,n=Math.abs((o._helper?o.offset.left-c.left:o.offset.left-c.left)+o.sizeDiff.width),r=Math.abs((o._helper?o.offset.top-c.top:o.offset.top-a.top)+o.sizeDiff.height),i=o.containerElement.get(0)===o.element.parent().get(0),s=/relative|absolute/.test(o.containerElement.css("position")),i&&s&&(n-=o.parentData.left),n+o.size.width>=o.parentData.width&&(o.size.width=o.parentData.width-n,l&&(o.size.height=o.size.width/o.aspectRatio)),r+o.size.height>=o.parentData.height&&(o.size.height=o.parentData.height-r,l&&(o.size.width=o.size.height*o.aspectRatio))},stop:function(){var t=e(this).data("ui-resizable"),n=t.options,r=t.containerOffset,i=t.containerPosition,s=t.containerElement,o=e(t.helper),u=o.offset(),a=o.outerWidth()-t.sizeDiff.width,f=o.outerHeight()-t.sizeDiff.height;t._helper&&!n.animate&&/relative/.test(s.css("position"))&&e(this).css({left:u.left-i.left-r.left,width:a,height:f}),t._helper&&!n.animate&&/static/.test(s.css("position"))&&e(this).css({left:u.left-i.left-r.left,width:a,height:f})}}),e.ui.plugin.add("resizable","alsoResize",{start:function(){var t=e(this).data("ui-resizable"),n=t.options,r=function(t){e(t).each(function(){var t=e(this);t.data("ui-resizable-alsoresize",{width:parseInt(t.width(),10),height:parseInt(t.height(),10),left:parseInt(t.css("left"),10),top:parseInt(t.css("top"),10)})})};typeof n.alsoResize=="object"&&!n.alsoResize.parentNode?n.alsoResize.length?(n.alsoResize=n.alsoResize[0],r(n.alsoResize)):e.each(n.alsoResize,function(e){r(e)}):r(n.alsoResize)},resize:function(t,n){var r=e(this).data("ui-resizable"),i=r.options,s=r.originalSize,o=r.originalPosition,u={height:r.size.height-s.height||0,width:r.size.width-s.width||0,top:r.position.top-o.top||0,left:r.position.left-o.left||0},a=function(t,r){e(t).each(function(){var t=e(this),i=e(this).data("ui-resizable-alsoresize"),s={},o=r&&r.length?r:t.parents(n.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(o,function(e,t){var n=(i[t]||0)+(u[t]||0);n&&n>=0&&(s[t]=n||null)}),t.css(s)})};typeof i.alsoResize=="object"&&!i.alsoResize.nodeType?e.each(i.alsoResize,function(e,t){a(e,t)}):a(i.alsoResize)},stop:function(){e(this).removeData("resizable-alsoresize")}}),e.ui.plugin.add("resizable","ghost",{start:function(){var t=e(this).data("ui-resizable"),n=t.options,r=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:r.height,width:r.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof n.ghost=="string"?n.ghost:""),t.ghost.appendTo(t.helper)},resize:function(){var t=e(this).data("ui-resizable");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=e(this).data("ui-resizable");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),e.ui.plugin.add("resizable","grid",{resize:function(){var t=e(this).data("ui-resizable"),n=t.options,r=t.size,i=t.originalSize,s=t.originalPosition,o=t.axis,u=typeof n.grid=="number"?[n.grid,n.grid]:n.grid,a=u[0]||1,f=u[1]||1,l=Math.round((r.width-i.width)/a)*a,c=Math.round((r.height-i.height)/f)*f,h=i.width+l,p=i.height+c,d=n.maxWidth&&n.maxWidth<h,v=n.maxHeight&&n.maxHeight<p,m=n.minWidth&&n.minWidth>h,g=n.minHeight&&n.minHeight>p;n.grid=u,m&&(h+=a),g&&(p+=f),d&&(h-=a),v&&(p-=f),/^(se|s|e)$/.test(o)?(t.size.width=h,t.size.height=p):/^(ne)$/.test(o)?(t.size.width=h,t.size.height=p,t.position.top=s.top-c):/^(sw)$/.test(o)?(t.size.width=h,t.size.height=p,t.position.left=s.left-l):(t.size.width=h,t.size.height=p,t.position.top=s.top-c,t.position.left=s.left-l)}})})(jQuery);
0 7
\ No newline at end of file
... ...
@@ -0,0 +1,107 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Stacking</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.stack.js"></script>
11
+	<script type="text/javascript">
12
+
13
+	$(function() {
14
+
15
+		var d1 = [];
16
+		for (var i = 0; i <= 10; i += 1) {
17
+			d1.push([i, parseInt(Math.random() * 30)]);
18
+		}
19
+
20
+		var d2 = [];
21
+		for (var i = 0; i <= 10; i += 1) {
22
+			d2.push([i, parseInt(Math.random() * 30)]);
23
+		}
24
+
25
+		var d3 = [];
26
+		for (var i = 0; i <= 10; i += 1) {
27
+			d3.push([i, parseInt(Math.random() * 30)]);
28
+		}
29
+
30
+		var stack = 0,
31
+			bars = true,
32
+			lines = false,
33
+			steps = false;
34
+
35
+		function plotWithOptions() {
36
+			$.plot("#placeholder", [ d1, d2, d3 ], {
37
+				series: {
38
+					stack: stack,
39
+					lines: {
40
+						show: lines,
41
+						fill: true,
42
+						steps: steps
43
+					},
44
+					bars: {
45
+						show: bars,
46
+						barWidth: 0.6
47
+					}
48
+				}
49
+			});
50
+		}
51
+
52
+		plotWithOptions();
53
+
54
+		$(".stackControls button").click(function (e) {
55
+			e.preventDefault();
56
+			stack = $(this).text() == "With stacking" ? true : null;
57
+			plotWithOptions();
58
+		});
59
+
60
+		$(".graphControls button").click(function (e) {
61
+			e.preventDefault();
62
+			bars = $(this).text().indexOf("Bars") != -1;
63
+			lines = $(this).text().indexOf("Lines") != -1;
64
+			steps = $(this).text().indexOf("steps") != -1;
65
+			plotWithOptions();
66
+		});
67
+
68
+		// Add the Flot version string to the footer
69
+
70
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
71
+	});
72
+
73
+	</script>
74
+</head>
75
+<body>
76
+
77
+	<div id="header">
78
+		<h2>Stacking</h2>
79
+	</div>
80
+
81
+	<div id="content">
82
+
83
+		<div class="demo-container">
84
+			<div id="placeholder" class="demo-placeholder"></div>
85
+		</div>
86
+
87
+		<p>With the stack plugin, you can have Flot stack the series. This is useful if you wish to display both a total and the constituents it is made of. The only requirement is that you provide the input sorted on x.</p>
88
+
89
+		<p class="stackControls">
90
+			<button>With stacking</button>
91
+			<button>Without stacking</button>
92
+		</p>
93
+
94
+		<p class="graphControls">
95
+			<button>Bars</button>
96
+			<button>Lines</button>
97
+			<button>Lines with steps</button>
98
+		</p>
99
+
100
+	</div>
101
+
102
+	<div id="footer">
103
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
104
+	</div>
105
+
106
+</body>
107
+</html>
... ...
@@ -0,0 +1,76 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Symbols</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.symbol.js"></script>
11
+	<script type="text/javascript">
12
+
13
+	$(function() {
14
+
15
+		function generate(offset, amplitude) {
16
+
17
+			var res = [];
18
+			var start = 0, end = 10;
19
+
20
+			for (var i = 0; i <= 50; ++i) {
21
+				var x = start + i / 50 * (end - start);
22
+				res.push([x, amplitude * Math.sin(x + offset)]);
23
+			}
24
+
25
+			return res;
26
+		}
27
+
28
+		var data = [
29
+			{ data: generate(2, 1.8), points: { symbol: "circle" } },
30
+			{ data: generate(3, 1.5), points: { symbol: "square" } },
31
+			{ data: generate(4, 0.9), points: { symbol: "diamond" } },
32
+			{ data: generate(6, 1.4), points: { symbol: "triangle" } },
33
+			{ data: generate(7, 1.1), points: { symbol: "cross" } }
34
+		];
35
+
36
+		$.plot("#placeholder", data, {
37
+			series: {
38
+				points: {
39
+					show: true,
40
+					radius: 3
41
+				}
42
+			},
43
+			grid: {
44
+				hoverable: true
45
+			}
46
+		});
47
+
48
+		// Add the Flot version string to the footer
49
+
50
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
51
+	});
52
+
53
+	</script>
54
+</head>
55
+<body>
56
+
57
+	<div id="header">
58
+		<h2>Symbols</h2>
59
+	</div>
60
+
61
+	<div id="content">
62
+
63
+		<div class="demo-container">
64
+			<div id="placeholder" class="demo-placeholder"></div>
65
+		</div>
66
+
67
+		<p>Points can be marked in several ways, with circles being the built-in default. For other point types, you can define a callback function to draw the symbol. Some common symbols are available in the symbol plugin.</p>
68
+
69
+	</div>
70
+
71
+	<div id="footer">
72
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
73
+	</div>
74
+
75
+</body>
76
+</html>
... ...
@@ -0,0 +1,76 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Thresholds</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.threshold.js"></script>
11
+	<script type="text/javascript">
12
+
13
+	$(function() {
14
+
15
+		var d1 = [];
16
+		for (var i = 0; i <= 60; i += 1) {
17
+			d1.push([i, parseInt(Math.random() * 30 - 10)]);
18
+		}
19
+
20
+		function plotWithOptions(t) {
21
+			$.plot("#placeholder", [{
22
+				data: d1,
23
+				color: "rgb(30, 180, 20)",
24
+				threshold: {
25
+					below: t,
26
+					color: "rgb(200, 20, 30)"
27
+				},
28
+				lines: {
29
+					steps: true
30
+				}
31
+			}]);
32
+		}
33
+
34
+		plotWithOptions(0);
35
+
36
+		$(".controls button").click(function (e) {
37
+			e.preventDefault();
38
+			var t = parseFloat($(this).text().replace("Threshold at ", ""));
39
+			plotWithOptions(t);
40
+		});
41
+
42
+		// Add the Flot version string to the footer
43
+
44
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
45
+	});
46
+
47
+	</script>
48
+</head>
49
+<body>
50
+
51
+	<div id="header">
52
+		<h2>Thresholds</h2>
53
+	</div>
54
+
55
+	<div id="content">
56
+
57
+		<div class="demo-container">
58
+			<div id="placeholder" class="demo-placeholder"></div>
59
+		</div>
60
+
61
+		<p>With the threshold plugin, you can apply a specific color to the part of a data series below a threshold. This is can be useful for highlighting negative values, e.g. when displaying net results or what's in stock.</p>
62
+
63
+		<p class="controls">
64
+			<button>Threshold at 5</button>
65
+			<button>Threshold at 0</button>
66
+			<button>Threshold at -2.5</button>
67
+		</p>
68
+
69
+	</div>
70
+
71
+	<div id="footer">
72
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
73
+	</div>
74
+
75
+</body>
76
+</html>
... ...
@@ -0,0 +1,135 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Tracking</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.crosshair.js"></script>
11
+	<script type="text/javascript">
12
+
13
+	$(function() {
14
+
15
+		var sin = [], cos = [];
16
+		for (var i = 0; i < 14; i += 0.1) {
17
+			sin.push([i, Math.sin(i)]);
18
+			cos.push([i, Math.cos(i)]);
19
+		}
20
+
21
+		plot = $.plot("#placeholder", [
22
+			{ data: sin, label: "sin(x) = -0.00"},
23
+			{ data: cos, label: "cos(x) = -0.00" }
24
+		], {
25
+			series: {
26
+				lines: {
27
+					show: true
28
+				}
29
+			},
30
+			crosshair: {
31
+				mode: "x"
32
+			},
33
+			grid: {
34
+				hoverable: true,
35
+				autoHighlight: false
36
+			},
37
+			yaxis: {
38
+				min: -1.2,
39
+				max: 1.2
40
+			}
41
+		});
42
+
43
+		var legends = $("#placeholder .legendLabel");
44
+
45
+		legends.each(function () {
46
+			// fix the widths so they don't jump around
47
+			$(this).css('width', $(this).width());
48
+		});
49
+
50
+		var updateLegendTimeout = null;
51
+		var latestPosition = null;
52
+
53
+		function updateLegend() {
54
+
55
+			updateLegendTimeout = null;
56
+
57
+			var pos = latestPosition;
58
+
59
+			var axes = plot.getAxes();
60
+			if (pos.x < axes.xaxis.min || pos.x > axes.xaxis.max ||
61
+				pos.y < axes.yaxis.min || pos.y > axes.yaxis.max) {
62
+				return;
63
+			}
64
+
65
+			var i, j, dataset = plot.getData();
66
+			for (i = 0; i < dataset.length; ++i) {
67
+
68
+				var series = dataset[i];
69
+
70
+				// Find the nearest points, x-wise
71
+
72
+				for (j = 0; j < series.data.length; ++j) {
73
+					if (series.data[j][0] > pos.x) {
74
+						break;
75
+					}
76
+				}
77
+
78
+				// Now Interpolate
79
+
80
+				var y,
81
+					p1 = series.data[j - 1],
82
+					p2 = series.data[j];
83
+
84
+				if (p1 == null) {
85
+					y = p2[1];
86
+				} else if (p2 == null) {
87
+					y = p1[1];
88
+				} else {
89
+					y = p1[1] + (p2[1] - p1[1]) * (pos.x - p1[0]) / (p2[0] - p1[0]);
90
+				}
91
+
92
+				legends.eq(i).text(series.label.replace(/=.*/, "= " + y.toFixed(2)));
93
+			}
94
+		}
95
+
96
+		$("#placeholder").bind("plothover",  function (event, pos, item) {
97
+			latestPosition = pos;
98
+			if (!updateLegendTimeout) {
99
+				updateLegendTimeout = setTimeout(updateLegend, 50);
100
+			}
101
+		});
102
+
103
+		// Add the Flot version string to the footer
104
+
105
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
106
+	});
107
+
108
+	</script>
109
+</head>
110
+<body>
111
+
112
+	<div id="header">
113
+		<h2>Tracking</h2>
114
+	</div>
115
+
116
+	<div id="content">
117
+
118
+		<div class="demo-container">
119
+			<div id="placeholder" class="demo-placeholder"></div>
120
+		</div>
121
+
122
+		<p>You can add crosshairs that'll track the mouse position, either on both axes or as here on only one.</p>
123
+
124
+		<p>If you combine it with listening on hover events, you can use it to track the intersection on the curves by interpolating the data points (look at the legend).</p>
125
+
126
+		<p id="hoverdata"></p>
127
+
128
+	</div>
129
+
130
+	<div id="footer">
131
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
132
+	</div>
133
+
134
+</body>
135
+</html>
... ...
@@ -0,0 +1,147 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Visitors</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.time.js"></script>
11
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.selection.js"></script>
12
+	<script type="text/javascript">
13
+
14
+	$(function() {
15
+
16
+		var d = [[1196463600000, 0], [1196550000000, 0], [1196636400000, 0], [1196722800000, 77], [1196809200000, 3636], [1196895600000, 3575], [1196982000000, 2736], [1197068400000, 1086], [1197154800000, 676], [1197241200000, 1205], [1197327600000, 906], [1197414000000, 710], [1197500400000, 639], [1197586800000, 540], [1197673200000, 435], [1197759600000, 301], [1197846000000, 575], [1197932400000, 481], [1198018800000, 591], [1198105200000, 608], [1198191600000, 459], [1198278000000, 234], [1198364400000, 1352], [1198450800000, 686], [1198537200000, 279], [1198623600000, 449], [1198710000000, 468], [1198796400000, 392], [1198882800000, 282], [1198969200000, 208], [1199055600000, 229], [1199142000000, 177], [1199228400000, 374], [1199314800000, 436], [1199401200000, 404], [1199487600000, 253], [1199574000000, 218], [1199660400000, 476], [1199746800000, 462], [1199833200000, 448], [1199919600000, 442], [1200006000000, 403], [1200092400000, 204], [1200178800000, 194], [1200265200000, 327], [1200351600000, 374], [1200438000000, 507], [1200524400000, 546], [1200610800000, 482], [1200697200000, 283], [1200783600000, 221], [1200870000000, 483], [1200956400000, 523], [1201042800000, 528], [1201129200000, 483], [1201215600000, 452], [1201302000000, 270], [1201388400000, 222], [1201474800000, 439], [1201561200000, 559], [1201647600000, 521], [1201734000000, 477], [1201820400000, 442], [1201906800000, 252], [1201993200000, 236], [1202079600000, 525], [1202166000000, 477], [1202252400000, 386], [1202338800000, 409], [1202425200000, 408], [1202511600000, 237], [1202598000000, 193], [1202684400000, 357], [1202770800000, 414], [1202857200000, 393], [1202943600000, 353], [1203030000000, 364], [1203116400000, 215], [1203202800000, 214], [1203289200000, 356], [1203375600000, 399], [1203462000000, 334], [1203548400000, 348], [1203634800000, 243], [1203721200000, 126], [1203807600000, 157], [1203894000000, 288]];
17
+
18
+		// first correct the timestamps - they are recorded as the daily
19
+		// midnights in UTC+0100, but Flot always displays dates in UTC
20
+		// so we have to add one hour to hit the midnights in the plot
21
+
22
+		for (var i = 0; i < d.length; ++i) {
23
+			d[i][0] += 60 * 60 * 1000;
24
+		}
25
+
26
+		// helper for returning the weekends in a period
27
+
28
+		function weekendAreas(axes) {
29
+
30
+			var markings = [],
31
+				d = new Date(axes.xaxis.min);
32
+
33
+			// go to the first Saturday
34
+
35
+			d.setUTCDate(d.getUTCDate() - ((d.getUTCDay() + 1) % 7))
36
+			d.setUTCSeconds(0);
37
+			d.setUTCMinutes(0);
38
+			d.setUTCHours(0);
39
+
40
+			var i = d.getTime();
41
+
42
+			// when we don't set yaxis, the rectangle automatically
43
+			// extends to infinity upwards and downwards
44
+
45
+			do {
46
+				markings.push({ xaxis: { from: i, to: i + 2 * 24 * 60 * 60 * 1000 } });
47
+				i += 7 * 24 * 60 * 60 * 1000;
48
+			} while (i < axes.xaxis.max);
49
+
50
+			return markings;
51
+		}
52
+
53
+		var options = {
54
+			xaxis: {
55
+				mode: "time",
56
+				tickLength: 5
57
+			},
58
+			selection: {
59
+				mode: "x"
60
+			},
61
+			grid: {
62
+				markings: weekendAreas
63
+			}
64
+		};
65
+
66
+		var plot = $.plot("#placeholder", [d], options);
67
+
68
+		var overview = $.plot("#overview", [d], {
69
+			series: {
70
+				lines: {
71
+					show: true,
72
+					lineWidth: 1
73
+				},
74
+				shadowSize: 0
75
+			},
76
+			xaxis: {
77
+				ticks: [],
78
+				mode: "time"
79
+			},
80
+			yaxis: {
81
+				ticks: [],
82
+				min: 0,
83
+				autoscaleMargin: 0.1
84
+			},
85
+			selection: {
86
+				mode: "x"
87
+			}
88
+		});
89
+
90
+		// now connect the two
91
+
92
+		$("#placeholder").bind("plotselected", function (event, ranges) {
93
+
94
+			// do the zooming
95
+			$.each(plot.getXAxes(), function(_, axis) {
96
+				var opts = axis.options;
97
+				opts.min = ranges.xaxis.from;
98
+				opts.max = ranges.xaxis.to;
99
+			});
100
+			plot.setupGrid();
101
+			plot.draw();
102
+			plot.clearSelection();
103
+
104
+			// don't fire event on the overview to prevent eternal loop
105
+
106
+			overview.setSelection(ranges, true);
107
+		});
108
+
109
+		$("#overview").bind("plotselected", function (event, ranges) {
110
+			plot.setSelection(ranges);
111
+		});
112
+
113
+		// Add the Flot version string to the footer
114
+
115
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
116
+	});
117
+
118
+	</script>
119
+</head>
120
+<body>
121
+
122
+	<div id="header">
123
+		<h2>Visitors</h2>
124
+	</div>
125
+
126
+	<div id="content">
127
+
128
+		<div class="demo-container">
129
+			<div id="placeholder" class="demo-placeholder"></div>
130
+		</div>
131
+
132
+		<div class="demo-container" style="height:150px;">
133
+			<div id="overview" class="demo-placeholder"></div>
134
+		</div>
135
+
136
+		<p>This plot shows visitors per day to the Flot homepage, with weekends colored.</p>
137
+
138
+		<p>The smaller plot is linked to the main plot, so it acts as an overview. Try dragging a selection on either plot, and watch the behavior of the other.</p>
139
+
140
+	</div>
141
+
142
+	<div id="footer">
143
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
144
+	</div>
145
+
146
+</body>
147
+</html>
... ...
@@ -0,0 +1,144 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+<html>
3
+<head>
4
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+	<title>Flot Examples: Selection and zooming</title>
6
+	<link href="../examples.css" rel="stylesheet" type="text/css">
7
+	<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
8
+	<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
9
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
10
+	<script language="javascript" type="text/javascript" src="../../jquery.flot.selection.js"></script>
11
+	<script type="text/javascript">
12
+
13
+	$(function() {
14
+
15
+		// setup plot
16
+
17
+		function getData(x1, x2) {
18
+
19
+			var d = [];
20
+			for (var i = 0; i <= 100; ++i) {
21
+				var x = x1 + i * (x2 - x1) / 100;
22
+				d.push([x, Math.sin(x * Math.sin(x))]);
23
+			}
24
+
25
+			return [
26
+				{ label: "sin(x sin(x))", data: d }
27
+			];
28
+		}
29
+
30
+		var options = {
31
+			legend: {
32
+				show: false
33
+			},
34
+			series: {
35
+				lines: {
36
+					show: true
37
+				},
38
+				points: {
39
+					show: true
40
+				}
41
+			},
42
+			yaxis: {
43
+				ticks: 10
44
+			},
45
+			selection: {
46
+				mode: "xy"
47
+			}
48
+		};
49
+
50
+		var startData = getData(0, 3 * Math.PI);
51
+
52
+		var plot = $.plot("#placeholder", startData, options);
53
+
54
+		// Create the overview plot
55
+
56
+		var overview = $.plot("#overview", startData, {
57
+			legend: {
58
+				show: false
59
+			},
60
+			series: {
61
+				lines: {
62
+					show: true,
63
+					lineWidth: 1
64
+				},
65
+				shadowSize: 0
66
+			},
67
+			xaxis: {
68
+				ticks: 4
69
+			},
70
+			yaxis: {
71
+				ticks: 3,
72
+				min: -2,
73
+				max: 2
74
+			},
75
+			grid: {
76
+				color: "#999"
77
+			},
78
+			selection: {
79
+				mode: "xy"
80
+			}
81
+		});
82
+
83
+		// now connect the two
84
+
85
+		$("#placeholder").bind("plotselected", function (event, ranges) {
86
+
87
+			// clamp the zooming to prevent eternal zoom
88
+
89
+			if (ranges.xaxis.to - ranges.xaxis.from < 0.00001) {
90
+				ranges.xaxis.to = ranges.xaxis.from + 0.00001;
91
+			}
92
+
93
+			if (ranges.yaxis.to - ranges.yaxis.from < 0.00001) {
94
+				ranges.yaxis.to = ranges.yaxis.from + 0.00001;
95
+			}
96
+
97
+			// do the zooming
98
+
99
+			plot = $.plot("#placeholder", getData(ranges.xaxis.from, ranges.xaxis.to),
100
+				$.extend(true, {}, options, {
101
+					xaxis: { min: ranges.xaxis.from, max: ranges.xaxis.to },
102
+					yaxis: { min: ranges.yaxis.from, max: ranges.yaxis.to }
103
+				})
104
+			);
105
+
106
+			// don't fire event on the overview to prevent eternal loop
107
+
108
+			overview.setSelection(ranges, true);
109
+		});
110
+
111
+		$("#overview").bind("plotselected", function (event, ranges) {
112
+			plot.setSelection(ranges);
113
+		});
114
+
115
+		// Add the Flot version string to the footer
116
+
117
+		$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
118
+	});
119
+
120
+	</script>
121
+</head>
122
+<body>
123
+
124
+	<div id="header">
125
+		<h2>Selection and zooming</h2>
126
+	</div>
127
+
128
+	<div id="content">
129
+
130
+		<div class="demo-container">
131
+			<div id="placeholder" class="demo-placeholder" style="float:left; width:650px;"></div>
132
+			<div id="overview" class="demo-placeholder" style="float:right;width:160px; height:125px;"></div>
133
+		</div>
134
+
135
+		<p>Selection support makes it easy to construct flexible zooming schemes. With a few lines of code, the small overview plot to the right has been connected to the large plot. Try selecting a rectangle on either of them.</p>
136
+
137
+	</div>
138
+
139
+	<div id="footer">
140
+		Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
141
+	</div>
142
+
143
+</body>
144
+</html>
... ...
@@ -0,0 +1,1428 @@
1
+// Copyright 2006 Google Inc.
2
+//
3
+// Licensed under the Apache License, Version 2.0 (the "License");
4
+// you may not use this file except in compliance with the License.
5
+// You may obtain a copy of the License at
6
+//
7
+//   http://www.apache.org/licenses/LICENSE-2.0
8
+//
9
+// Unless required by applicable law or agreed to in writing, software
10
+// distributed under the License is distributed on an "AS IS" BASIS,
11
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+// See the License for the specific language governing permissions and
13
+// limitations under the License.
14
+
15
+
16
+// Known Issues:
17
+//
18
+// * Patterns only support repeat.
19
+// * Radial gradient are not implemented. The VML version of these look very
20
+//   different from the canvas one.
21
+// * Clipping paths are not implemented.
22
+// * Coordsize. The width and height attribute have higher priority than the
23
+//   width and height style values which isn't correct.
24
+// * Painting mode isn't implemented.
25
+// * Canvas width/height should is using content-box by default. IE in
26
+//   Quirks mode will draw the canvas using border-box. Either change your
27
+//   doctype to HTML5
28
+//   (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
29
+//   or use Box Sizing Behavior from WebFX
30
+//   (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
31
+// * Non uniform scaling does not correctly scale strokes.
32
+// * Filling very large shapes (above 5000 points) is buggy.
33
+// * Optimize. There is always room for speed improvements.
34
+
35
+// Only add this code if we do not already have a canvas implementation
36
+if (!document.createElement('canvas').getContext) {
37
+
38
+(function() {
39
+
40
+  // alias some functions to make (compiled) code shorter
41
+  var m = Math;
42
+  var mr = m.round;
43
+  var ms = m.sin;
44
+  var mc = m.cos;
45
+  var abs = m.abs;
46
+  var sqrt = m.sqrt;
47
+
48
+  // this is used for sub pixel precision
49
+  var Z = 10;
50
+  var Z2 = Z / 2;
51
+
52
+  var IE_VERSION = +navigator.userAgent.match(/MSIE ([\d.]+)?/)[1];
53
+
54
+  /**
55
+   * This funtion is assigned to the <canvas> elements as element.getContext().
56
+   * @this {HTMLElement}
57
+   * @return {CanvasRenderingContext2D_}
58
+   */
59
+  function getContext() {
60
+    return this.context_ ||
61
+        (this.context_ = new CanvasRenderingContext2D_(this));
62
+  }
63
+
64
+  var slice = Array.prototype.slice;
65
+
66
+  /**
67
+   * Binds a function to an object. The returned function will always use the
68
+   * passed in {@code obj} as {@code this}.
69
+   *
70
+   * Example:
71
+   *
72
+   *   g = bind(f, obj, a, b)
73
+   *   g(c, d) // will do f.call(obj, a, b, c, d)
74
+   *
75
+   * @param {Function} f The function to bind the object to
76
+   * @param {Object} obj The object that should act as this when the function
77
+   *     is called
78
+   * @param {*} var_args Rest arguments that will be used as the initial
79
+   *     arguments when the function is called
80
+   * @return {Function} A new function that has bound this
81
+   */
82
+  function bind(f, obj, var_args) {
83
+    var a = slice.call(arguments, 2);
84
+    return function() {
85
+      return f.apply(obj, a.concat(slice.call(arguments)));
86
+    };
87
+  }
88
+
89
+  function encodeHtmlAttribute(s) {
90
+    return String(s).replace(/&/g, '&amp;').replace(/"/g, '&quot;');
91
+  }
92
+
93
+  function addNamespace(doc, prefix, urn) {
94
+    if (!doc.namespaces[prefix]) {
95
+      doc.namespaces.add(prefix, urn, '#default#VML');
96
+    }
97
+  }
98
+
99
+  function addNamespacesAndStylesheet(doc) {
100
+    addNamespace(doc, 'g_vml_', 'urn:schemas-microsoft-com:vml');
101
+    addNamespace(doc, 'g_o_', 'urn:schemas-microsoft-com:office:office');
102
+
103
+    // Setup default CSS.  Only add one style sheet per document
104
+    if (!doc.styleSheets['ex_canvas_']) {
105
+      var ss = doc.createStyleSheet();
106
+      ss.owningElement.id = 'ex_canvas_';
107
+      ss.cssText = 'canvas{display:inline-block;overflow:hidden;' +
108
+          // default size is 300x150 in Gecko and Opera
109
+          'text-align:left;width:300px;height:150px}';
110
+    }
111
+  }
112
+
113
+  // Add namespaces and stylesheet at startup.
114
+  addNamespacesAndStylesheet(document);
115
+
116
+  var G_vmlCanvasManager_ = {
117
+    init: function(opt_doc) {
118
+      var doc = opt_doc || document;
119
+      // Create a dummy element so that IE will allow canvas elements to be
120
+      // recognized.
121
+      doc.createElement('canvas');
122
+      doc.attachEvent('onreadystatechange', bind(this.init_, this, doc));
123
+    },
124
+
125
+    init_: function(doc) {
126
+      // find all canvas elements
127
+      var els = doc.getElementsByTagName('canvas');
128
+      for (var i = 0; i < els.length; i++) {
129
+        this.initElement(els[i]);
130
+      }
131
+    },
132
+
133
+    /**
134
+     * Public initializes a canvas element so that it can be used as canvas
135
+     * element from now on. This is called automatically before the page is
136
+     * loaded but if you are creating elements using createElement you need to
137
+     * make sure this is called on the element.
138
+     * @param {HTMLElement} el The canvas element to initialize.
139
+     * @return {HTMLElement} the element that was created.
140
+     */
141
+    initElement: function(el) {
142
+      if (!el.getContext) {
143
+        el.getContext = getContext;
144
+
145
+        // Add namespaces and stylesheet to document of the element.
146
+        addNamespacesAndStylesheet(el.ownerDocument);
147
+
148
+        // Remove fallback content. There is no way to hide text nodes so we
149
+        // just remove all childNodes. We could hide all elements and remove
150
+        // text nodes but who really cares about the fallback content.
151
+        el.innerHTML = '';
152
+
153
+        // do not use inline function because that will leak memory
154
+        el.attachEvent('onpropertychange', onPropertyChange);
155
+        el.attachEvent('onresize', onResize);
156
+
157
+        var attrs = el.attributes;
158
+        if (attrs.width && attrs.width.specified) {
159
+          // TODO: use runtimeStyle and coordsize
160
+          // el.getContext().setWidth_(attrs.width.nodeValue);
161
+          el.style.width = attrs.width.nodeValue + 'px';
162
+        } else {
163
+          el.width = el.clientWidth;
164
+        }
165
+        if (attrs.height && attrs.height.specified) {
166
+          // TODO: use runtimeStyle and coordsize
167
+          // el.getContext().setHeight_(attrs.height.nodeValue);
168
+          el.style.height = attrs.height.nodeValue + 'px';
169
+        } else {
170
+          el.height = el.clientHeight;
171
+        }
172
+        //el.getContext().setCoordsize_()
173
+      }
174
+      return el;
175
+    }
176
+  };
177
+
178
+  function onPropertyChange(e) {
179
+    var el = e.srcElement;
180
+
181
+    switch (e.propertyName) {
182
+      case 'width':
183
+        el.getContext().clearRect();
184
+        el.style.width = el.attributes.width.nodeValue + 'px';
185
+        // In IE8 this does not trigger onresize.
186
+        el.firstChild.style.width =  el.clientWidth + 'px';
187
+        break;
188
+      case 'height':
189
+        el.getContext().clearRect();
190
+        el.style.height = el.attributes.height.nodeValue + 'px';
191
+        el.firstChild.style.height = el.clientHeight + 'px';
192
+        break;
193
+    }
194
+  }
195
+
196
+  function onResize(e) {
197
+    var el = e.srcElement;
198
+    if (el.firstChild) {
199
+      el.firstChild.style.width =  el.clientWidth + 'px';
200
+      el.firstChild.style.height = el.clientHeight + 'px';
201
+    }
202
+  }
203
+
204
+  G_vmlCanvasManager_.init();
205
+
206
+  // precompute "00" to "FF"
207
+  var decToHex = [];
208
+  for (var i = 0; i < 16; i++) {
209
+    for (var j = 0; j < 16; j++) {
210
+      decToHex[i * 16 + j] = i.toString(16) + j.toString(16);
211
+    }
212
+  }
213
+
214
+  function createMatrixIdentity() {
215
+    return [
216
+      [1, 0, 0],
217
+      [0, 1, 0],
218
+      [0, 0, 1]
219
+    ];
220
+  }
221
+
222
+  function matrixMultiply(m1, m2) {
223
+    var result = createMatrixIdentity();
224
+
225
+    for (var x = 0; x < 3; x++) {
226
+      for (var y = 0; y < 3; y++) {
227
+        var sum = 0;
228
+
229
+        for (var z = 0; z < 3; z++) {
230
+          sum += m1[x][z] * m2[z][y];
231
+        }
232
+
233
+        result[x][y] = sum;
234
+      }
235
+    }
236
+    return result;
237
+  }
238
+
239
+  function copyState(o1, o2) {
240
+    o2.fillStyle     = o1.fillStyle;
241
+    o2.lineCap       = o1.lineCap;
242
+    o2.lineJoin      = o1.lineJoin;
243
+    o2.lineWidth     = o1.lineWidth;
244
+    o2.miterLimit    = o1.miterLimit;
245
+    o2.shadowBlur    = o1.shadowBlur;
246
+    o2.shadowColor   = o1.shadowColor;
247
+    o2.shadowOffsetX = o1.shadowOffsetX;
248
+    o2.shadowOffsetY = o1.shadowOffsetY;
249
+    o2.strokeStyle   = o1.strokeStyle;
250
+    o2.globalAlpha   = o1.globalAlpha;
251
+    o2.font          = o1.font;
252
+    o2.textAlign     = o1.textAlign;
253
+    o2.textBaseline  = o1.textBaseline;
254
+    o2.arcScaleX_    = o1.arcScaleX_;
255
+    o2.arcScaleY_    = o1.arcScaleY_;
256
+    o2.lineScale_    = o1.lineScale_;
257
+  }
258
+
259
+  var colorData = {
260
+    aliceblue: '#F0F8FF',
261
+    antiquewhite: '#FAEBD7',
262
+    aquamarine: '#7FFFD4',
263
+    azure: '#F0FFFF',
264
+    beige: '#F5F5DC',
265
+    bisque: '#FFE4C4',
266
+    black: '#000000',
267
+    blanchedalmond: '#FFEBCD',
268
+    blueviolet: '#8A2BE2',
269
+    brown: '#A52A2A',
270
+    burlywood: '#DEB887',
271
+    cadetblue: '#5F9EA0',
272
+    chartreuse: '#7FFF00',
273
+    chocolate: '#D2691E',
274
+    coral: '#FF7F50',
275
+    cornflowerblue: '#6495ED',
276
+    cornsilk: '#FFF8DC',
277
+    crimson: '#DC143C',
278
+    cyan: '#00FFFF',
279
+    darkblue: '#00008B',
280
+    darkcyan: '#008B8B',
281
+    darkgoldenrod: '#B8860B',
282
+    darkgray: '#A9A9A9',
283
+    darkgreen: '#006400',
284
+    darkgrey: '#A9A9A9',
285
+    darkkhaki: '#BDB76B',
286
+    darkmagenta: '#8B008B',
287
+    darkolivegreen: '#556B2F',
288
+    darkorange: '#FF8C00',
289
+    darkorchid: '#9932CC',
290
+    darkred: '#8B0000',
291
+    darksalmon: '#E9967A',
292
+    darkseagreen: '#8FBC8F',
293
+    darkslateblue: '#483D8B',
294
+    darkslategray: '#2F4F4F',
295
+    darkslategrey: '#2F4F4F',
296
+    darkturquoise: '#00CED1',
297
+    darkviolet: '#9400D3',
298
+    deeppink: '#FF1493',
299
+    deepskyblue: '#00BFFF',
300
+    dimgray: '#696969',
301
+    dimgrey: '#696969',
302
+    dodgerblue: '#1E90FF',
303
+    firebrick: '#B22222',
304
+    floralwhite: '#FFFAF0',
305
+    forestgreen: '#228B22',
306
+    gainsboro: '#DCDCDC',
307
+    ghostwhite: '#F8F8FF',
308
+    gold: '#FFD700',
309
+    goldenrod: '#DAA520',
310
+    grey: '#808080',
311
+    greenyellow: '#ADFF2F',
312
+    honeydew: '#F0FFF0',
313
+    hotpink: '#FF69B4',
314
+    indianred: '#CD5C5C',
315
+    indigo: '#4B0082',
316
+    ivory: '#FFFFF0',
317
+    khaki: '#F0E68C',
318
+    lavender: '#E6E6FA',
319
+    lavenderblush: '#FFF0F5',
320
+    lawngreen: '#7CFC00',
321
+    lemonchiffon: '#FFFACD',
322
+    lightblue: '#ADD8E6',
323
+    lightcoral: '#F08080',
324
+    lightcyan: '#E0FFFF',
325
+    lightgoldenrodyellow: '#FAFAD2',
326
+    lightgreen: '#90EE90',
327
+    lightgrey: '#D3D3D3',
328
+    lightpink: '#FFB6C1',
329
+    lightsalmon: '#FFA07A',
330
+    lightseagreen: '#20B2AA',
331
+    lightskyblue: '#87CEFA',
332
+    lightslategray: '#778899',
333
+    lightslategrey: '#778899',
334
+    lightsteelblue: '#B0C4DE',
335
+    lightyellow: '#FFFFE0',
336
+    limegreen: '#32CD32',
337
+    linen: '#FAF0E6',
338
+    magenta: '#FF00FF',
339
+    mediumaquamarine: '#66CDAA',
340
+    mediumblue: '#0000CD',
341
+    mediumorchid: '#BA55D3',
342
+    mediumpurple: '#9370DB',
343
+    mediumseagreen: '#3CB371',
344
+    mediumslateblue: '#7B68EE',
345
+    mediumspringgreen: '#00FA9A',
346
+    mediumturquoise: '#48D1CC',
347
+    mediumvioletred: '#C71585',
348
+    midnightblue: '#191970',
349
+    mintcream: '#F5FFFA',
350
+    mistyrose: '#FFE4E1',
351
+    moccasin: '#FFE4B5',
352
+    navajowhite: '#FFDEAD',
353
+    oldlace: '#FDF5E6',
354
+    olivedrab: '#6B8E23',
355
+    orange: '#FFA500',
356
+    orangered: '#FF4500',
357
+    orchid: '#DA70D6',
358
+    palegoldenrod: '#EEE8AA',
359
+    palegreen: '#98FB98',
360
+    paleturquoise: '#AFEEEE',
361
+    palevioletred: '#DB7093',
362
+    papayawhip: '#FFEFD5',
363
+    peachpuff: '#FFDAB9',
364
+    peru: '#CD853F',
365
+    pink: '#FFC0CB',
366
+    plum: '#DDA0DD',
367
+    powderblue: '#B0E0E6',
368
+    rosybrown: '#BC8F8F',
369
+    royalblue: '#4169E1',
370
+    saddlebrown: '#8B4513',
371
+    salmon: '#FA8072',
372
+    sandybrown: '#F4A460',
373
+    seagreen: '#2E8B57',
374
+    seashell: '#FFF5EE',
375
+    sienna: '#A0522D',
376
+    skyblue: '#87CEEB',
377
+    slateblue: '#6A5ACD',
378
+    slategray: '#708090',
379
+    slategrey: '#708090',
380
+    snow: '#FFFAFA',
381
+    springgreen: '#00FF7F',
382
+    steelblue: '#4682B4',
383
+    tan: '#D2B48C',
384
+    thistle: '#D8BFD8',
385
+    tomato: '#FF6347',
386
+    turquoise: '#40E0D0',
387
+    violet: '#EE82EE',
388
+    wheat: '#F5DEB3',
389
+    whitesmoke: '#F5F5F5',
390
+    yellowgreen: '#9ACD32'
391
+  };
392
+
393
+
394
+  function getRgbHslContent(styleString) {
395
+    var start = styleString.indexOf('(', 3);
396
+    var end = styleString.indexOf(')', start + 1);
397
+    var parts = styleString.substring(start + 1, end).split(',');
398
+    // add alpha if needed
399
+    if (parts.length != 4 || styleString.charAt(3) != 'a') {
400
+      parts[3] = 1;
401
+    }
402
+    return parts;
403
+  }
404
+
405
+  function percent(s) {
406
+    return parseFloat(s) / 100;
407
+  }
408
+
409
+  function clamp(v, min, max) {
410
+    return Math.min(max, Math.max(min, v));
411
+  }
412
+
413
+  function hslToRgb(parts){
414
+    var r, g, b, h, s, l;
415
+    h = parseFloat(parts[0]) / 360 % 360;
416
+    if (h < 0)
417
+      h++;
418
+    s = clamp(percent(parts[1]), 0, 1);
419
+    l = clamp(percent(parts[2]), 0, 1);
420
+    if (s == 0) {
421
+      r = g = b = l; // achromatic
422
+    } else {
423
+      var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
424
+      var p = 2 * l - q;
425
+      r = hueToRgb(p, q, h + 1 / 3);
426
+      g = hueToRgb(p, q, h);
427
+      b = hueToRgb(p, q, h - 1 / 3);
428
+    }
429
+
430
+    return '#' + decToHex[Math.floor(r * 255)] +
431
+        decToHex[Math.floor(g * 255)] +
432
+        decToHex[Math.floor(b * 255)];
433
+  }
434
+
435
+  function hueToRgb(m1, m2, h) {
436
+    if (h < 0)
437
+      h++;
438
+    if (h > 1)
439
+      h--;
440
+
441
+    if (6 * h < 1)
442
+      return m1 + (m2 - m1) * 6 * h;
443
+    else if (2 * h < 1)
444
+      return m2;
445
+    else if (3 * h < 2)
446
+      return m1 + (m2 - m1) * (2 / 3 - h) * 6;
447
+    else
448
+      return m1;
449
+  }
450
+
451
+  var processStyleCache = {};
452
+
453
+  function processStyle(styleString) {
454
+    if (styleString in processStyleCache) {
455
+      return processStyleCache[styleString];
456
+    }
457
+
458
+    var str, alpha = 1;
459
+
460
+    styleString = String(styleString);
461
+    if (styleString.charAt(0) == '#') {
462
+      str = styleString;
463
+    } else if (/^rgb/.test(styleString)) {
464
+      var parts = getRgbHslContent(styleString);
465
+      var str = '#', n;
466
+      for (var i = 0; i < 3; i++) {
467
+        if (parts[i].indexOf('%') != -1) {
468
+          n = Math.floor(percent(parts[i]) * 255);
469
+        } else {
470
+          n = +parts[i];
471
+        }
472
+        str += decToHex[clamp(n, 0, 255)];
473
+      }
474
+      alpha = +parts[3];
475
+    } else if (/^hsl/.test(styleString)) {
476
+      var parts = getRgbHslContent(styleString);
477
+      str = hslToRgb(parts);
478
+      alpha = parts[3];
479
+    } else {
480
+      str = colorData[styleString] || styleString;
481
+    }
482
+    return processStyleCache[styleString] = {color: str, alpha: alpha};
483
+  }
484
+
485
+  var DEFAULT_STYLE = {
486
+    style: 'normal',
487
+    variant: 'normal',
488
+    weight: 'normal',
489
+    size: 10,
490
+    family: 'sans-serif'
491
+  };
492
+
493
+  // Internal text style cache
494
+  var fontStyleCache = {};
495
+
496
+  function processFontStyle(styleString) {
497
+    if (fontStyleCache[styleString]) {
498
+      return fontStyleCache[styleString];
499
+    }
500
+
501
+    var el = document.createElement('div');
502
+    var style = el.style;
503
+    try {
504
+      style.font = styleString;
505
+    } catch (ex) {
506
+      // Ignore failures to set to invalid font.
507
+    }
508
+
509
+    return fontStyleCache[styleString] = {
510
+      style: style.fontStyle || DEFAULT_STYLE.style,
511
+      variant: style.fontVariant || DEFAULT_STYLE.variant,
512
+      weight: style.fontWeight || DEFAULT_STYLE.weight,
513
+      size: style.fontSize || DEFAULT_STYLE.size,
514
+      family: style.fontFamily || DEFAULT_STYLE.family
515
+    };
516
+  }
517
+
518
+  function getComputedStyle(style, element) {
519
+    var computedStyle = {};
520
+
521
+    for (var p in style) {
522
+      computedStyle[p] = style[p];
523
+    }
524
+
525
+    // Compute the size
526
+    var canvasFontSize = parseFloat(element.currentStyle.fontSize),
527
+        fontSize = parseFloat(style.size);
528
+
529
+    if (typeof style.size == 'number') {
530
+      computedStyle.size = style.size;
531
+    } else if (style.size.indexOf('px') != -1) {
532
+      computedStyle.size = fontSize;
533
+    } else if (style.size.indexOf('em') != -1) {
534
+      computedStyle.size = canvasFontSize * fontSize;
535
+    } else if(style.size.indexOf('%') != -1) {
536
+      computedStyle.size = (canvasFontSize / 100) * fontSize;
537
+    } else if (style.size.indexOf('pt') != -1) {
538
+      computedStyle.size = fontSize / .75;
539
+    } else {
540
+      computedStyle.size = canvasFontSize;
541
+    }
542
+
543
+    // Different scaling between normal text and VML text. This was found using
544
+    // trial and error to get the same size as non VML text.
545
+    computedStyle.size *= 0.981;
546
+
547
+    return computedStyle;
548
+  }
549
+
550
+  function buildStyle(style) {
551
+    return style.style + ' ' + style.variant + ' ' + style.weight + ' ' +
552
+        style.size + 'px ' + style.family;
553
+  }
554
+
555
+  var lineCapMap = {
556
+    'butt': 'flat',
557
+    'round': 'round'
558
+  };
559
+
560
+  function processLineCap(lineCap) {
561
+    return lineCapMap[lineCap] || 'square';
562
+  }
563
+
564
+  /**
565
+   * This class implements CanvasRenderingContext2D interface as described by
566
+   * the WHATWG.
567
+   * @param {HTMLElement} canvasElement The element that the 2D context should
568
+   * be associated with
569
+   */
570
+  function CanvasRenderingContext2D_(canvasElement) {
571
+    this.m_ = createMatrixIdentity();
572
+
573
+    this.mStack_ = [];
574
+    this.aStack_ = [];
575
+    this.currentPath_ = [];
576
+
577
+    // Canvas context properties
578
+    this.strokeStyle = '#000';
579
+    this.fillStyle = '#000';
580
+
581
+    this.lineWidth = 1;
582
+    this.lineJoin = 'miter';
583
+    this.lineCap = 'butt';
584
+    this.miterLimit = Z * 1;
585
+    this.globalAlpha = 1;
586
+    this.font = '10px sans-serif';
587
+    this.textAlign = 'left';
588
+    this.textBaseline = 'alphabetic';
589
+    this.canvas = canvasElement;
590
+
591
+    var cssText = 'width:' + canvasElement.clientWidth + 'px;height:' +
592
+        canvasElement.clientHeight + 'px;overflow:hidden;position:absolute';
593
+    var el = canvasElement.ownerDocument.createElement('div');
594
+    el.style.cssText = cssText;
595
+    canvasElement.appendChild(el);
596
+
597
+    var overlayEl = el.cloneNode(false);
598
+    // Use a non transparent background.
599
+    overlayEl.style.backgroundColor = 'red';
600
+    overlayEl.style.filter = 'alpha(opacity=0)';
601
+    canvasElement.appendChild(overlayEl);
602
+
603
+    this.element_ = el;
604
+    this.arcScaleX_ = 1;
605
+    this.arcScaleY_ = 1;
606
+    this.lineScale_ = 1;
607
+  }
608
+
609
+  var contextPrototype = CanvasRenderingContext2D_.prototype;
610
+  contextPrototype.clearRect = function() {
611
+    if (this.textMeasureEl_) {
612
+      this.textMeasureEl_.removeNode(true);
613
+      this.textMeasureEl_ = null;
614
+    }
615
+    this.element_.innerHTML = '';
616
+  };
617
+
618
+  contextPrototype.beginPath = function() {
619
+    // TODO: Branch current matrix so that save/restore has no effect
620
+    //       as per safari docs.
621
+    this.currentPath_ = [];
622
+  };
623
+
624
+  contextPrototype.moveTo = function(aX, aY) {
625
+    var p = getCoords(this, aX, aY);
626
+    this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y});
627
+    this.currentX_ = p.x;
628
+    this.currentY_ = p.y;
629
+  };
630
+
631
+  contextPrototype.lineTo = function(aX, aY) {
632
+    var p = getCoords(this, aX, aY);
633
+    this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y});
634
+
635
+    this.currentX_ = p.x;
636
+    this.currentY_ = p.y;
637
+  };
638
+
639
+  contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,
640
+                                            aCP2x, aCP2y,
641
+                                            aX, aY) {
642
+    var p = getCoords(this, aX, aY);
643
+    var cp1 = getCoords(this, aCP1x, aCP1y);
644
+    var cp2 = getCoords(this, aCP2x, aCP2y);
645
+    bezierCurveTo(this, cp1, cp2, p);
646
+  };
647
+
648
+  // Helper function that takes the already fixed cordinates.
649
+  function bezierCurveTo(self, cp1, cp2, p) {
650
+    self.currentPath_.push({
651
+      type: 'bezierCurveTo',
652
+      cp1x: cp1.x,
653
+      cp1y: cp1.y,
654
+      cp2x: cp2.x,
655
+      cp2y: cp2.y,
656
+      x: p.x,
657
+      y: p.y
658
+    });
659
+    self.currentX_ = p.x;
660
+    self.currentY_ = p.y;
661
+  }
662
+
663
+  contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {
664
+    // the following is lifted almost directly from
665
+    // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes
666
+
667
+    var cp = getCoords(this, aCPx, aCPy);
668
+    var p = getCoords(this, aX, aY);
669
+
670
+    var cp1 = {
671
+      x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_),
672
+      y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_)
673
+    };
674
+    var cp2 = {
675
+      x: cp1.x + (p.x - this.currentX_) / 3.0,
676
+      y: cp1.y + (p.y - this.currentY_) / 3.0
677
+    };
678
+
679
+    bezierCurveTo(this, cp1, cp2, p);
680
+  };
681
+
682
+  contextPrototype.arc = function(aX, aY, aRadius,
683
+                                  aStartAngle, aEndAngle, aClockwise) {
684
+    aRadius *= Z;
685
+    var arcType = aClockwise ? 'at' : 'wa';
686
+
687
+    var xStart = aX + mc(aStartAngle) * aRadius - Z2;
688
+    var yStart = aY + ms(aStartAngle) * aRadius - Z2;
689
+
690
+    var xEnd = aX + mc(aEndAngle) * aRadius - Z2;
691
+    var yEnd = aY + ms(aEndAngle) * aRadius - Z2;
692
+
693
+    // IE won't render arches drawn counter clockwise if xStart == xEnd.
694
+    if (xStart == xEnd && !aClockwise) {
695
+      xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something
696
+                       // that can be represented in binary
697
+    }
698
+
699
+    var p = getCoords(this, aX, aY);
700
+    var pStart = getCoords(this, xStart, yStart);
701
+    var pEnd = getCoords(this, xEnd, yEnd);
702
+
703
+    this.currentPath_.push({type: arcType,
704
+                           x: p.x,
705
+                           y: p.y,
706
+                           radius: aRadius,
707
+                           xStart: pStart.x,
708
+                           yStart: pStart.y,
709
+                           xEnd: pEnd.x,
710
+                           yEnd: pEnd.y});
711
+
712
+  };
713
+
714
+  contextPrototype.rect = function(aX, aY, aWidth, aHeight) {
715
+    this.moveTo(aX, aY);
716
+    this.lineTo(aX + aWidth, aY);
717
+    this.lineTo(aX + aWidth, aY + aHeight);
718
+    this.lineTo(aX, aY + aHeight);
719
+    this.closePath();
720
+  };
721
+
722
+  contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {
723
+    var oldPath = this.currentPath_;
724
+    this.beginPath();
725
+
726
+    this.moveTo(aX, aY);
727
+    this.lineTo(aX + aWidth, aY);
728
+    this.lineTo(aX + aWidth, aY + aHeight);
729
+    this.lineTo(aX, aY + aHeight);
730
+    this.closePath();
731
+    this.stroke();
732
+
733
+    this.currentPath_ = oldPath;
734
+  };
735
+
736
+  contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {
737
+    var oldPath = this.currentPath_;
738
+    this.beginPath();
739
+
740
+    this.moveTo(aX, aY);
741
+    this.lineTo(aX + aWidth, aY);
742
+    this.lineTo(aX + aWidth, aY + aHeight);
743
+    this.lineTo(aX, aY + aHeight);
744
+    this.closePath();
745
+    this.fill();
746
+
747
+    this.currentPath_ = oldPath;
748
+  };
749
+
750
+  contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {
751
+    var gradient = new CanvasGradient_('gradient');
752
+    gradient.x0_ = aX0;
753
+    gradient.y0_ = aY0;
754
+    gradient.x1_ = aX1;
755
+    gradient.y1_ = aY1;
756
+    return gradient;
757
+  };
758
+
759
+  contextPrototype.createRadialGradient = function(aX0, aY0, aR0,
760
+                                                   aX1, aY1, aR1) {
761
+    var gradient = new CanvasGradient_('gradientradial');
762
+    gradient.x0_ = aX0;
763
+    gradient.y0_ = aY0;
764
+    gradient.r0_ = aR0;
765
+    gradient.x1_ = aX1;
766
+    gradient.y1_ = aY1;
767
+    gradient.r1_ = aR1;
768
+    return gradient;
769
+  };
770
+
771
+  contextPrototype.drawImage = function(image, var_args) {
772
+    var dx, dy, dw, dh, sx, sy, sw, sh;
773
+
774
+    // to find the original width we overide the width and height
775
+    var oldRuntimeWidth = image.runtimeStyle.width;
776
+    var oldRuntimeHeight = image.runtimeStyle.height;
777
+    image.runtimeStyle.width = 'auto';
778
+    image.runtimeStyle.height = 'auto';
779
+
780
+    // get the original size
781
+    var w = image.width;
782
+    var h = image.height;
783
+
784
+    // and remove overides
785
+    image.runtimeStyle.width = oldRuntimeWidth;
786
+    image.runtimeStyle.height = oldRuntimeHeight;
787
+
788
+    if (arguments.length == 3) {
789
+      dx = arguments[1];
790
+      dy = arguments[2];
791
+      sx = sy = 0;
792
+      sw = dw = w;
793
+      sh = dh = h;
794
+    } else if (arguments.length == 5) {
795
+      dx = arguments[1];
796
+      dy = arguments[2];
797
+      dw = arguments[3];
798
+      dh = arguments[4];
799
+      sx = sy = 0;
800
+      sw = w;
801
+      sh = h;
802
+    } else if (arguments.length == 9) {
803
+      sx = arguments[1];
804
+      sy = arguments[2];
805
+      sw = arguments[3];
806
+      sh = arguments[4];
807
+      dx = arguments[5];
808
+      dy = arguments[6];
809
+      dw = arguments[7];
810
+      dh = arguments[8];
811
+    } else {
812
+      throw Error('Invalid number of arguments');
813
+    }
814
+
815
+    var d = getCoords(this, dx, dy);
816
+
817
+    var w2 = sw / 2;
818
+    var h2 = sh / 2;
819
+
820
+    var vmlStr = [];
821
+
822
+    var W = 10;
823
+    var H = 10;
824
+
825
+    // For some reason that I've now forgotten, using divs didn't work
826
+    vmlStr.push(' <g_vml_:group',
827
+                ' coordsize="', Z * W, ',', Z * H, '"',
828
+                ' coordorigin="0,0"' ,
829
+                ' style="width:', W, 'px;height:', H, 'px;position:absolute;');
830
+
831
+    // If filters are necessary (rotation exists), create them
832
+    // filters are bog-slow, so only create them if abbsolutely necessary
833
+    // The following check doesn't account for skews (which don't exist
834
+    // in the canvas spec (yet) anyway.
835
+
836
+    if (this.m_[0][0] != 1 || this.m_[0][1] ||
837
+        this.m_[1][1] != 1 || this.m_[1][0]) {
838
+      var filter = [];
839
+
840
+      // Note the 12/21 reversal
841
+      filter.push('M11=', this.m_[0][0], ',',
842
+                  'M12=', this.m_[1][0], ',',
843
+                  'M21=', this.m_[0][1], ',',
844
+                  'M22=', this.m_[1][1], ',',
845
+                  'Dx=', mr(d.x / Z), ',',
846
+                  'Dy=', mr(d.y / Z), '');
847
+
848
+      // Bounding box calculation (need to minimize displayed area so that
849
+      // filters don't waste time on unused pixels.
850
+      var max = d;
851
+      var c2 = getCoords(this, dx + dw, dy);
852
+      var c3 = getCoords(this, dx, dy + dh);
853
+      var c4 = getCoords(this, dx + dw, dy + dh);
854
+
855
+      max.x = m.max(max.x, c2.x, c3.x, c4.x);
856
+      max.y = m.max(max.y, c2.y, c3.y, c4.y);
857
+
858
+      vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z),
859
+                  'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(',
860
+                  filter.join(''), ", sizingmethod='clip');");
861
+
862
+    } else {
863
+      vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;');
864
+    }
865
+
866
+    vmlStr.push(' ">' ,
867
+                '<g_vml_:image src="', image.src, '"',
868
+                ' style="width:', Z * dw, 'px;',
869
+                ' height:', Z * dh, 'px"',
870
+                ' cropleft="', sx / w, '"',
871
+                ' croptop="', sy / h, '"',
872
+                ' cropright="', (w - sx - sw) / w, '"',
873
+                ' cropbottom="', (h - sy - sh) / h, '"',
874
+                ' />',
875
+                '</g_vml_:group>');
876
+
877
+    this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join(''));
878
+  };
879
+
880
+  contextPrototype.stroke = function(aFill) {
881
+    var W = 10;
882
+    var H = 10;
883
+    // Divide the shape into chunks if it's too long because IE has a limit
884
+    // somewhere for how long a VML shape can be. This simple division does
885
+    // not work with fills, only strokes, unfortunately.
886
+    var chunkSize = 5000;
887
+
888
+    var min = {x: null, y: null};
889
+    var max = {x: null, y: null};
890
+
891
+    for (var j = 0; j < this.currentPath_.length; j += chunkSize) {
892
+      var lineStr = [];
893
+      var lineOpen = false;
894
+
895
+      lineStr.push('<g_vml_:shape',
896
+                   ' filled="', !!aFill, '"',
897
+                   ' style="position:absolute;width:', W, 'px;height:', H, 'px;"',
898
+                   ' coordorigin="0,0"',
899
+                   ' coordsize="', Z * W, ',', Z * H, '"',
900
+                   ' stroked="', !aFill, '"',
901
+                   ' path="');
902
+
903
+      var newSeq = false;
904
+
905
+      for (var i = j; i < Math.min(j + chunkSize, this.currentPath_.length); i++) {
906
+        if (i % chunkSize == 0 && i > 0) { // move into position for next chunk
907
+          lineStr.push(' m ', mr(this.currentPath_[i-1].x), ',', mr(this.currentPath_[i-1].y));
908
+        }
909
+
910
+        var p = this.currentPath_[i];
911
+        var c;
912
+
913
+        switch (p.type) {
914
+          case 'moveTo':
915
+            c = p;
916
+            lineStr.push(' m ', mr(p.x), ',', mr(p.y));
917
+            break;
918
+          case 'lineTo':
919
+            lineStr.push(' l ', mr(p.x), ',', mr(p.y));
920
+            break;
921
+          case 'close':
922
+            lineStr.push(' x ');
923
+            p = null;
924
+            break;
925
+          case 'bezierCurveTo':
926
+            lineStr.push(' c ',
927
+                         mr(p.cp1x), ',', mr(p.cp1y), ',',
928
+                         mr(p.cp2x), ',', mr(p.cp2y), ',',
929
+                         mr(p.x), ',', mr(p.y));
930
+            break;
931
+          case 'at':
932
+          case 'wa':
933
+            lineStr.push(' ', p.type, ' ',
934
+                         mr(p.x - this.arcScaleX_ * p.radius), ',',
935
+                         mr(p.y - this.arcScaleY_ * p.radius), ' ',
936
+                         mr(p.x + this.arcScaleX_ * p.radius), ',',
937
+                         mr(p.y + this.arcScaleY_ * p.radius), ' ',
938
+                         mr(p.xStart), ',', mr(p.yStart), ' ',
939
+                         mr(p.xEnd), ',', mr(p.yEnd));
940
+            break;
941
+        }
942
+  
943
+  
944
+        // TODO: Following is broken for curves due to
945
+        //       move to proper paths.
946
+  
947
+        // Figure out dimensions so we can do gradient fills
948
+        // properly
949
+        if (p) {
950
+          if (min.x == null || p.x < min.x) {
951
+            min.x = p.x;
952
+          }
953
+          if (max.x == null || p.x > max.x) {
954
+            max.x = p.x;
955
+          }
956
+          if (min.y == null || p.y < min.y) {
957
+            min.y = p.y;
958
+          }
959
+          if (max.y == null || p.y > max.y) {
960
+            max.y = p.y;
961
+          }
962
+        }
963
+      }
964
+      lineStr.push(' ">');
965
+  
966
+      if (!aFill) {
967
+        appendStroke(this, lineStr);
968
+      } else {
969
+        appendFill(this, lineStr, min, max);
970
+      }
971
+  
972
+      lineStr.push('</g_vml_:shape>');
973
+  
974
+      this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));
975
+    }
976
+  };
977
+
978
+  function appendStroke(ctx, lineStr) {
979
+    var a = processStyle(ctx.strokeStyle);
980
+    var color = a.color;
981
+    var opacity = a.alpha * ctx.globalAlpha;
982
+    var lineWidth = ctx.lineScale_ * ctx.lineWidth;
983
+
984
+    // VML cannot correctly render a line if the width is less than 1px.
985
+    // In that case, we dilute the color to make the line look thinner.
986
+    if (lineWidth < 1) {
987
+      opacity *= lineWidth;
988
+    }
989
+
990
+    lineStr.push(
991
+      '<g_vml_:stroke',
992
+      ' opacity="', opacity, '"',
993
+      ' joinstyle="', ctx.lineJoin, '"',
994
+      ' miterlimit="', ctx.miterLimit, '"',
995
+      ' endcap="', processLineCap(ctx.lineCap), '"',
996
+      ' weight="', lineWidth, 'px"',
997
+      ' color="', color, '" />'
998
+    );
999
+  }
1000
+
1001
+  function appendFill(ctx, lineStr, min, max) {
1002
+    var fillStyle = ctx.fillStyle;
1003
+    var arcScaleX = ctx.arcScaleX_;
1004
+    var arcScaleY = ctx.arcScaleY_;
1005
+    var width = max.x - min.x;
1006
+    var height = max.y - min.y;
1007
+    if (fillStyle instanceof CanvasGradient_) {
1008
+      // TODO: Gradients transformed with the transformation matrix.
1009
+      var angle = 0;
1010
+      var focus = {x: 0, y: 0};
1011
+
1012
+      // additional offset
1013
+      var shift = 0;
1014
+      // scale factor for offset
1015
+      var expansion = 1;
1016
+
1017
+      if (fillStyle.type_ == 'gradient') {
1018
+        var x0 = fillStyle.x0_ / arcScaleX;
1019
+        var y0 = fillStyle.y0_ / arcScaleY;
1020
+        var x1 = fillStyle.x1_ / arcScaleX;
1021
+        var y1 = fillStyle.y1_ / arcScaleY;
1022
+        var p0 = getCoords(ctx, x0, y0);
1023
+        var p1 = getCoords(ctx, x1, y1);
1024
+        var dx = p1.x - p0.x;
1025
+        var dy = p1.y - p0.y;
1026
+        angle = Math.atan2(dx, dy) * 180 / Math.PI;
1027
+
1028
+        // The angle should be a non-negative number.
1029
+        if (angle < 0) {
1030
+          angle += 360;
1031
+        }
1032
+
1033
+        // Very small angles produce an unexpected result because they are
1034
+        // converted to a scientific notation string.
1035
+        if (angle < 1e-6) {
1036
+          angle = 0;
1037
+        }
1038
+      } else {
1039
+        var p0 = getCoords(ctx, fillStyle.x0_, fillStyle.y0_);
1040
+        focus = {
1041
+          x: (p0.x - min.x) / width,
1042
+          y: (p0.y - min.y) / height
1043
+        };
1044
+
1045
+        width  /= arcScaleX * Z;
1046
+        height /= arcScaleY * Z;
1047
+        var dimension = m.max(width, height);
1048
+        shift = 2 * fillStyle.r0_ / dimension;
1049
+        expansion = 2 * fillStyle.r1_ / dimension - shift;
1050
+      }
1051
+
1052
+      // We need to sort the color stops in ascending order by offset,
1053
+      // otherwise IE won't interpret it correctly.
1054
+      var stops = fillStyle.colors_;
1055
+      stops.sort(function(cs1, cs2) {
1056
+        return cs1.offset - cs2.offset;
1057
+      });
1058
+
1059
+      var length = stops.length;
1060
+      var color1 = stops[0].color;
1061
+      var color2 = stops[length - 1].color;
1062
+      var opacity1 = stops[0].alpha * ctx.globalAlpha;
1063
+      var opacity2 = stops[length - 1].alpha * ctx.globalAlpha;
1064
+
1065
+      var colors = [];
1066
+      for (var i = 0; i < length; i++) {
1067
+        var stop = stops[i];
1068
+        colors.push(stop.offset * expansion + shift + ' ' + stop.color);
1069
+      }
1070
+
1071
+      // When colors attribute is used, the meanings of opacity and o:opacity2
1072
+      // are reversed.
1073
+      lineStr.push('<g_vml_:fill type="', fillStyle.type_, '"',
1074
+                   ' method="none" focus="100%"',
1075
+                   ' color="', color1, '"',
1076
+                   ' color2="', color2, '"',
1077
+                   ' colors="', colors.join(','), '"',
1078
+                   ' opacity="', opacity2, '"',
1079
+                   ' g_o_:opacity2="', opacity1, '"',
1080
+                   ' angle="', angle, '"',
1081
+                   ' focusposition="', focus.x, ',', focus.y, '" />');
1082
+    } else if (fillStyle instanceof CanvasPattern_) {
1083
+      if (width && height) {
1084
+        var deltaLeft = -min.x;
1085
+        var deltaTop = -min.y;
1086
+        lineStr.push('<g_vml_:fill',
1087
+                     ' position="',
1088
+                     deltaLeft / width * arcScaleX * arcScaleX, ',',
1089
+                     deltaTop / height * arcScaleY * arcScaleY, '"',
1090
+                     ' type="tile"',
1091
+                     // TODO: Figure out the correct size to fit the scale.
1092
+                     //' size="', w, 'px ', h, 'px"',
1093
+                     ' src="', fillStyle.src_, '" />');
1094
+       }
1095
+    } else {
1096
+      var a = processStyle(ctx.fillStyle);
1097
+      var color = a.color;
1098
+      var opacity = a.alpha * ctx.globalAlpha;
1099
+      lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity,
1100
+                   '" />');
1101
+    }
1102
+  }
1103
+
1104
+  contextPrototype.fill = function() {
1105
+    this.stroke(true);
1106
+  };
1107
+
1108
+  contextPrototype.closePath = function() {
1109
+    this.currentPath_.push({type: 'close'});
1110
+  };
1111
+
1112
+  function getCoords(ctx, aX, aY) {
1113
+    var m = ctx.m_;
1114
+    return {
1115
+      x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2,
1116
+      y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2
1117
+    };
1118
+  };
1119
+
1120
+  contextPrototype.save = function() {
1121
+    var o = {};
1122
+    copyState(this, o);
1123
+    this.aStack_.push(o);
1124
+    this.mStack_.push(this.m_);
1125
+    this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);
1126
+  };
1127
+
1128
+  contextPrototype.restore = function() {
1129
+    if (this.aStack_.length) {
1130
+      copyState(this.aStack_.pop(), this);
1131
+      this.m_ = this.mStack_.pop();
1132
+    }
1133
+  };
1134
+
1135
+  function matrixIsFinite(m) {
1136
+    return isFinite(m[0][0]) && isFinite(m[0][1]) &&
1137
+        isFinite(m[1][0]) && isFinite(m[1][1]) &&
1138
+        isFinite(m[2][0]) && isFinite(m[2][1]);
1139
+  }
1140
+
1141
+  function setM(ctx, m, updateLineScale) {
1142
+    if (!matrixIsFinite(m)) {
1143
+      return;
1144
+    }
1145
+    ctx.m_ = m;
1146
+
1147
+    if (updateLineScale) {
1148
+      // Get the line scale.
1149
+      // Determinant of this.m_ means how much the area is enlarged by the
1150
+      // transformation. So its square root can be used as a scale factor
1151
+      // for width.
1152
+      var det = m[0][0] * m[1][1] - m[0][1] * m[1][0];
1153
+      ctx.lineScale_ = sqrt(abs(det));
1154
+    }
1155
+  }
1156
+
1157
+  contextPrototype.translate = function(aX, aY) {
1158
+    var m1 = [
1159
+      [1,  0,  0],
1160
+      [0,  1,  0],
1161
+      [aX, aY, 1]
1162
+    ];
1163
+
1164
+    setM(this, matrixMultiply(m1, this.m_), false);
1165
+  };
1166
+
1167
+  contextPrototype.rotate = function(aRot) {
1168
+    var c = mc(aRot);
1169
+    var s = ms(aRot);
1170
+
1171
+    var m1 = [
1172
+      [c,  s, 0],
1173
+      [-s, c, 0],
1174
+      [0,  0, 1]
1175
+    ];
1176
+
1177
+    setM(this, matrixMultiply(m1, this.m_), false);
1178
+  };
1179
+
1180
+  contextPrototype.scale = function(aX, aY) {
1181
+    this.arcScaleX_ *= aX;
1182
+    this.arcScaleY_ *= aY;
1183
+    var m1 = [
1184
+      [aX, 0,  0],
1185
+      [0,  aY, 0],
1186
+      [0,  0,  1]
1187
+    ];
1188
+
1189
+    setM(this, matrixMultiply(m1, this.m_), true);
1190
+  };
1191
+
1192
+  contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) {
1193
+    var m1 = [
1194
+      [m11, m12, 0],
1195
+      [m21, m22, 0],
1196
+      [dx,  dy,  1]
1197
+    ];
1198
+
1199
+    setM(this, matrixMultiply(m1, this.m_), true);
1200
+  };
1201
+
1202
+  contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) {
1203
+    var m = [
1204
+      [m11, m12, 0],
1205
+      [m21, m22, 0],
1206
+      [dx,  dy,  1]
1207
+    ];
1208
+
1209
+    setM(this, m, true);
1210
+  };
1211
+
1212
+  /**
1213
+   * The text drawing function.
1214
+   * The maxWidth argument isn't taken in account, since no browser supports
1215
+   * it yet.
1216
+   */
1217
+  contextPrototype.drawText_ = function(text, x, y, maxWidth, stroke) {
1218
+    var m = this.m_,
1219
+        delta = 1000,
1220
+        left = 0,
1221
+        right = delta,
1222
+        offset = {x: 0, y: 0},
1223
+        lineStr = [];
1224
+
1225
+    var fontStyle = getComputedStyle(processFontStyle(this.font),
1226
+                                     this.element_);
1227
+
1228
+    var fontStyleString = buildStyle(fontStyle);
1229
+
1230
+    var elementStyle = this.element_.currentStyle;
1231
+    var textAlign = this.textAlign.toLowerCase();
1232
+    switch (textAlign) {
1233
+      case 'left':
1234
+      case 'center':
1235
+      case 'right':
1236
+        break;
1237
+      case 'end':
1238
+        textAlign = elementStyle.direction == 'ltr' ? 'right' : 'left';
1239
+        break;
1240
+      case 'start':
1241
+        textAlign = elementStyle.direction == 'rtl' ? 'right' : 'left';
1242
+        break;
1243
+      default:
1244
+        textAlign = 'left';
1245
+    }
1246
+
1247
+    // 1.75 is an arbitrary number, as there is no info about the text baseline
1248
+    switch (this.textBaseline) {
1249
+      case 'hanging':
1250
+      case 'top':
1251
+        offset.y = fontStyle.size / 1.75;
1252
+        break;
1253
+      case 'middle':
1254
+        break;
1255
+      default:
1256
+      case null:
1257
+      case 'alphabetic':
1258
+      case 'ideographic':
1259
+      case 'bottom':
1260
+        offset.y = -fontStyle.size / 2.25;
1261
+        break;
1262
+    }
1263
+
1264
+    switch(textAlign) {
1265
+      case 'right':
1266
+        left = delta;
1267
+        right = 0.05;
1268
+        break;
1269
+      case 'center':
1270
+        left = right = delta / 2;
1271
+        break;
1272
+    }
1273
+
1274
+    var d = getCoords(this, x + offset.x, y + offset.y);
1275
+
1276
+    lineStr.push('<g_vml_:line from="', -left ,' 0" to="', right ,' 0.05" ',
1277
+                 ' coordsize="100 100" coordorigin="0 0"',
1278
+                 ' filled="', !stroke, '" stroked="', !!stroke,
1279
+                 '" style="position:absolute;width:1px;height:1px;">');
1280
+
1281
+    if (stroke) {
1282
+      appendStroke(this, lineStr);
1283
+    } else {
1284
+      // TODO: Fix the min and max params.
1285
+      appendFill(this, lineStr, {x: -left, y: 0},
1286
+                 {x: right, y: fontStyle.size});
1287
+    }
1288
+
1289
+    var skewM = m[0][0].toFixed(3) + ',' + m[1][0].toFixed(3) + ',' +
1290
+                m[0][1].toFixed(3) + ',' + m[1][1].toFixed(3) + ',0,0';
1291
+
1292
+    var skewOffset = mr(d.x / Z) + ',' + mr(d.y / Z);
1293
+
1294
+    lineStr.push('<g_vml_:skew on="t" matrix="', skewM ,'" ',
1295
+                 ' offset="', skewOffset, '" origin="', left ,' 0" />',
1296
+                 '<g_vml_:path textpathok="true" />',
1297
+                 '<g_vml_:textpath on="true" string="',
1298
+                 encodeHtmlAttribute(text),
1299
+                 '" style="v-text-align:', textAlign,
1300
+                 ';font:', encodeHtmlAttribute(fontStyleString),
1301
+                 '" /></g_vml_:line>');
1302
+
1303
+    this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));
1304
+  };
1305
+
1306
+  contextPrototype.fillText = function(text, x, y, maxWidth) {
1307
+    this.drawText_(text, x, y, maxWidth, false);
1308
+  };
1309
+
1310
+  contextPrototype.strokeText = function(text, x, y, maxWidth) {
1311
+    this.drawText_(text, x, y, maxWidth, true);
1312
+  };
1313
+
1314
+  contextPrototype.measureText = function(text) {
1315
+    if (!this.textMeasureEl_) {
1316
+      var s = '<span style="position:absolute;' +
1317
+          'top:-20000px;left:0;padding:0;margin:0;border:none;' +
1318
+          'white-space:pre;"></span>';
1319
+      this.element_.insertAdjacentHTML('beforeEnd', s);
1320
+      this.textMeasureEl_ = this.element_.lastChild;
1321
+    }
1322
+    var doc = this.element_.ownerDocument;
1323
+    this.textMeasureEl_.innerHTML = '';
1324
+    this.textMeasureEl_.style.font = this.font;
1325
+    // Don't use innerHTML or innerText because they allow markup/whitespace.
1326
+    this.textMeasureEl_.appendChild(doc.createTextNode(text));
1327
+    return {width: this.textMeasureEl_.offsetWidth};
1328
+  };
1329
+
1330
+  /******** STUBS ********/
1331
+  contextPrototype.clip = function() {
1332
+    // TODO: Implement
1333
+  };
1334
+
1335
+  contextPrototype.arcTo = function() {
1336
+    // TODO: Implement
1337
+  };
1338
+
1339
+  contextPrototype.createPattern = function(image, repetition) {
1340
+    return new CanvasPattern_(image, repetition);
1341
+  };
1342
+
1343
+  // Gradient / Pattern Stubs
1344
+  function CanvasGradient_(aType) {
1345
+    this.type_ = aType;
1346
+    this.x0_ = 0;
1347
+    this.y0_ = 0;
1348
+    this.r0_ = 0;
1349
+    this.x1_ = 0;
1350
+    this.y1_ = 0;
1351
+    this.r1_ = 0;
1352
+    this.colors_ = [];
1353
+  }
1354
+
1355
+  CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {
1356
+    aColor = processStyle(aColor);
1357
+    this.colors_.push({offset: aOffset,
1358
+                       color: aColor.color,
1359
+                       alpha: aColor.alpha});
1360
+  };
1361
+
1362
+  function CanvasPattern_(image, repetition) {
1363
+    assertImageIsValid(image);
1364
+    switch (repetition) {
1365
+      case 'repeat':
1366
+      case null:
1367
+      case '':
1368
+        this.repetition_ = 'repeat';
1369
+        break
1370
+      case 'repeat-x':
1371
+      case 'repeat-y':
1372
+      case 'no-repeat':
1373
+        this.repetition_ = repetition;
1374
+        break;
1375
+      default:
1376
+        throwException('SYNTAX_ERR');
1377
+    }
1378
+
1379
+    this.src_ = image.src;
1380
+    this.width_ = image.width;
1381
+    this.height_ = image.height;
1382
+  }
1383
+
1384
+  function throwException(s) {
1385
+    throw new DOMException_(s);
1386
+  }
1387
+
1388
+  function assertImageIsValid(img) {
1389
+    if (!img || img.nodeType != 1 || img.tagName != 'IMG') {
1390
+      throwException('TYPE_MISMATCH_ERR');
1391
+    }
1392
+    if (img.readyState != 'complete') {
1393
+      throwException('INVALID_STATE_ERR');
1394
+    }
1395
+  }
1396
+
1397
+  function DOMException_(s) {
1398
+    this.code = this[s];
1399
+    this.message = s +': DOM Exception ' + this.code;
1400
+  }
1401
+  var p = DOMException_.prototype = new Error;
1402
+  p.INDEX_SIZE_ERR = 1;
1403
+  p.DOMSTRING_SIZE_ERR = 2;
1404
+  p.HIERARCHY_REQUEST_ERR = 3;
1405
+  p.WRONG_DOCUMENT_ERR = 4;
1406
+  p.INVALID_CHARACTER_ERR = 5;
1407
+  p.NO_DATA_ALLOWED_ERR = 6;
1408
+  p.NO_MODIFICATION_ALLOWED_ERR = 7;
1409
+  p.NOT_FOUND_ERR = 8;
1410
+  p.NOT_SUPPORTED_ERR = 9;
1411
+  p.INUSE_ATTRIBUTE_ERR = 10;
1412
+  p.INVALID_STATE_ERR = 11;
1413
+  p.SYNTAX_ERR = 12;
1414
+  p.INVALID_MODIFICATION_ERR = 13;
1415
+  p.NAMESPACE_ERR = 14;
1416
+  p.INVALID_ACCESS_ERR = 15;
1417
+  p.VALIDATION_ERR = 16;
1418
+  p.TYPE_MISMATCH_ERR = 17;
1419
+
1420
+  // set up externs
1421
+  G_vmlCanvasManager = G_vmlCanvasManager_;
1422
+  CanvasRenderingContext2D = CanvasRenderingContext2D_;
1423
+  CanvasGradient = CanvasGradient_;
1424
+  CanvasPattern = CanvasPattern_;
1425
+  DOMException = DOMException_;
1426
+})();
1427
+
1428
+} // if
... ...
@@ -0,0 +1 @@
1
+if(!document.createElement("canvas").getContext){(function(){var ab=Math;var n=ab.round;var l=ab.sin;var A=ab.cos;var H=ab.abs;var N=ab.sqrt;var d=10;var f=d/2;var z=+navigator.userAgent.match(/MSIE ([\d.]+)?/)[1];function y(){return this.context_||(this.context_=new D(this))}var t=Array.prototype.slice;function g(j,m,p){var i=t.call(arguments,2);return function(){return j.apply(m,i.concat(t.call(arguments)))}}function af(i){return String(i).replace(/&/g,"&amp;").replace(/"/g,"&quot;")}function Y(m,j,i){if(!m.namespaces[j]){m.namespaces.add(j,i,"#default#VML")}}function R(j){Y(j,"g_vml_","urn:schemas-microsoft-com:vml");Y(j,"g_o_","urn:schemas-microsoft-com:office:office");if(!j.styleSheets.ex_canvas_){var i=j.createStyleSheet();i.owningElement.id="ex_canvas_";i.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}"}}R(document);var e={init:function(i){var j=i||document;j.createElement("canvas");j.attachEvent("onreadystatechange",g(this.init_,this,j))},init_:function(p){var m=p.getElementsByTagName("canvas");for(var j=0;j<m.length;j++){this.initElement(m[j])}},initElement:function(j){if(!j.getContext){j.getContext=y;R(j.ownerDocument);j.innerHTML="";j.attachEvent("onpropertychange",x);j.attachEvent("onresize",W);var i=j.attributes;if(i.width&&i.width.specified){j.style.width=i.width.nodeValue+"px"}else{j.width=j.clientWidth}if(i.height&&i.height.specified){j.style.height=i.height.nodeValue+"px"}else{j.height=j.clientHeight}}return j}};function x(j){var i=j.srcElement;switch(j.propertyName){case"width":i.getContext().clearRect();i.style.width=i.attributes.width.nodeValue+"px";i.firstChild.style.width=i.clientWidth+"px";break;case"height":i.getContext().clearRect();i.style.height=i.attributes.height.nodeValue+"px";i.firstChild.style.height=i.clientHeight+"px";break}}function W(j){var i=j.srcElement;if(i.firstChild){i.firstChild.style.width=i.clientWidth+"px";i.firstChild.style.height=i.clientHeight+"px"}}e.init();var k=[];for(var ae=0;ae<16;ae++){for(var ad=0;ad<16;ad++){k[ae*16+ad]=ae.toString(16)+ad.toString(16)}}function B(){return[[1,0,0],[0,1,0],[0,0,1]]}function J(p,m){var j=B();for(var i=0;i<3;i++){for(var ah=0;ah<3;ah++){var Z=0;for(var ag=0;ag<3;ag++){Z+=p[i][ag]*m[ag][ah]}j[i][ah]=Z}}return j}function v(j,i){i.fillStyle=j.fillStyle;i.lineCap=j.lineCap;i.lineJoin=j.lineJoin;i.lineWidth=j.lineWidth;i.miterLimit=j.miterLimit;i.shadowBlur=j.shadowBlur;i.shadowColor=j.shadowColor;i.shadowOffsetX=j.shadowOffsetX;i.shadowOffsetY=j.shadowOffsetY;i.strokeStyle=j.strokeStyle;i.globalAlpha=j.globalAlpha;i.font=j.font;i.textAlign=j.textAlign;i.textBaseline=j.textBaseline;i.arcScaleX_=j.arcScaleX_;i.arcScaleY_=j.arcScaleY_;i.lineScale_=j.lineScale_}var b={aliceblue:"#F0F8FF",antiquewhite:"#FAEBD7",aquamarine:"#7FFFD4",azure:"#F0FFFF",beige:"#F5F5DC",bisque:"#FFE4C4",black:"#000000",blanchedalmond:"#FFEBCD",blueviolet:"#8A2BE2",brown:"#A52A2A",burlywood:"#DEB887",cadetblue:"#5F9EA0",chartreuse:"#7FFF00",chocolate:"#D2691E",coral:"#FF7F50",cornflowerblue:"#6495ED",cornsilk:"#FFF8DC",crimson:"#DC143C",cyan:"#00FFFF",darkblue:"#00008B",darkcyan:"#008B8B",darkgoldenrod:"#B8860B",darkgray:"#A9A9A9",darkgreen:"#006400",darkgrey:"#A9A9A9",darkkhaki:"#BDB76B",darkmagenta:"#8B008B",darkolivegreen:"#556B2F",darkorange:"#FF8C00",darkorchid:"#9932CC",darkred:"#8B0000",darksalmon:"#E9967A",darkseagreen:"#8FBC8F",darkslateblue:"#483D8B",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",darkturquoise:"#00CED1",darkviolet:"#9400D3",deeppink:"#FF1493",deepskyblue:"#00BFFF",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1E90FF",firebrick:"#B22222",floralwhite:"#FFFAF0",forestgreen:"#228B22",gainsboro:"#DCDCDC",ghostwhite:"#F8F8FF",gold:"#FFD700",goldenrod:"#DAA520",grey:"#808080",greenyellow:"#ADFF2F",honeydew:"#F0FFF0",hotpink:"#FF69B4",indianred:"#CD5C5C",indigo:"#4B0082",ivory:"#FFFFF0",khaki:"#F0E68C",lavender:"#E6E6FA",lavenderblush:"#FFF0F5",lawngreen:"#7CFC00",lemonchiffon:"#FFFACD",lightblue:"#ADD8E6",lightcoral:"#F08080",lightcyan:"#E0FFFF",lightgoldenrodyellow:"#FAFAD2",lightgreen:"#90EE90",lightgrey:"#D3D3D3",lightpink:"#FFB6C1",lightsalmon:"#FFA07A",lightseagreen:"#20B2AA",lightskyblue:"#87CEFA",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#B0C4DE",lightyellow:"#FFFFE0",limegreen:"#32CD32",linen:"#FAF0E6",magenta:"#FF00FF",mediumaquamarine:"#66CDAA",mediumblue:"#0000CD",mediumorchid:"#BA55D3",mediumpurple:"#9370DB",mediumseagreen:"#3CB371",mediumslateblue:"#7B68EE",mediumspringgreen:"#00FA9A",mediumturquoise:"#48D1CC",mediumvioletred:"#C71585",midnightblue:"#191970",mintcream:"#F5FFFA",mistyrose:"#FFE4E1",moccasin:"#FFE4B5",navajowhite:"#FFDEAD",oldlace:"#FDF5E6",olivedrab:"#6B8E23",orange:"#FFA500",orangered:"#FF4500",orchid:"#DA70D6",palegoldenrod:"#EEE8AA",palegreen:"#98FB98",paleturquoise:"#AFEEEE",palevioletred:"#DB7093",papayawhip:"#FFEFD5",peachpuff:"#FFDAB9",peru:"#CD853F",pink:"#FFC0CB",plum:"#DDA0DD",powderblue:"#B0E0E6",rosybrown:"#BC8F8F",royalblue:"#4169E1",saddlebrown:"#8B4513",salmon:"#FA8072",sandybrown:"#F4A460",seagreen:"#2E8B57",seashell:"#FFF5EE",sienna:"#A0522D",skyblue:"#87CEEB",slateblue:"#6A5ACD",slategray:"#708090",slategrey:"#708090",snow:"#FFFAFA",springgreen:"#00FF7F",steelblue:"#4682B4",tan:"#D2B48C",thistle:"#D8BFD8",tomato:"#FF6347",turquoise:"#40E0D0",violet:"#EE82EE",wheat:"#F5DEB3",whitesmoke:"#F5F5F5",yellowgreen:"#9ACD32"};function M(j){var p=j.indexOf("(",3);var i=j.indexOf(")",p+1);var m=j.substring(p+1,i).split(",");if(m.length!=4||j.charAt(3)!="a"){m[3]=1}return m}function c(i){return parseFloat(i)/100}function r(j,m,i){return Math.min(i,Math.max(m,j))}function I(ag){var i,ai,aj,ah,ak,Z;ah=parseFloat(ag[0])/360%360;if(ah<0){ah++}ak=r(c(ag[1]),0,1);Z=r(c(ag[2]),0,1);if(ak==0){i=ai=aj=Z}else{var j=Z<0.5?Z*(1+ak):Z+ak-Z*ak;var m=2*Z-j;i=a(m,j,ah+1/3);ai=a(m,j,ah);aj=a(m,j,ah-1/3)}return"#"+k[Math.floor(i*255)]+k[Math.floor(ai*255)]+k[Math.floor(aj*255)]}function a(j,i,m){if(m<0){m++}if(m>1){m--}if(6*m<1){return j+(i-j)*6*m}else{if(2*m<1){return i}else{if(3*m<2){return j+(i-j)*(2/3-m)*6}else{return j}}}}var C={};function F(j){if(j in C){return C[j]}var ag,Z=1;j=String(j);if(j.charAt(0)=="#"){ag=j}else{if(/^rgb/.test(j)){var p=M(j);var ag="#",ah;for(var m=0;m<3;m++){if(p[m].indexOf("%")!=-1){ah=Math.floor(c(p[m])*255)}else{ah=+p[m]}ag+=k[r(ah,0,255)]}Z=+p[3]}else{if(/^hsl/.test(j)){var p=M(j);ag=I(p);Z=p[3]}else{ag=b[j]||j}}}return C[j]={color:ag,alpha:Z}}var o={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"};var L={};function E(i){if(L[i]){return L[i]}var p=document.createElement("div");var m=p.style;try{m.font=i}catch(j){}return L[i]={style:m.fontStyle||o.style,variant:m.fontVariant||o.variant,weight:m.fontWeight||o.weight,size:m.fontSize||o.size,family:m.fontFamily||o.family}}function u(m,j){var i={};for(var ah in m){i[ah]=m[ah]}var ag=parseFloat(j.currentStyle.fontSize),Z=parseFloat(m.size);if(typeof m.size=="number"){i.size=m.size}else{if(m.size.indexOf("px")!=-1){i.size=Z}else{if(m.size.indexOf("em")!=-1){i.size=ag*Z}else{if(m.size.indexOf("%")!=-1){i.size=(ag/100)*Z}else{if(m.size.indexOf("pt")!=-1){i.size=Z/0.75}else{i.size=ag}}}}}i.size*=0.981;return i}function ac(i){return i.style+" "+i.variant+" "+i.weight+" "+i.size+"px "+i.family}var s={butt:"flat",round:"round"};function S(i){return s[i]||"square"}function D(i){this.m_=B();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=d*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=i;var m="width:"+i.clientWidth+"px;height:"+i.clientHeight+"px;overflow:hidden;position:absolute";var j=i.ownerDocument.createElement("div");j.style.cssText=m;i.appendChild(j);var p=j.cloneNode(false);p.style.backgroundColor="red";p.style.filter="alpha(opacity=0)";i.appendChild(p);this.element_=j;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var q=D.prototype;q.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};q.beginPath=function(){this.currentPath_=[]};q.moveTo=function(j,i){var m=V(this,j,i);this.currentPath_.push({type:"moveTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};q.lineTo=function(j,i){var m=V(this,j,i);this.currentPath_.push({type:"lineTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};q.bezierCurveTo=function(m,j,ak,aj,ai,ag){var i=V(this,ai,ag);var ah=V(this,m,j);var Z=V(this,ak,aj);K(this,ah,Z,i)};function K(i,Z,m,j){i.currentPath_.push({type:"bezierCurveTo",cp1x:Z.x,cp1y:Z.y,cp2x:m.x,cp2y:m.y,x:j.x,y:j.y});i.currentX_=j.x;i.currentY_=j.y}q.quadraticCurveTo=function(ai,m,j,i){var ah=V(this,ai,m);var ag=V(this,j,i);var aj={x:this.currentX_+2/3*(ah.x-this.currentX_),y:this.currentY_+2/3*(ah.y-this.currentY_)};var Z={x:aj.x+(ag.x-this.currentX_)/3,y:aj.y+(ag.y-this.currentY_)/3};K(this,aj,Z,ag)};q.arc=function(al,aj,ak,ag,j,m){ak*=d;var ap=m?"at":"wa";var am=al+A(ag)*ak-f;var ao=aj+l(ag)*ak-f;var i=al+A(j)*ak-f;var an=aj+l(j)*ak-f;if(am==i&&!m){am+=0.125}var Z=V(this,al,aj);var ai=V(this,am,ao);var ah=V(this,i,an);this.currentPath_.push({type:ap,x:Z.x,y:Z.y,radius:ak,xStart:ai.x,yStart:ai.y,xEnd:ah.x,yEnd:ah.y})};q.rect=function(m,j,i,p){this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath()};q.strokeRect=function(m,j,i,p){var Z=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath();this.stroke();this.currentPath_=Z};q.fillRect=function(m,j,i,p){var Z=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath();this.fill();this.currentPath_=Z};q.createLinearGradient=function(j,p,i,m){var Z=new U("gradient");Z.x0_=j;Z.y0_=p;Z.x1_=i;Z.y1_=m;return Z};q.createRadialGradient=function(p,ag,m,j,Z,i){var ah=new U("gradientradial");ah.x0_=p;ah.y0_=ag;ah.r0_=m;ah.x1_=j;ah.y1_=Z;ah.r1_=i;return ah};q.drawImage=function(aq,m){var aj,ah,al,ay,ao,am,at,aA;var ak=aq.runtimeStyle.width;var ap=aq.runtimeStyle.height;aq.runtimeStyle.width="auto";aq.runtimeStyle.height="auto";var ai=aq.width;var aw=aq.height;aq.runtimeStyle.width=ak;aq.runtimeStyle.height=ap;if(arguments.length==3){aj=arguments[1];ah=arguments[2];ao=am=0;at=al=ai;aA=ay=aw}else{if(arguments.length==5){aj=arguments[1];ah=arguments[2];al=arguments[3];ay=arguments[4];ao=am=0;at=ai;aA=aw}else{if(arguments.length==9){ao=arguments[1];am=arguments[2];at=arguments[3];aA=arguments[4];aj=arguments[5];ah=arguments[6];al=arguments[7];ay=arguments[8]}else{throw Error("Invalid number of arguments")}}}var az=V(this,aj,ah);var p=at/2;var j=aA/2;var ax=[];var i=10;var ag=10;ax.push(" <g_vml_:group",' coordsize="',d*i,",",d*ag,'"',' coordorigin="0,0"',' style="width:',i,"px;height:",ag,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]||this.m_[1][1]!=1||this.m_[1][0]){var Z=[];Z.push("M11=",this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",n(az.x/d),",","Dy=",n(az.y/d),"");var av=az;var au=V(this,aj+al,ah);var ar=V(this,aj,ah+ay);var an=V(this,aj+al,ah+ay);av.x=ab.max(av.x,au.x,ar.x,an.x);av.y=ab.max(av.y,au.y,ar.y,an.y);ax.push("padding:0 ",n(av.x/d),"px ",n(av.y/d),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",Z.join(""),", sizingmethod='clip');")}else{ax.push("top:",n(az.y/d),"px;left:",n(az.x/d),"px;")}ax.push(' ">','<g_vml_:image src="',aq.src,'"',' style="width:',d*al,"px;"," height:",d*ay,'px"',' cropleft="',ao/ai,'"',' croptop="',am/aw,'"',' cropright="',(ai-ao-at)/ai,'"',' cropbottom="',(aw-am-aA)/aw,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",ax.join(""))};q.stroke=function(ao){var Z=10;var ap=10;var ag=5000;var ai={x:null,y:null};var an={x:null,y:null};for(var aj=0;aj<this.currentPath_.length;aj+=ag){var am=[];var ah=false;am.push("<g_vml_:shape",' filled="',!!ao,'"',' style="position:absolute;width:',Z,"px;height:",ap,'px;"',' coordorigin="0,0"',' coordsize="',d*Z,",",d*ap,'"',' stroked="',!ao,'"',' path="');var aq=false;for(var ak=aj;ak<Math.min(aj+ag,this.currentPath_.length);ak++){if(ak%ag==0&&ak>0){am.push(" m ",n(this.currentPath_[ak-1].x),",",n(this.currentPath_[ak-1].y))}var m=this.currentPath_[ak];var al;switch(m.type){case"moveTo":al=m;am.push(" m ",n(m.x),",",n(m.y));break;case"lineTo":am.push(" l ",n(m.x),",",n(m.y));break;case"close":am.push(" x ");m=null;break;case"bezierCurveTo":am.push(" c ",n(m.cp1x),",",n(m.cp1y),",",n(m.cp2x),",",n(m.cp2y),",",n(m.x),",",n(m.y));break;case"at":case"wa":am.push(" ",m.type," ",n(m.x-this.arcScaleX_*m.radius),",",n(m.y-this.arcScaleY_*m.radius)," ",n(m.x+this.arcScaleX_*m.radius),",",n(m.y+this.arcScaleY_*m.radius)," ",n(m.xStart),",",n(m.yStart)," ",n(m.xEnd),",",n(m.yEnd));break}if(m){if(ai.x==null||m.x<ai.x){ai.x=m.x}if(an.x==null||m.x>an.x){an.x=m.x}if(ai.y==null||m.y<ai.y){ai.y=m.y}if(an.y==null||m.y>an.y){an.y=m.y}}}am.push(' ">');if(!ao){w(this,am)}else{G(this,am,ai,an)}am.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",am.join(""))}};function w(m,ag){var j=F(m.strokeStyle);var p=j.color;var Z=j.alpha*m.globalAlpha;var i=m.lineScale_*m.lineWidth;if(i<1){Z*=i}ag.push("<g_vml_:stroke",' opacity="',Z,'"',' joinstyle="',m.lineJoin,'"',' miterlimit="',m.miterLimit,'"',' endcap="',S(m.lineCap),'"',' weight="',i,'px"',' color="',p,'" />')}function G(aq,ai,aK,ar){var aj=aq.fillStyle;var aB=aq.arcScaleX_;var aA=aq.arcScaleY_;var j=ar.x-aK.x;var p=ar.y-aK.y;if(aj instanceof U){var an=0;var aF={x:0,y:0};var ax=0;var am=1;if(aj.type_=="gradient"){var al=aj.x0_/aB;var m=aj.y0_/aA;var ak=aj.x1_/aB;var aM=aj.y1_/aA;var aJ=V(aq,al,m);var aI=V(aq,ak,aM);var ag=aI.x-aJ.x;var Z=aI.y-aJ.y;an=Math.atan2(ag,Z)*180/Math.PI;if(an<0){an+=360}if(an<0.000001){an=0}}else{var aJ=V(aq,aj.x0_,aj.y0_);aF={x:(aJ.x-aK.x)/j,y:(aJ.y-aK.y)/p};j/=aB*d;p/=aA*d;var aD=ab.max(j,p);ax=2*aj.r0_/aD;am=2*aj.r1_/aD-ax}var av=aj.colors_;av.sort(function(aN,i){return aN.offset-i.offset});var ap=av.length;var au=av[0].color;var at=av[ap-1].color;var az=av[0].alpha*aq.globalAlpha;var ay=av[ap-1].alpha*aq.globalAlpha;var aE=[];for(var aH=0;aH<ap;aH++){var ao=av[aH];aE.push(ao.offset*am+ax+" "+ao.color)}ai.push('<g_vml_:fill type="',aj.type_,'"',' method="none" focus="100%"',' color="',au,'"',' color2="',at,'"',' colors="',aE.join(","),'"',' opacity="',ay,'"',' g_o_:opacity2="',az,'"',' angle="',an,'"',' focusposition="',aF.x,",",aF.y,'" />')}else{if(aj instanceof T){if(j&&p){var ah=-aK.x;var aC=-aK.y;ai.push("<g_vml_:fill",' position="',ah/j*aB*aB,",",aC/p*aA*aA,'"',' type="tile"',' src="',aj.src_,'" />')}}else{var aL=F(aq.fillStyle);var aw=aL.color;var aG=aL.alpha*aq.globalAlpha;ai.push('<g_vml_:fill color="',aw,'" opacity="',aG,'" />')}}}q.fill=function(){this.stroke(true)};q.closePath=function(){this.currentPath_.push({type:"close"})};function V(j,Z,p){var i=j.m_;return{x:d*(Z*i[0][0]+p*i[1][0]+i[2][0])-f,y:d*(Z*i[0][1]+p*i[1][1]+i[2][1])-f}}q.save=function(){var i={};v(this,i);this.aStack_.push(i);this.mStack_.push(this.m_);this.m_=J(B(),this.m_)};q.restore=function(){if(this.aStack_.length){v(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function h(i){return isFinite(i[0][0])&&isFinite(i[0][1])&&isFinite(i[1][0])&&isFinite(i[1][1])&&isFinite(i[2][0])&&isFinite(i[2][1])}function aa(j,i,p){if(!h(i)){return}j.m_=i;if(p){var Z=i[0][0]*i[1][1]-i[0][1]*i[1][0];j.lineScale_=N(H(Z))}}q.translate=function(m,j){var i=[[1,0,0],[0,1,0],[m,j,1]];aa(this,J(i,this.m_),false)};q.rotate=function(j){var p=A(j);var m=l(j);var i=[[p,m,0],[-m,p,0],[0,0,1]];aa(this,J(i,this.m_),false)};q.scale=function(m,j){this.arcScaleX_*=m;this.arcScaleY_*=j;var i=[[m,0,0],[0,j,0],[0,0,1]];aa(this,J(i,this.m_),true)};q.transform=function(Z,p,ah,ag,j,i){var m=[[Z,p,0],[ah,ag,0],[j,i,1]];aa(this,J(m,this.m_),true)};q.setTransform=function(ag,Z,ai,ah,p,j){var i=[[ag,Z,0],[ai,ah,0],[p,j,1]];aa(this,i,true)};q.drawText_=function(am,ak,aj,ap,ai){var ao=this.m_,at=1000,j=0,ar=at,ah={x:0,y:0},ag=[];var i=u(E(this.font),this.element_);var p=ac(i);var au=this.element_.currentStyle;var Z=this.textAlign.toLowerCase();switch(Z){case"left":case"center":case"right":break;case"end":Z=au.direction=="ltr"?"right":"left";break;case"start":Z=au.direction=="rtl"?"right":"left";break;default:Z="left"}switch(this.textBaseline){case"hanging":case"top":ah.y=i.size/1.75;break;case"middle":break;default:case null:case"alphabetic":case"ideographic":case"bottom":ah.y=-i.size/2.25;break}switch(Z){case"right":j=at;ar=0.05;break;case"center":j=ar=at/2;break}var aq=V(this,ak+ah.x,aj+ah.y);ag.push('<g_vml_:line from="',-j,' 0" to="',ar,' 0.05" ',' coordsize="100 100" coordorigin="0 0"',' filled="',!ai,'" stroked="',!!ai,'" style="position:absolute;width:1px;height:1px;">');if(ai){w(this,ag)}else{G(this,ag,{x:-j,y:0},{x:ar,y:i.size})}var an=ao[0][0].toFixed(3)+","+ao[1][0].toFixed(3)+","+ao[0][1].toFixed(3)+","+ao[1][1].toFixed(3)+",0,0";var al=n(aq.x/d)+","+n(aq.y/d);ag.push('<g_vml_:skew on="t" matrix="',an,'" ',' offset="',al,'" origin="',j,' 0" />','<g_vml_:path textpathok="true" />','<g_vml_:textpath on="true" string="',af(am),'" style="v-text-align:',Z,";font:",af(p),'" /></g_vml_:line>');this.element_.insertAdjacentHTML("beforeEnd",ag.join(""))};q.fillText=function(m,i,p,j){this.drawText_(m,i,p,j,false)};q.strokeText=function(m,i,p,j){this.drawText_(m,i,p,j,true)};q.measureText=function(m){if(!this.textMeasureEl_){var i='<span style="position:absolute;top:-20000px;left:0;padding:0;margin:0;border:none;white-space:pre;"></span>';this.element_.insertAdjacentHTML("beforeEnd",i);this.textMeasureEl_=this.element_.lastChild}var j=this.element_.ownerDocument;this.textMeasureEl_.innerHTML="";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(j.createTextNode(m));return{width:this.textMeasureEl_.offsetWidth}};q.clip=function(){};q.arcTo=function(){};q.createPattern=function(j,i){return new T(j,i)};function U(i){this.type_=i;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}U.prototype.addColorStop=function(j,i){i=F(i);this.colors_.push({offset:j,color:i.color,alpha:i.alpha})};function T(j,i){Q(j);switch(i){case"repeat":case null:case"":this.repetition_="repeat";break;case"repeat-x":case"repeat-y":case"no-repeat":this.repetition_=i;break;default:O("SYNTAX_ERR")}this.src_=j.src;this.width_=j.width;this.height_=j.height}function O(i){throw new P(i)}function Q(i){if(!i||i.nodeType!=1||i.tagName!="IMG"){O("TYPE_MISMATCH_ERR")}if(i.readyState!="complete"){O("INVALID_STATE_ERR")}}function P(i){this.code=this[i];this.message=i+": DOM Exception "+this.code}var X=P.prototype=new Error;X.INDEX_SIZE_ERR=1;X.DOMSTRING_SIZE_ERR=2;X.HIERARCHY_REQUEST_ERR=3;X.WRONG_DOCUMENT_ERR=4;X.INVALID_CHARACTER_ERR=5;X.NO_DATA_ALLOWED_ERR=6;X.NO_MODIFICATION_ALLOWED_ERR=7;X.NOT_FOUND_ERR=8;X.NOT_SUPPORTED_ERR=9;X.INUSE_ATTRIBUTE_ERR=10;X.INVALID_STATE_ERR=11;X.SYNTAX_ERR=12;X.INVALID_MODIFICATION_ERR=13;X.NAMESPACE_ERR=14;X.INVALID_ACCESS_ERR=15;X.VALIDATION_ERR=16;X.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=e;CanvasRenderingContext2D=D;CanvasGradient=U;CanvasPattern=T;DOMException=P})()};
0 2
\ No newline at end of file
... ...
@@ -0,0 +1,180 @@
1
+/* Plugin for jQuery for working with colors.
2
+ * 
3
+ * Version 1.1.
4
+ * 
5
+ * Inspiration from jQuery color animation plugin by John Resig.
6
+ *
7
+ * Released under the MIT license by Ole Laursen, October 2009.
8
+ *
9
+ * Examples:
10
+ *
11
+ *   $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString()
12
+ *   var c = $.color.extract($("#mydiv"), 'background-color');
13
+ *   console.log(c.r, c.g, c.b, c.a);
14
+ *   $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)"
15
+ *
16
+ * Note that .scale() and .add() return the same modified object
17
+ * instead of making a new one.
18
+ *
19
+ * V. 1.1: Fix error handling so e.g. parsing an empty string does
20
+ * produce a color rather than just crashing.
21
+ */ 
22
+
23
+(function($) {
24
+    $.color = {};
25
+
26
+    // construct color object with some convenient chainable helpers
27
+    $.color.make = function (r, g, b, a) {
28
+        var o = {};
29
+        o.r = r || 0;
30
+        o.g = g || 0;
31
+        o.b = b || 0;
32
+        o.a = a != null ? a : 1;
33
+
34
+        o.add = function (c, d) {
35
+            for (var i = 0; i < c.length; ++i)
36
+                o[c.charAt(i)] += d;
37
+            return o.normalize();
38
+        };
39
+        
40
+        o.scale = function (c, f) {
41
+            for (var i = 0; i < c.length; ++i)
42
+                o[c.charAt(i)] *= f;
43
+            return o.normalize();
44
+        };
45
+        
46
+        o.toString = function () {
47
+            if (o.a >= 1.0) {
48
+                return "rgb("+[o.r, o.g, o.b].join(",")+")";
49
+            } else {
50
+                return "rgba("+[o.r, o.g, o.b, o.a].join(",")+")";
51
+            }
52
+        };
53
+
54
+        o.normalize = function () {
55
+            function clamp(min, value, max) {
56
+                return value < min ? min: (value > max ? max: value);
57
+            }
58
+            
59
+            o.r = clamp(0, parseInt(o.r), 255);
60
+            o.g = clamp(0, parseInt(o.g), 255);
61
+            o.b = clamp(0, parseInt(o.b), 255);
62
+            o.a = clamp(0, o.a, 1);
63
+            return o;
64
+        };
65
+
66
+        o.clone = function () {
67
+            return $.color.make(o.r, o.b, o.g, o.a);
68
+        };
69
+
70
+        return o.normalize();
71
+    }
72
+
73
+    // extract CSS color property from element, going up in the DOM
74
+    // if it's "transparent"
75
+    $.color.extract = function (elem, css) {
76
+        var c;
77
+
78
+        do {
79
+            c = elem.css(css).toLowerCase();
80
+            // keep going until we find an element that has color, or
81
+            // we hit the body or root (have no parent)
82
+            if (c != '' && c != 'transparent')
83
+                break;
84
+            elem = elem.parent();
85
+        } while (elem.length && !$.nodeName(elem.get(0), "body"));
86
+
87
+        // catch Safari's way of signalling transparent
88
+        if (c == "rgba(0, 0, 0, 0)")
89
+            c = "transparent";
90
+        
91
+        return $.color.parse(c);
92
+    }
93
+    
94
+    // parse CSS color string (like "rgb(10, 32, 43)" or "#fff"),
95
+    // returns color object, if parsing failed, you get black (0, 0,
96
+    // 0) out
97
+    $.color.parse = function (str) {
98
+        var res, m = $.color.make;
99
+
100
+        // Look for rgb(num,num,num)
101
+        if (res = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))
102
+            return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10));
103
+        
104
+        // Look for rgba(num,num,num,num)
105
+        if (res = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
106
+            return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10), parseFloat(res[4]));
107
+            
108
+        // Look for rgb(num%,num%,num%)
109
+        if (res = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))
110
+            return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55);
111
+
112
+        // Look for rgba(num%,num%,num%,num)
113
+        if (res = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
114
+            return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55, parseFloat(res[4]));
115
+        
116
+        // Look for #a0b1c2
117
+        if (res = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))
118
+            return m(parseInt(res[1], 16), parseInt(res[2], 16), parseInt(res[3], 16));
119
+
120
+        // Look for #fff
121
+        if (res = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))
122
+            return m(parseInt(res[1]+res[1], 16), parseInt(res[2]+res[2], 16), parseInt(res[3]+res[3], 16));
123
+
124
+        // Otherwise, we're most likely dealing with a named color
125
+        var name = $.trim(str).toLowerCase();
126
+        if (name == "transparent")
127
+            return m(255, 255, 255, 0);
128
+        else {
129
+            // default to black
130
+            res = lookupColors[name] || [0, 0, 0];
131
+            return m(res[0], res[1], res[2]);
132
+        }
133
+    }
134
+    
135
+    var lookupColors = {
136
+        aqua:[0,255,255],
137
+        azure:[240,255,255],
138
+        beige:[245,245,220],
139
+        black:[0,0,0],
140
+        blue:[0,0,255],
141
+        brown:[165,42,42],
142
+        cyan:[0,255,255],
143
+        darkblue:[0,0,139],
144
+        darkcyan:[0,139,139],
145
+        darkgrey:[169,169,169],
146
+        darkgreen:[0,100,0],
147
+        darkkhaki:[189,183,107],
148
+        darkmagenta:[139,0,139],
149
+        darkolivegreen:[85,107,47],
150
+        darkorange:[255,140,0],
151
+        darkorchid:[153,50,204],
152
+        darkred:[139,0,0],
153
+        darksalmon:[233,150,122],
154
+        darkviolet:[148,0,211],
155
+        fuchsia:[255,0,255],
156
+        gold:[255,215,0],
157
+        green:[0,128,0],
158
+        indigo:[75,0,130],
159
+        khaki:[240,230,140],
160
+        lightblue:[173,216,230],
161
+        lightcyan:[224,255,255],
162
+        lightgreen:[144,238,144],
163
+        lightgrey:[211,211,211],
164
+        lightpink:[255,182,193],
165
+        lightyellow:[255,255,224],
166
+        lime:[0,255,0],
167
+        magenta:[255,0,255],
168
+        maroon:[128,0,0],
169
+        navy:[0,0,128],
170
+        olive:[128,128,0],
171
+        orange:[255,165,0],
172
+        pink:[255,192,203],
173
+        purple:[128,0,128],
174
+        violet:[128,0,128],
175
+        red:[255,0,0],
176
+        silver:[192,192,192],
177
+        white:[255,255,255],
178
+        yellow:[255,255,0]
179
+    };
180
+})(jQuery);
... ...
@@ -0,0 +1 @@
1
+(function($){$.color={};$.color.make=function(r,g,b,a){var o={};o.r=r||0;o.g=g||0;o.b=b||0;o.a=a!=null?a:1;o.add=function(c,d){for(var i=0;i<c.length;++i)o[c.charAt(i)]+=d;return o.normalize()};o.scale=function(c,f){for(var i=0;i<c.length;++i)o[c.charAt(i)]*=f;return o.normalize()};o.toString=function(){if(o.a>=1){return"rgb("+[o.r,o.g,o.b].join(",")+")"}else{return"rgba("+[o.r,o.g,o.b,o.a].join(",")+")"}};o.normalize=function(){function clamp(min,value,max){return value<min?min:value>max?max:value}o.r=clamp(0,parseInt(o.r),255);o.g=clamp(0,parseInt(o.g),255);o.b=clamp(0,parseInt(o.b),255);o.a=clamp(0,o.a,1);return o};o.clone=function(){return $.color.make(o.r,o.b,o.g,o.a)};return o.normalize()};$.color.extract=function(elem,css){var c;do{c=elem.css(css).toLowerCase();if(c!=""&&c!="transparent")break;elem=elem.parent()}while(elem.length&&!$.nodeName(elem.get(0),"body"));if(c=="rgba(0, 0, 0, 0)")c="transparent";return $.color.parse(c)};$.color.parse=function(str){var res,m=$.color.make;if(res=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10));if(res=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10),parseFloat(res[4]));if(res=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55);if(res=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55,parseFloat(res[4]));if(res=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))return m(parseInt(res[1],16),parseInt(res[2],16),parseInt(res[3],16));if(res=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))return m(parseInt(res[1]+res[1],16),parseInt(res[2]+res[2],16),parseInt(res[3]+res[3],16));var name=$.trim(str).toLowerCase();if(name=="transparent")return m(255,255,255,0);else{res=lookupColors[name]||[0,0,0];return m(res[0],res[1],res[2])}};var lookupColors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,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,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]}})(jQuery);
0 2
\ No newline at end of file
... ...
@@ -0,0 +1,345 @@
1
+/* Flot plugin for drawing all elements of a plot on the canvas.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+Flot normally produces certain elements, like axis labels and the legend, using
7
+HTML elements. This permits greater interactivity and customization, and often
8
+looks better, due to cross-browser canvas text inconsistencies and limitations.
9
+
10
+It can also be desirable to render the plot entirely in canvas, particularly
11
+if the goal is to save it as an image, or if Flot is being used in a context
12
+where the HTML DOM does not exist, as is the case within Node.js. This plugin
13
+switches out Flot's standard drawing operations for canvas-only replacements.
14
+
15
+Currently the plugin supports only axis labels, but it will eventually allow
16
+every element of the plot to be rendered directly to canvas.
17
+
18
+The plugin supports these options:
19
+
20
+{
21
+    canvas: boolean
22
+}
23
+
24
+The "canvas" option controls whether full canvas drawing is enabled, making it
25
+possible to toggle on and off. This is useful when a plot uses HTML text in the
26
+browser, but needs to redraw with canvas text when exporting as an image.
27
+
28
+*/
29
+
30
+(function($) {
31
+
32
+	var options = {
33
+		canvas: true
34
+	};
35
+
36
+	var render, getTextInfo, addText;
37
+
38
+	// Cache the prototype hasOwnProperty for faster access
39
+
40
+	var hasOwnProperty = Object.prototype.hasOwnProperty;
41
+
42
+	function init(plot, classes) {
43
+
44
+		var Canvas = classes.Canvas;
45
+
46
+		// We only want to replace the functions once; the second time around
47
+		// we would just get our new function back.  This whole replacing of
48
+		// prototype functions is a disaster, and needs to be changed ASAP.
49
+
50
+		if (render == null) {
51
+			getTextInfo = Canvas.prototype.getTextInfo,
52
+			addText = Canvas.prototype.addText,
53
+			render = Canvas.prototype.render;
54
+		}
55
+
56
+		// Finishes rendering the canvas, including overlaid text
57
+
58
+		Canvas.prototype.render = function() {
59
+
60
+			if (!plot.getOptions().canvas) {
61
+				return render.call(this);
62
+			}
63
+
64
+			var context = this.context,
65
+				cache = this._textCache;
66
+
67
+			// For each text layer, render elements marked as active
68
+
69
+			context.save();
70
+			context.textBaseline = "middle";
71
+
72
+			for (var layerKey in cache) {
73
+				if (hasOwnProperty.call(cache, layerKey)) {
74
+					var layerCache = cache[layerKey];
75
+					for (var styleKey in layerCache) {
76
+						if (hasOwnProperty.call(layerCache, styleKey)) {
77
+							var styleCache = layerCache[styleKey],
78
+								updateStyles = true;
79
+							for (var key in styleCache) {
80
+								if (hasOwnProperty.call(styleCache, key)) {
81
+
82
+									var info = styleCache[key],
83
+										positions = info.positions,
84
+										lines = info.lines;
85
+
86
+									// Since every element at this level of the cache have the
87
+									// same font and fill styles, we can just change them once
88
+									// using the values from the first element.
89
+
90
+									if (updateStyles) {
91
+										context.fillStyle = info.font.color;
92
+										context.font = info.font.definition;
93
+										updateStyles = false;
94
+									}
95
+
96
+									for (var i = 0, position; position = positions[i]; i++) {
97
+										if (position.active) {
98
+											for (var j = 0, line; line = position.lines[j]; j++) {
99
+												context.fillText(lines[j].text, line[0], line[1]);
100
+											}
101
+										} else {
102
+											positions.splice(i--, 1);
103
+										}
104
+									}
105
+
106
+									if (positions.length == 0) {
107
+										delete styleCache[key];
108
+									}
109
+								}
110
+							}
111
+						}
112
+					}
113
+				}
114
+			}
115
+
116
+			context.restore();
117
+		};
118
+
119
+		// Creates (if necessary) and returns a text info object.
120
+		//
121
+		// When the canvas option is set, the object looks like this:
122
+		//
123
+		// {
124
+		//     width: Width of the text's bounding box.
125
+		//     height: Height of the text's bounding box.
126
+		//     positions: Array of positions at which this text is drawn.
127
+		//     lines: [{
128
+		//         height: Height of this line.
129
+		//         widths: Width of this line.
130
+		//         text: Text on this line.
131
+		//     }],
132
+		//     font: {
133
+		//         definition: Canvas font property string.
134
+		//         color: Color of the text.
135
+		//     },
136
+		// }
137
+		//
138
+		// The positions array contains objects that look like this:
139
+		//
140
+		// {
141
+		//     active: Flag indicating whether the text should be visible.
142
+		//     lines: Array of [x, y] coordinates at which to draw the line.
143
+		//     x: X coordinate at which to draw the text.
144
+		//     y: Y coordinate at which to draw the text.
145
+		// }
146
+
147
+		Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) {
148
+
149
+			if (!plot.getOptions().canvas) {
150
+				return getTextInfo.call(this, layer, text, font, angle, width);
151
+			}
152
+
153
+			var textStyle, layerCache, styleCache, info;
154
+
155
+			// Cast the value to a string, in case we were given a number
156
+
157
+			text = "" + text;
158
+
159
+			// If the font is a font-spec object, generate a CSS definition
160
+
161
+			if (typeof font === "object") {
162
+				textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px " + font.family;
163
+			} else {
164
+				textStyle = font;
165
+			}
166
+
167
+			// Retrieve (or create) the cache for the text's layer and styles
168
+
169
+			layerCache = this._textCache[layer];
170
+
171
+			if (layerCache == null) {
172
+				layerCache = this._textCache[layer] = {};
173
+			}
174
+
175
+			styleCache = layerCache[textStyle];
176
+
177
+			if (styleCache == null) {
178
+				styleCache = layerCache[textStyle] = {};
179
+			}
180
+
181
+			info = styleCache[text];
182
+
183
+			if (info == null) {
184
+
185
+				var context = this.context;
186
+
187
+				// If the font was provided as CSS, create a div with those
188
+				// classes and examine it to generate a canvas font spec.
189
+
190
+				if (typeof font !== "object") {
191
+
192
+					var element = $("<div>&nbsp;</div>")
193
+						.css("position", "absolute")
194
+						.addClass(typeof font === "string" ? font : null)
195
+						.appendTo(this.getTextLayer(layer));
196
+
197
+					font = {
198
+						lineHeight: element.height(),
199
+						style: element.css("font-style"),
200
+						variant: element.css("font-variant"),
201
+						weight: element.css("font-weight"),
202
+						family: element.css("font-family"),
203
+						color: element.css("color")
204
+					};
205
+
206
+					// Setting line-height to 1, without units, sets it equal
207
+					// to the font-size, even if the font-size is abstract,
208
+					// like 'smaller'.  This enables us to read the real size
209
+					// via the element's height, working around browsers that
210
+					// return the literal 'smaller' value.
211
+
212
+					font.size = element.css("line-height", 1).height();
213
+
214
+					element.remove();
215
+				}
216
+
217
+				textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px " + font.family;
218
+
219
+				// Create a new info object, initializing the dimensions to
220
+				// zero so we can count them up line-by-line.
221
+
222
+				info = styleCache[text] = {
223
+					width: 0,
224
+					height: 0,
225
+					positions: [],
226
+					lines: [],
227
+					font: {
228
+						definition: textStyle,
229
+						color: font.color
230
+					}
231
+				};
232
+
233
+				context.save();
234
+				context.font = textStyle;
235
+
236
+				// Canvas can't handle multi-line strings; break on various
237
+				// newlines, including HTML brs, to build a list of lines.
238
+				// Note that we could split directly on regexps, but IE < 9 is
239
+				// broken; revisit when we drop IE 7/8 support.
240
+
241
+				var lines = (text + "").replace(/<br ?\/?>|\r\n|\r/g, "\n").split("\n");
242
+
243
+				for (var i = 0; i < lines.length; ++i) {
244
+
245
+					var lineText = lines[i],
246
+						measured = context.measureText(lineText);
247
+
248
+					info.width = Math.max(measured.width, info.width);
249
+					info.height += font.lineHeight;
250
+
251
+					info.lines.push({
252
+						text: lineText,
253
+						width: measured.width,
254
+						height: font.lineHeight
255
+					});
256
+				}
257
+
258
+				context.restore();
259
+			}
260
+
261
+			return info;
262
+		};
263
+
264
+		// Adds a text string to the canvas text overlay.
265
+
266
+		Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) {
267
+
268
+			if (!plot.getOptions().canvas) {
269
+				return addText.call(this, layer, x, y, text, font, angle, width, halign, valign);
270
+			}
271
+
272
+			var info = this.getTextInfo(layer, text, font, angle, width),
273
+				positions = info.positions,
274
+				lines = info.lines;
275
+
276
+			// Text is drawn with baseline 'middle', which we need to account
277
+			// for by adding half a line's height to the y position.
278
+
279
+			y += info.height / lines.length / 2;
280
+
281
+			// Tweak the initial y-position to match vertical alignment
282
+
283
+			if (valign == "middle") {
284
+				y = Math.round(y - info.height / 2);
285
+			} else if (valign == "bottom") {
286
+				y = Math.round(y - info.height);
287
+			} else {
288
+				y = Math.round(y);
289
+			}
290
+
291
+			// FIXME: LEGACY BROWSER FIX
292
+			// AFFECTS: Opera < 12.00
293
+
294
+			// Offset the y coordinate, since Opera is off pretty
295
+			// consistently compared to the other browsers.
296
+
297
+			if (!!(window.opera && window.opera.version().split(".")[0] < 12)) {
298
+				y -= 2;
299
+			}
300
+
301
+			// Determine whether this text already exists at this position.
302
+			// If so, mark it for inclusion in the next render pass.
303
+
304
+			for (var i = 0, position; position = positions[i]; i++) {
305
+				if (position.x == x && position.y == y) {
306
+					position.active = true;
307
+					return;
308
+				}
309
+			}
310
+
311
+			// If the text doesn't exist at this position, create a new entry
312
+
313
+			position = {
314
+				active: true,
315
+				lines: [],
316
+				x: x,
317
+				y: y
318
+			};
319
+
320
+			positions.push(position);
321
+
322
+			// Fill in the x & y positions of each line, adjusting them
323
+			// individually for horizontal alignment.
324
+
325
+			for (var i = 0, line; line = lines[i]; i++) {
326
+				if (halign == "center") {
327
+					position.lines.push([Math.round(x - line.width / 2), y]);
328
+				} else if (halign == "right") {
329
+					position.lines.push([Math.round(x - line.width), y]);
330
+				} else {
331
+					position.lines.push([Math.round(x), y]);
332
+				}
333
+				y += line.height;
334
+			}
335
+		};
336
+	}
337
+
338
+	$.plot.plugins.push({
339
+		init: init,
340
+		options: options,
341
+		name: "canvas",
342
+		version: "1.0"
343
+	});
344
+
345
+})(jQuery);
... ...
@@ -0,0 +1,7 @@
1
+/* Javascript plotting library for jQuery, version 0.8.3.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+*/
7
+(function($){var options={canvas:true};var render,getTextInfo,addText;var hasOwnProperty=Object.prototype.hasOwnProperty;function init(plot,classes){var Canvas=classes.Canvas;if(render==null){getTextInfo=Canvas.prototype.getTextInfo,addText=Canvas.prototype.addText,render=Canvas.prototype.render}Canvas.prototype.render=function(){if(!plot.getOptions().canvas){return render.call(this)}var context=this.context,cache=this._textCache;context.save();context.textBaseline="middle";for(var layerKey in cache){if(hasOwnProperty.call(cache,layerKey)){var layerCache=cache[layerKey];for(var styleKey in layerCache){if(hasOwnProperty.call(layerCache,styleKey)){var styleCache=layerCache[styleKey],updateStyles=true;for(var key in styleCache){if(hasOwnProperty.call(styleCache,key)){var info=styleCache[key],positions=info.positions,lines=info.lines;if(updateStyles){context.fillStyle=info.font.color;context.font=info.font.definition;updateStyles=false}for(var i=0,position;position=positions[i];i++){if(position.active){for(var j=0,line;line=position.lines[j];j++){context.fillText(lines[j].text,line[0],line[1])}}else{positions.splice(i--,1)}}if(positions.length==0){delete styleCache[key]}}}}}}}context.restore()};Canvas.prototype.getTextInfo=function(layer,text,font,angle,width){if(!plot.getOptions().canvas){return getTextInfo.call(this,layer,text,font,angle,width)}var textStyle,layerCache,styleCache,info;text=""+text;if(typeof font==="object"){textStyle=font.style+" "+font.variant+" "+font.weight+" "+font.size+"px "+font.family}else{textStyle=font}layerCache=this._textCache[layer];if(layerCache==null){layerCache=this._textCache[layer]={}}styleCache=layerCache[textStyle];if(styleCache==null){styleCache=layerCache[textStyle]={}}info=styleCache[text];if(info==null){var context=this.context;if(typeof font!=="object"){var element=$("<div>&nbsp;</div>").css("position","absolute").addClass(typeof font==="string"?font:null).appendTo(this.getTextLayer(layer));font={lineHeight:element.height(),style:element.css("font-style"),variant:element.css("font-variant"),weight:element.css("font-weight"),family:element.css("font-family"),color:element.css("color")};font.size=element.css("line-height",1).height();element.remove()}textStyle=font.style+" "+font.variant+" "+font.weight+" "+font.size+"px "+font.family;info=styleCache[text]={width:0,height:0,positions:[],lines:[],font:{definition:textStyle,color:font.color}};context.save();context.font=textStyle;var lines=(text+"").replace(/<br ?\/?>|\r\n|\r/g,"\n").split("\n");for(var i=0;i<lines.length;++i){var lineText=lines[i],measured=context.measureText(lineText);info.width=Math.max(measured.width,info.width);info.height+=font.lineHeight;info.lines.push({text:lineText,width:measured.width,height:font.lineHeight})}context.restore()}return info};Canvas.prototype.addText=function(layer,x,y,text,font,angle,width,halign,valign){if(!plot.getOptions().canvas){return addText.call(this,layer,x,y,text,font,angle,width,halign,valign)}var info=this.getTextInfo(layer,text,font,angle,width),positions=info.positions,lines=info.lines;y+=info.height/lines.length/2;if(valign=="middle"){y=Math.round(y-info.height/2)}else if(valign=="bottom"){y=Math.round(y-info.height)}else{y=Math.round(y)}if(!!(window.opera&&window.opera.version().split(".")[0]<12)){y-=2}for(var i=0,position;position=positions[i];i++){if(position.x==x&&position.y==y){position.active=true;return}}position={active:true,lines:[],x:x,y:y};positions.push(position);for(var i=0,line;line=lines[i];i++){if(halign=="center"){position.lines.push([Math.round(x-line.width/2),y])}else if(halign=="right"){position.lines.push([Math.round(x-line.width),y])}else{position.lines.push([Math.round(x),y])}y+=line.height}}}$.plot.plugins.push({init:init,options:options,name:"canvas",version:"1.0"})})(jQuery);
0 8
\ No newline at end of file
... ...
@@ -0,0 +1,190 @@
1
+/* Flot plugin for plotting textual data or categories.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+Consider a dataset like [["February", 34], ["March", 20], ...]. This plugin
7
+allows you to plot such a dataset directly.
8
+
9
+To enable it, you must specify mode: "categories" on the axis with the textual
10
+labels, e.g.
11
+
12
+	$.plot("#placeholder", data, { xaxis: { mode: "categories" } });
13
+
14
+By default, the labels are ordered as they are met in the data series. If you
15
+need a different ordering, you can specify "categories" on the axis options
16
+and list the categories there:
17
+
18
+	xaxis: {
19
+		mode: "categories",
20
+		categories: ["February", "March", "April"]
21
+	}
22
+
23
+If you need to customize the distances between the categories, you can specify
24
+"categories" as an object mapping labels to values
25
+
26
+	xaxis: {
27
+		mode: "categories",
28
+		categories: { "February": 1, "March": 3, "April": 4 }
29
+	}
30
+
31
+If you don't specify all categories, the remaining categories will be numbered
32
+from the max value plus 1 (with a spacing of 1 between each).
33
+
34
+Internally, the plugin works by transforming the input data through an auto-
35
+generated mapping where the first category becomes 0, the second 1, etc.
36
+Hence, a point like ["February", 34] becomes [0, 34] internally in Flot (this
37
+is visible in hover and click events that return numbers rather than the
38
+category labels). The plugin also overrides the tick generator to spit out the
39
+categories as ticks instead of the values.
40
+
41
+If you need to map a value back to its label, the mapping is always accessible
42
+as "categories" on the axis object, e.g. plot.getAxes().xaxis.categories.
43
+
44
+*/
45
+
46
+(function ($) {
47
+    var options = {
48
+        xaxis: {
49
+            categories: null
50
+        },
51
+        yaxis: {
52
+            categories: null
53
+        }
54
+    };
55
+    
56
+    function processRawData(plot, series, data, datapoints) {
57
+        // if categories are enabled, we need to disable
58
+        // auto-transformation to numbers so the strings are intact
59
+        // for later processing
60
+
61
+        var xCategories = series.xaxis.options.mode == "categories",
62
+            yCategories = series.yaxis.options.mode == "categories";
63
+        
64
+        if (!(xCategories || yCategories))
65
+            return;
66
+
67
+        var format = datapoints.format;
68
+
69
+        if (!format) {
70
+            // FIXME: auto-detection should really not be defined here
71
+            var s = series;
72
+            format = [];
73
+            format.push({ x: true, number: true, required: true });
74
+            format.push({ y: true, number: true, required: true });
75
+
76
+            if (s.bars.show || (s.lines.show && s.lines.fill)) {
77
+                var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));
78
+                format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });
79
+                if (s.bars.horizontal) {
80
+                    delete format[format.length - 1].y;
81
+                    format[format.length - 1].x = true;
82
+                }
83
+            }
84
+            
85
+            datapoints.format = format;
86
+        }
87
+
88
+        for (var m = 0; m < format.length; ++m) {
89
+            if (format[m].x && xCategories)
90
+                format[m].number = false;
91
+            
92
+            if (format[m].y && yCategories)
93
+                format[m].number = false;
94
+        }
95
+    }
96
+
97
+    function getNextIndex(categories) {
98
+        var index = -1;
99
+        
100
+        for (var v in categories)
101
+            if (categories[v] > index)
102
+                index = categories[v];
103
+
104
+        return index + 1;
105
+    }
106
+
107
+    function categoriesTickGenerator(axis) {
108
+        var res = [];
109
+        for (var label in axis.categories) {
110
+            var v = axis.categories[label];
111
+            if (v >= axis.min && v <= axis.max)
112
+                res.push([v, label]);
113
+        }
114
+
115
+        res.sort(function (a, b) { return a[0] - b[0]; });
116
+
117
+        return res;
118
+    }
119
+    
120
+    function setupCategoriesForAxis(series, axis, datapoints) {
121
+        if (series[axis].options.mode != "categories")
122
+            return;
123
+        
124
+        if (!series[axis].categories) {
125
+            // parse options
126
+            var c = {}, o = series[axis].options.categories || {};
127
+            if ($.isArray(o)) {
128
+                for (var i = 0; i < o.length; ++i)
129
+                    c[o[i]] = i;
130
+            }
131
+            else {
132
+                for (var v in o)
133
+                    c[v] = o[v];
134
+            }
135
+            
136
+            series[axis].categories = c;
137
+        }
138
+
139
+        // fix ticks
140
+        if (!series[axis].options.ticks)
141
+            series[axis].options.ticks = categoriesTickGenerator;
142
+
143
+        transformPointsOnAxis(datapoints, axis, series[axis].categories);
144
+    }
145
+    
146
+    function transformPointsOnAxis(datapoints, axis, categories) {
147
+        // go through the points, transforming them
148
+        var points = datapoints.points,
149
+            ps = datapoints.pointsize,
150
+            format = datapoints.format,
151
+            formatColumn = axis.charAt(0),
152
+            index = getNextIndex(categories);
153
+
154
+        for (var i = 0; i < points.length; i += ps) {
155
+            if (points[i] == null)
156
+                continue;
157
+            
158
+            for (var m = 0; m < ps; ++m) {
159
+                var val = points[i + m];
160
+
161
+                if (val == null || !format[m][formatColumn])
162
+                    continue;
163
+
164
+                if (!(val in categories)) {
165
+                    categories[val] = index;
166
+                    ++index;
167
+                }
168
+                
169
+                points[i + m] = categories[val];
170
+            }
171
+        }
172
+    }
173
+
174
+    function processDatapoints(plot, series, datapoints) {
175
+        setupCategoriesForAxis(series, "xaxis", datapoints);
176
+        setupCategoriesForAxis(series, "yaxis", datapoints);
177
+    }
178
+
179
+    function init(plot) {
180
+        plot.hooks.processRawData.push(processRawData);
181
+        plot.hooks.processDatapoints.push(processDatapoints);
182
+    }
183
+    
184
+    $.plot.plugins.push({
185
+        init: init,
186
+        options: options,
187
+        name: 'categories',
188
+        version: '1.0'
189
+    });
190
+})(jQuery);
... ...
@@ -0,0 +1,7 @@
1
+/* Javascript plotting library for jQuery, version 0.8.3.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+*/
7
+(function($){var options={xaxis:{categories:null},yaxis:{categories:null}};function processRawData(plot,series,data,datapoints){var xCategories=series.xaxis.options.mode=="categories",yCategories=series.yaxis.options.mode=="categories";if(!(xCategories||yCategories))return;var format=datapoints.format;if(!format){var s=series;format=[];format.push({x:true,number:true,required:true});format.push({y:true,number:true,required:true});if(s.bars.show||s.lines.show&&s.lines.fill){var autoscale=!!(s.bars.show&&s.bars.zero||s.lines.show&&s.lines.zero);format.push({y:true,number:true,required:false,defaultValue:0,autoscale:autoscale});if(s.bars.horizontal){delete format[format.length-1].y;format[format.length-1].x=true}}datapoints.format=format}for(var m=0;m<format.length;++m){if(format[m].x&&xCategories)format[m].number=false;if(format[m].y&&yCategories)format[m].number=false}}function getNextIndex(categories){var index=-1;for(var v in categories)if(categories[v]>index)index=categories[v];return index+1}function categoriesTickGenerator(axis){var res=[];for(var label in axis.categories){var v=axis.categories[label];if(v>=axis.min&&v<=axis.max)res.push([v,label])}res.sort(function(a,b){return a[0]-b[0]});return res}function setupCategoriesForAxis(series,axis,datapoints){if(series[axis].options.mode!="categories")return;if(!series[axis].categories){var c={},o=series[axis].options.categories||{};if($.isArray(o)){for(var i=0;i<o.length;++i)c[o[i]]=i}else{for(var v in o)c[v]=o[v]}series[axis].categories=c}if(!series[axis].options.ticks)series[axis].options.ticks=categoriesTickGenerator;transformPointsOnAxis(datapoints,axis,series[axis].categories)}function transformPointsOnAxis(datapoints,axis,categories){var points=datapoints.points,ps=datapoints.pointsize,format=datapoints.format,formatColumn=axis.charAt(0),index=getNextIndex(categories);for(var i=0;i<points.length;i+=ps){if(points[i]==null)continue;for(var m=0;m<ps;++m){var val=points[i+m];if(val==null||!format[m][formatColumn])continue;if(!(val in categories)){categories[val]=index;++index}points[i+m]=categories[val]}}}function processDatapoints(plot,series,datapoints){setupCategoriesForAxis(series,"xaxis",datapoints);setupCategoriesForAxis(series,"yaxis",datapoints)}function init(plot){plot.hooks.processRawData.push(processRawData);plot.hooks.processDatapoints.push(processDatapoints)}$.plot.plugins.push({init:init,options:options,name:"categories",version:"1.0"})})(jQuery);
0 8
\ No newline at end of file
... ...
@@ -0,0 +1,176 @@
1
+/* Flot plugin for showing crosshairs when the mouse hovers over the plot.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+The plugin supports these options:
7
+
8
+	crosshair: {
9
+		mode: null or "x" or "y" or "xy"
10
+		color: color
11
+		lineWidth: number
12
+	}
13
+
14
+Set the mode to one of "x", "y" or "xy". The "x" mode enables a vertical
15
+crosshair that lets you trace the values on the x axis, "y" enables a
16
+horizontal crosshair and "xy" enables them both. "color" is the color of the
17
+crosshair (default is "rgba(170, 0, 0, 0.80)"), "lineWidth" is the width of
18
+the drawn lines (default is 1).
19
+
20
+The plugin also adds four public methods:
21
+
22
+  - setCrosshair( pos )
23
+
24
+    Set the position of the crosshair. Note that this is cleared if the user
25
+    moves the mouse. "pos" is in coordinates of the plot and should be on the
26
+    form { x: xpos, y: ypos } (you can use x2/x3/... if you're using multiple
27
+    axes), which is coincidentally the same format as what you get from a
28
+    "plothover" event. If "pos" is null, the crosshair is cleared.
29
+
30
+  - clearCrosshair()
31
+
32
+    Clear the crosshair.
33
+
34
+  - lockCrosshair(pos)
35
+
36
+    Cause the crosshair to lock to the current location, no longer updating if
37
+    the user moves the mouse. Optionally supply a position (passed on to
38
+    setCrosshair()) to move it to.
39
+
40
+    Example usage:
41
+
42
+	var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } };
43
+	$("#graph").bind( "plothover", function ( evt, position, item ) {
44
+		if ( item ) {
45
+			// Lock the crosshair to the data point being hovered
46
+			myFlot.lockCrosshair({
47
+				x: item.datapoint[ 0 ],
48
+				y: item.datapoint[ 1 ]
49
+			});
50
+		} else {
51
+			// Return normal crosshair operation
52
+			myFlot.unlockCrosshair();
53
+		}
54
+	});
55
+
56
+  - unlockCrosshair()
57
+
58
+    Free the crosshair to move again after locking it.
59
+*/
60
+
61
+(function ($) {
62
+    var options = {
63
+        crosshair: {
64
+            mode: null, // one of null, "x", "y" or "xy",
65
+            color: "rgba(170, 0, 0, 0.80)",
66
+            lineWidth: 1
67
+        }
68
+    };
69
+    
70
+    function init(plot) {
71
+        // position of crosshair in pixels
72
+        var crosshair = { x: -1, y: -1, locked: false };
73
+
74
+        plot.setCrosshair = function setCrosshair(pos) {
75
+            if (!pos)
76
+                crosshair.x = -1;
77
+            else {
78
+                var o = plot.p2c(pos);
79
+                crosshair.x = Math.max(0, Math.min(o.left, plot.width()));
80
+                crosshair.y = Math.max(0, Math.min(o.top, plot.height()));
81
+            }
82
+            
83
+            plot.triggerRedrawOverlay();
84
+        };
85
+        
86
+        plot.clearCrosshair = plot.setCrosshair; // passes null for pos
87
+        
88
+        plot.lockCrosshair = function lockCrosshair(pos) {
89
+            if (pos)
90
+                plot.setCrosshair(pos);
91
+            crosshair.locked = true;
92
+        };
93
+
94
+        plot.unlockCrosshair = function unlockCrosshair() {
95
+            crosshair.locked = false;
96
+        };
97
+
98
+        function onMouseOut(e) {
99
+            if (crosshair.locked)
100
+                return;
101
+
102
+            if (crosshair.x != -1) {
103
+                crosshair.x = -1;
104
+                plot.triggerRedrawOverlay();
105
+            }
106
+        }
107
+
108
+        function onMouseMove(e) {
109
+            if (crosshair.locked)
110
+                return;
111
+                
112
+            if (plot.getSelection && plot.getSelection()) {
113
+                crosshair.x = -1; // hide the crosshair while selecting
114
+                return;
115
+            }
116
+                
117
+            var offset = plot.offset();
118
+            crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width()));
119
+            crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height()));
120
+            plot.triggerRedrawOverlay();
121
+        }
122
+        
123
+        plot.hooks.bindEvents.push(function (plot, eventHolder) {
124
+            if (!plot.getOptions().crosshair.mode)
125
+                return;
126
+
127
+            eventHolder.mouseout(onMouseOut);
128
+            eventHolder.mousemove(onMouseMove);
129
+        });
130
+
131
+        plot.hooks.drawOverlay.push(function (plot, ctx) {
132
+            var c = plot.getOptions().crosshair;
133
+            if (!c.mode)
134
+                return;
135
+
136
+            var plotOffset = plot.getPlotOffset();
137
+            
138
+            ctx.save();
139
+            ctx.translate(plotOffset.left, plotOffset.top);
140
+
141
+            if (crosshair.x != -1) {
142
+                var adj = plot.getOptions().crosshair.lineWidth % 2 ? 0.5 : 0;
143
+
144
+                ctx.strokeStyle = c.color;
145
+                ctx.lineWidth = c.lineWidth;
146
+                ctx.lineJoin = "round";
147
+
148
+                ctx.beginPath();
149
+                if (c.mode.indexOf("x") != -1) {
150
+                    var drawX = Math.floor(crosshair.x) + adj;
151
+                    ctx.moveTo(drawX, 0);
152
+                    ctx.lineTo(drawX, plot.height());
153
+                }
154
+                if (c.mode.indexOf("y") != -1) {
155
+                    var drawY = Math.floor(crosshair.y) + adj;
156
+                    ctx.moveTo(0, drawY);
157
+                    ctx.lineTo(plot.width(), drawY);
158
+                }
159
+                ctx.stroke();
160
+            }
161
+            ctx.restore();
162
+        });
163
+
164
+        plot.hooks.shutdown.push(function (plot, eventHolder) {
165
+            eventHolder.unbind("mouseout", onMouseOut);
166
+            eventHolder.unbind("mousemove", onMouseMove);
167
+        });
168
+    }
169
+    
170
+    $.plot.plugins.push({
171
+        init: init,
172
+        options: options,
173
+        name: 'crosshair',
174
+        version: '1.0'
175
+    });
176
+})(jQuery);
... ...
@@ -0,0 +1,7 @@
1
+/* Javascript plotting library for jQuery, version 0.8.3.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+*/
7
+(function($){var options={crosshair:{mode:null,color:"rgba(170, 0, 0, 0.80)",lineWidth:1}};function init(plot){var crosshair={x:-1,y:-1,locked:false};plot.setCrosshair=function setCrosshair(pos){if(!pos)crosshair.x=-1;else{var o=plot.p2c(pos);crosshair.x=Math.max(0,Math.min(o.left,plot.width()));crosshair.y=Math.max(0,Math.min(o.top,plot.height()))}plot.triggerRedrawOverlay()};plot.clearCrosshair=plot.setCrosshair;plot.lockCrosshair=function lockCrosshair(pos){if(pos)plot.setCrosshair(pos);crosshair.locked=true};plot.unlockCrosshair=function unlockCrosshair(){crosshair.locked=false};function onMouseOut(e){if(crosshair.locked)return;if(crosshair.x!=-1){crosshair.x=-1;plot.triggerRedrawOverlay()}}function onMouseMove(e){if(crosshair.locked)return;if(plot.getSelection&&plot.getSelection()){crosshair.x=-1;return}var offset=plot.offset();crosshair.x=Math.max(0,Math.min(e.pageX-offset.left,plot.width()));crosshair.y=Math.max(0,Math.min(e.pageY-offset.top,plot.height()));plot.triggerRedrawOverlay()}plot.hooks.bindEvents.push(function(plot,eventHolder){if(!plot.getOptions().crosshair.mode)return;eventHolder.mouseout(onMouseOut);eventHolder.mousemove(onMouseMove)});plot.hooks.drawOverlay.push(function(plot,ctx){var c=plot.getOptions().crosshair;if(!c.mode)return;var plotOffset=plot.getPlotOffset();ctx.save();ctx.translate(plotOffset.left,plotOffset.top);if(crosshair.x!=-1){var adj=plot.getOptions().crosshair.lineWidth%2?.5:0;ctx.strokeStyle=c.color;ctx.lineWidth=c.lineWidth;ctx.lineJoin="round";ctx.beginPath();if(c.mode.indexOf("x")!=-1){var drawX=Math.floor(crosshair.x)+adj;ctx.moveTo(drawX,0);ctx.lineTo(drawX,plot.height())}if(c.mode.indexOf("y")!=-1){var drawY=Math.floor(crosshair.y)+adj;ctx.moveTo(0,drawY);ctx.lineTo(plot.width(),drawY)}ctx.stroke()}ctx.restore()});plot.hooks.shutdown.push(function(plot,eventHolder){eventHolder.unbind("mouseout",onMouseOut);eventHolder.unbind("mousemove",onMouseMove)})}$.plot.plugins.push({init:init,options:options,name:"crosshair",version:"1.0"})})(jQuery);
0 8
\ No newline at end of file
... ...
@@ -0,0 +1,353 @@
1
+/* Flot plugin for plotting error bars.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+Error bars are used to show standard deviation and other statistical
7
+properties in a plot.
8
+
9
+* Created by Rui Pereira  -  rui (dot) pereira (at) gmail (dot) com
10
+
11
+This plugin allows you to plot error-bars over points. Set "errorbars" inside
12
+the points series to the axis name over which there will be error values in
13
+your data array (*even* if you do not intend to plot them later, by setting
14
+"show: null" on xerr/yerr).
15
+
16
+The plugin supports these options:
17
+
18
+	series: {
19
+		points: {
20
+			errorbars: "x" or "y" or "xy",
21
+			xerr: {
22
+				show: null/false or true,
23
+				asymmetric: null/false or true,
24
+				upperCap: null or "-" or function,
25
+				lowerCap: null or "-" or function,
26
+				color: null or color,
27
+				radius: null or number
28
+			},
29
+			yerr: { same options as xerr }
30
+		}
31
+	}
32
+
33
+Each data point array is expected to be of the type:
34
+
35
+	"x"  [ x, y, xerr ]
36
+	"y"  [ x, y, yerr ]
37
+	"xy" [ x, y, xerr, yerr ]
38
+
39
+Where xerr becomes xerr_lower,xerr_upper for the asymmetric error case, and
40
+equivalently for yerr. Eg., a datapoint for the "xy" case with symmetric
41
+error-bars on X and asymmetric on Y would be:
42
+
43
+	[ x, y, xerr, yerr_lower, yerr_upper ]
44
+
45
+By default no end caps are drawn. Setting upperCap and/or lowerCap to "-" will
46
+draw a small cap perpendicular to the error bar. They can also be set to a
47
+user-defined drawing function, with (ctx, x, y, radius) as parameters, as eg.
48
+
49
+	function drawSemiCircle( ctx, x, y, radius ) {
50
+		ctx.beginPath();
51
+		ctx.arc( x, y, radius, 0, Math.PI, false );
52
+		ctx.moveTo( x - radius, y );
53
+		ctx.lineTo( x + radius, y );
54
+		ctx.stroke();
55
+	}
56
+
57
+Color and radius both default to the same ones of the points series if not
58
+set. The independent radius parameter on xerr/yerr is useful for the case when
59
+we may want to add error-bars to a line, without showing the interconnecting
60
+points (with radius: 0), and still showing end caps on the error-bars.
61
+shadowSize and lineWidth are derived as well from the points series.
62
+
63
+*/
64
+
65
+(function ($) {
66
+    var options = {
67
+        series: {
68
+            points: {
69
+                errorbars: null, //should be 'x', 'y' or 'xy'
70
+                xerr: { err: 'x', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null},
71
+                yerr: { err: 'y', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null}
72
+            }
73
+        }
74
+    };
75
+
76
+    function processRawData(plot, series, data, datapoints){
77
+        if (!series.points.errorbars)
78
+            return;
79
+
80
+        // x,y values
81
+        var format = [
82
+            { x: true, number: true, required: true },
83
+            { y: true, number: true, required: true }
84
+        ];
85
+
86
+        var errors = series.points.errorbars;
87
+        // error bars - first X then Y
88
+        if (errors == 'x' || errors == 'xy') {
89
+            // lower / upper error
90
+            if (series.points.xerr.asymmetric) {
91
+                format.push({ x: true, number: true, required: true });
92
+                format.push({ x: true, number: true, required: true });
93
+            } else
94
+                format.push({ x: true, number: true, required: true });
95
+        }
96
+        if (errors == 'y' || errors == 'xy') {
97
+            // lower / upper error
98
+            if (series.points.yerr.asymmetric) {
99
+                format.push({ y: true, number: true, required: true });
100
+                format.push({ y: true, number: true, required: true });
101
+            } else
102
+                format.push({ y: true, number: true, required: true });
103
+        }
104
+        datapoints.format = format;
105
+    }
106
+
107
+    function parseErrors(series, i){
108
+
109
+        var points = series.datapoints.points;
110
+
111
+        // read errors from points array
112
+        var exl = null,
113
+                exu = null,
114
+                eyl = null,
115
+                eyu = null;
116
+        var xerr = series.points.xerr,
117
+                yerr = series.points.yerr;
118
+
119
+        var eb = series.points.errorbars;
120
+        // error bars - first X
121
+        if (eb == 'x' || eb == 'xy') {
122
+            if (xerr.asymmetric) {
123
+                exl = points[i + 2];
124
+                exu = points[i + 3];
125
+                if (eb == 'xy')
126
+                    if (yerr.asymmetric){
127
+                        eyl = points[i + 4];
128
+                        eyu = points[i + 5];
129
+                    } else eyl = points[i + 4];
130
+            } else {
131
+                exl = points[i + 2];
132
+                if (eb == 'xy')
133
+                    if (yerr.asymmetric) {
134
+                        eyl = points[i + 3];
135
+                        eyu = points[i + 4];
136
+                    } else eyl = points[i + 3];
137
+            }
138
+        // only Y
139
+        } else if (eb == 'y')
140
+            if (yerr.asymmetric) {
141
+                eyl = points[i + 2];
142
+                eyu = points[i + 3];
143
+            } else eyl = points[i + 2];
144
+
145
+        // symmetric errors?
146
+        if (exu == null) exu = exl;
147
+        if (eyu == null) eyu = eyl;
148
+
149
+        var errRanges = [exl, exu, eyl, eyu];
150
+        // nullify if not showing
151
+        if (!xerr.show){
152
+            errRanges[0] = null;
153
+            errRanges[1] = null;
154
+        }
155
+        if (!yerr.show){
156
+            errRanges[2] = null;
157
+            errRanges[3] = null;
158
+        }
159
+        return errRanges;
160
+    }
161
+
162
+    function drawSeriesErrors(plot, ctx, s){
163
+
164
+        var points = s.datapoints.points,
165
+                ps = s.datapoints.pointsize,
166
+                ax = [s.xaxis, s.yaxis],
167
+                radius = s.points.radius,
168
+                err = [s.points.xerr, s.points.yerr];
169
+
170
+        //sanity check, in case some inverted axis hack is applied to flot
171
+        var invertX = false;
172
+        if (ax[0].p2c(ax[0].max) < ax[0].p2c(ax[0].min)) {
173
+            invertX = true;
174
+            var tmp = err[0].lowerCap;
175
+            err[0].lowerCap = err[0].upperCap;
176
+            err[0].upperCap = tmp;
177
+        }
178
+
179
+        var invertY = false;
180
+        if (ax[1].p2c(ax[1].min) < ax[1].p2c(ax[1].max)) {
181
+            invertY = true;
182
+            var tmp = err[1].lowerCap;
183
+            err[1].lowerCap = err[1].upperCap;
184
+            err[1].upperCap = tmp;
185
+        }
186
+
187
+        for (var i = 0; i < s.datapoints.points.length; i += ps) {
188
+
189
+            //parse
190
+            var errRanges = parseErrors(s, i);
191
+
192
+            //cycle xerr & yerr
193
+            for (var e = 0; e < err.length; e++){
194
+
195
+                var minmax = [ax[e].min, ax[e].max];
196
+
197
+                //draw this error?
198
+                if (errRanges[e * err.length]){
199
+
200
+                    //data coordinates
201
+                    var x = points[i],
202
+                        y = points[i + 1];
203
+
204
+                    //errorbar ranges
205
+                    var upper = [x, y][e] + errRanges[e * err.length + 1],
206
+                        lower = [x, y][e] - errRanges[e * err.length];
207
+
208
+                    //points outside of the canvas
209
+                    if (err[e].err == 'x')
210
+                        if (y > ax[1].max || y < ax[1].min || upper < ax[0].min || lower > ax[0].max)
211
+                            continue;
212
+                    if (err[e].err == 'y')
213
+                        if (x > ax[0].max || x < ax[0].min || upper < ax[1].min || lower > ax[1].max)
214
+                            continue;
215
+
216
+                    // prevent errorbars getting out of the canvas
217
+                    var drawUpper = true,
218
+                        drawLower = true;
219
+
220
+                    if (upper > minmax[1]) {
221
+                        drawUpper = false;
222
+                        upper = minmax[1];
223
+                    }
224
+                    if (lower < minmax[0]) {
225
+                        drawLower = false;
226
+                        lower = minmax[0];
227
+                    }
228
+
229
+                    //sanity check, in case some inverted axis hack is applied to flot
230
+                    if ((err[e].err == 'x' && invertX) || (err[e].err == 'y' && invertY)) {
231
+                        //swap coordinates
232
+                        var tmp = lower;
233
+                        lower = upper;
234
+                        upper = tmp;
235
+                        tmp = drawLower;
236
+                        drawLower = drawUpper;
237
+                        drawUpper = tmp;
238
+                        tmp = minmax[0];
239
+                        minmax[0] = minmax[1];
240
+                        minmax[1] = tmp;
241
+                    }
242
+
243
+                    // convert to pixels
244
+                    x = ax[0].p2c(x),
245
+                        y = ax[1].p2c(y),
246
+                        upper = ax[e].p2c(upper);
247
+                    lower = ax[e].p2c(lower);
248
+                    minmax[0] = ax[e].p2c(minmax[0]);
249
+                    minmax[1] = ax[e].p2c(minmax[1]);
250
+
251
+                    //same style as points by default
252
+                    var lw = err[e].lineWidth ? err[e].lineWidth : s.points.lineWidth,
253
+                        sw = s.points.shadowSize != null ? s.points.shadowSize : s.shadowSize;
254
+
255
+                    //shadow as for points
256
+                    if (lw > 0 && sw > 0) {
257
+                        var w = sw / 2;
258
+                        ctx.lineWidth = w;
259
+                        ctx.strokeStyle = "rgba(0,0,0,0.1)";
260
+                        drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w + w/2, minmax);
261
+
262
+                        ctx.strokeStyle = "rgba(0,0,0,0.2)";
263
+                        drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w/2, minmax);
264
+                    }
265
+
266
+                    ctx.strokeStyle = err[e].color? err[e].color: s.color;
267
+                    ctx.lineWidth = lw;
268
+                    //draw it
269
+                    drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, 0, minmax);
270
+                }
271
+            }
272
+        }
273
+    }
274
+
275
+    function drawError(ctx,err,x,y,upper,lower,drawUpper,drawLower,radius,offset,minmax){
276
+
277
+        //shadow offset
278
+        y += offset;
279
+        upper += offset;
280
+        lower += offset;
281
+
282
+        // error bar - avoid plotting over circles
283
+        if (err.err == 'x'){
284
+            if (upper > x + radius) drawPath(ctx, [[upper,y],[Math.max(x + radius,minmax[0]),y]]);
285
+            else drawUpper = false;
286
+            if (lower < x - radius) drawPath(ctx, [[Math.min(x - radius,minmax[1]),y],[lower,y]] );
287
+            else drawLower = false;
288
+        }
289
+        else {
290
+            if (upper < y - radius) drawPath(ctx, [[x,upper],[x,Math.min(y - radius,minmax[0])]] );
291
+            else drawUpper = false;
292
+            if (lower > y + radius) drawPath(ctx, [[x,Math.max(y + radius,minmax[1])],[x,lower]] );
293
+            else drawLower = false;
294
+        }
295
+
296
+        //internal radius value in errorbar, allows to plot radius 0 points and still keep proper sized caps
297
+        //this is a way to get errorbars on lines without visible connecting dots
298
+        radius = err.radius != null? err.radius: radius;
299
+
300
+        // upper cap
301
+        if (drawUpper) {
302
+            if (err.upperCap == '-'){
303
+                if (err.err=='x') drawPath(ctx, [[upper,y - radius],[upper,y + radius]] );
304
+                else drawPath(ctx, [[x - radius,upper],[x + radius,upper]] );
305
+            } else if ($.isFunction(err.upperCap)){
306
+                if (err.err=='x') err.upperCap(ctx, upper, y, radius);
307
+                else err.upperCap(ctx, x, upper, radius);
308
+            }
309
+        }
310
+        // lower cap
311
+        if (drawLower) {
312
+            if (err.lowerCap == '-'){
313
+                if (err.err=='x') drawPath(ctx, [[lower,y - radius],[lower,y + radius]] );
314
+                else drawPath(ctx, [[x - radius,lower],[x + radius,lower]] );
315
+            } else if ($.isFunction(err.lowerCap)){
316
+                if (err.err=='x') err.lowerCap(ctx, lower, y, radius);
317
+                else err.lowerCap(ctx, x, lower, radius);
318
+            }
319
+        }
320
+    }
321
+
322
+    function drawPath(ctx, pts){
323
+        ctx.beginPath();
324
+        ctx.moveTo(pts[0][0], pts[0][1]);
325
+        for (var p=1; p < pts.length; p++)
326
+            ctx.lineTo(pts[p][0], pts[p][1]);
327
+        ctx.stroke();
328
+    }
329
+
330
+    function draw(plot, ctx){
331
+        var plotOffset = plot.getPlotOffset();
332
+
333
+        ctx.save();
334
+        ctx.translate(plotOffset.left, plotOffset.top);
335
+        $.each(plot.getData(), function (i, s) {
336
+            if (s.points.errorbars && (s.points.xerr.show || s.points.yerr.show))
337
+                drawSeriesErrors(plot, ctx, s);
338
+        });
339
+        ctx.restore();
340
+    }
341
+
342
+    function init(plot) {
343
+        plot.hooks.processRawData.push(processRawData);
344
+        plot.hooks.draw.push(draw);
345
+    }
346
+
347
+    $.plot.plugins.push({
348
+                init: init,
349
+                options: options,
350
+                name: 'errorbars',
351
+                version: '1.0'
352
+            });
353
+})(jQuery);
... ...
@@ -0,0 +1,7 @@
1
+/* Javascript plotting library for jQuery, version 0.8.3.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+*/
7
+(function($){var options={series:{points:{errorbars:null,xerr:{err:"x",show:null,asymmetric:null,upperCap:null,lowerCap:null,color:null,radius:null},yerr:{err:"y",show:null,asymmetric:null,upperCap:null,lowerCap:null,color:null,radius:null}}}};function processRawData(plot,series,data,datapoints){if(!series.points.errorbars)return;var format=[{x:true,number:true,required:true},{y:true,number:true,required:true}];var errors=series.points.errorbars;if(errors=="x"||errors=="xy"){if(series.points.xerr.asymmetric){format.push({x:true,number:true,required:true});format.push({x:true,number:true,required:true})}else format.push({x:true,number:true,required:true})}if(errors=="y"||errors=="xy"){if(series.points.yerr.asymmetric){format.push({y:true,number:true,required:true});format.push({y:true,number:true,required:true})}else format.push({y:true,number:true,required:true})}datapoints.format=format}function parseErrors(series,i){var points=series.datapoints.points;var exl=null,exu=null,eyl=null,eyu=null;var xerr=series.points.xerr,yerr=series.points.yerr;var eb=series.points.errorbars;if(eb=="x"||eb=="xy"){if(xerr.asymmetric){exl=points[i+2];exu=points[i+3];if(eb=="xy")if(yerr.asymmetric){eyl=points[i+4];eyu=points[i+5]}else eyl=points[i+4]}else{exl=points[i+2];if(eb=="xy")if(yerr.asymmetric){eyl=points[i+3];eyu=points[i+4]}else eyl=points[i+3]}}else if(eb=="y")if(yerr.asymmetric){eyl=points[i+2];eyu=points[i+3]}else eyl=points[i+2];if(exu==null)exu=exl;if(eyu==null)eyu=eyl;var errRanges=[exl,exu,eyl,eyu];if(!xerr.show){errRanges[0]=null;errRanges[1]=null}if(!yerr.show){errRanges[2]=null;errRanges[3]=null}return errRanges}function drawSeriesErrors(plot,ctx,s){var points=s.datapoints.points,ps=s.datapoints.pointsize,ax=[s.xaxis,s.yaxis],radius=s.points.radius,err=[s.points.xerr,s.points.yerr];var invertX=false;if(ax[0].p2c(ax[0].max)<ax[0].p2c(ax[0].min)){invertX=true;var tmp=err[0].lowerCap;err[0].lowerCap=err[0].upperCap;err[0].upperCap=tmp}var invertY=false;if(ax[1].p2c(ax[1].min)<ax[1].p2c(ax[1].max)){invertY=true;var tmp=err[1].lowerCap;err[1].lowerCap=err[1].upperCap;err[1].upperCap=tmp}for(var i=0;i<s.datapoints.points.length;i+=ps){var errRanges=parseErrors(s,i);for(var e=0;e<err.length;e++){var minmax=[ax[e].min,ax[e].max];if(errRanges[e*err.length]){var x=points[i],y=points[i+1];var upper=[x,y][e]+errRanges[e*err.length+1],lower=[x,y][e]-errRanges[e*err.length];if(err[e].err=="x")if(y>ax[1].max||y<ax[1].min||upper<ax[0].min||lower>ax[0].max)continue;if(err[e].err=="y")if(x>ax[0].max||x<ax[0].min||upper<ax[1].min||lower>ax[1].max)continue;var drawUpper=true,drawLower=true;if(upper>minmax[1]){drawUpper=false;upper=minmax[1]}if(lower<minmax[0]){drawLower=false;lower=minmax[0]}if(err[e].err=="x"&&invertX||err[e].err=="y"&&invertY){var tmp=lower;lower=upper;upper=tmp;tmp=drawLower;drawLower=drawUpper;drawUpper=tmp;tmp=minmax[0];minmax[0]=minmax[1];minmax[1]=tmp}x=ax[0].p2c(x),y=ax[1].p2c(y),upper=ax[e].p2c(upper);lower=ax[e].p2c(lower);minmax[0]=ax[e].p2c(minmax[0]);minmax[1]=ax[e].p2c(minmax[1]);var lw=err[e].lineWidth?err[e].lineWidth:s.points.lineWidth,sw=s.points.shadowSize!=null?s.points.shadowSize:s.shadowSize;if(lw>0&&sw>0){var w=sw/2;ctx.lineWidth=w;ctx.strokeStyle="rgba(0,0,0,0.1)";drawError(ctx,err[e],x,y,upper,lower,drawUpper,drawLower,radius,w+w/2,minmax);ctx.strokeStyle="rgba(0,0,0,0.2)";drawError(ctx,err[e],x,y,upper,lower,drawUpper,drawLower,radius,w/2,minmax)}ctx.strokeStyle=err[e].color?err[e].color:s.color;ctx.lineWidth=lw;drawError(ctx,err[e],x,y,upper,lower,drawUpper,drawLower,radius,0,minmax)}}}}function drawError(ctx,err,x,y,upper,lower,drawUpper,drawLower,radius,offset,minmax){y+=offset;upper+=offset;lower+=offset;if(err.err=="x"){if(upper>x+radius)drawPath(ctx,[[upper,y],[Math.max(x+radius,minmax[0]),y]]);else drawUpper=false;if(lower<x-radius)drawPath(ctx,[[Math.min(x-radius,minmax[1]),y],[lower,y]]);else drawLower=false}else{if(upper<y-radius)drawPath(ctx,[[x,upper],[x,Math.min(y-radius,minmax[0])]]);else drawUpper=false;if(lower>y+radius)drawPath(ctx,[[x,Math.max(y+radius,minmax[1])],[x,lower]]);else drawLower=false}radius=err.radius!=null?err.radius:radius;if(drawUpper){if(err.upperCap=="-"){if(err.err=="x")drawPath(ctx,[[upper,y-radius],[upper,y+radius]]);else drawPath(ctx,[[x-radius,upper],[x+radius,upper]])}else if($.isFunction(err.upperCap)){if(err.err=="x")err.upperCap(ctx,upper,y,radius);else err.upperCap(ctx,x,upper,radius)}}if(drawLower){if(err.lowerCap=="-"){if(err.err=="x")drawPath(ctx,[[lower,y-radius],[lower,y+radius]]);else drawPath(ctx,[[x-radius,lower],[x+radius,lower]])}else if($.isFunction(err.lowerCap)){if(err.err=="x")err.lowerCap(ctx,lower,y,radius);else err.lowerCap(ctx,x,lower,radius)}}}function drawPath(ctx,pts){ctx.beginPath();ctx.moveTo(pts[0][0],pts[0][1]);for(var p=1;p<pts.length;p++)ctx.lineTo(pts[p][0],pts[p][1]);ctx.stroke()}function draw(plot,ctx){var plotOffset=plot.getPlotOffset();ctx.save();ctx.translate(plotOffset.left,plotOffset.top);$.each(plot.getData(),function(i,s){if(s.points.errorbars&&(s.points.xerr.show||s.points.yerr.show))drawSeriesErrors(plot,ctx,s)});ctx.restore()}function init(plot){plot.hooks.processRawData.push(processRawData);plot.hooks.draw.push(draw)}$.plot.plugins.push({init:init,options:options,name:"errorbars",version:"1.0"})})(jQuery);
0 8
\ No newline at end of file
... ...
@@ -0,0 +1,226 @@
1
+/* Flot plugin for computing bottoms for filled line and bar charts.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+The case: you've got two series that you want to fill the area between. In Flot
7
+terms, you need to use one as the fill bottom of the other. You can specify the
8
+bottom of each data point as the third coordinate manually, or you can use this
9
+plugin to compute it for you.
10
+
11
+In order to name the other series, you need to give it an id, like this:
12
+
13
+	var dataset = [
14
+		{ data: [ ... ], id: "foo" } ,         // use default bottom
15
+		{ data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom
16
+	];
17
+
18
+	$.plot($("#placeholder"), dataset, { lines: { show: true, fill: true }});
19
+
20
+As a convenience, if the id given is a number that doesn't appear as an id in
21
+the series, it is interpreted as the index in the array instead (so fillBetween:
22
+0 can also mean the first series).
23
+
24
+Internally, the plugin modifies the datapoints in each series. For line series,
25
+extra data points might be inserted through interpolation. Note that at points
26
+where the bottom line is not defined (due to a null point or start/end of line),
27
+the current line will show a gap too. The algorithm comes from the
28
+jquery.flot.stack.js plugin, possibly some code could be shared.
29
+
30
+*/
31
+
32
+(function ( $ ) {
33
+
34
+	var options = {
35
+		series: {
36
+			fillBetween: null	// or number
37
+		}
38
+	};
39
+
40
+	function init( plot ) {
41
+
42
+		function findBottomSeries( s, allseries ) {
43
+
44
+			var i;
45
+
46
+			for ( i = 0; i < allseries.length; ++i ) {
47
+				if ( allseries[ i ].id === s.fillBetween ) {
48
+					return allseries[ i ];
49
+				}
50
+			}
51
+
52
+			if ( typeof s.fillBetween === "number" ) {
53
+				if ( s.fillBetween < 0 || s.fillBetween >= allseries.length ) {
54
+					return null;
55
+				}
56
+				return allseries[ s.fillBetween ];
57
+			}
58
+
59
+			return null;
60
+		}
61
+
62
+		function computeFillBottoms( plot, s, datapoints ) {
63
+
64
+			if ( s.fillBetween == null ) {
65
+				return;
66
+			}
67
+
68
+			var other = findBottomSeries( s, plot.getData() );
69
+
70
+			if ( !other ) {
71
+				return;
72
+			}
73
+
74
+			var ps = datapoints.pointsize,
75
+				points = datapoints.points,
76
+				otherps = other.datapoints.pointsize,
77
+				otherpoints = other.datapoints.points,
78
+				newpoints = [],
79
+				px, py, intery, qx, qy, bottom,
80
+				withlines = s.lines.show,
81
+				withbottom = ps > 2 && datapoints.format[2].y,
82
+				withsteps = withlines && s.lines.steps,
83
+				fromgap = true,
84
+				i = 0,
85
+				j = 0,
86
+				l, m;
87
+
88
+			while ( true ) {
89
+
90
+				if ( i >= points.length ) {
91
+					break;
92
+				}
93
+
94
+				l = newpoints.length;
95
+
96
+				if ( points[ i ] == null ) {
97
+
98
+					// copy gaps
99
+
100
+					for ( m = 0; m < ps; ++m ) {
101
+						newpoints.push( points[ i + m ] );
102
+					}
103
+
104
+					i += ps;
105
+
106
+				} else if ( j >= otherpoints.length ) {
107
+
108
+					// for lines, we can't use the rest of the points
109
+
110
+					if ( !withlines ) {
111
+						for ( m = 0; m < ps; ++m ) {
112
+							newpoints.push( points[ i + m ] );
113
+						}
114
+					}
115
+
116
+					i += ps;
117
+
118
+				} else if ( otherpoints[ j ] == null ) {
119
+
120
+					// oops, got a gap
121
+
122
+					for ( m = 0; m < ps; ++m ) {
123
+						newpoints.push( null );
124
+					}
125
+
126
+					fromgap = true;
127
+					j += otherps;
128
+
129
+				} else {
130
+
131
+					// cases where we actually got two points
132
+
133
+					px = points[ i ];
134
+					py = points[ i + 1 ];
135
+					qx = otherpoints[ j ];
136
+					qy = otherpoints[ j + 1 ];
137
+					bottom = 0;
138
+
139
+					if ( px === qx ) {
140
+
141
+						for ( m = 0; m < ps; ++m ) {
142
+							newpoints.push( points[ i + m ] );
143
+						}
144
+
145
+						//newpoints[ l + 1 ] += qy;
146
+						bottom = qy;
147
+
148
+						i += ps;
149
+						j += otherps;
150
+
151
+					} else if ( px > qx ) {
152
+
153
+						// we got past point below, might need to
154
+						// insert interpolated extra point
155
+
156
+						if ( withlines && i > 0 && points[ i - ps ] != null ) {
157
+							intery = py + ( points[ i - ps + 1 ] - py ) * ( qx - px ) / ( points[ i - ps ] - px );
158
+							newpoints.push( qx );
159
+							newpoints.push( intery );
160
+							for ( m = 2; m < ps; ++m ) {
161
+								newpoints.push( points[ i + m ] );
162
+							}
163
+							bottom = qy;
164
+						}
165
+
166
+						j += otherps;
167
+
168
+					} else { // px < qx
169
+
170
+						// if we come from a gap, we just skip this point
171
+
172
+						if ( fromgap && withlines ) {
173
+							i += ps;
174
+							continue;
175
+						}
176
+
177
+						for ( m = 0; m < ps; ++m ) {
178
+							newpoints.push( points[ i + m ] );
179
+						}
180
+
181
+						// we might be able to interpolate a point below,
182
+						// this can give us a better y
183
+
184
+						if ( withlines && j > 0 && otherpoints[ j - otherps ] != null ) {
185
+							bottom = qy + ( otherpoints[ j - otherps + 1 ] - qy ) * ( px - qx ) / ( otherpoints[ j - otherps ] - qx );
186
+						}
187
+
188
+						//newpoints[l + 1] += bottom;
189
+
190
+						i += ps;
191
+					}
192
+
193
+					fromgap = false;
194
+
195
+					if ( l !== newpoints.length && withbottom ) {
196
+						newpoints[ l + 2 ] = bottom;
197
+					}
198
+				}
199
+
200
+				// maintain the line steps invariant
201
+
202
+				if ( withsteps && l !== newpoints.length && l > 0 &&
203
+					newpoints[ l ] !== null &&
204
+					newpoints[ l ] !== newpoints[ l - ps ] &&
205
+					newpoints[ l + 1 ] !== newpoints[ l - ps + 1 ] ) {
206
+					for (m = 0; m < ps; ++m) {
207
+						newpoints[ l + ps + m ] = newpoints[ l + m ];
208
+					}
209
+					newpoints[ l + 1 ] = newpoints[ l - ps + 1 ];
210
+				}
211
+			}
212
+
213
+			datapoints.points = newpoints;
214
+		}
215
+
216
+		plot.hooks.processDatapoints.push( computeFillBottoms );
217
+	}
218
+
219
+	$.plot.plugins.push({
220
+		init: init,
221
+		options: options,
222
+		name: "fillbetween",
223
+		version: "1.0"
224
+	});
225
+
226
+})(jQuery);
... ...
@@ -0,0 +1,7 @@
1
+/* Javascript plotting library for jQuery, version 0.8.3.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+*/
7
+(function($){var options={series:{fillBetween:null}};function init(plot){function findBottomSeries(s,allseries){var i;for(i=0;i<allseries.length;++i){if(allseries[i].id===s.fillBetween){return allseries[i]}}if(typeof s.fillBetween==="number"){if(s.fillBetween<0||s.fillBetween>=allseries.length){return null}return allseries[s.fillBetween]}return null}function computeFillBottoms(plot,s,datapoints){if(s.fillBetween==null){return}var other=findBottomSeries(s,plot.getData());if(!other){return}var ps=datapoints.pointsize,points=datapoints.points,otherps=other.datapoints.pointsize,otherpoints=other.datapoints.points,newpoints=[],px,py,intery,qx,qy,bottom,withlines=s.lines.show,withbottom=ps>2&&datapoints.format[2].y,withsteps=withlines&&s.lines.steps,fromgap=true,i=0,j=0,l,m;while(true){if(i>=points.length){break}l=newpoints.length;if(points[i]==null){for(m=0;m<ps;++m){newpoints.push(points[i+m])}i+=ps}else if(j>=otherpoints.length){if(!withlines){for(m=0;m<ps;++m){newpoints.push(points[i+m])}}i+=ps}else if(otherpoints[j]==null){for(m=0;m<ps;++m){newpoints.push(null)}fromgap=true;j+=otherps}else{px=points[i];py=points[i+1];qx=otherpoints[j];qy=otherpoints[j+1];bottom=0;if(px===qx){for(m=0;m<ps;++m){newpoints.push(points[i+m])}bottom=qy;i+=ps;j+=otherps}else if(px>qx){if(withlines&&i>0&&points[i-ps]!=null){intery=py+(points[i-ps+1]-py)*(qx-px)/(points[i-ps]-px);newpoints.push(qx);newpoints.push(intery);for(m=2;m<ps;++m){newpoints.push(points[i+m])}bottom=qy}j+=otherps}else{if(fromgap&&withlines){i+=ps;continue}for(m=0;m<ps;++m){newpoints.push(points[i+m])}if(withlines&&j>0&&otherpoints[j-otherps]!=null){bottom=qy+(otherpoints[j-otherps+1]-qy)*(px-qx)/(otherpoints[j-otherps]-qx)}i+=ps}fromgap=false;if(l!==newpoints.length&&withbottom){newpoints[l+2]=bottom}}if(withsteps&&l!==newpoints.length&&l>0&&newpoints[l]!==null&&newpoints[l]!==newpoints[l-ps]&&newpoints[l+1]!==newpoints[l-ps+1]){for(m=0;m<ps;++m){newpoints[l+ps+m]=newpoints[l+m]}newpoints[l+1]=newpoints[l-ps+1]}}datapoints.points=newpoints}plot.hooks.processDatapoints.push(computeFillBottoms)}$.plot.plugins.push({init:init,options:options,name:"fillbetween",version:"1.0"})})(jQuery);
0 8
\ No newline at end of file
... ...
@@ -0,0 +1,241 @@
1
+/* Flot plugin for plotting images.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+The data syntax is [ [ image, x1, y1, x2, y2 ], ... ] where (x1, y1) and
7
+(x2, y2) are where you intend the two opposite corners of the image to end up
8
+in the plot. Image must be a fully loaded Javascript image (you can make one
9
+with new Image()). If the image is not complete, it's skipped when plotting.
10
+
11
+There are two helpers included for retrieving images. The easiest work the way
12
+that you put in URLs instead of images in the data, like this:
13
+
14
+	[ "myimage.png", 0, 0, 10, 10 ]
15
+
16
+Then call $.plot.image.loadData( data, options, callback ) where data and
17
+options are the same as you pass in to $.plot. This loads the images, replaces
18
+the URLs in the data with the corresponding images and calls "callback" when
19
+all images are loaded (or failed loading). In the callback, you can then call
20
+$.plot with the data set. See the included example.
21
+
22
+A more low-level helper, $.plot.image.load(urls, callback) is also included.
23
+Given a list of URLs, it calls callback with an object mapping from URL to
24
+Image object when all images are loaded or have failed loading.
25
+
26
+The plugin supports these options:
27
+
28
+	series: {
29
+		images: {
30
+			show: boolean
31
+			anchor: "corner" or "center"
32
+			alpha: [ 0, 1 ]
33
+		}
34
+	}
35
+
36
+They can be specified for a specific series:
37
+
38
+	$.plot( $("#placeholder"), [{
39
+		data: [ ... ],
40
+		images: { ... }
41
+	])
42
+
43
+Note that because the data format is different from usual data points, you
44
+can't use images with anything else in a specific data series.
45
+
46
+Setting "anchor" to "center" causes the pixels in the image to be anchored at
47
+the corner pixel centers inside of at the pixel corners, effectively letting
48
+half a pixel stick out to each side in the plot.
49
+
50
+A possible future direction could be support for tiling for large images (like
51
+Google Maps).
52
+
53
+*/
54
+
55
+(function ($) {
56
+    var options = {
57
+        series: {
58
+            images: {
59
+                show: false,
60
+                alpha: 1,
61
+                anchor: "corner" // or "center"
62
+            }
63
+        }
64
+    };
65
+
66
+    $.plot.image = {};
67
+
68
+    $.plot.image.loadDataImages = function (series, options, callback) {
69
+        var urls = [], points = [];
70
+
71
+        var defaultShow = options.series.images.show;
72
+        
73
+        $.each(series, function (i, s) {
74
+            if (!(defaultShow || s.images.show))
75
+                return;
76
+            
77
+            if (s.data)
78
+                s = s.data;
79
+
80
+            $.each(s, function (i, p) {
81
+                if (typeof p[0] == "string") {
82
+                    urls.push(p[0]);
83
+                    points.push(p);
84
+                }
85
+            });
86
+        });
87
+
88
+        $.plot.image.load(urls, function (loadedImages) {
89
+            $.each(points, function (i, p) {
90
+                var url = p[0];
91
+                if (loadedImages[url])
92
+                    p[0] = loadedImages[url];
93
+            });
94
+
95
+            callback();
96
+        });
97
+    }
98
+    
99
+    $.plot.image.load = function (urls, callback) {
100
+        var missing = urls.length, loaded = {};
101
+        if (missing == 0)
102
+            callback({});
103
+
104
+        $.each(urls, function (i, url) {
105
+            var handler = function () {
106
+                --missing;
107
+                
108
+                loaded[url] = this;
109
+                
110
+                if (missing == 0)
111
+                    callback(loaded);
112
+            };
113
+
114
+            $('<img />').load(handler).error(handler).attr('src', url);
115
+        });
116
+    };
117
+    
118
+    function drawSeries(plot, ctx, series) {
119
+        var plotOffset = plot.getPlotOffset();
120
+        
121
+        if (!series.images || !series.images.show)
122
+            return;
123
+        
124
+        var points = series.datapoints.points,
125
+            ps = series.datapoints.pointsize;
126
+        
127
+        for (var i = 0; i < points.length; i += ps) {
128
+            var img = points[i],
129
+                x1 = points[i + 1], y1 = points[i + 2],
130
+                x2 = points[i + 3], y2 = points[i + 4],
131
+                xaxis = series.xaxis, yaxis = series.yaxis,
132
+                tmp;
133
+
134
+            // actually we should check img.complete, but it
135
+            // appears to be a somewhat unreliable indicator in
136
+            // IE6 (false even after load event)
137
+            if (!img || img.width <= 0 || img.height <= 0)
138
+                continue;
139
+
140
+            if (x1 > x2) {
141
+                tmp = x2;
142
+                x2 = x1;
143
+                x1 = tmp;
144
+            }
145
+            if (y1 > y2) {
146
+                tmp = y2;
147
+                y2 = y1;
148
+                y1 = tmp;
149
+            }
150
+            
151
+            // if the anchor is at the center of the pixel, expand the 
152
+            // image by 1/2 pixel in each direction
153
+            if (series.images.anchor == "center") {
154
+                tmp = 0.5 * (x2-x1) / (img.width - 1);
155
+                x1 -= tmp;
156
+                x2 += tmp;
157
+                tmp = 0.5 * (y2-y1) / (img.height - 1);
158
+                y1 -= tmp;
159
+                y2 += tmp;
160
+            }
161
+            
162
+            // clip
163
+            if (x1 == x2 || y1 == y2 ||
164
+                x1 >= xaxis.max || x2 <= xaxis.min ||
165
+                y1 >= yaxis.max || y2 <= yaxis.min)
166
+                continue;
167
+
168
+            var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height;
169
+            if (x1 < xaxis.min) {
170
+                sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1);
171
+                x1 = xaxis.min;
172
+            }
173
+
174
+            if (x2 > xaxis.max) {
175
+                sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1);
176
+                x2 = xaxis.max;
177
+            }
178
+
179
+            if (y1 < yaxis.min) {
180
+                sy2 += (sy1 - sy2) * (yaxis.min - y1) / (y2 - y1);
181
+                y1 = yaxis.min;
182
+            }
183
+
184
+            if (y2 > yaxis.max) {
185
+                sy1 += (sy1 - sy2) * (yaxis.max - y2) / (y2 - y1);
186
+                y2 = yaxis.max;
187
+            }
188
+            
189
+            x1 = xaxis.p2c(x1);
190
+            x2 = xaxis.p2c(x2);
191
+            y1 = yaxis.p2c(y1);
192
+            y2 = yaxis.p2c(y2);
193
+            
194
+            // the transformation may have swapped us
195
+            if (x1 > x2) {
196
+                tmp = x2;
197
+                x2 = x1;
198
+                x1 = tmp;
199
+            }
200
+            if (y1 > y2) {
201
+                tmp = y2;
202
+                y2 = y1;
203
+                y1 = tmp;
204
+            }
205
+
206
+            tmp = ctx.globalAlpha;
207
+            ctx.globalAlpha *= series.images.alpha;
208
+            ctx.drawImage(img,
209
+                          sx1, sy1, sx2 - sx1, sy2 - sy1,
210
+                          x1 + plotOffset.left, y1 + plotOffset.top,
211
+                          x2 - x1, y2 - y1);
212
+            ctx.globalAlpha = tmp;
213
+        }
214
+    }
215
+
216
+    function processRawData(plot, series, data, datapoints) {
217
+        if (!series.images.show)
218
+            return;
219
+
220
+        // format is Image, x1, y1, x2, y2 (opposite corners)
221
+        datapoints.format = [
222
+            { required: true },
223
+            { x: true, number: true, required: true },
224
+            { y: true, number: true, required: true },
225
+            { x: true, number: true, required: true },
226
+            { y: true, number: true, required: true }
227
+        ];
228
+    }
229
+    
230
+    function init(plot) {
231
+        plot.hooks.processRawData.push(processRawData);
232
+        plot.hooks.drawSeries.push(drawSeries);
233
+    }
234
+    
235
+    $.plot.plugins.push({
236
+        init: init,
237
+        options: options,
238
+        name: 'image',
239
+        version: '1.1'
240
+    });
241
+})(jQuery);
... ...
@@ -0,0 +1,7 @@
1
+/* Javascript plotting library for jQuery, version 0.8.3.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+*/
7
+(function($){var options={series:{images:{show:false,alpha:1,anchor:"corner"}}};$.plot.image={};$.plot.image.loadDataImages=function(series,options,callback){var urls=[],points=[];var defaultShow=options.series.images.show;$.each(series,function(i,s){if(!(defaultShow||s.images.show))return;if(s.data)s=s.data;$.each(s,function(i,p){if(typeof p[0]=="string"){urls.push(p[0]);points.push(p)}})});$.plot.image.load(urls,function(loadedImages){$.each(points,function(i,p){var url=p[0];if(loadedImages[url])p[0]=loadedImages[url]});callback()})};$.plot.image.load=function(urls,callback){var missing=urls.length,loaded={};if(missing==0)callback({});$.each(urls,function(i,url){var handler=function(){--missing;loaded[url]=this;if(missing==0)callback(loaded)};$("<img />").load(handler).error(handler).attr("src",url)})};function drawSeries(plot,ctx,series){var plotOffset=plot.getPlotOffset();if(!series.images||!series.images.show)return;var points=series.datapoints.points,ps=series.datapoints.pointsize;for(var i=0;i<points.length;i+=ps){var img=points[i],x1=points[i+1],y1=points[i+2],x2=points[i+3],y2=points[i+4],xaxis=series.xaxis,yaxis=series.yaxis,tmp;if(!img||img.width<=0||img.height<=0)continue;if(x1>x2){tmp=x2;x2=x1;x1=tmp}if(y1>y2){tmp=y2;y2=y1;y1=tmp}if(series.images.anchor=="center"){tmp=.5*(x2-x1)/(img.width-1);x1-=tmp;x2+=tmp;tmp=.5*(y2-y1)/(img.height-1);y1-=tmp;y2+=tmp}if(x1==x2||y1==y2||x1>=xaxis.max||x2<=xaxis.min||y1>=yaxis.max||y2<=yaxis.min)continue;var sx1=0,sy1=0,sx2=img.width,sy2=img.height;if(x1<xaxis.min){sx1+=(sx2-sx1)*(xaxis.min-x1)/(x2-x1);x1=xaxis.min}if(x2>xaxis.max){sx2+=(sx2-sx1)*(xaxis.max-x2)/(x2-x1);x2=xaxis.max}if(y1<yaxis.min){sy2+=(sy1-sy2)*(yaxis.min-y1)/(y2-y1);y1=yaxis.min}if(y2>yaxis.max){sy1+=(sy1-sy2)*(yaxis.max-y2)/(y2-y1);y2=yaxis.max}x1=xaxis.p2c(x1);x2=xaxis.p2c(x2);y1=yaxis.p2c(y1);y2=yaxis.p2c(y2);if(x1>x2){tmp=x2;x2=x1;x1=tmp}if(y1>y2){tmp=y2;y2=y1;y1=tmp}tmp=ctx.globalAlpha;ctx.globalAlpha*=series.images.alpha;ctx.drawImage(img,sx1,sy1,sx2-sx1,sy2-sy1,x1+plotOffset.left,y1+plotOffset.top,x2-x1,y2-y1);ctx.globalAlpha=tmp}}function processRawData(plot,series,data,datapoints){if(!series.images.show)return;datapoints.format=[{required:true},{x:true,number:true,required:true},{y:true,number:true,required:true},{x:true,number:true,required:true},{y:true,number:true,required:true}]}function init(plot){plot.hooks.processRawData.push(processRawData);plot.hooks.drawSeries.push(drawSeries)}$.plot.plugins.push({init:init,options:options,name:"image",version:"1.1"})})(jQuery);
0 8
\ No newline at end of file
... ...
@@ -0,0 +1,3168 @@
1
+/* Javascript plotting library for jQuery, version 0.8.3.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+*/
7
+
8
+// first an inline dependency, jquery.colorhelpers.js, we inline it here
9
+// for convenience
10
+
11
+/* Plugin for jQuery for working with colors.
12
+ *
13
+ * Version 1.1.
14
+ *
15
+ * Inspiration from jQuery color animation plugin by John Resig.
16
+ *
17
+ * Released under the MIT license by Ole Laursen, October 2009.
18
+ *
19
+ * Examples:
20
+ *
21
+ *   $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString()
22
+ *   var c = $.color.extract($("#mydiv"), 'background-color');
23
+ *   console.log(c.r, c.g, c.b, c.a);
24
+ *   $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)"
25
+ *
26
+ * Note that .scale() and .add() return the same modified object
27
+ * instead of making a new one.
28
+ *
29
+ * V. 1.1: Fix error handling so e.g. parsing an empty string does
30
+ * produce a color rather than just crashing.
31
+ */
32
+(function($){$.color={};$.color.make=function(r,g,b,a){var o={};o.r=r||0;o.g=g||0;o.b=b||0;o.a=a!=null?a:1;o.add=function(c,d){for(var i=0;i<c.length;++i)o[c.charAt(i)]+=d;return o.normalize()};o.scale=function(c,f){for(var i=0;i<c.length;++i)o[c.charAt(i)]*=f;return o.normalize()};o.toString=function(){if(o.a>=1){return"rgb("+[o.r,o.g,o.b].join(",")+")"}else{return"rgba("+[o.r,o.g,o.b,o.a].join(",")+")"}};o.normalize=function(){function clamp(min,value,max){return value<min?min:value>max?max:value}o.r=clamp(0,parseInt(o.r),255);o.g=clamp(0,parseInt(o.g),255);o.b=clamp(0,parseInt(o.b),255);o.a=clamp(0,o.a,1);return o};o.clone=function(){return $.color.make(o.r,o.b,o.g,o.a)};return o.normalize()};$.color.extract=function(elem,css){var c;do{c=elem.css(css).toLowerCase();if(c!=""&&c!="transparent")break;elem=elem.parent()}while(elem.length&&!$.nodeName(elem.get(0),"body"));if(c=="rgba(0, 0, 0, 0)")c="transparent";return $.color.parse(c)};$.color.parse=function(str){var res,m=$.color.make;if(res=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10));if(res=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10),parseFloat(res[4]));if(res=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55);if(res=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55,parseFloat(res[4]));if(res=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))return m(parseInt(res[1],16),parseInt(res[2],16),parseInt(res[3],16));if(res=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))return m(parseInt(res[1]+res[1],16),parseInt(res[2]+res[2],16),parseInt(res[3]+res[3],16));var name=$.trim(str).toLowerCase();if(name=="transparent")return m(255,255,255,0);else{res=lookupColors[name]||[0,0,0];return m(res[0],res[1],res[2])}};var lookupColors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,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,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]}})(jQuery);
33
+
34
+// the actual Flot code
35
+(function($) {
36
+
37
+	// Cache the prototype hasOwnProperty for faster access
38
+
39
+	var hasOwnProperty = Object.prototype.hasOwnProperty;
40
+
41
+    // A shim to provide 'detach' to jQuery versions prior to 1.4.  Using a DOM
42
+    // operation produces the same effect as detach, i.e. removing the element
43
+    // without touching its jQuery data.
44
+
45
+    // Do not merge this into Flot 0.9, since it requires jQuery 1.4.4+.
46
+
47
+    if (!$.fn.detach) {
48
+        $.fn.detach = function() {
49
+            return this.each(function() {
50
+                if (this.parentNode) {
51
+                    this.parentNode.removeChild( this );
52
+                }
53
+            });
54
+        };
55
+    }
56
+
57
+	///////////////////////////////////////////////////////////////////////////
58
+	// The Canvas object is a wrapper around an HTML5 <canvas> tag.
59
+	//
60
+	// @constructor
61
+	// @param {string} cls List of classes to apply to the canvas.
62
+	// @param {element} container Element onto which to append the canvas.
63
+	//
64
+	// Requiring a container is a little iffy, but unfortunately canvas
65
+	// operations don't work unless the canvas is attached to the DOM.
66
+
67
+	function Canvas(cls, container) {
68
+
69
+		var element = container.children("." + cls)[0];
70
+
71
+		if (element == null) {
72
+
73
+			element = document.createElement("canvas");
74
+			element.className = cls;
75
+
76
+			$(element).css({ direction: "ltr", position: "absolute", left: 0, top: 0 })
77
+				.appendTo(container);
78
+
79
+			// If HTML5 Canvas isn't available, fall back to [Ex|Flash]canvas
80
+
81
+			if (!element.getContext) {
82
+				if (window.G_vmlCanvasManager) {
83
+					element = window.G_vmlCanvasManager.initElement(element);
84
+				} else {
85
+					throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode.");
86
+				}
87
+			}
88
+		}
89
+
90
+		this.element = element;
91
+
92
+		var context = this.context = element.getContext("2d");
93
+
94
+		// Determine the screen's ratio of physical to device-independent
95
+		// pixels.  This is the ratio between the canvas width that the browser
96
+		// advertises and the number of pixels actually present in that space.
97
+
98
+		// The iPhone 4, for example, has a device-independent width of 320px,
99
+		// but its screen is actually 640px wide.  It therefore has a pixel
100
+		// ratio of 2, while most normal devices have a ratio of 1.
101
+
102
+		var devicePixelRatio = window.devicePixelRatio || 1,
103
+			backingStoreRatio =
104
+				context.webkitBackingStorePixelRatio ||
105
+				context.mozBackingStorePixelRatio ||
106
+				context.msBackingStorePixelRatio ||
107
+				context.oBackingStorePixelRatio ||
108
+				context.backingStorePixelRatio || 1;
109
+
110
+		this.pixelRatio = devicePixelRatio / backingStoreRatio;
111
+
112
+		// Size the canvas to match the internal dimensions of its container
113
+
114
+		this.resize(container.width(), container.height());
115
+
116
+		// Collection of HTML div layers for text overlaid onto the canvas
117
+
118
+		this.textContainer = null;
119
+		this.text = {};
120
+
121
+		// Cache of text fragments and metrics, so we can avoid expensively
122
+		// re-calculating them when the plot is re-rendered in a loop.
123
+
124
+		this._textCache = {};
125
+	}
126
+
127
+	// Resizes the canvas to the given dimensions.
128
+	//
129
+	// @param {number} width New width of the canvas, in pixels.
130
+	// @param {number} width New height of the canvas, in pixels.
131
+
132
+	Canvas.prototype.resize = function(width, height) {
133
+
134
+		if (width <= 0 || height <= 0) {
135
+			throw new Error("Invalid dimensions for plot, width = " + width + ", height = " + height);
136
+		}
137
+
138
+		var element = this.element,
139
+			context = this.context,
140
+			pixelRatio = this.pixelRatio;
141
+
142
+		// Resize the canvas, increasing its density based on the display's
143
+		// pixel ratio; basically giving it more pixels without increasing the
144
+		// size of its element, to take advantage of the fact that retina
145
+		// displays have that many more pixels in the same advertised space.
146
+
147
+		// Resizing should reset the state (excanvas seems to be buggy though)
148
+
149
+		if (this.width != width) {
150
+			element.width = width * pixelRatio;
151
+			element.style.width = width + "px";
152
+			this.width = width;
153
+		}
154
+
155
+		if (this.height != height) {
156
+			element.height = height * pixelRatio;
157
+			element.style.height = height + "px";
158
+			this.height = height;
159
+		}
160
+
161
+		// Save the context, so we can reset in case we get replotted.  The
162
+		// restore ensure that we're really back at the initial state, and
163
+		// should be safe even if we haven't saved the initial state yet.
164
+
165
+		context.restore();
166
+		context.save();
167
+
168
+		// Scale the coordinate space to match the display density; so even though we
169
+		// may have twice as many pixels, we still want lines and other drawing to
170
+		// appear at the same size; the extra pixels will just make them crisper.
171
+
172
+		context.scale(pixelRatio, pixelRatio);
173
+	};
174
+
175
+	// Clears the entire canvas area, not including any overlaid HTML text
176
+
177
+	Canvas.prototype.clear = function() {
178
+		this.context.clearRect(0, 0, this.width, this.height);
179
+	};
180
+
181
+	// Finishes rendering the canvas, including managing the text overlay.
182
+
183
+	Canvas.prototype.render = function() {
184
+
185
+		var cache = this._textCache;
186
+
187
+		// For each text layer, add elements marked as active that haven't
188
+		// already been rendered, and remove those that are no longer active.
189
+
190
+		for (var layerKey in cache) {
191
+			if (hasOwnProperty.call(cache, layerKey)) {
192
+
193
+				var layer = this.getTextLayer(layerKey),
194
+					layerCache = cache[layerKey];
195
+
196
+				layer.hide();
197
+
198
+				for (var styleKey in layerCache) {
199
+					if (hasOwnProperty.call(layerCache, styleKey)) {
200
+						var styleCache = layerCache[styleKey];
201
+						for (var key in styleCache) {
202
+							if (hasOwnProperty.call(styleCache, key)) {
203
+
204
+								var positions = styleCache[key].positions;
205
+
206
+								for (var i = 0, position; position = positions[i]; i++) {
207
+									if (position.active) {
208
+										if (!position.rendered) {
209
+											layer.append(position.element);
210
+											position.rendered = true;
211
+										}
212
+									} else {
213
+										positions.splice(i--, 1);
214
+										if (position.rendered) {
215
+											position.element.detach();
216
+										}
217
+									}
218
+								}
219
+
220
+								if (positions.length == 0) {
221
+									delete styleCache[key];
222
+								}
223
+							}
224
+						}
225
+					}
226
+				}
227
+
228
+				layer.show();
229
+			}
230
+		}
231
+	};
232
+
233
+	// Creates (if necessary) and returns the text overlay container.
234
+	//
235
+	// @param {string} classes String of space-separated CSS classes used to
236
+	//     uniquely identify the text layer.
237
+	// @return {object} The jQuery-wrapped text-layer div.
238
+
239
+	Canvas.prototype.getTextLayer = function(classes) {
240
+
241
+		var layer = this.text[classes];
242
+
243
+		// Create the text layer if it doesn't exist
244
+
245
+		if (layer == null) {
246
+
247
+			// Create the text layer container, if it doesn't exist
248
+
249
+			if (this.textContainer == null) {
250
+				this.textContainer = $("<div class='flot-text'></div>")
251
+					.css({
252
+						position: "absolute",
253
+						top: 0,
254
+						left: 0,
255
+						bottom: 0,
256
+						right: 0,
257
+						'font-size': "smaller",
258
+						color: "#545454"
259
+					})
260
+					.insertAfter(this.element);
261
+			}
262
+
263
+			layer = this.text[classes] = $("<div></div>")
264
+				.addClass(classes)
265
+				.css({
266
+					position: "absolute",
267
+					top: 0,
268
+					left: 0,
269
+					bottom: 0,
270
+					right: 0
271
+				})
272
+				.appendTo(this.textContainer);
273
+		}
274
+
275
+		return layer;
276
+	};
277
+
278
+	// Creates (if necessary) and returns a text info object.
279
+	//
280
+	// The object looks like this:
281
+	//
282
+	// {
283
+	//     width: Width of the text's wrapper div.
284
+	//     height: Height of the text's wrapper div.
285
+	//     element: The jQuery-wrapped HTML div containing the text.
286
+	//     positions: Array of positions at which this text is drawn.
287
+	// }
288
+	//
289
+	// The positions array contains objects that look like this:
290
+	//
291
+	// {
292
+	//     active: Flag indicating whether the text should be visible.
293
+	//     rendered: Flag indicating whether the text is currently visible.
294
+	//     element: The jQuery-wrapped HTML div containing the text.
295
+	//     x: X coordinate at which to draw the text.
296
+	//     y: Y coordinate at which to draw the text.
297
+	// }
298
+	//
299
+	// Each position after the first receives a clone of the original element.
300
+	//
301
+	// The idea is that that the width, height, and general 'identity' of the
302
+	// text is constant no matter where it is placed; the placements are a
303
+	// secondary property.
304
+	//
305
+	// Canvas maintains a cache of recently-used text info objects; getTextInfo
306
+	// either returns the cached element or creates a new entry.
307
+	//
308
+	// @param {string} layer A string of space-separated CSS classes uniquely
309
+	//     identifying the layer containing this text.
310
+	// @param {string} text Text string to retrieve info for.
311
+	// @param {(string|object)=} font Either a string of space-separated CSS
312
+	//     classes or a font-spec object, defining the text's font and style.
313
+	// @param {number=} angle Angle at which to rotate the text, in degrees.
314
+	//     Angle is currently unused, it will be implemented in the future.
315
+	// @param {number=} width Maximum width of the text before it wraps.
316
+	// @return {object} a text info object.
317
+
318
+	Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) {
319
+
320
+		var textStyle, layerCache, styleCache, info;
321
+
322
+		// Cast the value to a string, in case we were given a number or such
323
+
324
+		text = "" + text;
325
+
326
+		// If the font is a font-spec object, generate a CSS font definition
327
+
328
+		if (typeof font === "object") {
329
+			textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px/" + font.lineHeight + "px " + font.family;
330
+		} else {
331
+			textStyle = font;
332
+		}
333
+
334
+		// Retrieve (or create) the cache for the text's layer and styles
335
+
336
+		layerCache = this._textCache[layer];
337
+
338
+		if (layerCache == null) {
339
+			layerCache = this._textCache[layer] = {};
340
+		}
341
+
342
+		styleCache = layerCache[textStyle];
343
+
344
+		if (styleCache == null) {
345
+			styleCache = layerCache[textStyle] = {};
346
+		}
347
+
348
+		info = styleCache[text];
349
+
350
+		// If we can't find a matching element in our cache, create a new one
351
+
352
+		if (info == null) {
353
+
354
+			var element = $("<div></div>").html(text)
355
+				.css({
356
+					position: "absolute",
357
+					'max-width': width,
358
+					top: -9999
359
+				})
360
+				.appendTo(this.getTextLayer(layer));
361
+
362
+			if (typeof font === "object") {
363
+				element.css({
364
+					font: textStyle,
365
+					color: font.color
366
+				});
367
+			} else if (typeof font === "string") {
368
+				element.addClass(font);
369
+			}
370
+
371
+			info = styleCache[text] = {
372
+				width: element.outerWidth(true),
373
+				height: element.outerHeight(true),
374
+				element: element,
375
+				positions: []
376
+			};
377
+
378
+			element.detach();
379
+		}
380
+
381
+		return info;
382
+	};
383
+
384
+	// Adds a text string to the canvas text overlay.
385
+	//
386
+	// The text isn't drawn immediately; it is marked as rendering, which will
387
+	// result in its addition to the canvas on the next render pass.
388
+	//
389
+	// @param {string} layer A string of space-separated CSS classes uniquely
390
+	//     identifying the layer containing this text.
391
+	// @param {number} x X coordinate at which to draw the text.
392
+	// @param {number} y Y coordinate at which to draw the text.
393
+	// @param {string} text Text string to draw.
394
+	// @param {(string|object)=} font Either a string of space-separated CSS
395
+	//     classes or a font-spec object, defining the text's font and style.
396
+	// @param {number=} angle Angle at which to rotate the text, in degrees.
397
+	//     Angle is currently unused, it will be implemented in the future.
398
+	// @param {number=} width Maximum width of the text before it wraps.
399
+	// @param {string=} halign Horizontal alignment of the text; either "left",
400
+	//     "center" or "right".
401
+	// @param {string=} valign Vertical alignment of the text; either "top",
402
+	//     "middle" or "bottom".
403
+
404
+	Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) {
405
+
406
+		var info = this.getTextInfo(layer, text, font, angle, width),
407
+			positions = info.positions;
408
+
409
+		// Tweak the div's position to match the text's alignment
410
+
411
+		if (halign == "center") {
412
+			x -= info.width / 2;
413
+		} else if (halign == "right") {
414
+			x -= info.width;
415
+		}
416
+
417
+		if (valign == "middle") {
418
+			y -= info.height / 2;
419
+		} else if (valign == "bottom") {
420
+			y -= info.height;
421
+		}
422
+
423
+		// Determine whether this text already exists at this position.
424
+		// If so, mark it for inclusion in the next render pass.
425
+
426
+		for (var i = 0, position; position = positions[i]; i++) {
427
+			if (position.x == x && position.y == y) {
428
+				position.active = true;
429
+				return;
430
+			}
431
+		}
432
+
433
+		// If the text doesn't exist at this position, create a new entry
434
+
435
+		// For the very first position we'll re-use the original element,
436
+		// while for subsequent ones we'll clone it.
437
+
438
+		position = {
439
+			active: true,
440
+			rendered: false,
441
+			element: positions.length ? info.element.clone() : info.element,
442
+			x: x,
443
+			y: y
444
+		};
445
+
446
+		positions.push(position);
447
+
448
+		// Move the element to its final position within the container
449
+
450
+		position.element.css({
451
+			top: Math.round(y),
452
+			left: Math.round(x),
453
+			'text-align': halign	// In case the text wraps
454
+		});
455
+	};
456
+
457
+	// Removes one or more text strings from the canvas text overlay.
458
+	//
459
+	// If no parameters are given, all text within the layer is removed.
460
+	//
461
+	// Note that the text is not immediately removed; it is simply marked as
462
+	// inactive, which will result in its removal on the next render pass.
463
+	// This avoids the performance penalty for 'clear and redraw' behavior,
464
+	// where we potentially get rid of all text on a layer, but will likely
465
+	// add back most or all of it later, as when redrawing axes, for example.
466
+	//
467
+	// @param {string} layer A string of space-separated CSS classes uniquely
468
+	//     identifying the layer containing this text.
469
+	// @param {number=} x X coordinate of the text.
470
+	// @param {number=} y Y coordinate of the text.
471
+	// @param {string=} text Text string to remove.
472
+	// @param {(string|object)=} font Either a string of space-separated CSS
473
+	//     classes or a font-spec object, defining the text's font and style.
474
+	// @param {number=} angle Angle at which the text is rotated, in degrees.
475
+	//     Angle is currently unused, it will be implemented in the future.
476
+
477
+	Canvas.prototype.removeText = function(layer, x, y, text, font, angle) {
478
+		if (text == null) {
479
+			var layerCache = this._textCache[layer];
480
+			if (layerCache != null) {
481
+				for (var styleKey in layerCache) {
482
+					if (hasOwnProperty.call(layerCache, styleKey)) {
483
+						var styleCache = layerCache[styleKey];
484
+						for (var key in styleCache) {
485
+							if (hasOwnProperty.call(styleCache, key)) {
486
+								var positions = styleCache[key].positions;
487
+								for (var i = 0, position; position = positions[i]; i++) {
488
+									position.active = false;
489
+								}
490
+							}
491
+						}
492
+					}
493
+				}
494
+			}
495
+		} else {
496
+			var positions = this.getTextInfo(layer, text, font, angle).positions;
497
+			for (var i = 0, position; position = positions[i]; i++) {
498
+				if (position.x == x && position.y == y) {
499
+					position.active = false;
500
+				}
501
+			}
502
+		}
503
+	};
504
+
505
+	///////////////////////////////////////////////////////////////////////////
506
+	// The top-level container for the entire plot.
507
+
508
+    function Plot(placeholder, data_, options_, plugins) {
509
+        // data is on the form:
510
+        //   [ series1, series2 ... ]
511
+        // where series is either just the data as [ [x1, y1], [x2, y2], ... ]
512
+        // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... }
513
+
514
+        var series = [],
515
+            options = {
516
+                // the color theme used for graphs
517
+                colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"],
518
+                legend: {
519
+                    show: true,
520
+                    noColumns: 1, // number of colums in legend table
521
+                    labelFormatter: null, // fn: string -> string
522
+                    labelBoxBorderColor: "#ccc", // border color for the little label boxes
523
+                    container: null, // container (as jQuery object) to put legend in, null means default on top of graph
524
+                    position: "ne", // position of default legend container within plot
525
+                    margin: 5, // distance from grid edge to default legend container within plot
526
+                    backgroundColor: null, // null means auto-detect
527
+                    backgroundOpacity: 0.85, // set to 0 to avoid background
528
+                    sorted: null    // default to no legend sorting
529
+                },
530
+                xaxis: {
531
+                    show: null, // null = auto-detect, true = always, false = never
532
+                    position: "bottom", // or "top"
533
+                    mode: null, // null or "time"
534
+                    font: null, // null (derived from CSS in placeholder) or object like { size: 11, lineHeight: 13, style: "italic", weight: "bold", family: "sans-serif", variant: "small-caps" }
535
+                    color: null, // base color, labels, ticks
536
+                    tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)"
537
+                    transform: null, // null or f: number -> number to transform axis
538
+                    inverseTransform: null, // if transform is set, this should be the inverse function
539
+                    min: null, // min. value to show, null means set automatically
540
+                    max: null, // max. value to show, null means set automatically
541
+                    autoscaleMargin: null, // margin in % to add if auto-setting min/max
542
+                    ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks
543
+                    tickFormatter: null, // fn: number -> string
544
+                    labelWidth: null, // size of tick labels in pixels
545
+                    labelHeight: null,
546
+                    reserveSpace: null, // whether to reserve space even if axis isn't shown
547
+                    tickLength: null, // size in pixels of ticks, or "full" for whole line
548
+                    alignTicksWithAxis: null, // axis number or null for no sync
549
+                    tickDecimals: null, // no. of decimals, null means auto
550
+                    tickSize: null, // number or [number, "unit"]
551
+                    minTickSize: null // number or [number, "unit"]
552
+                },
553
+                yaxis: {
554
+                    autoscaleMargin: 0.02,
555
+                    position: "left" // or "right"
556
+                },
557
+                xaxes: [],
558
+                yaxes: [],
559
+                series: {
560
+                    points: {
561
+                        show: false,
562
+                        radius: 3,
563
+                        lineWidth: 2, // in pixels
564
+                        fill: true,
565
+                        fillColor: "#ffffff",
566
+                        symbol: "circle" // or callback
567
+                    },
568
+                    lines: {
569
+                        // we don't put in show: false so we can see
570
+                        // whether lines were actively disabled
571
+                        lineWidth: 2, // in pixels
572
+                        fill: false,
573
+                        fillColor: null,
574
+                        steps: false
575
+                        // Omit 'zero', so we can later default its value to
576
+                        // match that of the 'fill' option.
577
+                    },
578
+                    bars: {
579
+                        show: false,
580
+                        lineWidth: 2, // in pixels
581
+                        barWidth: 1, // in units of the x axis
582
+                        fill: true,
583
+                        fillColor: null,
584
+                        align: "left", // "left", "right", or "center"
585
+                        horizontal: false,
586
+                        zero: true
587
+                    },
588
+                    shadowSize: 3,
589
+                    highlightColor: null
590
+                },
591
+                grid: {
592
+                    show: true,
593
+                    aboveData: false,
594
+                    color: "#545454", // primary color used for outline and labels
595
+                    backgroundColor: null, // null for transparent, else color
596
+                    borderColor: null, // set if different from the grid color
597
+                    tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)"
598
+                    margin: 0, // distance from the canvas edge to the grid
599
+                    labelMargin: 5, // in pixels
600
+                    axisMargin: 8, // in pixels
601
+                    borderWidth: 2, // in pixels
602
+                    minBorderMargin: null, // in pixels, null means taken from points radius
603
+                    markings: null, // array of ranges or fn: axes -> array of ranges
604
+                    markingsColor: "#f4f4f4",
605
+                    markingsLineWidth: 2,
606
+                    // interactive stuff
607
+                    clickable: false,
608
+                    hoverable: false,
609
+                    autoHighlight: true, // highlight in case mouse is near
610
+                    mouseActiveRadius: 10 // how far the mouse can be away to activate an item
611
+                },
612
+                interaction: {
613
+                    redrawOverlayInterval: 1000/60 // time between updates, -1 means in same flow
614
+                },
615
+                hooks: {}
616
+            },
617
+        surface = null,     // the canvas for the plot itself
618
+        overlay = null,     // canvas for interactive stuff on top of plot
619
+        eventHolder = null, // jQuery object that events should be bound to
620
+        ctx = null, octx = null,
621
+        xaxes = [], yaxes = [],
622
+        plotOffset = { left: 0, right: 0, top: 0, bottom: 0},
623
+        plotWidth = 0, plotHeight = 0,
624
+        hooks = {
625
+            processOptions: [],
626
+            processRawData: [],
627
+            processDatapoints: [],
628
+            processOffset: [],
629
+            drawBackground: [],
630
+            drawSeries: [],
631
+            draw: [],
632
+            bindEvents: [],
633
+            drawOverlay: [],
634
+            shutdown: []
635
+        },
636
+        plot = this;
637
+
638
+        // public functions
639
+        plot.setData = setData;
640
+        plot.setupGrid = setupGrid;
641
+        plot.draw = draw;
642
+        plot.getPlaceholder = function() { return placeholder; };
643
+        plot.getCanvas = function() { return surface.element; };
644
+        plot.getPlotOffset = function() { return plotOffset; };
645
+        plot.width = function () { return plotWidth; };
646
+        plot.height = function () { return plotHeight; };
647
+        plot.offset = function () {
648
+            var o = eventHolder.offset();
649
+            o.left += plotOffset.left;
650
+            o.top += plotOffset.top;
651
+            return o;
652
+        };
653
+        plot.getData = function () { return series; };
654
+        plot.getAxes = function () {
655
+            var res = {}, i;
656
+            $.each(xaxes.concat(yaxes), function (_, axis) {
657
+                if (axis)
658
+                    res[axis.direction + (axis.n != 1 ? axis.n : "") + "axis"] = axis;
659
+            });
660
+            return res;
661
+        };
662
+        plot.getXAxes = function () { return xaxes; };
663
+        plot.getYAxes = function () { return yaxes; };
664
+        plot.c2p = canvasToAxisCoords;
665
+        plot.p2c = axisToCanvasCoords;
666
+        plot.getOptions = function () { return options; };
667
+        plot.highlight = highlight;
668
+        plot.unhighlight = unhighlight;
669
+        plot.triggerRedrawOverlay = triggerRedrawOverlay;
670
+        plot.pointOffset = function(point) {
671
+            return {
672
+                left: parseInt(xaxes[axisNumber(point, "x") - 1].p2c(+point.x) + plotOffset.left, 10),
673
+                top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top, 10)
674
+            };
675
+        };
676
+        plot.shutdown = shutdown;
677
+        plot.destroy = function () {
678
+            shutdown();
679
+            placeholder.removeData("plot").empty();
680
+
681
+            series = [];
682
+            options = null;
683
+            surface = null;
684
+            overlay = null;
685
+            eventHolder = null;
686
+            ctx = null;
687
+            octx = null;
688
+            xaxes = [];
689
+            yaxes = [];
690
+            hooks = null;
691
+            highlights = [];
692
+            plot = null;
693
+        };
694
+        plot.resize = function () {
695
+        	var width = placeholder.width(),
696
+        		height = placeholder.height();
697
+            surface.resize(width, height);
698
+            overlay.resize(width, height);
699
+        };
700
+
701
+        // public attributes
702
+        plot.hooks = hooks;
703
+
704
+        // initialize
705
+        initPlugins(plot);
706
+        parseOptions(options_);
707
+        setupCanvases();
708
+        setData(data_);
709
+        setupGrid();
710
+        draw();
711
+        bindEvents();
712
+
713
+
714
+        function executeHooks(hook, args) {
715
+            args = [plot].concat(args);
716
+            for (var i = 0; i < hook.length; ++i)
717
+                hook[i].apply(this, args);
718
+        }
719
+
720
+        function initPlugins() {
721
+
722
+            // References to key classes, allowing plugins to modify them
723
+
724
+            var classes = {
725
+                Canvas: Canvas
726
+            };
727
+
728
+            for (var i = 0; i < plugins.length; ++i) {
729
+                var p = plugins[i];
730
+                p.init(plot, classes);
731
+                if (p.options)
732
+                    $.extend(true, options, p.options);
733
+            }
734
+        }
735
+
736
+        function parseOptions(opts) {
737
+
738
+            $.extend(true, options, opts);
739
+
740
+            // $.extend merges arrays, rather than replacing them.  When less
741
+            // colors are provided than the size of the default palette, we
742
+            // end up with those colors plus the remaining defaults, which is
743
+            // not expected behavior; avoid it by replacing them here.
744
+
745
+            if (opts && opts.colors) {
746
+            	options.colors = opts.colors;
747
+            }
748
+
749
+            if (options.xaxis.color == null)
750
+                options.xaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();
751
+            if (options.yaxis.color == null)
752
+                options.yaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();
753
+
754
+            if (options.xaxis.tickColor == null) // grid.tickColor for back-compatibility
755
+                options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color;
756
+            if (options.yaxis.tickColor == null) // grid.tickColor for back-compatibility
757
+                options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color;
758
+
759
+            if (options.grid.borderColor == null)
760
+                options.grid.borderColor = options.grid.color;
761
+            if (options.grid.tickColor == null)
762
+                options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString();
763
+
764
+            // Fill in defaults for axis options, including any unspecified
765
+            // font-spec fields, if a font-spec was provided.
766
+
767
+            // If no x/y axis options were provided, create one of each anyway,
768
+            // since the rest of the code assumes that they exist.
769
+
770
+            var i, axisOptions, axisCount,
771
+                fontSize = placeholder.css("font-size"),
772
+                fontSizeDefault = fontSize ? +fontSize.replace("px", "") : 13,
773
+                fontDefaults = {
774
+                    style: placeholder.css("font-style"),
775
+                    size: Math.round(0.8 * fontSizeDefault),
776
+                    variant: placeholder.css("font-variant"),
777
+                    weight: placeholder.css("font-weight"),
778
+                    family: placeholder.css("font-family")
779
+                };
780
+
781
+            axisCount = options.xaxes.length || 1;
782
+            for (i = 0; i < axisCount; ++i) {
783
+
784
+                axisOptions = options.xaxes[i];
785
+                if (axisOptions && !axisOptions.tickColor) {
786
+                    axisOptions.tickColor = axisOptions.color;
787
+                }
788
+
789
+                axisOptions = $.extend(true, {}, options.xaxis, axisOptions);
790
+                options.xaxes[i] = axisOptions;
791
+
792
+                if (axisOptions.font) {
793
+                    axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);
794
+                    if (!axisOptions.font.color) {
795
+                        axisOptions.font.color = axisOptions.color;
796
+                    }
797
+                    if (!axisOptions.font.lineHeight) {
798
+                        axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15);
799
+                    }
800
+                }
801
+            }
802
+
803
+            axisCount = options.yaxes.length || 1;
804
+            for (i = 0; i < axisCount; ++i) {
805
+
806
+                axisOptions = options.yaxes[i];
807
+                if (axisOptions && !axisOptions.tickColor) {
808
+                    axisOptions.tickColor = axisOptions.color;
809
+                }
810
+
811
+                axisOptions = $.extend(true, {}, options.yaxis, axisOptions);
812
+                options.yaxes[i] = axisOptions;
813
+
814
+                if (axisOptions.font) {
815
+                    axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);
816
+                    if (!axisOptions.font.color) {
817
+                        axisOptions.font.color = axisOptions.color;
818
+                    }
819
+                    if (!axisOptions.font.lineHeight) {
820
+                        axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15);
821
+                    }
822
+                }
823
+            }
824
+
825
+            // backwards compatibility, to be removed in future
826
+            if (options.xaxis.noTicks && options.xaxis.ticks == null)
827
+                options.xaxis.ticks = options.xaxis.noTicks;
828
+            if (options.yaxis.noTicks && options.yaxis.ticks == null)
829
+                options.yaxis.ticks = options.yaxis.noTicks;
830
+            if (options.x2axis) {
831
+                options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis);
832
+                options.xaxes[1].position = "top";
833
+                // Override the inherit to allow the axis to auto-scale
834
+                if (options.x2axis.min == null) {
835
+                    options.xaxes[1].min = null;
836
+                }
837
+                if (options.x2axis.max == null) {
838
+                    options.xaxes[1].max = null;
839
+                }
840
+            }
841
+            if (options.y2axis) {
842
+                options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis);
843
+                options.yaxes[1].position = "right";
844
+                // Override the inherit to allow the axis to auto-scale
845
+                if (options.y2axis.min == null) {
846
+                    options.yaxes[1].min = null;
847
+                }
848
+                if (options.y2axis.max == null) {
849
+                    options.yaxes[1].max = null;
850
+                }
851
+            }
852
+            if (options.grid.coloredAreas)
853
+                options.grid.markings = options.grid.coloredAreas;
854
+            if (options.grid.coloredAreasColor)
855
+                options.grid.markingsColor = options.grid.coloredAreasColor;
856
+            if (options.lines)
857
+                $.extend(true, options.series.lines, options.lines);
858
+            if (options.points)
859
+                $.extend(true, options.series.points, options.points);
860
+            if (options.bars)
861
+                $.extend(true, options.series.bars, options.bars);
862
+            if (options.shadowSize != null)
863
+                options.series.shadowSize = options.shadowSize;
864
+            if (options.highlightColor != null)
865
+                options.series.highlightColor = options.highlightColor;
866
+
867
+            // save options on axes for future reference
868
+            for (i = 0; i < options.xaxes.length; ++i)
869
+                getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i];
870
+            for (i = 0; i < options.yaxes.length; ++i)
871
+                getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i];
872
+
873
+            // add hooks from options
874
+            for (var n in hooks)
875
+                if (options.hooks[n] && options.hooks[n].length)
876
+                    hooks[n] = hooks[n].concat(options.hooks[n]);
877
+
878
+            executeHooks(hooks.processOptions, [options]);
879
+        }
880
+
881
+        function setData(d) {
882
+            series = parseData(d);
883
+            fillInSeriesOptions();
884
+            processData();
885
+        }
886
+
887
+        function parseData(d) {
888
+            var res = [];
889
+            for (var i = 0; i < d.length; ++i) {
890
+                var s = $.extend(true, {}, options.series);
891
+
892
+                if (d[i].data != null) {
893
+                    s.data = d[i].data; // move the data instead of deep-copy
894
+                    delete d[i].data;
895
+
896
+                    $.extend(true, s, d[i]);
897
+
898
+                    d[i].data = s.data;
899
+                }
900
+                else
901
+                    s.data = d[i];
902
+                res.push(s);
903
+            }
904
+
905
+            return res;
906
+        }
907
+
908
+        function axisNumber(obj, coord) {
909
+            var a = obj[coord + "axis"];
910
+            if (typeof a == "object") // if we got a real axis, extract number
911
+                a = a.n;
912
+            if (typeof a != "number")
913
+                a = 1; // default to first axis
914
+            return a;
915
+        }
916
+
917
+        function allAxes() {
918
+            // return flat array without annoying null entries
919
+            return $.grep(xaxes.concat(yaxes), function (a) { return a; });
920
+        }
921
+
922
+        function canvasToAxisCoords(pos) {
923
+            // return an object with x/y corresponding to all used axes
924
+            var res = {}, i, axis;
925
+            for (i = 0; i < xaxes.length; ++i) {
926
+                axis = xaxes[i];
927
+                if (axis && axis.used)
928
+                    res["x" + axis.n] = axis.c2p(pos.left);
929
+            }
930
+
931
+            for (i = 0; i < yaxes.length; ++i) {
932
+                axis = yaxes[i];
933
+                if (axis && axis.used)
934
+                    res["y" + axis.n] = axis.c2p(pos.top);
935
+            }
936
+
937
+            if (res.x1 !== undefined)
938
+                res.x = res.x1;
939
+            if (res.y1 !== undefined)
940
+                res.y = res.y1;
941
+
942
+            return res;
943
+        }
944
+
945
+        function axisToCanvasCoords(pos) {
946
+            // get canvas coords from the first pair of x/y found in pos
947
+            var res = {}, i, axis, key;
948
+
949
+            for (i = 0; i < xaxes.length; ++i) {
950
+                axis = xaxes[i];
951
+                if (axis && axis.used) {
952
+                    key = "x" + axis.n;
953
+                    if (pos[key] == null && axis.n == 1)
954
+                        key = "x";
955
+
956
+                    if (pos[key] != null) {
957
+                        res.left = axis.p2c(pos[key]);
958
+                        break;
959
+                    }
960
+                }
961
+            }
962
+
963
+            for (i = 0; i < yaxes.length; ++i) {
964
+                axis = yaxes[i];
965
+                if (axis && axis.used) {
966
+                    key = "y" + axis.n;
967
+                    if (pos[key] == null && axis.n == 1)
968
+                        key = "y";
969
+
970
+                    if (pos[key] != null) {
971
+                        res.top = axis.p2c(pos[key]);
972
+                        break;
973
+                    }
974
+                }
975
+            }
976
+
977
+            return res;
978
+        }
979
+
980
+        function getOrCreateAxis(axes, number) {
981
+            if (!axes[number - 1])
982
+                axes[number - 1] = {
983
+                    n: number, // save the number for future reference
984
+                    direction: axes == xaxes ? "x" : "y",
985
+                    options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis)
986
+                };
987
+
988
+            return axes[number - 1];
989
+        }
990
+
991
+        function fillInSeriesOptions() {
992
+
993
+            var neededColors = series.length, maxIndex = -1, i;
994
+
995
+            // Subtract the number of series that already have fixed colors or
996
+            // color indexes from the number that we still need to generate.
997
+
998
+            for (i = 0; i < series.length; ++i) {
999
+                var sc = series[i].color;
1000
+                if (sc != null) {
1001
+                    neededColors--;
1002
+                    if (typeof sc == "number" && sc > maxIndex) {
1003
+                        maxIndex = sc;
1004
+                    }
1005
+                }
1006
+            }
1007
+
1008
+            // If any of the series have fixed color indexes, then we need to
1009
+            // generate at least as many colors as the highest index.
1010
+
1011
+            if (neededColors <= maxIndex) {
1012
+                neededColors = maxIndex + 1;
1013
+            }
1014
+
1015
+            // Generate all the colors, using first the option colors and then
1016
+            // variations on those colors once they're exhausted.
1017
+
1018
+            var c, colors = [], colorPool = options.colors,
1019
+                colorPoolSize = colorPool.length, variation = 0;
1020
+
1021
+            for (i = 0; i < neededColors; i++) {
1022
+
1023
+                c = $.color.parse(colorPool[i % colorPoolSize] || "#666");
1024
+
1025
+                // Each time we exhaust the colors in the pool we adjust
1026
+                // a scaling factor used to produce more variations on
1027
+                // those colors. The factor alternates negative/positive
1028
+                // to produce lighter/darker colors.
1029
+
1030
+                // Reset the variation after every few cycles, or else
1031
+                // it will end up producing only white or black colors.
1032
+
1033
+                if (i % colorPoolSize == 0 && i) {
1034
+                    if (variation >= 0) {
1035
+                        if (variation < 0.5) {
1036
+                            variation = -variation - 0.2;
1037
+                        } else variation = 0;
1038
+                    } else variation = -variation;
1039
+                }
1040
+
1041
+                colors[i] = c.scale('rgb', 1 + variation);
1042
+            }
1043
+
1044
+            // Finalize the series options, filling in their colors
1045
+
1046
+            var colori = 0, s;
1047
+            for (i = 0; i < series.length; ++i) {
1048
+                s = series[i];
1049
+
1050
+                // assign colors
1051
+                if (s.color == null) {
1052
+                    s.color = colors[colori].toString();
1053
+                    ++colori;
1054
+                }
1055
+                else if (typeof s.color == "number")
1056
+                    s.color = colors[s.color].toString();
1057
+
1058
+                // turn on lines automatically in case nothing is set
1059
+                if (s.lines.show == null) {
1060
+                    var v, show = true;
1061
+                    for (v in s)
1062
+                        if (s[v] && s[v].show) {
1063
+                            show = false;
1064
+                            break;
1065
+                        }
1066
+                    if (show)
1067
+                        s.lines.show = true;
1068
+                }
1069
+
1070
+                // If nothing was provided for lines.zero, default it to match
1071
+                // lines.fill, since areas by default should extend to zero.
1072
+
1073
+                if (s.lines.zero == null) {
1074
+                    s.lines.zero = !!s.lines.fill;
1075
+                }
1076
+
1077
+                // setup axes
1078
+                s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, "x"));
1079
+                s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, "y"));
1080
+            }
1081
+        }
1082
+
1083
+        function processData() {
1084
+            var topSentry = Number.POSITIVE_INFINITY,
1085
+                bottomSentry = Number.NEGATIVE_INFINITY,
1086
+                fakeInfinity = Number.MAX_VALUE,
1087
+                i, j, k, m, length,
1088
+                s, points, ps, x, y, axis, val, f, p,
1089
+                data, format;
1090
+
1091
+            function updateAxis(axis, min, max) {
1092
+                if (min < axis.datamin && min != -fakeInfinity)
1093
+                    axis.datamin = min;
1094
+                if (max > axis.datamax && max != fakeInfinity)
1095
+                    axis.datamax = max;
1096
+            }
1097
+
1098
+            $.each(allAxes(), function (_, axis) {
1099
+                // init axis
1100
+                axis.datamin = topSentry;
1101
+                axis.datamax = bottomSentry;
1102
+                axis.used = false;
1103
+            });
1104
+
1105
+            for (i = 0; i < series.length; ++i) {
1106
+                s = series[i];
1107
+                s.datapoints = { points: [] };
1108
+
1109
+                executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]);
1110
+            }
1111
+
1112
+            // first pass: clean and copy data
1113
+            for (i = 0; i < series.length; ++i) {
1114
+                s = series[i];
1115
+
1116
+                data = s.data;
1117
+                format = s.datapoints.format;
1118
+
1119
+                if (!format) {
1120
+                    format = [];
1121
+                    // find out how to copy
1122
+                    format.push({ x: true, number: true, required: true });
1123
+                    format.push({ y: true, number: true, required: true });
1124
+
1125
+                    if (s.bars.show || (s.lines.show && s.lines.fill)) {
1126
+                        var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));
1127
+                        format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });
1128
+                        if (s.bars.horizontal) {
1129
+                            delete format[format.length - 1].y;
1130
+                            format[format.length - 1].x = true;
1131
+                        }
1132
+                    }
1133
+
1134
+                    s.datapoints.format = format;
1135
+                }
1136
+
1137
+                if (s.datapoints.pointsize != null)
1138
+                    continue; // already filled in
1139
+
1140
+                s.datapoints.pointsize = format.length;
1141
+
1142
+                ps = s.datapoints.pointsize;
1143
+                points = s.datapoints.points;
1144
+
1145
+                var insertSteps = s.lines.show && s.lines.steps;
1146
+                s.xaxis.used = s.yaxis.used = true;
1147
+
1148
+                for (j = k = 0; j < data.length; ++j, k += ps) {
1149
+                    p = data[j];
1150
+
1151
+                    var nullify = p == null;
1152
+                    if (!nullify) {
1153
+                        for (m = 0; m < ps; ++m) {
1154
+                            val = p[m];
1155
+                            f = format[m];
1156
+
1157
+                            if (f) {
1158
+                                if (f.number && val != null) {
1159
+                                    val = +val; // convert to number
1160
+                                    if (isNaN(val))
1161
+                                        val = null;
1162
+                                    else if (val == Infinity)
1163
+                                        val = fakeInfinity;
1164
+                                    else if (val == -Infinity)
1165
+                                        val = -fakeInfinity;
1166
+                                }
1167
+
1168
+                                if (val == null) {
1169
+                                    if (f.required)
1170
+                                        nullify = true;
1171
+
1172
+                                    if (f.defaultValue != null)
1173
+                                        val = f.defaultValue;
1174
+                                }
1175
+                            }
1176
+
1177
+                            points[k + m] = val;
1178
+                        }
1179
+                    }
1180
+
1181
+                    if (nullify) {
1182
+                        for (m = 0; m < ps; ++m) {
1183
+                            val = points[k + m];
1184
+                            if (val != null) {
1185
+                                f = format[m];
1186
+                                // extract min/max info
1187
+                                if (f.autoscale !== false) {
1188
+                                    if (f.x) {
1189
+                                        updateAxis(s.xaxis, val, val);
1190
+                                    }
1191
+                                    if (f.y) {
1192
+                                        updateAxis(s.yaxis, val, val);
1193
+                                    }
1194
+                                }
1195
+                            }
1196
+                            points[k + m] = null;
1197
+                        }
1198
+                    }
1199
+                    else {
1200
+                        // a little bit of line specific stuff that
1201
+                        // perhaps shouldn't be here, but lacking
1202
+                        // better means...
1203
+                        if (insertSteps && k > 0
1204
+                            && points[k - ps] != null
1205
+                            && points[k - ps] != points[k]
1206
+                            && points[k - ps + 1] != points[k + 1]) {
1207
+                            // copy the point to make room for a middle point
1208
+                            for (m = 0; m < ps; ++m)
1209
+                                points[k + ps + m] = points[k + m];
1210
+
1211
+                            // middle point has same y
1212
+                            points[k + 1] = points[k - ps + 1];
1213
+
1214
+                            // we've added a point, better reflect that
1215
+                            k += ps;
1216
+                        }
1217
+                    }
1218
+                }
1219
+            }
1220
+
1221
+            // give the hooks a chance to run
1222
+            for (i = 0; i < series.length; ++i) {
1223
+                s = series[i];
1224
+
1225
+                executeHooks(hooks.processDatapoints, [ s, s.datapoints]);
1226
+            }
1227
+
1228
+            // second pass: find datamax/datamin for auto-scaling
1229
+            for (i = 0; i < series.length; ++i) {
1230
+                s = series[i];
1231
+                points = s.datapoints.points;
1232
+                ps = s.datapoints.pointsize;
1233
+                format = s.datapoints.format;
1234
+
1235
+                var xmin = topSentry, ymin = topSentry,
1236
+                    xmax = bottomSentry, ymax = bottomSentry;
1237
+
1238
+                for (j = 0; j < points.length; j += ps) {
1239
+                    if (points[j] == null)
1240
+                        continue;
1241
+
1242
+                    for (m = 0; m < ps; ++m) {
1243
+                        val = points[j + m];
1244
+                        f = format[m];
1245
+                        if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity)
1246
+                            continue;
1247
+
1248
+                        if (f.x) {
1249
+                            if (val < xmin)
1250
+                                xmin = val;
1251
+                            if (val > xmax)
1252
+                                xmax = val;
1253
+                        }
1254
+                        if (f.y) {
1255
+                            if (val < ymin)
1256
+                                ymin = val;
1257
+                            if (val > ymax)
1258
+                                ymax = val;
1259
+                        }
1260
+                    }
1261
+                }
1262
+
1263
+                if (s.bars.show) {
1264
+                    // make sure we got room for the bar on the dancing floor
1265
+                    var delta;
1266
+
1267
+                    switch (s.bars.align) {
1268
+                        case "left":
1269
+                            delta = 0;
1270
+                            break;
1271
+                        case "right":
1272
+                            delta = -s.bars.barWidth;
1273
+                            break;
1274
+                        default:
1275
+                            delta = -s.bars.barWidth / 2;
1276
+                    }
1277
+
1278
+                    if (s.bars.horizontal) {
1279
+                        ymin += delta;
1280
+                        ymax += delta + s.bars.barWidth;
1281
+                    }
1282
+                    else {
1283
+                        xmin += delta;
1284
+                        xmax += delta + s.bars.barWidth;
1285
+                    }
1286
+                }
1287
+
1288
+                updateAxis(s.xaxis, xmin, xmax);
1289
+                updateAxis(s.yaxis, ymin, ymax);
1290
+            }
1291
+
1292
+            $.each(allAxes(), function (_, axis) {
1293
+                if (axis.datamin == topSentry)
1294
+                    axis.datamin = null;
1295
+                if (axis.datamax == bottomSentry)
1296
+                    axis.datamax = null;
1297
+            });
1298
+        }
1299
+
1300
+        function setupCanvases() {
1301
+
1302
+            // Make sure the placeholder is clear of everything except canvases
1303
+            // from a previous plot in this container that we'll try to re-use.
1304
+
1305
+            placeholder.css("padding", 0) // padding messes up the positioning
1306
+                .children().filter(function(){
1307
+                    return !$(this).hasClass("flot-overlay") && !$(this).hasClass('flot-base');
1308
+                }).remove();
1309
+
1310
+            if (placeholder.css("position") == 'static')
1311
+                placeholder.css("position", "relative"); // for positioning labels and overlay
1312
+
1313
+            surface = new Canvas("flot-base", placeholder);
1314
+            overlay = new Canvas("flot-overlay", placeholder); // overlay canvas for interactive features
1315
+
1316
+            ctx = surface.context;
1317
+            octx = overlay.context;
1318
+
1319
+            // define which element we're listening for events on
1320
+            eventHolder = $(overlay.element).unbind();
1321
+
1322
+            // If we're re-using a plot object, shut down the old one
1323
+
1324
+            var existing = placeholder.data("plot");
1325
+
1326
+            if (existing) {
1327
+                existing.shutdown();
1328
+                overlay.clear();
1329
+            }
1330
+
1331
+            // save in case we get replotted
1332
+            placeholder.data("plot", plot);
1333
+        }
1334
+
1335
+        function bindEvents() {
1336
+            // bind events
1337
+            if (options.grid.hoverable) {
1338
+                eventHolder.mousemove(onMouseMove);
1339
+
1340
+                // Use bind, rather than .mouseleave, because we officially
1341
+                // still support jQuery 1.2.6, which doesn't define a shortcut
1342
+                // for mouseenter or mouseleave.  This was a bug/oversight that
1343
+                // was fixed somewhere around 1.3.x.  We can return to using
1344
+                // .mouseleave when we drop support for 1.2.6.
1345
+
1346
+                eventHolder.bind("mouseleave", onMouseLeave);
1347
+            }
1348
+
1349
+            if (options.grid.clickable)
1350
+                eventHolder.click(onClick);
1351
+
1352
+            executeHooks(hooks.bindEvents, [eventHolder]);
1353
+        }
1354
+
1355
+        function shutdown() {
1356
+            if (redrawTimeout)
1357
+                clearTimeout(redrawTimeout);
1358
+
1359
+            eventHolder.unbind("mousemove", onMouseMove);
1360
+            eventHolder.unbind("mouseleave", onMouseLeave);
1361
+            eventHolder.unbind("click", onClick);
1362
+
1363
+            executeHooks(hooks.shutdown, [eventHolder]);
1364
+        }
1365
+
1366
+        function setTransformationHelpers(axis) {
1367
+            // set helper functions on the axis, assumes plot area
1368
+            // has been computed already
1369
+
1370
+            function identity(x) { return x; }
1371
+
1372
+            var s, m, t = axis.options.transform || identity,
1373
+                it = axis.options.inverseTransform;
1374
+
1375
+            // precompute how much the axis is scaling a point
1376
+            // in canvas space
1377
+            if (axis.direction == "x") {
1378
+                s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min));
1379
+                m = Math.min(t(axis.max), t(axis.min));
1380
+            }
1381
+            else {
1382
+                s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min));
1383
+                s = -s;
1384
+                m = Math.max(t(axis.max), t(axis.min));
1385
+            }
1386
+
1387
+            // data point to canvas coordinate
1388
+            if (t == identity) // slight optimization
1389
+                axis.p2c = function (p) { return (p - m) * s; };
1390
+            else
1391
+                axis.p2c = function (p) { return (t(p) - m) * s; };
1392
+            // canvas coordinate to data point
1393
+            if (!it)
1394
+                axis.c2p = function (c) { return m + c / s; };
1395
+            else
1396
+                axis.c2p = function (c) { return it(m + c / s); };
1397
+        }
1398
+
1399
+        function measureTickLabels(axis) {
1400
+
1401
+            var opts = axis.options,
1402
+                ticks = axis.ticks || [],
1403
+                labelWidth = opts.labelWidth || 0,
1404
+                labelHeight = opts.labelHeight || 0,
1405
+                maxWidth = labelWidth || (axis.direction == "x" ? Math.floor(surface.width / (ticks.length || 1)) : null),
1406
+                legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis",
1407
+                layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles,
1408
+                font = opts.font || "flot-tick-label tickLabel";
1409
+
1410
+            for (var i = 0; i < ticks.length; ++i) {
1411
+
1412
+                var t = ticks[i];
1413
+
1414
+                if (!t.label)
1415
+                    continue;
1416
+
1417
+                var info = surface.getTextInfo(layer, t.label, font, null, maxWidth);
1418
+
1419
+                labelWidth = Math.max(labelWidth, info.width);
1420
+                labelHeight = Math.max(labelHeight, info.height);
1421
+            }
1422
+
1423
+            axis.labelWidth = opts.labelWidth || labelWidth;
1424
+            axis.labelHeight = opts.labelHeight || labelHeight;
1425
+        }
1426
+
1427
+        function allocateAxisBoxFirstPhase(axis) {
1428
+            // find the bounding box of the axis by looking at label
1429
+            // widths/heights and ticks, make room by diminishing the
1430
+            // plotOffset; this first phase only looks at one
1431
+            // dimension per axis, the other dimension depends on the
1432
+            // other axes so will have to wait
1433
+
1434
+            var lw = axis.labelWidth,
1435
+                lh = axis.labelHeight,
1436
+                pos = axis.options.position,
1437
+                isXAxis = axis.direction === "x",
1438
+                tickLength = axis.options.tickLength,
1439
+                axisMargin = options.grid.axisMargin,
1440
+                padding = options.grid.labelMargin,
1441
+                innermost = true,
1442
+                outermost = true,
1443
+                first = true,
1444
+                found = false;
1445
+
1446
+            // Determine the axis's position in its direction and on its side
1447
+
1448
+            $.each(isXAxis ? xaxes : yaxes, function(i, a) {
1449
+                if (a && (a.show || a.reserveSpace)) {
1450
+                    if (a === axis) {
1451
+                        found = true;
1452
+                    } else if (a.options.position === pos) {
1453
+                        if (found) {
1454
+                            outermost = false;
1455
+                        } else {
1456
+                            innermost = false;
1457
+                        }
1458
+                    }
1459
+                    if (!found) {
1460
+                        first = false;
1461
+                    }
1462
+                }
1463
+            });
1464
+
1465
+            // The outermost axis on each side has no margin
1466
+
1467
+            if (outermost) {
1468
+                axisMargin = 0;
1469
+            }
1470
+
1471
+            // The ticks for the first axis in each direction stretch across
1472
+
1473
+            if (tickLength == null) {
1474
+                tickLength = first ? "full" : 5;
1475
+            }
1476
+
1477
+            if (!isNaN(+tickLength))
1478
+                padding += +tickLength;
1479
+
1480
+            if (isXAxis) {
1481
+                lh += padding;
1482
+
1483
+                if (pos == "bottom") {
1484
+                    plotOffset.bottom += lh + axisMargin;
1485
+                    axis.box = { top: surface.height - plotOffset.bottom, height: lh };
1486
+                }
1487
+                else {
1488
+                    axis.box = { top: plotOffset.top + axisMargin, height: lh };
1489
+                    plotOffset.top += lh + axisMargin;
1490
+                }
1491
+            }
1492
+            else {
1493
+                lw += padding;
1494
+
1495
+                if (pos == "left") {
1496
+                    axis.box = { left: plotOffset.left + axisMargin, width: lw };
1497
+                    plotOffset.left += lw + axisMargin;
1498
+                }
1499
+                else {
1500
+                    plotOffset.right += lw + axisMargin;
1501
+                    axis.box = { left: surface.width - plotOffset.right, width: lw };
1502
+                }
1503
+            }
1504
+
1505
+             // save for future reference
1506
+            axis.position = pos;
1507
+            axis.tickLength = tickLength;
1508
+            axis.box.padding = padding;
1509
+            axis.innermost = innermost;
1510
+        }
1511
+
1512
+        function allocateAxisBoxSecondPhase(axis) {
1513
+            // now that all axis boxes have been placed in one
1514
+            // dimension, we can set the remaining dimension coordinates
1515
+            if (axis.direction == "x") {
1516
+                axis.box.left = plotOffset.left - axis.labelWidth / 2;
1517
+                axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth;
1518
+            }
1519
+            else {
1520
+                axis.box.top = plotOffset.top - axis.labelHeight / 2;
1521
+                axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight;
1522
+            }
1523
+        }
1524
+
1525
+        function adjustLayoutForThingsStickingOut() {
1526
+            // possibly adjust plot offset to ensure everything stays
1527
+            // inside the canvas and isn't clipped off
1528
+
1529
+            var minMargin = options.grid.minBorderMargin,
1530
+                axis, i;
1531
+
1532
+            // check stuff from the plot (FIXME: this should just read
1533
+            // a value from the series, otherwise it's impossible to
1534
+            // customize)
1535
+            if (minMargin == null) {
1536
+                minMargin = 0;
1537
+                for (i = 0; i < series.length; ++i)
1538
+                    minMargin = Math.max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth/2));
1539
+            }
1540
+
1541
+            var margins = {
1542
+                left: minMargin,
1543
+                right: minMargin,
1544
+                top: minMargin,
1545
+                bottom: minMargin
1546
+            };
1547
+
1548
+            // check axis labels, note we don't check the actual
1549
+            // labels but instead use the overall width/height to not
1550
+            // jump as much around with replots
1551
+            $.each(allAxes(), function (_, axis) {
1552
+                if (axis.reserveSpace && axis.ticks && axis.ticks.length) {
1553
+                    if (axis.direction === "x") {
1554
+                        margins.left = Math.max(margins.left, axis.labelWidth / 2);
1555
+                        margins.right = Math.max(margins.right, axis.labelWidth / 2);
1556
+                    } else {
1557
+                        margins.bottom = Math.max(margins.bottom, axis.labelHeight / 2);
1558
+                        margins.top = Math.max(margins.top, axis.labelHeight / 2);
1559
+                    }
1560
+                }
1561
+            });
1562
+
1563
+            plotOffset.left = Math.ceil(Math.max(margins.left, plotOffset.left));
1564
+            plotOffset.right = Math.ceil(Math.max(margins.right, plotOffset.right));
1565
+            plotOffset.top = Math.ceil(Math.max(margins.top, plotOffset.top));
1566
+            plotOffset.bottom = Math.ceil(Math.max(margins.bottom, plotOffset.bottom));
1567
+        }
1568
+
1569
+        function setupGrid() {
1570
+            var i, axes = allAxes(), showGrid = options.grid.show;
1571
+
1572
+            // Initialize the plot's offset from the edge of the canvas
1573
+
1574
+            for (var a in plotOffset) {
1575
+                var margin = options.grid.margin || 0;
1576
+                plotOffset[a] = typeof margin == "number" ? margin : margin[a] || 0;
1577
+            }
1578
+
1579
+            executeHooks(hooks.processOffset, [plotOffset]);
1580
+
1581
+            // If the grid is visible, add its border width to the offset
1582
+
1583
+            for (var a in plotOffset) {
1584
+                if(typeof(options.grid.borderWidth) == "object") {
1585
+                    plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0;
1586
+                }
1587
+                else {
1588
+                    plotOffset[a] += showGrid ? options.grid.borderWidth : 0;
1589
+                }
1590
+            }
1591
+
1592
+            $.each(axes, function (_, axis) {
1593
+                var axisOpts = axis.options;
1594
+                axis.show = axisOpts.show == null ? axis.used : axisOpts.show;
1595
+                axis.reserveSpace = axisOpts.reserveSpace == null ? axis.show : axisOpts.reserveSpace;
1596
+                setRange(axis);
1597
+            });
1598
+
1599
+            if (showGrid) {
1600
+
1601
+                var allocatedAxes = $.grep(axes, function (axis) {
1602
+                    return axis.show || axis.reserveSpace;
1603
+                });
1604
+
1605
+                $.each(allocatedAxes, function (_, axis) {
1606
+                    // make the ticks
1607
+                    setupTickGeneration(axis);
1608
+                    setTicks(axis);
1609
+                    snapRangeToTicks(axis, axis.ticks);
1610
+                    // find labelWidth/Height for axis
1611
+                    measureTickLabels(axis);
1612
+                });
1613
+
1614
+                // with all dimensions calculated, we can compute the
1615
+                // axis bounding boxes, start from the outside
1616
+                // (reverse order)
1617
+                for (i = allocatedAxes.length - 1; i >= 0; --i)
1618
+                    allocateAxisBoxFirstPhase(allocatedAxes[i]);
1619
+
1620
+                // make sure we've got enough space for things that
1621
+                // might stick out
1622
+                adjustLayoutForThingsStickingOut();
1623
+
1624
+                $.each(allocatedAxes, function (_, axis) {
1625
+                    allocateAxisBoxSecondPhase(axis);
1626
+                });
1627
+            }
1628
+
1629
+            plotWidth = surface.width - plotOffset.left - plotOffset.right;
1630
+            plotHeight = surface.height - plotOffset.bottom - plotOffset.top;
1631
+
1632
+            // now we got the proper plot dimensions, we can compute the scaling
1633
+            $.each(axes, function (_, axis) {
1634
+                setTransformationHelpers(axis);
1635
+            });
1636
+
1637
+            if (showGrid) {
1638
+                drawAxisLabels();
1639
+            }
1640
+
1641
+            insertLegend();
1642
+        }
1643
+
1644
+        function setRange(axis) {
1645
+            var opts = axis.options,
1646
+                min = +(opts.min != null ? opts.min : axis.datamin),
1647
+                max = +(opts.max != null ? opts.max : axis.datamax),
1648
+                delta = max - min;
1649
+
1650
+            if (delta == 0.0) {
1651
+                // degenerate case
1652
+                var widen = max == 0 ? 1 : 0.01;
1653
+
1654
+                if (opts.min == null)
1655
+                    min -= widen;
1656
+                // always widen max if we couldn't widen min to ensure we
1657
+                // don't fall into min == max which doesn't work
1658
+                if (opts.max == null || opts.min != null)
1659
+                    max += widen;
1660
+            }
1661
+            else {
1662
+                // consider autoscaling
1663
+                var margin = opts.autoscaleMargin;
1664
+                if (margin != null) {
1665
+                    if (opts.min == null) {
1666
+                        min -= delta * margin;
1667
+                        // make sure we don't go below zero if all values
1668
+                        // are positive
1669
+                        if (min < 0 && axis.datamin != null && axis.datamin >= 0)
1670
+                            min = 0;
1671
+                    }
1672
+                    if (opts.max == null) {
1673
+                        max += delta * margin;
1674
+                        if (max > 0 && axis.datamax != null && axis.datamax <= 0)
1675
+                            max = 0;
1676
+                    }
1677
+                }
1678
+            }
1679
+            axis.min = min;
1680
+            axis.max = max;
1681
+        }
1682
+
1683
+        function setupTickGeneration(axis) {
1684
+            var opts = axis.options;
1685
+
1686
+            // estimate number of ticks
1687
+            var noTicks;
1688
+            if (typeof opts.ticks == "number" && opts.ticks > 0)
1689
+                noTicks = opts.ticks;
1690
+            else
1691
+                // heuristic based on the model a*sqrt(x) fitted to
1692
+                // some data points that seemed reasonable
1693
+                noTicks = 0.3 * Math.sqrt(axis.direction == "x" ? surface.width : surface.height);
1694
+
1695
+            var delta = (axis.max - axis.min) / noTicks,
1696
+                dec = -Math.floor(Math.log(delta) / Math.LN10),
1697
+                maxDec = opts.tickDecimals;
1698
+
1699
+            if (maxDec != null && dec > maxDec) {
1700
+                dec = maxDec;
1701
+            }
1702
+
1703
+            var magn = Math.pow(10, -dec),
1704
+                norm = delta / magn, // norm is between 1.0 and 10.0
1705
+                size;
1706
+
1707
+            if (norm < 1.5) {
1708
+                size = 1;
1709
+            } else if (norm < 3) {
1710
+                size = 2;
1711
+                // special case for 2.5, requires an extra decimal
1712
+                if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) {
1713
+                    size = 2.5;
1714
+                    ++dec;
1715
+                }
1716
+            } else if (norm < 7.5) {
1717
+                size = 5;
1718
+            } else {
1719
+                size = 10;
1720
+            }
1721
+
1722
+            size *= magn;
1723
+
1724
+            if (opts.minTickSize != null && size < opts.minTickSize) {
1725
+                size = opts.minTickSize;
1726
+            }
1727
+
1728
+            axis.delta = delta;
1729
+            axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec);
1730
+            axis.tickSize = opts.tickSize || size;
1731
+
1732
+            // Time mode was moved to a plug-in in 0.8, and since so many people use it
1733
+            // we'll add an especially friendly reminder to make sure they included it.
1734
+
1735
+            if (opts.mode == "time" && !axis.tickGenerator) {
1736
+                throw new Error("Time mode requires the flot.time plugin.");
1737
+            }
1738
+
1739
+            // Flot supports base-10 axes; any other mode else is handled by a plug-in,
1740
+            // like flot.time.js.
1741
+
1742
+            if (!axis.tickGenerator) {
1743
+
1744
+                axis.tickGenerator = function (axis) {
1745
+
1746
+                    var ticks = [],
1747
+                        start = floorInBase(axis.min, axis.tickSize),
1748
+                        i = 0,
1749
+                        v = Number.NaN,
1750
+                        prev;
1751
+
1752
+                    do {
1753
+                        prev = v;
1754
+                        v = start + i * axis.tickSize;
1755
+                        ticks.push(v);
1756
+                        ++i;
1757
+                    } while (v < axis.max && v != prev);
1758
+                    return ticks;
1759
+                };
1760
+
1761
+				axis.tickFormatter = function (value, axis) {
1762
+
1763
+					var factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1;
1764
+					var formatted = "" + Math.round(value * factor) / factor;
1765
+
1766
+					// If tickDecimals was specified, ensure that we have exactly that
1767
+					// much precision; otherwise default to the value's own precision.
1768
+
1769
+					if (axis.tickDecimals != null) {
1770
+						var decimal = formatted.indexOf(".");
1771
+						var precision = decimal == -1 ? 0 : formatted.length - decimal - 1;
1772
+						if (precision < axis.tickDecimals) {
1773
+							return (precision ? formatted : formatted + ".") + ("" + factor).substr(1, axis.tickDecimals - precision);
1774
+						}
1775
+					}
1776
+
1777
+                    return formatted;
1778
+                };
1779
+            }
1780
+
1781
+            if ($.isFunction(opts.tickFormatter))
1782
+                axis.tickFormatter = function (v, axis) { return "" + opts.tickFormatter(v, axis); };
1783
+
1784
+            if (opts.alignTicksWithAxis != null) {
1785
+                var otherAxis = (axis.direction == "x" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1];
1786
+                if (otherAxis && otherAxis.used && otherAxis != axis) {
1787
+                    // consider snapping min/max to outermost nice ticks
1788
+                    var niceTicks = axis.tickGenerator(axis);
1789
+                    if (niceTicks.length > 0) {
1790
+                        if (opts.min == null)
1791
+                            axis.min = Math.min(axis.min, niceTicks[0]);
1792
+                        if (opts.max == null && niceTicks.length > 1)
1793
+                            axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]);
1794
+                    }
1795
+
1796
+                    axis.tickGenerator = function (axis) {
1797
+                        // copy ticks, scaled to this axis
1798
+                        var ticks = [], v, i;
1799
+                        for (i = 0; i < otherAxis.ticks.length; ++i) {
1800
+                            v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min);
1801
+                            v = axis.min + v * (axis.max - axis.min);
1802
+                            ticks.push(v);
1803
+                        }
1804
+                        return ticks;
1805
+                    };
1806
+
1807
+                    // we might need an extra decimal since forced
1808
+                    // ticks don't necessarily fit naturally
1809
+                    if (!axis.mode && opts.tickDecimals == null) {
1810
+                        var extraDec = Math.max(0, -Math.floor(Math.log(axis.delta) / Math.LN10) + 1),
1811
+                            ts = axis.tickGenerator(axis);
1812
+
1813
+                        // only proceed if the tick interval rounded
1814
+                        // with an extra decimal doesn't give us a
1815
+                        // zero at end
1816
+                        if (!(ts.length > 1 && /\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec))))
1817
+                            axis.tickDecimals = extraDec;
1818
+                    }
1819
+                }
1820
+            }
1821
+        }
1822
+
1823
+        function setTicks(axis) {
1824
+            var oticks = axis.options.ticks, ticks = [];
1825
+            if (oticks == null || (typeof oticks == "number" && oticks > 0))
1826
+                ticks = axis.tickGenerator(axis);
1827
+            else if (oticks) {
1828
+                if ($.isFunction(oticks))
1829
+                    // generate the ticks
1830
+                    ticks = oticks(axis);
1831
+                else
1832
+                    ticks = oticks;
1833
+            }
1834
+
1835
+            // clean up/labelify the supplied ticks, copy them over
1836
+            var i, v;
1837
+            axis.ticks = [];
1838
+            for (i = 0; i < ticks.length; ++i) {
1839
+                var label = null;
1840
+                var t = ticks[i];
1841
+                if (typeof t == "object") {
1842
+                    v = +t[0];
1843
+                    if (t.length > 1)
1844
+                        label = t[1];
1845
+                }
1846
+                else
1847
+                    v = +t;
1848
+                if (label == null)
1849
+                    label = axis.tickFormatter(v, axis);
1850
+                if (!isNaN(v))
1851
+                    axis.ticks.push({ v: v, label: label });
1852
+            }
1853
+        }
1854
+
1855
+        function snapRangeToTicks(axis, ticks) {
1856
+            if (axis.options.autoscaleMargin && ticks.length > 0) {
1857
+                // snap to ticks
1858
+                if (axis.options.min == null)
1859
+                    axis.min = Math.min(axis.min, ticks[0].v);
1860
+                if (axis.options.max == null && ticks.length > 1)
1861
+                    axis.max = Math.max(axis.max, ticks[ticks.length - 1].v);
1862
+            }
1863
+        }
1864
+
1865
+        function draw() {
1866
+
1867
+            surface.clear();
1868
+
1869
+            executeHooks(hooks.drawBackground, [ctx]);
1870
+
1871
+            var grid = options.grid;
1872
+
1873
+            // draw background, if any
1874
+            if (grid.show && grid.backgroundColor)
1875
+                drawBackground();
1876
+
1877
+            if (grid.show && !grid.aboveData) {
1878
+                drawGrid();
1879
+            }
1880
+
1881
+            for (var i = 0; i < series.length; ++i) {
1882
+                executeHooks(hooks.drawSeries, [ctx, series[i]]);
1883
+                drawSeries(series[i]);
1884
+            }
1885
+
1886
+            executeHooks(hooks.draw, [ctx]);
1887
+
1888
+            if (grid.show && grid.aboveData) {
1889
+                drawGrid();
1890
+            }
1891
+
1892
+            surface.render();
1893
+
1894
+            // A draw implies that either the axes or data have changed, so we
1895
+            // should probably update the overlay highlights as well.
1896
+
1897
+            triggerRedrawOverlay();
1898
+        }
1899
+
1900
+        function extractRange(ranges, coord) {
1901
+            var axis, from, to, key, axes = allAxes();
1902
+
1903
+            for (var i = 0; i < axes.length; ++i) {
1904
+                axis = axes[i];
1905
+                if (axis.direction == coord) {
1906
+                    key = coord + axis.n + "axis";
1907
+                    if (!ranges[key] && axis.n == 1)
1908
+                        key = coord + "axis"; // support x1axis as xaxis
1909
+                    if (ranges[key]) {
1910
+                        from = ranges[key].from;
1911
+                        to = ranges[key].to;
1912
+                        break;
1913
+                    }
1914
+                }
1915
+            }
1916
+
1917
+            // backwards-compat stuff - to be removed in future
1918
+            if (!ranges[key]) {
1919
+                axis = coord == "x" ? xaxes[0] : yaxes[0];
1920
+                from = ranges[coord + "1"];
1921
+                to = ranges[coord + "2"];
1922
+            }
1923
+
1924
+            // auto-reverse as an added bonus
1925
+            if (from != null && to != null && from > to) {
1926
+                var tmp = from;
1927
+                from = to;
1928
+                to = tmp;
1929
+            }
1930
+
1931
+            return { from: from, to: to, axis: axis };
1932
+        }
1933
+
1934
+        function drawBackground() {
1935
+            ctx.save();
1936
+            ctx.translate(plotOffset.left, plotOffset.top);
1937
+
1938
+            ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)");
1939
+            ctx.fillRect(0, 0, plotWidth, plotHeight);
1940
+            ctx.restore();
1941
+        }
1942
+
1943
+        function drawGrid() {
1944
+            var i, axes, bw, bc;
1945
+
1946
+            ctx.save();
1947
+            ctx.translate(plotOffset.left, plotOffset.top);
1948
+
1949
+            // draw markings
1950
+            var markings = options.grid.markings;
1951
+            if (markings) {
1952
+                if ($.isFunction(markings)) {
1953
+                    axes = plot.getAxes();
1954
+                    // xmin etc. is backwards compatibility, to be
1955
+                    // removed in the future
1956
+                    axes.xmin = axes.xaxis.min;
1957
+                    axes.xmax = axes.xaxis.max;
1958
+                    axes.ymin = axes.yaxis.min;
1959
+                    axes.ymax = axes.yaxis.max;
1960
+
1961
+                    markings = markings(axes);
1962
+                }
1963
+
1964
+                for (i = 0; i < markings.length; ++i) {
1965
+                    var m = markings[i],
1966
+                        xrange = extractRange(m, "x"),
1967
+                        yrange = extractRange(m, "y");
1968
+
1969
+                    // fill in missing
1970
+                    if (xrange.from == null)
1971
+                        xrange.from = xrange.axis.min;
1972
+                    if (xrange.to == null)
1973
+                        xrange.to = xrange.axis.max;
1974
+                    if (yrange.from == null)
1975
+                        yrange.from = yrange.axis.min;
1976
+                    if (yrange.to == null)
1977
+                        yrange.to = yrange.axis.max;
1978
+
1979
+                    // clip
1980
+                    if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max ||
1981
+                        yrange.to < yrange.axis.min || yrange.from > yrange.axis.max)
1982
+                        continue;
1983
+
1984
+                    xrange.from = Math.max(xrange.from, xrange.axis.min);
1985
+                    xrange.to = Math.min(xrange.to, xrange.axis.max);
1986
+                    yrange.from = Math.max(yrange.from, yrange.axis.min);
1987
+                    yrange.to = Math.min(yrange.to, yrange.axis.max);
1988
+
1989
+                    var xequal = xrange.from === xrange.to,
1990
+                        yequal = yrange.from === yrange.to;
1991
+
1992
+                    if (xequal && yequal) {
1993
+                        continue;
1994
+                    }
1995
+
1996
+                    // then draw
1997
+                    xrange.from = Math.floor(xrange.axis.p2c(xrange.from));
1998
+                    xrange.to = Math.floor(xrange.axis.p2c(xrange.to));
1999
+                    yrange.from = Math.floor(yrange.axis.p2c(yrange.from));
2000
+                    yrange.to = Math.floor(yrange.axis.p2c(yrange.to));
2001
+
2002
+                    if (xequal || yequal) {
2003
+                        var lineWidth = m.lineWidth || options.grid.markingsLineWidth,
2004
+                            subPixel = lineWidth % 2 ? 0.5 : 0;
2005
+                        ctx.beginPath();
2006
+                        ctx.strokeStyle = m.color || options.grid.markingsColor;
2007
+                        ctx.lineWidth = lineWidth;
2008
+                        if (xequal) {
2009
+                            ctx.moveTo(xrange.to + subPixel, yrange.from);
2010
+                            ctx.lineTo(xrange.to + subPixel, yrange.to);
2011
+                        } else {
2012
+                            ctx.moveTo(xrange.from, yrange.to + subPixel);
2013
+                            ctx.lineTo(xrange.to, yrange.to + subPixel);                            
2014
+                        }
2015
+                        ctx.stroke();
2016
+                    } else {
2017
+                        ctx.fillStyle = m.color || options.grid.markingsColor;
2018
+                        ctx.fillRect(xrange.from, yrange.to,
2019
+                                     xrange.to - xrange.from,
2020
+                                     yrange.from - yrange.to);
2021
+                    }
2022
+                }
2023
+            }
2024
+
2025
+            // draw the ticks
2026
+            axes = allAxes();
2027
+            bw = options.grid.borderWidth;
2028
+
2029
+            for (var j = 0; j < axes.length; ++j) {
2030
+                var axis = axes[j], box = axis.box,
2031
+                    t = axis.tickLength, x, y, xoff, yoff;
2032
+                if (!axis.show || axis.ticks.length == 0)
2033
+                    continue;
2034
+
2035
+                ctx.lineWidth = 1;
2036
+
2037
+                // find the edges
2038
+                if (axis.direction == "x") {
2039
+                    x = 0;
2040
+                    if (t == "full")
2041
+                        y = (axis.position == "top" ? 0 : plotHeight);
2042
+                    else
2043
+                        y = box.top - plotOffset.top + (axis.position == "top" ? box.height : 0);
2044
+                }
2045
+                else {
2046
+                    y = 0;
2047
+                    if (t == "full")
2048
+                        x = (axis.position == "left" ? 0 : plotWidth);
2049
+                    else
2050
+                        x = box.left - plotOffset.left + (axis.position == "left" ? box.width : 0);
2051
+                }
2052
+
2053
+                // draw tick bar
2054
+                if (!axis.innermost) {
2055
+                    ctx.strokeStyle = axis.options.color;
2056
+                    ctx.beginPath();
2057
+                    xoff = yoff = 0;
2058
+                    if (axis.direction == "x")
2059
+                        xoff = plotWidth + 1;
2060
+                    else
2061
+                        yoff = plotHeight + 1;
2062
+
2063
+                    if (ctx.lineWidth == 1) {
2064
+                        if (axis.direction == "x") {
2065
+                            y = Math.floor(y) + 0.5;
2066
+                        } else {
2067
+                            x = Math.floor(x) + 0.5;
2068
+                        }
2069
+                    }
2070
+
2071
+                    ctx.moveTo(x, y);
2072
+                    ctx.lineTo(x + xoff, y + yoff);
2073
+                    ctx.stroke();
2074
+                }
2075
+
2076
+                // draw ticks
2077
+
2078
+                ctx.strokeStyle = axis.options.tickColor;
2079
+
2080
+                ctx.beginPath();
2081
+                for (i = 0; i < axis.ticks.length; ++i) {
2082
+                    var v = axis.ticks[i].v;
2083
+
2084
+                    xoff = yoff = 0;
2085
+
2086
+                    if (isNaN(v) || v < axis.min || v > axis.max
2087
+                        // skip those lying on the axes if we got a border
2088
+                        || (t == "full"
2089
+                            && ((typeof bw == "object" && bw[axis.position] > 0) || bw > 0)
2090
+                            && (v == axis.min || v == axis.max)))
2091
+                        continue;
2092
+
2093
+                    if (axis.direction == "x") {
2094
+                        x = axis.p2c(v);
2095
+                        yoff = t == "full" ? -plotHeight : t;
2096
+
2097
+                        if (axis.position == "top")
2098
+                            yoff = -yoff;
2099
+                    }
2100
+                    else {
2101
+                        y = axis.p2c(v);
2102
+                        xoff = t == "full" ? -plotWidth : t;
2103
+
2104
+                        if (axis.position == "left")
2105
+                            xoff = -xoff;
2106
+                    }
2107
+
2108
+                    if (ctx.lineWidth == 1) {
2109
+                        if (axis.direction == "x")
2110
+                            x = Math.floor(x) + 0.5;
2111
+                        else
2112
+                            y = Math.floor(y) + 0.5;
2113
+                    }
2114
+
2115
+                    ctx.moveTo(x, y);
2116
+                    ctx.lineTo(x + xoff, y + yoff);
2117
+                }
2118
+
2119
+                ctx.stroke();
2120
+            }
2121
+
2122
+
2123
+            // draw border
2124
+            if (bw) {
2125
+                // If either borderWidth or borderColor is an object, then draw the border
2126
+                // line by line instead of as one rectangle
2127
+                bc = options.grid.borderColor;
2128
+                if(typeof bw == "object" || typeof bc == "object") {
2129
+                    if (typeof bw !== "object") {
2130
+                        bw = {top: bw, right: bw, bottom: bw, left: bw};
2131
+                    }
2132
+                    if (typeof bc !== "object") {
2133
+                        bc = {top: bc, right: bc, bottom: bc, left: bc};
2134
+                    }
2135
+
2136
+                    if (bw.top > 0) {
2137
+                        ctx.strokeStyle = bc.top;
2138
+                        ctx.lineWidth = bw.top;
2139
+                        ctx.beginPath();
2140
+                        ctx.moveTo(0 - bw.left, 0 - bw.top/2);
2141
+                        ctx.lineTo(plotWidth, 0 - bw.top/2);
2142
+                        ctx.stroke();
2143
+                    }
2144
+
2145
+                    if (bw.right > 0) {
2146
+                        ctx.strokeStyle = bc.right;
2147
+                        ctx.lineWidth = bw.right;
2148
+                        ctx.beginPath();
2149
+                        ctx.moveTo(plotWidth + bw.right / 2, 0 - bw.top);
2150
+                        ctx.lineTo(plotWidth + bw.right / 2, plotHeight);
2151
+                        ctx.stroke();
2152
+                    }
2153
+
2154
+                    if (bw.bottom > 0) {
2155
+                        ctx.strokeStyle = bc.bottom;
2156
+                        ctx.lineWidth = bw.bottom;
2157
+                        ctx.beginPath();
2158
+                        ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2);
2159
+                        ctx.lineTo(0, plotHeight + bw.bottom / 2);
2160
+                        ctx.stroke();
2161
+                    }
2162
+
2163
+                    if (bw.left > 0) {
2164
+                        ctx.strokeStyle = bc.left;
2165
+                        ctx.lineWidth = bw.left;
2166
+                        ctx.beginPath();
2167
+                        ctx.moveTo(0 - bw.left/2, plotHeight + bw.bottom);
2168
+                        ctx.lineTo(0- bw.left/2, 0);
2169
+                        ctx.stroke();
2170
+                    }
2171
+                }
2172
+                else {
2173
+                    ctx.lineWidth = bw;
2174
+                    ctx.strokeStyle = options.grid.borderColor;
2175
+                    ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw);
2176
+                }
2177
+            }
2178
+
2179
+            ctx.restore();
2180
+        }
2181
+
2182
+        function drawAxisLabels() {
2183
+
2184
+            $.each(allAxes(), function (_, axis) {
2185
+                var box = axis.box,
2186
+                    legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis",
2187
+                    layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles,
2188
+                    font = axis.options.font || "flot-tick-label tickLabel",
2189
+                    tick, x, y, halign, valign;
2190
+
2191
+                // Remove text before checking for axis.show and ticks.length;
2192
+                // otherwise plugins, like flot-tickrotor, that draw their own
2193
+                // tick labels will end up with both theirs and the defaults.
2194
+
2195
+                surface.removeText(layer);
2196
+
2197
+                if (!axis.show || axis.ticks.length == 0)
2198
+                    return;
2199
+
2200
+                for (var i = 0; i < axis.ticks.length; ++i) {
2201
+
2202
+                    tick = axis.ticks[i];
2203
+                    if (!tick.label || tick.v < axis.min || tick.v > axis.max)
2204
+                        continue;
2205
+
2206
+                    if (axis.direction == "x") {
2207
+                        halign = "center";
2208
+                        x = plotOffset.left + axis.p2c(tick.v);
2209
+                        if (axis.position == "bottom") {
2210
+                            y = box.top + box.padding;
2211
+                        } else {
2212
+                            y = box.top + box.height - box.padding;
2213
+                            valign = "bottom";
2214
+                        }
2215
+                    } else {
2216
+                        valign = "middle";
2217
+                        y = plotOffset.top + axis.p2c(tick.v);
2218
+                        if (axis.position == "left") {
2219
+                            x = box.left + box.width - box.padding;
2220
+                            halign = "right";
2221
+                        } else {
2222
+                            x = box.left + box.padding;
2223
+                        }
2224
+                    }
2225
+
2226
+                    surface.addText(layer, x, y, tick.label, font, null, null, halign, valign);
2227
+                }
2228
+            });
2229
+        }
2230
+
2231
+        function drawSeries(series) {
2232
+            if (series.lines.show)
2233
+                drawSeriesLines(series);
2234
+            if (series.bars.show)
2235
+                drawSeriesBars(series);
2236
+            if (series.points.show)
2237
+                drawSeriesPoints(series);
2238
+        }
2239
+
2240
+        function drawSeriesLines(series) {
2241
+            function plotLine(datapoints, xoffset, yoffset, axisx, axisy) {
2242
+                var points = datapoints.points,
2243
+                    ps = datapoints.pointsize,
2244
+                    prevx = null, prevy = null;
2245
+
2246
+                ctx.beginPath();
2247
+                for (var i = ps; i < points.length; i += ps) {
2248
+                    var x1 = points[i - ps], y1 = points[i - ps + 1],
2249
+                        x2 = points[i], y2 = points[i + 1];
2250
+
2251
+                    if (x1 == null || x2 == null)
2252
+                        continue;
2253
+
2254
+                    // clip with ymin
2255
+                    if (y1 <= y2 && y1 < axisy.min) {
2256
+                        if (y2 < axisy.min)
2257
+                            continue;   // line segment is outside
2258
+                        // compute new intersection point
2259
+                        x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
2260
+                        y1 = axisy.min;
2261
+                    }
2262
+                    else if (y2 <= y1 && y2 < axisy.min) {
2263
+                        if (y1 < axisy.min)
2264
+                            continue;
2265
+                        x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
2266
+                        y2 = axisy.min;
2267
+                    }
2268
+
2269
+                    // clip with ymax
2270
+                    if (y1 >= y2 && y1 > axisy.max) {
2271
+                        if (y2 > axisy.max)
2272
+                            continue;
2273
+                        x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
2274
+                        y1 = axisy.max;
2275
+                    }
2276
+                    else if (y2 >= y1 && y2 > axisy.max) {
2277
+                        if (y1 > axisy.max)
2278
+                            continue;
2279
+                        x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
2280
+                        y2 = axisy.max;
2281
+                    }
2282
+
2283
+                    // clip with xmin
2284
+                    if (x1 <= x2 && x1 < axisx.min) {
2285
+                        if (x2 < axisx.min)
2286
+                            continue;
2287
+                        y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
2288
+                        x1 = axisx.min;
2289
+                    }
2290
+                    else if (x2 <= x1 && x2 < axisx.min) {
2291
+                        if (x1 < axisx.min)
2292
+                            continue;
2293
+                        y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
2294
+                        x2 = axisx.min;
2295
+                    }
2296
+
2297
+                    // clip with xmax
2298
+                    if (x1 >= x2 && x1 > axisx.max) {
2299
+                        if (x2 > axisx.max)
2300
+                            continue;
2301
+                        y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
2302
+                        x1 = axisx.max;
2303
+                    }
2304
+                    else if (x2 >= x1 && x2 > axisx.max) {
2305
+                        if (x1 > axisx.max)
2306
+                            continue;
2307
+                        y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
2308
+                        x2 = axisx.max;
2309
+                    }
2310
+
2311
+                    if (x1 != prevx || y1 != prevy)
2312
+                        ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset);
2313
+
2314
+                    prevx = x2;
2315
+                    prevy = y2;
2316
+                    ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset);
2317
+                }
2318
+                ctx.stroke();
2319
+            }
2320
+
2321
+            function plotLineArea(datapoints, axisx, axisy) {
2322
+                var points = datapoints.points,
2323
+                    ps = datapoints.pointsize,
2324
+                    bottom = Math.min(Math.max(0, axisy.min), axisy.max),
2325
+                    i = 0, top, areaOpen = false,
2326
+                    ypos = 1, segmentStart = 0, segmentEnd = 0;
2327
+
2328
+                // we process each segment in two turns, first forward
2329
+                // direction to sketch out top, then once we hit the
2330
+                // end we go backwards to sketch the bottom
2331
+                while (true) {
2332
+                    if (ps > 0 && i > points.length + ps)
2333
+                        break;
2334
+
2335
+                    i += ps; // ps is negative if going backwards
2336
+
2337
+                    var x1 = points[i - ps],
2338
+                        y1 = points[i - ps + ypos],
2339
+                        x2 = points[i], y2 = points[i + ypos];
2340
+
2341
+                    if (areaOpen) {
2342
+                        if (ps > 0 && x1 != null && x2 == null) {
2343
+                            // at turning point
2344
+                            segmentEnd = i;
2345
+                            ps = -ps;
2346
+                            ypos = 2;
2347
+                            continue;
2348
+                        }
2349
+
2350
+                        if (ps < 0 && i == segmentStart + ps) {
2351
+                            // done with the reverse sweep
2352
+                            ctx.fill();
2353
+                            areaOpen = false;
2354
+                            ps = -ps;
2355
+                            ypos = 1;
2356
+                            i = segmentStart = segmentEnd + ps;
2357
+                            continue;
2358
+                        }
2359
+                    }
2360
+
2361
+                    if (x1 == null || x2 == null)
2362
+                        continue;
2363
+
2364
+                    // clip x values
2365
+
2366
+                    // clip with xmin
2367
+                    if (x1 <= x2 && x1 < axisx.min) {
2368
+                        if (x2 < axisx.min)
2369
+                            continue;
2370
+                        y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
2371
+                        x1 = axisx.min;
2372
+                    }
2373
+                    else if (x2 <= x1 && x2 < axisx.min) {
2374
+                        if (x1 < axisx.min)
2375
+                            continue;
2376
+                        y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
2377
+                        x2 = axisx.min;
2378
+                    }
2379
+
2380
+                    // clip with xmax
2381
+                    if (x1 >= x2 && x1 > axisx.max) {
2382
+                        if (x2 > axisx.max)
2383
+                            continue;
2384
+                        y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
2385
+                        x1 = axisx.max;
2386
+                    }
2387
+                    else if (x2 >= x1 && x2 > axisx.max) {
2388
+                        if (x1 > axisx.max)
2389
+                            continue;
2390
+                        y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
2391
+                        x2 = axisx.max;
2392
+                    }
2393
+
2394
+                    if (!areaOpen) {
2395
+                        // open area
2396
+                        ctx.beginPath();
2397
+                        ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom));
2398
+                        areaOpen = true;
2399
+                    }
2400
+
2401
+                    // now first check the case where both is outside
2402
+                    if (y1 >= axisy.max && y2 >= axisy.max) {
2403
+                        ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max));
2404
+                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max));
2405
+                        continue;
2406
+                    }
2407
+                    else if (y1 <= axisy.min && y2 <= axisy.min) {
2408
+                        ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min));
2409
+                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min));
2410
+                        continue;
2411
+                    }
2412
+
2413
+                    // else it's a bit more complicated, there might
2414
+                    // be a flat maxed out rectangle first, then a
2415
+                    // triangular cutout or reverse; to find these
2416
+                    // keep track of the current x values
2417
+                    var x1old = x1, x2old = x2;
2418
+
2419
+                    // clip the y values, without shortcutting, we
2420
+                    // go through all cases in turn
2421
+
2422
+                    // clip with ymin
2423
+                    if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) {
2424
+                        x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
2425
+                        y1 = axisy.min;
2426
+                    }
2427
+                    else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) {
2428
+                        x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
2429
+                        y2 = axisy.min;
2430
+                    }
2431
+
2432
+                    // clip with ymax
2433
+                    if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) {
2434
+                        x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
2435
+                        y1 = axisy.max;
2436
+                    }
2437
+                    else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) {
2438
+                        x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
2439
+                        y2 = axisy.max;
2440
+                    }
2441
+
2442
+                    // if the x value was changed we got a rectangle
2443
+                    // to fill
2444
+                    if (x1 != x1old) {
2445
+                        ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1));
2446
+                        // it goes to (x1, y1), but we fill that below
2447
+                    }
2448
+
2449
+                    // fill triangular section, this sometimes result
2450
+                    // in redundant points if (x1, y1) hasn't changed
2451
+                    // from previous line to, but we just ignore that
2452
+                    ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1));
2453
+                    ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
2454
+
2455
+                    // fill the other rectangle if it's there
2456
+                    if (x2 != x2old) {
2457
+                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
2458
+                        ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2));
2459
+                    }
2460
+                }
2461
+            }
2462
+
2463
+            ctx.save();
2464
+            ctx.translate(plotOffset.left, plotOffset.top);
2465
+            ctx.lineJoin = "round";
2466
+
2467
+            var lw = series.lines.lineWidth,
2468
+                sw = series.shadowSize;
2469
+            // FIXME: consider another form of shadow when filling is turned on
2470
+            if (lw > 0 && sw > 0) {
2471
+                // draw shadow as a thick and thin line with transparency
2472
+                ctx.lineWidth = sw;
2473
+                ctx.strokeStyle = "rgba(0,0,0,0.1)";
2474
+                // position shadow at angle from the mid of line
2475
+                var angle = Math.PI/18;
2476
+                plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis);
2477
+                ctx.lineWidth = sw/2;
2478
+                plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis);
2479
+            }
2480
+
2481
+            ctx.lineWidth = lw;
2482
+            ctx.strokeStyle = series.color;
2483
+            var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight);
2484
+            if (fillStyle) {
2485
+                ctx.fillStyle = fillStyle;
2486
+                plotLineArea(series.datapoints, series.xaxis, series.yaxis);
2487
+            }
2488
+
2489
+            if (lw > 0)
2490
+                plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis);
2491
+            ctx.restore();
2492
+        }
2493
+
2494
+        function drawSeriesPoints(series) {
2495
+            function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) {
2496
+                var points = datapoints.points, ps = datapoints.pointsize;
2497
+
2498
+                for (var i = 0; i < points.length; i += ps) {
2499
+                    var x = points[i], y = points[i + 1];
2500
+                    if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
2501
+                        continue;
2502
+
2503
+                    ctx.beginPath();
2504
+                    x = axisx.p2c(x);
2505
+                    y = axisy.p2c(y) + offset;
2506
+                    if (symbol == "circle")
2507
+                        ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false);
2508
+                    else
2509
+                        symbol(ctx, x, y, radius, shadow);
2510
+                    ctx.closePath();
2511
+
2512
+                    if (fillStyle) {
2513
+                        ctx.fillStyle = fillStyle;
2514
+                        ctx.fill();
2515
+                    }
2516
+                    ctx.stroke();
2517
+                }
2518
+            }
2519
+
2520
+            ctx.save();
2521
+            ctx.translate(plotOffset.left, plotOffset.top);
2522
+
2523
+            var lw = series.points.lineWidth,
2524
+                sw = series.shadowSize,
2525
+                radius = series.points.radius,
2526
+                symbol = series.points.symbol;
2527
+
2528
+            // If the user sets the line width to 0, we change it to a very 
2529
+            // small value. A line width of 0 seems to force the default of 1.
2530
+            // Doing the conditional here allows the shadow setting to still be 
2531
+            // optional even with a lineWidth of 0.
2532
+
2533
+            if( lw == 0 )
2534
+                lw = 0.0001;
2535
+
2536
+            if (lw > 0 && sw > 0) {
2537
+                // draw shadow in two steps
2538
+                var w = sw / 2;
2539
+                ctx.lineWidth = w;
2540
+                ctx.strokeStyle = "rgba(0,0,0,0.1)";
2541
+                plotPoints(series.datapoints, radius, null, w + w/2, true,
2542
+                           series.xaxis, series.yaxis, symbol);
2543
+
2544
+                ctx.strokeStyle = "rgba(0,0,0,0.2)";
2545
+                plotPoints(series.datapoints, radius, null, w/2, true,
2546
+                           series.xaxis, series.yaxis, symbol);
2547
+            }
2548
+
2549
+            ctx.lineWidth = lw;
2550
+            ctx.strokeStyle = series.color;
2551
+            plotPoints(series.datapoints, radius,
2552
+                       getFillStyle(series.points, series.color), 0, false,
2553
+                       series.xaxis, series.yaxis, symbol);
2554
+            ctx.restore();
2555
+        }
2556
+
2557
+        function drawBar(x, y, b, barLeft, barRight, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) {
2558
+            var left, right, bottom, top,
2559
+                drawLeft, drawRight, drawTop, drawBottom,
2560
+                tmp;
2561
+
2562
+            // in horizontal mode, we start the bar from the left
2563
+            // instead of from the bottom so it appears to be
2564
+            // horizontal rather than vertical
2565
+            if (horizontal) {
2566
+                drawBottom = drawRight = drawTop = true;
2567
+                drawLeft = false;
2568
+                left = b;
2569
+                right = x;
2570
+                top = y + barLeft;
2571
+                bottom = y + barRight;
2572
+
2573
+                // account for negative bars
2574
+                if (right < left) {
2575
+                    tmp = right;
2576
+                    right = left;
2577
+                    left = tmp;
2578
+                    drawLeft = true;
2579
+                    drawRight = false;
2580
+                }
2581
+            }
2582
+            else {
2583
+                drawLeft = drawRight = drawTop = true;
2584
+                drawBottom = false;
2585
+                left = x + barLeft;
2586
+                right = x + barRight;
2587
+                bottom = b;
2588
+                top = y;
2589
+
2590
+                // account for negative bars
2591
+                if (top < bottom) {
2592
+                    tmp = top;
2593
+                    top = bottom;
2594
+                    bottom = tmp;
2595
+                    drawBottom = true;
2596
+                    drawTop = false;
2597
+                }
2598
+            }
2599
+
2600
+            // clip
2601
+            if (right < axisx.min || left > axisx.max ||
2602
+                top < axisy.min || bottom > axisy.max)
2603
+                return;
2604
+
2605
+            if (left < axisx.min) {
2606
+                left = axisx.min;
2607
+                drawLeft = false;
2608
+            }
2609
+
2610
+            if (right > axisx.max) {
2611
+                right = axisx.max;
2612
+                drawRight = false;
2613
+            }
2614
+
2615
+            if (bottom < axisy.min) {
2616
+                bottom = axisy.min;
2617
+                drawBottom = false;
2618
+            }
2619
+
2620
+            if (top > axisy.max) {
2621
+                top = axisy.max;
2622
+                drawTop = false;
2623
+            }
2624
+
2625
+            left = axisx.p2c(left);
2626
+            bottom = axisy.p2c(bottom);
2627
+            right = axisx.p2c(right);
2628
+            top = axisy.p2c(top);
2629
+
2630
+            // fill the bar
2631
+            if (fillStyleCallback) {
2632
+                c.fillStyle = fillStyleCallback(bottom, top);
2633
+                c.fillRect(left, top, right - left, bottom - top)
2634
+            }
2635
+
2636
+            // draw outline
2637
+            if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) {
2638
+                c.beginPath();
2639
+
2640
+                // FIXME: inline moveTo is buggy with excanvas
2641
+                c.moveTo(left, bottom);
2642
+                if (drawLeft)
2643
+                    c.lineTo(left, top);
2644
+                else
2645
+                    c.moveTo(left, top);
2646
+                if (drawTop)
2647
+                    c.lineTo(right, top);
2648
+                else
2649
+                    c.moveTo(right, top);
2650
+                if (drawRight)
2651
+                    c.lineTo(right, bottom);
2652
+                else
2653
+                    c.moveTo(right, bottom);
2654
+                if (drawBottom)
2655
+                    c.lineTo(left, bottom);
2656
+                else
2657
+                    c.moveTo(left, bottom);
2658
+                c.stroke();
2659
+            }
2660
+        }
2661
+
2662
+        function drawSeriesBars(series) {
2663
+            function plotBars(datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy) {
2664
+                var points = datapoints.points, ps = datapoints.pointsize;
2665
+
2666
+                for (var i = 0; i < points.length; i += ps) {
2667
+                    if (points[i] == null)
2668
+                        continue;
2669
+                    drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth);
2670
+                }
2671
+            }
2672
+
2673
+            ctx.save();
2674
+            ctx.translate(plotOffset.left, plotOffset.top);
2675
+
2676
+            // FIXME: figure out a way to add shadows (for instance along the right edge)
2677
+            ctx.lineWidth = series.bars.lineWidth;
2678
+            ctx.strokeStyle = series.color;
2679
+
2680
+            var barLeft;
2681
+
2682
+            switch (series.bars.align) {
2683
+                case "left":
2684
+                    barLeft = 0;
2685
+                    break;
2686
+                case "right":
2687
+                    barLeft = -series.bars.barWidth;
2688
+                    break;
2689
+                default:
2690
+                    barLeft = -series.bars.barWidth / 2;
2691
+            }
2692
+
2693
+            var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null;
2694
+            plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, fillStyleCallback, series.xaxis, series.yaxis);
2695
+            ctx.restore();
2696
+        }
2697
+
2698
+        function getFillStyle(filloptions, seriesColor, bottom, top) {
2699
+            var fill = filloptions.fill;
2700
+            if (!fill)
2701
+                return null;
2702
+
2703
+            if (filloptions.fillColor)
2704
+                return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor);
2705
+
2706
+            var c = $.color.parse(seriesColor);
2707
+            c.a = typeof fill == "number" ? fill : 0.4;
2708
+            c.normalize();
2709
+            return c.toString();
2710
+        }
2711
+
2712
+        function insertLegend() {
2713
+
2714
+            if (options.legend.container != null) {
2715
+                $(options.legend.container).html("");
2716
+            } else {
2717
+                placeholder.find(".legend").remove();
2718
+            }
2719
+
2720
+            if (!options.legend.show) {
2721
+                return;
2722
+            }
2723
+
2724
+            var fragments = [], entries = [], rowStarted = false,
2725
+                lf = options.legend.labelFormatter, s, label;
2726
+
2727
+            // Build a list of legend entries, with each having a label and a color
2728
+
2729
+            for (var i = 0; i < series.length; ++i) {
2730
+                s = series[i];
2731
+                if (s.label) {
2732
+                    label = lf ? lf(s.label, s) : s.label;
2733
+                    if (label) {
2734
+                        entries.push({
2735
+                            label: label,
2736
+                            color: s.color
2737
+                        });
2738
+                    }
2739
+                }
2740
+            }
2741
+
2742
+            // Sort the legend using either the default or a custom comparator
2743
+
2744
+            if (options.legend.sorted) {
2745
+                if ($.isFunction(options.legend.sorted)) {
2746
+                    entries.sort(options.legend.sorted);
2747
+                } else if (options.legend.sorted == "reverse") {
2748
+                	entries.reverse();
2749
+                } else {
2750
+                    var ascending = options.legend.sorted != "descending";
2751
+                    entries.sort(function(a, b) {
2752
+                        return a.label == b.label ? 0 : (
2753
+                            (a.label < b.label) != ascending ? 1 : -1   // Logical XOR
2754
+                        );
2755
+                    });
2756
+                }
2757
+            }
2758
+
2759
+            // Generate markup for the list of entries, in their final order
2760
+
2761
+            for (var i = 0; i < entries.length; ++i) {
2762
+
2763
+                var entry = entries[i];
2764
+
2765
+                if (i % options.legend.noColumns == 0) {
2766
+                    if (rowStarted)
2767
+                        fragments.push('</tr>');
2768
+                    fragments.push('<tr>');
2769
+                    rowStarted = true;
2770
+                }
2771
+
2772
+                fragments.push(
2773
+                    '<td class="legendColorBox"><div style="border:1px solid ' + options.legend.labelBoxBorderColor + ';padding:1px"><div style="width:4px;height:0;border:5px solid ' + entry.color + ';overflow:hidden"></div></div></td>' +
2774
+                    '<td class="legendLabel">' + entry.label + '</td>'
2775
+                );
2776
+            }
2777
+
2778
+            if (rowStarted)
2779
+                fragments.push('</tr>');
2780
+
2781
+            if (fragments.length == 0)
2782
+                return;
2783
+
2784
+            var table = '<table style="font-size:smaller;color:' + options.grid.color + '">' + fragments.join("") + '</table>';
2785
+            if (options.legend.container != null)
2786
+                $(options.legend.container).html(table);
2787
+            else {
2788
+                var pos = "",
2789
+                    p = options.legend.position,
2790
+                    m = options.legend.margin;
2791
+                if (m[0] == null)
2792
+                    m = [m, m];
2793
+                if (p.charAt(0) == "n")
2794
+                    pos += 'top:' + (m[1] + plotOffset.top) + 'px;';
2795
+                else if (p.charAt(0) == "s")
2796
+                    pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;';
2797
+                if (p.charAt(1) == "e")
2798
+                    pos += 'right:' + (m[0] + plotOffset.right) + 'px;';
2799
+                else if (p.charAt(1) == "w")
2800
+                    pos += 'left:' + (m[0] + plotOffset.left) + 'px;';
2801
+                var legend = $('<div class="legend">' + table.replace('style="', 'style="position:absolute;' + pos +';') + '</div>').appendTo(placeholder);
2802
+                if (options.legend.backgroundOpacity != 0.0) {
2803
+                    // put in the transparent background
2804
+                    // separately to avoid blended labels and
2805
+                    // label boxes
2806
+                    var c = options.legend.backgroundColor;
2807
+                    if (c == null) {
2808
+                        c = options.grid.backgroundColor;
2809
+                        if (c && typeof c == "string")
2810
+                            c = $.color.parse(c);
2811
+                        else
2812
+                            c = $.color.extract(legend, 'background-color');
2813
+                        c.a = 1;
2814
+                        c = c.toString();
2815
+                    }
2816
+                    var div = legend.children();
2817
+                    $('<div style="position:absolute;width:' + div.width() + 'px;height:' + div.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').prependTo(legend).css('opacity', options.legend.backgroundOpacity);
2818
+                }
2819
+            }
2820
+        }
2821
+
2822
+
2823
+        // interactive features
2824
+
2825
+        var highlights = [],
2826
+            redrawTimeout = null;
2827
+
2828
+        // returns the data item the mouse is over, or null if none is found
2829
+        function findNearbyItem(mouseX, mouseY, seriesFilter) {
2830
+            var maxDistance = options.grid.mouseActiveRadius,
2831
+                smallestDistance = maxDistance * maxDistance + 1,
2832
+                item = null, foundPoint = false, i, j, ps;
2833
+
2834
+            for (i = series.length - 1; i >= 0; --i) {
2835
+                if (!seriesFilter(series[i]))
2836
+                    continue;
2837
+
2838
+                var s = series[i],
2839
+                    axisx = s.xaxis,
2840
+                    axisy = s.yaxis,
2841
+                    points = s.datapoints.points,
2842
+                    mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster
2843
+                    my = axisy.c2p(mouseY),
2844
+                    maxx = maxDistance / axisx.scale,
2845
+                    maxy = maxDistance / axisy.scale;
2846
+
2847
+                ps = s.datapoints.pointsize;
2848
+                // with inverse transforms, we can't use the maxx/maxy
2849
+                // optimization, sadly
2850
+                if (axisx.options.inverseTransform)
2851
+                    maxx = Number.MAX_VALUE;
2852
+                if (axisy.options.inverseTransform)
2853
+                    maxy = Number.MAX_VALUE;
2854
+
2855
+                if (s.lines.show || s.points.show) {
2856
+                    for (j = 0; j < points.length; j += ps) {
2857
+                        var x = points[j], y = points[j + 1];
2858
+                        if (x == null)
2859
+                            continue;
2860
+
2861
+                        // For points and lines, the cursor must be within a
2862
+                        // certain distance to the data point
2863
+                        if (x - mx > maxx || x - mx < -maxx ||
2864
+                            y - my > maxy || y - my < -maxy)
2865
+                            continue;
2866
+
2867
+                        // We have to calculate distances in pixels, not in
2868
+                        // data units, because the scales of the axes may be different
2869
+                        var dx = Math.abs(axisx.p2c(x) - mouseX),
2870
+                            dy = Math.abs(axisy.p2c(y) - mouseY),
2871
+                            dist = dx * dx + dy * dy; // we save the sqrt
2872
+
2873
+                        // use <= to ensure last point takes precedence
2874
+                        // (last generally means on top of)
2875
+                        if (dist < smallestDistance) {
2876
+                            smallestDistance = dist;
2877
+                            item = [i, j / ps];
2878
+                        }
2879
+                    }
2880
+                }
2881
+
2882
+                if (s.bars.show && !item) { // no other point can be nearby
2883
+
2884
+                    var barLeft, barRight;
2885
+
2886
+                    switch (s.bars.align) {
2887
+                        case "left":
2888
+                            barLeft = 0;
2889
+                            break;
2890
+                        case "right":
2891
+                            barLeft = -s.bars.barWidth;
2892
+                            break;
2893
+                        default:
2894
+                            barLeft = -s.bars.barWidth / 2;
2895
+                    }
2896
+
2897
+                    barRight = barLeft + s.bars.barWidth;
2898
+
2899
+                    for (j = 0; j < points.length; j += ps) {
2900
+                        var x = points[j], y = points[j + 1], b = points[j + 2];
2901
+                        if (x == null)
2902
+                            continue;
2903
+
2904
+                        // for a bar graph, the cursor must be inside the bar
2905
+                        if (series[i].bars.horizontal ?
2906
+                            (mx <= Math.max(b, x) && mx >= Math.min(b, x) &&
2907
+                             my >= y + barLeft && my <= y + barRight) :
2908
+                            (mx >= x + barLeft && mx <= x + barRight &&
2909
+                             my >= Math.min(b, y) && my <= Math.max(b, y)))
2910
+                                item = [i, j / ps];
2911
+                    }
2912
+                }
2913
+            }
2914
+
2915
+            if (item) {
2916
+                i = item[0];
2917
+                j = item[1];
2918
+                ps = series[i].datapoints.pointsize;
2919
+
2920
+                return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps),
2921
+                         dataIndex: j,
2922
+                         series: series[i],
2923
+                         seriesIndex: i };
2924
+            }
2925
+
2926
+            return null;
2927
+        }
2928
+
2929
+        function onMouseMove(e) {
2930
+            if (options.grid.hoverable)
2931
+                triggerClickHoverEvent("plothover", e,
2932
+                                       function (s) { return s["hoverable"] != false; });
2933
+        }
2934
+
2935
+        function onMouseLeave(e) {
2936
+            if (options.grid.hoverable)
2937
+                triggerClickHoverEvent("plothover", e,
2938
+                                       function (s) { return false; });
2939
+        }
2940
+
2941
+        function onClick(e) {
2942
+            triggerClickHoverEvent("plotclick", e,
2943
+                                   function (s) { return s["clickable"] != false; });
2944
+        }
2945
+
2946
+        // trigger click or hover event (they send the same parameters
2947
+        // so we share their code)
2948
+        function triggerClickHoverEvent(eventname, event, seriesFilter) {
2949
+            var offset = eventHolder.offset(),
2950
+                canvasX = event.pageX - offset.left - plotOffset.left,
2951
+                canvasY = event.pageY - offset.top - plotOffset.top,
2952
+            pos = canvasToAxisCoords({ left: canvasX, top: canvasY });
2953
+
2954
+            pos.pageX = event.pageX;
2955
+            pos.pageY = event.pageY;
2956
+
2957
+            var item = findNearbyItem(canvasX, canvasY, seriesFilter);
2958
+
2959
+            if (item) {
2960
+                // fill in mouse pos for any listeners out there
2961
+                item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left, 10);
2962
+                item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top, 10);
2963
+            }
2964
+
2965
+            if (options.grid.autoHighlight) {
2966
+                // clear auto-highlights
2967
+                for (var i = 0; i < highlights.length; ++i) {
2968
+                    var h = highlights[i];
2969
+                    if (h.auto == eventname &&
2970
+                        !(item && h.series == item.series &&
2971
+                          h.point[0] == item.datapoint[0] &&
2972
+                          h.point[1] == item.datapoint[1]))
2973
+                        unhighlight(h.series, h.point);
2974
+                }
2975
+
2976
+                if (item)
2977
+                    highlight(item.series, item.datapoint, eventname);
2978
+            }
2979
+
2980
+            placeholder.trigger(eventname, [ pos, item ]);
2981
+        }
2982
+
2983
+        function triggerRedrawOverlay() {
2984
+            var t = options.interaction.redrawOverlayInterval;
2985
+            if (t == -1) {      // skip event queue
2986
+                drawOverlay();
2987
+                return;
2988
+            }
2989
+
2990
+            if (!redrawTimeout)
2991
+                redrawTimeout = setTimeout(drawOverlay, t);
2992
+        }
2993
+
2994
+        function drawOverlay() {
2995
+            redrawTimeout = null;
2996
+
2997
+            // draw highlights
2998
+            octx.save();
2999
+            overlay.clear();
3000
+            octx.translate(plotOffset.left, plotOffset.top);
3001
+
3002
+            var i, hi;
3003
+            for (i = 0; i < highlights.length; ++i) {
3004
+                hi = highlights[i];
3005
+
3006
+                if (hi.series.bars.show)
3007
+                    drawBarHighlight(hi.series, hi.point);
3008
+                else
3009
+                    drawPointHighlight(hi.series, hi.point);
3010
+            }
3011
+            octx.restore();
3012
+
3013
+            executeHooks(hooks.drawOverlay, [octx]);
3014
+        }
3015
+
3016
+        function highlight(s, point, auto) {
3017
+            if (typeof s == "number")
3018
+                s = series[s];
3019
+
3020
+            if (typeof point == "number") {
3021
+                var ps = s.datapoints.pointsize;
3022
+                point = s.datapoints.points.slice(ps * point, ps * (point + 1));
3023
+            }
3024
+
3025
+            var i = indexOfHighlight(s, point);
3026
+            if (i == -1) {
3027
+                highlights.push({ series: s, point: point, auto: auto });
3028
+
3029
+                triggerRedrawOverlay();
3030
+            }
3031
+            else if (!auto)
3032
+                highlights[i].auto = false;
3033
+        }
3034
+
3035
+        function unhighlight(s, point) {
3036
+            if (s == null && point == null) {
3037
+                highlights = [];
3038
+                triggerRedrawOverlay();
3039
+                return;
3040
+            }
3041
+
3042
+            if (typeof s == "number")
3043
+                s = series[s];
3044
+
3045
+            if (typeof point == "number") {
3046
+                var ps = s.datapoints.pointsize;
3047
+                point = s.datapoints.points.slice(ps * point, ps * (point + 1));
3048
+            }
3049
+
3050
+            var i = indexOfHighlight(s, point);
3051
+            if (i != -1) {
3052
+                highlights.splice(i, 1);
3053
+
3054
+                triggerRedrawOverlay();
3055
+            }
3056
+        }
3057
+
3058
+        function indexOfHighlight(s, p) {
3059
+            for (var i = 0; i < highlights.length; ++i) {
3060
+                var h = highlights[i];
3061
+                if (h.series == s && h.point[0] == p[0]
3062
+                    && h.point[1] == p[1])
3063
+                    return i;
3064
+            }
3065
+            return -1;
3066
+        }
3067
+
3068
+        function drawPointHighlight(series, point) {
3069
+            var x = point[0], y = point[1],
3070
+                axisx = series.xaxis, axisy = series.yaxis,
3071
+                highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString();
3072
+
3073
+            if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
3074
+                return;
3075
+
3076
+            var pointRadius = series.points.radius + series.points.lineWidth / 2;
3077
+            octx.lineWidth = pointRadius;
3078
+            octx.strokeStyle = highlightColor;
3079
+            var radius = 1.5 * pointRadius;
3080
+            x = axisx.p2c(x);
3081
+            y = axisy.p2c(y);
3082
+
3083
+            octx.beginPath();
3084
+            if (series.points.symbol == "circle")
3085
+                octx.arc(x, y, radius, 0, 2 * Math.PI, false);
3086
+            else
3087
+                series.points.symbol(octx, x, y, radius, false);
3088
+            octx.closePath();
3089
+            octx.stroke();
3090
+        }
3091
+
3092
+        function drawBarHighlight(series, point) {
3093
+            var highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(),
3094
+                fillStyle = highlightColor,
3095
+                barLeft;
3096
+
3097
+            switch (series.bars.align) {
3098
+                case "left":
3099
+                    barLeft = 0;
3100
+                    break;
3101
+                case "right":
3102
+                    barLeft = -series.bars.barWidth;
3103
+                    break;
3104
+                default:
3105
+                    barLeft = -series.bars.barWidth / 2;
3106
+            }
3107
+
3108
+            octx.lineWidth = series.bars.lineWidth;
3109
+            octx.strokeStyle = highlightColor;
3110
+
3111
+            drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth,
3112
+                    function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth);
3113
+        }
3114
+
3115
+        function getColorOrGradient(spec, bottom, top, defaultColor) {
3116
+            if (typeof spec == "string")
3117
+                return spec;
3118
+            else {
3119
+                // assume this is a gradient spec; IE currently only
3120
+                // supports a simple vertical gradient properly, so that's
3121
+                // what we support too
3122
+                var gradient = ctx.createLinearGradient(0, top, 0, bottom);
3123
+
3124
+                for (var i = 0, l = spec.colors.length; i < l; ++i) {
3125
+                    var c = spec.colors[i];
3126
+                    if (typeof c != "string") {
3127
+                        var co = $.color.parse(defaultColor);
3128
+                        if (c.brightness != null)
3129
+                            co = co.scale('rgb', c.brightness);
3130
+                        if (c.opacity != null)
3131
+                            co.a *= c.opacity;
3132
+                        c = co.toString();
3133
+                    }
3134
+                    gradient.addColorStop(i / (l - 1), c);
3135
+                }
3136
+
3137
+                return gradient;
3138
+            }
3139
+        }
3140
+    }
3141
+
3142
+    // Add the plot function to the top level of the jQuery object
3143
+
3144
+    $.plot = function(placeholder, data, options) {
3145
+        //var t0 = new Date();
3146
+        var plot = new Plot($(placeholder), data, options, $.plot.plugins);
3147
+        //(window.console ? console.log : alert)("time used (msecs): " + ((new Date()).getTime() - t0.getTime()));
3148
+        return plot;
3149
+    };
3150
+
3151
+    $.plot.version = "0.8.3";
3152
+
3153
+    $.plot.plugins = [];
3154
+
3155
+    // Also add the plot function as a chainable property
3156
+
3157
+    $.fn.plot = function(data, options) {
3158
+        return this.each(function() {
3159
+            $.plot(this, data, options);
3160
+        });
3161
+    };
3162
+
3163
+    // round to nearby lower multiple of base
3164
+    function floorInBase(n, base) {
3165
+        return base * Math.floor(n / base);
3166
+    }
3167
+
3168
+})(jQuery);
... ...
@@ -0,0 +1,8 @@
1
+/* Javascript plotting library for jQuery, version 0.8.3.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+*/
7
+(function($){$.color={};$.color.make=function(r,g,b,a){var o={};o.r=r||0;o.g=g||0;o.b=b||0;o.a=a!=null?a:1;o.add=function(c,d){for(var i=0;i<c.length;++i)o[c.charAt(i)]+=d;return o.normalize()};o.scale=function(c,f){for(var i=0;i<c.length;++i)o[c.charAt(i)]*=f;return o.normalize()};o.toString=function(){if(o.a>=1){return"rgb("+[o.r,o.g,o.b].join(",")+")"}else{return"rgba("+[o.r,o.g,o.b,o.a].join(",")+")"}};o.normalize=function(){function clamp(min,value,max){return value<min?min:value>max?max:value}o.r=clamp(0,parseInt(o.r),255);o.g=clamp(0,parseInt(o.g),255);o.b=clamp(0,parseInt(o.b),255);o.a=clamp(0,o.a,1);return o};o.clone=function(){return $.color.make(o.r,o.b,o.g,o.a)};return o.normalize()};$.color.extract=function(elem,css){var c;do{c=elem.css(css).toLowerCase();if(c!=""&&c!="transparent")break;elem=elem.parent()}while(elem.length&&!$.nodeName(elem.get(0),"body"));if(c=="rgba(0, 0, 0, 0)")c="transparent";return $.color.parse(c)};$.color.parse=function(str){var res,m=$.color.make;if(res=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10));if(res=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10),parseFloat(res[4]));if(res=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55);if(res=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55,parseFloat(res[4]));if(res=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))return m(parseInt(res[1],16),parseInt(res[2],16),parseInt(res[3],16));if(res=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))return m(parseInt(res[1]+res[1],16),parseInt(res[2]+res[2],16),parseInt(res[3]+res[3],16));var name=$.trim(str).toLowerCase();if(name=="transparent")return m(255,255,255,0);else{res=lookupColors[name]||[0,0,0];return m(res[0],res[1],res[2])}};var lookupColors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,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,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]}})(jQuery);(function($){var hasOwnProperty=Object.prototype.hasOwnProperty;if(!$.fn.detach){$.fn.detach=function(){return this.each(function(){if(this.parentNode){this.parentNode.removeChild(this)}})}}function Canvas(cls,container){var element=container.children("."+cls)[0];if(element==null){element=document.createElement("canvas");element.className=cls;$(element).css({direction:"ltr",position:"absolute",left:0,top:0}).appendTo(container);if(!element.getContext){if(window.G_vmlCanvasManager){element=window.G_vmlCanvasManager.initElement(element)}else{throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode.")}}}this.element=element;var context=this.context=element.getContext("2d");var devicePixelRatio=window.devicePixelRatio||1,backingStoreRatio=context.webkitBackingStorePixelRatio||context.mozBackingStorePixelRatio||context.msBackingStorePixelRatio||context.oBackingStorePixelRatio||context.backingStorePixelRatio||1;this.pixelRatio=devicePixelRatio/backingStoreRatio;this.resize(container.width(),container.height());this.textContainer=null;this.text={};this._textCache={}}Canvas.prototype.resize=function(width,height){if(width<=0||height<=0){throw new Error("Invalid dimensions for plot, width = "+width+", height = "+height)}var element=this.element,context=this.context,pixelRatio=this.pixelRatio;if(this.width!=width){element.width=width*pixelRatio;element.style.width=width+"px";this.width=width}if(this.height!=height){element.height=height*pixelRatio;element.style.height=height+"px";this.height=height}context.restore();context.save();context.scale(pixelRatio,pixelRatio)};Canvas.prototype.clear=function(){this.context.clearRect(0,0,this.width,this.height)};Canvas.prototype.render=function(){var cache=this._textCache;for(var layerKey in cache){if(hasOwnProperty.call(cache,layerKey)){var layer=this.getTextLayer(layerKey),layerCache=cache[layerKey];layer.hide();for(var styleKey in layerCache){if(hasOwnProperty.call(layerCache,styleKey)){var styleCache=layerCache[styleKey];for(var key in styleCache){if(hasOwnProperty.call(styleCache,key)){var positions=styleCache[key].positions;for(var i=0,position;position=positions[i];i++){if(position.active){if(!position.rendered){layer.append(position.element);position.rendered=true}}else{positions.splice(i--,1);if(position.rendered){position.element.detach()}}}if(positions.length==0){delete styleCache[key]}}}}}layer.show()}}};Canvas.prototype.getTextLayer=function(classes){var layer=this.text[classes];if(layer==null){if(this.textContainer==null){this.textContainer=$("<div class='flot-text'></div>").css({position:"absolute",top:0,left:0,bottom:0,right:0,"font-size":"smaller",color:"#545454"}).insertAfter(this.element)}layer=this.text[classes]=$("<div></div>").addClass(classes).css({position:"absolute",top:0,left:0,bottom:0,right:0}).appendTo(this.textContainer)}return layer};Canvas.prototype.getTextInfo=function(layer,text,font,angle,width){var textStyle,layerCache,styleCache,info;text=""+text;if(typeof font==="object"){textStyle=font.style+" "+font.variant+" "+font.weight+" "+font.size+"px/"+font.lineHeight+"px "+font.family}else{textStyle=font}layerCache=this._textCache[layer];if(layerCache==null){layerCache=this._textCache[layer]={}}styleCache=layerCache[textStyle];if(styleCache==null){styleCache=layerCache[textStyle]={}}info=styleCache[text];if(info==null){var element=$("<div></div>").html(text).css({position:"absolute","max-width":width,top:-9999}).appendTo(this.getTextLayer(layer));if(typeof font==="object"){element.css({font:textStyle,color:font.color})}else if(typeof font==="string"){element.addClass(font)}info=styleCache[text]={width:element.outerWidth(true),height:element.outerHeight(true),element:element,positions:[]};element.detach()}return info};Canvas.prototype.addText=function(layer,x,y,text,font,angle,width,halign,valign){var info=this.getTextInfo(layer,text,font,angle,width),positions=info.positions;if(halign=="center"){x-=info.width/2}else if(halign=="right"){x-=info.width}if(valign=="middle"){y-=info.height/2}else if(valign=="bottom"){y-=info.height}for(var i=0,position;position=positions[i];i++){if(position.x==x&&position.y==y){position.active=true;return}}position={active:true,rendered:false,element:positions.length?info.element.clone():info.element,x:x,y:y};positions.push(position);position.element.css({top:Math.round(y),left:Math.round(x),"text-align":halign})};Canvas.prototype.removeText=function(layer,x,y,text,font,angle){if(text==null){var layerCache=this._textCache[layer];if(layerCache!=null){for(var styleKey in layerCache){if(hasOwnProperty.call(layerCache,styleKey)){var styleCache=layerCache[styleKey];for(var key in styleCache){if(hasOwnProperty.call(styleCache,key)){var positions=styleCache[key].positions;for(var i=0,position;position=positions[i];i++){position.active=false}}}}}}}else{var positions=this.getTextInfo(layer,text,font,angle).positions;for(var i=0,position;position=positions[i];i++){if(position.x==x&&position.y==y){position.active=false}}}};function Plot(placeholder,data_,options_,plugins){var series=[],options={colors:["#edc240","#afd8f8","#cb4b4b","#4da74d","#9440ed"],legend:{show:true,noColumns:1,labelFormatter:null,labelBoxBorderColor:"#ccc",container:null,position:"ne",margin:5,backgroundColor:null,backgroundOpacity:.85,sorted:null},xaxis:{show:null,position:"bottom",mode:null,font:null,color:null,tickColor:null,transform:null,inverseTransform:null,min:null,max:null,autoscaleMargin:null,ticks:null,tickFormatter:null,labelWidth:null,labelHeight:null,reserveSpace:null,tickLength:null,alignTicksWithAxis:null,tickDecimals:null,tickSize:null,minTickSize:null},yaxis:{autoscaleMargin:.02,position:"left"},xaxes:[],yaxes:[],series:{points:{show:false,radius:3,lineWidth:2,fill:true,fillColor:"#ffffff",symbol:"circle"},lines:{lineWidth:2,fill:false,fillColor:null,steps:false},bars:{show:false,lineWidth:2,barWidth:1,fill:true,fillColor:null,align:"left",horizontal:false,zero:true},shadowSize:3,highlightColor:null},grid:{show:true,aboveData:false,color:"#545454",backgroundColor:null,borderColor:null,tickColor:null,margin:0,labelMargin:5,axisMargin:8,borderWidth:2,minBorderMargin:null,markings:null,markingsColor:"#f4f4f4",markingsLineWidth:2,clickable:false,hoverable:false,autoHighlight:true,mouseActiveRadius:10},interaction:{redrawOverlayInterval:1e3/60},hooks:{}},surface=null,overlay=null,eventHolder=null,ctx=null,octx=null,xaxes=[],yaxes=[],plotOffset={left:0,right:0,top:0,bottom:0},plotWidth=0,plotHeight=0,hooks={processOptions:[],processRawData:[],processDatapoints:[],processOffset:[],drawBackground:[],drawSeries:[],draw:[],bindEvents:[],drawOverlay:[],shutdown:[]},plot=this;plot.setData=setData;plot.setupGrid=setupGrid;plot.draw=draw;plot.getPlaceholder=function(){return placeholder};plot.getCanvas=function(){return surface.element};plot.getPlotOffset=function(){return plotOffset};plot.width=function(){return plotWidth};plot.height=function(){return plotHeight};plot.offset=function(){var o=eventHolder.offset();o.left+=plotOffset.left;o.top+=plotOffset.top;return o};plot.getData=function(){return series};plot.getAxes=function(){var res={},i;$.each(xaxes.concat(yaxes),function(_,axis){if(axis)res[axis.direction+(axis.n!=1?axis.n:"")+"axis"]=axis});return res};plot.getXAxes=function(){return xaxes};plot.getYAxes=function(){return yaxes};plot.c2p=canvasToAxisCoords;plot.p2c=axisToCanvasCoords;plot.getOptions=function(){return options};plot.highlight=highlight;plot.unhighlight=unhighlight;plot.triggerRedrawOverlay=triggerRedrawOverlay;plot.pointOffset=function(point){return{left:parseInt(xaxes[axisNumber(point,"x")-1].p2c(+point.x)+plotOffset.left,10),top:parseInt(yaxes[axisNumber(point,"y")-1].p2c(+point.y)+plotOffset.top,10)}};plot.shutdown=shutdown;plot.destroy=function(){shutdown();placeholder.removeData("plot").empty();series=[];options=null;surface=null;overlay=null;eventHolder=null;ctx=null;octx=null;xaxes=[];yaxes=[];hooks=null;highlights=[];plot=null};plot.resize=function(){var width=placeholder.width(),height=placeholder.height();surface.resize(width,height);overlay.resize(width,height)};plot.hooks=hooks;initPlugins(plot);parseOptions(options_);setupCanvases();setData(data_);setupGrid();draw();bindEvents();function executeHooks(hook,args){args=[plot].concat(args);for(var i=0;i<hook.length;++i)hook[i].apply(this,args)}function initPlugins(){var classes={Canvas:Canvas};for(var i=0;i<plugins.length;++i){var p=plugins[i];p.init(plot,classes);if(p.options)$.extend(true,options,p.options)}}function parseOptions(opts){$.extend(true,options,opts);if(opts&&opts.colors){options.colors=opts.colors}if(options.xaxis.color==null)options.xaxis.color=$.color.parse(options.grid.color).scale("a",.22).toString();if(options.yaxis.color==null)options.yaxis.color=$.color.parse(options.grid.color).scale("a",.22).toString();if(options.xaxis.tickColor==null)options.xaxis.tickColor=options.grid.tickColor||options.xaxis.color;if(options.yaxis.tickColor==null)options.yaxis.tickColor=options.grid.tickColor||options.yaxis.color;if(options.grid.borderColor==null)options.grid.borderColor=options.grid.color;if(options.grid.tickColor==null)options.grid.tickColor=$.color.parse(options.grid.color).scale("a",.22).toString();var i,axisOptions,axisCount,fontSize=placeholder.css("font-size"),fontSizeDefault=fontSize?+fontSize.replace("px",""):13,fontDefaults={style:placeholder.css("font-style"),size:Math.round(.8*fontSizeDefault),variant:placeholder.css("font-variant"),weight:placeholder.css("font-weight"),family:placeholder.css("font-family")};axisCount=options.xaxes.length||1;for(i=0;i<axisCount;++i){axisOptions=options.xaxes[i];if(axisOptions&&!axisOptions.tickColor){axisOptions.tickColor=axisOptions.color}axisOptions=$.extend(true,{},options.xaxis,axisOptions);options.xaxes[i]=axisOptions;if(axisOptions.font){axisOptions.font=$.extend({},fontDefaults,axisOptions.font);if(!axisOptions.font.color){axisOptions.font.color=axisOptions.color}if(!axisOptions.font.lineHeight){axisOptions.font.lineHeight=Math.round(axisOptions.font.size*1.15)}}}axisCount=options.yaxes.length||1;for(i=0;i<axisCount;++i){axisOptions=options.yaxes[i];if(axisOptions&&!axisOptions.tickColor){axisOptions.tickColor=axisOptions.color}axisOptions=$.extend(true,{},options.yaxis,axisOptions);options.yaxes[i]=axisOptions;if(axisOptions.font){axisOptions.font=$.extend({},fontDefaults,axisOptions.font);if(!axisOptions.font.color){axisOptions.font.color=axisOptions.color}if(!axisOptions.font.lineHeight){axisOptions.font.lineHeight=Math.round(axisOptions.font.size*1.15)}}}if(options.xaxis.noTicks&&options.xaxis.ticks==null)options.xaxis.ticks=options.xaxis.noTicks;if(options.yaxis.noTicks&&options.yaxis.ticks==null)options.yaxis.ticks=options.yaxis.noTicks;if(options.x2axis){options.xaxes[1]=$.extend(true,{},options.xaxis,options.x2axis);options.xaxes[1].position="top";if(options.x2axis.min==null){options.xaxes[1].min=null}if(options.x2axis.max==null){options.xaxes[1].max=null}}if(options.y2axis){options.yaxes[1]=$.extend(true,{},options.yaxis,options.y2axis);options.yaxes[1].position="right";if(options.y2axis.min==null){options.yaxes[1].min=null}if(options.y2axis.max==null){options.yaxes[1].max=null}}if(options.grid.coloredAreas)options.grid.markings=options.grid.coloredAreas;if(options.grid.coloredAreasColor)options.grid.markingsColor=options.grid.coloredAreasColor;if(options.lines)$.extend(true,options.series.lines,options.lines);if(options.points)$.extend(true,options.series.points,options.points);if(options.bars)$.extend(true,options.series.bars,options.bars);if(options.shadowSize!=null)options.series.shadowSize=options.shadowSize;if(options.highlightColor!=null)options.series.highlightColor=options.highlightColor;for(i=0;i<options.xaxes.length;++i)getOrCreateAxis(xaxes,i+1).options=options.xaxes[i];for(i=0;i<options.yaxes.length;++i)getOrCreateAxis(yaxes,i+1).options=options.yaxes[i];for(var n in hooks)if(options.hooks[n]&&options.hooks[n].length)hooks[n]=hooks[n].concat(options.hooks[n]);executeHooks(hooks.processOptions,[options])}function setData(d){series=parseData(d);fillInSeriesOptions();processData()}function parseData(d){var res=[];for(var i=0;i<d.length;++i){var s=$.extend(true,{},options.series);if(d[i].data!=null){s.data=d[i].data;delete d[i].data;$.extend(true,s,d[i]);d[i].data=s.data}else s.data=d[i];res.push(s)}return res}function axisNumber(obj,coord){var a=obj[coord+"axis"];if(typeof a=="object")a=a.n;if(typeof a!="number")a=1;return a}function allAxes(){return $.grep(xaxes.concat(yaxes),function(a){return a})}function canvasToAxisCoords(pos){var res={},i,axis;for(i=0;i<xaxes.length;++i){axis=xaxes[i];if(axis&&axis.used)res["x"+axis.n]=axis.c2p(pos.left)}for(i=0;i<yaxes.length;++i){axis=yaxes[i];if(axis&&axis.used)res["y"+axis.n]=axis.c2p(pos.top)}if(res.x1!==undefined)res.x=res.x1;if(res.y1!==undefined)res.y=res.y1;return res}function axisToCanvasCoords(pos){var res={},i,axis,key;for(i=0;i<xaxes.length;++i){axis=xaxes[i];if(axis&&axis.used){key="x"+axis.n;if(pos[key]==null&&axis.n==1)key="x";if(pos[key]!=null){res.left=axis.p2c(pos[key]);break}}}for(i=0;i<yaxes.length;++i){axis=yaxes[i];if(axis&&axis.used){key="y"+axis.n;if(pos[key]==null&&axis.n==1)key="y";if(pos[key]!=null){res.top=axis.p2c(pos[key]);break}}}return res}function getOrCreateAxis(axes,number){if(!axes[number-1])axes[number-1]={n:number,direction:axes==xaxes?"x":"y",options:$.extend(true,{},axes==xaxes?options.xaxis:options.yaxis)};return axes[number-1]}function fillInSeriesOptions(){var neededColors=series.length,maxIndex=-1,i;for(i=0;i<series.length;++i){var sc=series[i].color;if(sc!=null){neededColors--;if(typeof sc=="number"&&sc>maxIndex){maxIndex=sc}}}if(neededColors<=maxIndex){neededColors=maxIndex+1}var c,colors=[],colorPool=options.colors,colorPoolSize=colorPool.length,variation=0;for(i=0;i<neededColors;i++){c=$.color.parse(colorPool[i%colorPoolSize]||"#666");if(i%colorPoolSize==0&&i){if(variation>=0){if(variation<.5){variation=-variation-.2}else variation=0}else variation=-variation}colors[i]=c.scale("rgb",1+variation)}var colori=0,s;for(i=0;i<series.length;++i){s=series[i];if(s.color==null){s.color=colors[colori].toString();++colori}else if(typeof s.color=="number")s.color=colors[s.color].toString();if(s.lines.show==null){var v,show=true;for(v in s)if(s[v]&&s[v].show){show=false;break}if(show)s.lines.show=true}if(s.lines.zero==null){s.lines.zero=!!s.lines.fill}s.xaxis=getOrCreateAxis(xaxes,axisNumber(s,"x"));s.yaxis=getOrCreateAxis(yaxes,axisNumber(s,"y"))}}function processData(){var topSentry=Number.POSITIVE_INFINITY,bottomSentry=Number.NEGATIVE_INFINITY,fakeInfinity=Number.MAX_VALUE,i,j,k,m,length,s,points,ps,x,y,axis,val,f,p,data,format;function updateAxis(axis,min,max){if(min<axis.datamin&&min!=-fakeInfinity)axis.datamin=min;if(max>axis.datamax&&max!=fakeInfinity)axis.datamax=max}$.each(allAxes(),function(_,axis){axis.datamin=topSentry;axis.datamax=bottomSentry;axis.used=false});for(i=0;i<series.length;++i){s=series[i];s.datapoints={points:[]};executeHooks(hooks.processRawData,[s,s.data,s.datapoints])}for(i=0;i<series.length;++i){s=series[i];data=s.data;format=s.datapoints.format;if(!format){format=[];format.push({x:true,number:true,required:true});format.push({y:true,number:true,required:true});if(s.bars.show||s.lines.show&&s.lines.fill){var autoscale=!!(s.bars.show&&s.bars.zero||s.lines.show&&s.lines.zero);format.push({y:true,number:true,required:false,defaultValue:0,autoscale:autoscale});if(s.bars.horizontal){delete format[format.length-1].y;format[format.length-1].x=true}}s.datapoints.format=format}if(s.datapoints.pointsize!=null)continue;s.datapoints.pointsize=format.length;ps=s.datapoints.pointsize;points=s.datapoints.points;var insertSteps=s.lines.show&&s.lines.steps;s.xaxis.used=s.yaxis.used=true;for(j=k=0;j<data.length;++j,k+=ps){p=data[j];var nullify=p==null;if(!nullify){for(m=0;m<ps;++m){val=p[m];f=format[m];if(f){if(f.number&&val!=null){val=+val;if(isNaN(val))val=null;else if(val==Infinity)val=fakeInfinity;else if(val==-Infinity)val=-fakeInfinity}if(val==null){if(f.required)nullify=true;if(f.defaultValue!=null)val=f.defaultValue}}points[k+m]=val}}if(nullify){for(m=0;m<ps;++m){val=points[k+m];if(val!=null){f=format[m];if(f.autoscale!==false){if(f.x){updateAxis(s.xaxis,val,val)}if(f.y){updateAxis(s.yaxis,val,val)}}}points[k+m]=null}}else{if(insertSteps&&k>0&&points[k-ps]!=null&&points[k-ps]!=points[k]&&points[k-ps+1]!=points[k+1]){for(m=0;m<ps;++m)points[k+ps+m]=points[k+m];points[k+1]=points[k-ps+1];k+=ps}}}}for(i=0;i<series.length;++i){s=series[i];executeHooks(hooks.processDatapoints,[s,s.datapoints])}for(i=0;i<series.length;++i){s=series[i];points=s.datapoints.points;ps=s.datapoints.pointsize;format=s.datapoints.format;var xmin=topSentry,ymin=topSentry,xmax=bottomSentry,ymax=bottomSentry;for(j=0;j<points.length;j+=ps){if(points[j]==null)continue;for(m=0;m<ps;++m){val=points[j+m];f=format[m];if(!f||f.autoscale===false||val==fakeInfinity||val==-fakeInfinity)continue;if(f.x){if(val<xmin)xmin=val;if(val>xmax)xmax=val}if(f.y){if(val<ymin)ymin=val;if(val>ymax)ymax=val}}}if(s.bars.show){var delta;switch(s.bars.align){case"left":delta=0;break;case"right":delta=-s.bars.barWidth;break;default:delta=-s.bars.barWidth/2}if(s.bars.horizontal){ymin+=delta;ymax+=delta+s.bars.barWidth}else{xmin+=delta;xmax+=delta+s.bars.barWidth}}updateAxis(s.xaxis,xmin,xmax);updateAxis(s.yaxis,ymin,ymax)}$.each(allAxes(),function(_,axis){if(axis.datamin==topSentry)axis.datamin=null;if(axis.datamax==bottomSentry)axis.datamax=null})}function setupCanvases(){placeholder.css("padding",0).children().filter(function(){return!$(this).hasClass("flot-overlay")&&!$(this).hasClass("flot-base")}).remove();if(placeholder.css("position")=="static")placeholder.css("position","relative");surface=new Canvas("flot-base",placeholder);overlay=new Canvas("flot-overlay",placeholder);ctx=surface.context;octx=overlay.context;eventHolder=$(overlay.element).unbind();var existing=placeholder.data("plot");if(existing){existing.shutdown();overlay.clear()}placeholder.data("plot",plot)}function bindEvents(){if(options.grid.hoverable){eventHolder.mousemove(onMouseMove);eventHolder.bind("mouseleave",onMouseLeave)}if(options.grid.clickable)eventHolder.click(onClick);executeHooks(hooks.bindEvents,[eventHolder])}function shutdown(){if(redrawTimeout)clearTimeout(redrawTimeout);eventHolder.unbind("mousemove",onMouseMove);eventHolder.unbind("mouseleave",onMouseLeave);eventHolder.unbind("click",onClick);executeHooks(hooks.shutdown,[eventHolder])}function setTransformationHelpers(axis){function identity(x){return x}var s,m,t=axis.options.transform||identity,it=axis.options.inverseTransform;if(axis.direction=="x"){s=axis.scale=plotWidth/Math.abs(t(axis.max)-t(axis.min));m=Math.min(t(axis.max),t(axis.min))}else{s=axis.scale=plotHeight/Math.abs(t(axis.max)-t(axis.min));s=-s;m=Math.max(t(axis.max),t(axis.min))}if(t==identity)axis.p2c=function(p){return(p-m)*s};else axis.p2c=function(p){return(t(p)-m)*s};if(!it)axis.c2p=function(c){return m+c/s};else axis.c2p=function(c){return it(m+c/s)}}function measureTickLabels(axis){var opts=axis.options,ticks=axis.ticks||[],labelWidth=opts.labelWidth||0,labelHeight=opts.labelHeight||0,maxWidth=labelWidth||(axis.direction=="x"?Math.floor(surface.width/(ticks.length||1)):null),legacyStyles=axis.direction+"Axis "+axis.direction+axis.n+"Axis",layer="flot-"+axis.direction+"-axis flot-"+axis.direction+axis.n+"-axis "+legacyStyles,font=opts.font||"flot-tick-label tickLabel";for(var i=0;i<ticks.length;++i){var t=ticks[i];if(!t.label)continue;var info=surface.getTextInfo(layer,t.label,font,null,maxWidth);labelWidth=Math.max(labelWidth,info.width);labelHeight=Math.max(labelHeight,info.height)}axis.labelWidth=opts.labelWidth||labelWidth;axis.labelHeight=opts.labelHeight||labelHeight}function allocateAxisBoxFirstPhase(axis){var lw=axis.labelWidth,lh=axis.labelHeight,pos=axis.options.position,isXAxis=axis.direction==="x",tickLength=axis.options.tickLength,axisMargin=options.grid.axisMargin,padding=options.grid.labelMargin,innermost=true,outermost=true,first=true,found=false;$.each(isXAxis?xaxes:yaxes,function(i,a){if(a&&(a.show||a.reserveSpace)){if(a===axis){found=true}else if(a.options.position===pos){if(found){outermost=false}else{innermost=false}}if(!found){first=false}}});if(outermost){axisMargin=0}if(tickLength==null){tickLength=first?"full":5}if(!isNaN(+tickLength))padding+=+tickLength;if(isXAxis){lh+=padding;if(pos=="bottom"){plotOffset.bottom+=lh+axisMargin;axis.box={top:surface.height-plotOffset.bottom,height:lh}}else{axis.box={top:plotOffset.top+axisMargin,height:lh};plotOffset.top+=lh+axisMargin}}else{lw+=padding;if(pos=="left"){axis.box={left:plotOffset.left+axisMargin,width:lw};plotOffset.left+=lw+axisMargin}else{plotOffset.right+=lw+axisMargin;axis.box={left:surface.width-plotOffset.right,width:lw}}}axis.position=pos;axis.tickLength=tickLength;axis.box.padding=padding;axis.innermost=innermost}function allocateAxisBoxSecondPhase(axis){if(axis.direction=="x"){axis.box.left=plotOffset.left-axis.labelWidth/2;axis.box.width=surface.width-plotOffset.left-plotOffset.right+axis.labelWidth}else{axis.box.top=plotOffset.top-axis.labelHeight/2;axis.box.height=surface.height-plotOffset.bottom-plotOffset.top+axis.labelHeight}}function adjustLayoutForThingsStickingOut(){var minMargin=options.grid.minBorderMargin,axis,i;if(minMargin==null){minMargin=0;for(i=0;i<series.length;++i)minMargin=Math.max(minMargin,2*(series[i].points.radius+series[i].points.lineWidth/2))}var margins={left:minMargin,right:minMargin,top:minMargin,bottom:minMargin};$.each(allAxes(),function(_,axis){if(axis.reserveSpace&&axis.ticks&&axis.ticks.length){if(axis.direction==="x"){margins.left=Math.max(margins.left,axis.labelWidth/2);margins.right=Math.max(margins.right,axis.labelWidth/2)}else{margins.bottom=Math.max(margins.bottom,axis.labelHeight/2);margins.top=Math.max(margins.top,axis.labelHeight/2)}}});plotOffset.left=Math.ceil(Math.max(margins.left,plotOffset.left));plotOffset.right=Math.ceil(Math.max(margins.right,plotOffset.right));plotOffset.top=Math.ceil(Math.max(margins.top,plotOffset.top));plotOffset.bottom=Math.ceil(Math.max(margins.bottom,plotOffset.bottom))}function setupGrid(){var i,axes=allAxes(),showGrid=options.grid.show;for(var a in plotOffset){var margin=options.grid.margin||0;plotOffset[a]=typeof margin=="number"?margin:margin[a]||0}executeHooks(hooks.processOffset,[plotOffset]);for(var a in plotOffset){if(typeof options.grid.borderWidth=="object"){plotOffset[a]+=showGrid?options.grid.borderWidth[a]:0}else{plotOffset[a]+=showGrid?options.grid.borderWidth:0}}$.each(axes,function(_,axis){var axisOpts=axis.options;axis.show=axisOpts.show==null?axis.used:axisOpts.show;axis.reserveSpace=axisOpts.reserveSpace==null?axis.show:axisOpts.reserveSpace;setRange(axis)});if(showGrid){var allocatedAxes=$.grep(axes,function(axis){return axis.show||axis.reserveSpace});$.each(allocatedAxes,function(_,axis){setupTickGeneration(axis);setTicks(axis);snapRangeToTicks(axis,axis.ticks);measureTickLabels(axis)});for(i=allocatedAxes.length-1;i>=0;--i)allocateAxisBoxFirstPhase(allocatedAxes[i]);adjustLayoutForThingsStickingOut();$.each(allocatedAxes,function(_,axis){allocateAxisBoxSecondPhase(axis)})}plotWidth=surface.width-plotOffset.left-plotOffset.right;plotHeight=surface.height-plotOffset.bottom-plotOffset.top;$.each(axes,function(_,axis){setTransformationHelpers(axis)});if(showGrid){drawAxisLabels()}insertLegend()}function setRange(axis){var opts=axis.options,min=+(opts.min!=null?opts.min:axis.datamin),max=+(opts.max!=null?opts.max:axis.datamax),delta=max-min;if(delta==0){var widen=max==0?1:.01;if(opts.min==null)min-=widen;if(opts.max==null||opts.min!=null)max+=widen}else{var margin=opts.autoscaleMargin;if(margin!=null){if(opts.min==null){min-=delta*margin;if(min<0&&axis.datamin!=null&&axis.datamin>=0)min=0}if(opts.max==null){max+=delta*margin;if(max>0&&axis.datamax!=null&&axis.datamax<=0)max=0}}}axis.min=min;axis.max=max}function setupTickGeneration(axis){var opts=axis.options;var noTicks;if(typeof opts.ticks=="number"&&opts.ticks>0)noTicks=opts.ticks;else noTicks=.3*Math.sqrt(axis.direction=="x"?surface.width:surface.height);var delta=(axis.max-axis.min)/noTicks,dec=-Math.floor(Math.log(delta)/Math.LN10),maxDec=opts.tickDecimals;if(maxDec!=null&&dec>maxDec){dec=maxDec}var magn=Math.pow(10,-dec),norm=delta/magn,size;if(norm<1.5){size=1}else if(norm<3){size=2;if(norm>2.25&&(maxDec==null||dec+1<=maxDec)){size=2.5;++dec}}else if(norm<7.5){size=5}else{size=10}size*=magn;if(opts.minTickSize!=null&&size<opts.minTickSize){size=opts.minTickSize}axis.delta=delta;axis.tickDecimals=Math.max(0,maxDec!=null?maxDec:dec);axis.tickSize=opts.tickSize||size;if(opts.mode=="time"&&!axis.tickGenerator){throw new Error("Time mode requires the flot.time plugin.")}if(!axis.tickGenerator){axis.tickGenerator=function(axis){var ticks=[],start=floorInBase(axis.min,axis.tickSize),i=0,v=Number.NaN,prev;do{prev=v;v=start+i*axis.tickSize;ticks.push(v);++i}while(v<axis.max&&v!=prev);return ticks};axis.tickFormatter=function(value,axis){var factor=axis.tickDecimals?Math.pow(10,axis.tickDecimals):1;var formatted=""+Math.round(value*factor)/factor;if(axis.tickDecimals!=null){var decimal=formatted.indexOf(".");var precision=decimal==-1?0:formatted.length-decimal-1;if(precision<axis.tickDecimals){return(precision?formatted:formatted+".")+(""+factor).substr(1,axis.tickDecimals-precision)}}return formatted}}if($.isFunction(opts.tickFormatter))axis.tickFormatter=function(v,axis){return""+opts.tickFormatter(v,axis)};if(opts.alignTicksWithAxis!=null){var otherAxis=(axis.direction=="x"?xaxes:yaxes)[opts.alignTicksWithAxis-1];if(otherAxis&&otherAxis.used&&otherAxis!=axis){var niceTicks=axis.tickGenerator(axis);if(niceTicks.length>0){if(opts.min==null)axis.min=Math.min(axis.min,niceTicks[0]);if(opts.max==null&&niceTicks.length>1)axis.max=Math.max(axis.max,niceTicks[niceTicks.length-1])}axis.tickGenerator=function(axis){var ticks=[],v,i;for(i=0;i<otherAxis.ticks.length;++i){v=(otherAxis.ticks[i].v-otherAxis.min)/(otherAxis.max-otherAxis.min);v=axis.min+v*(axis.max-axis.min);ticks.push(v)}return ticks};if(!axis.mode&&opts.tickDecimals==null){var extraDec=Math.max(0,-Math.floor(Math.log(axis.delta)/Math.LN10)+1),ts=axis.tickGenerator(axis);if(!(ts.length>1&&/\..*0$/.test((ts[1]-ts[0]).toFixed(extraDec))))axis.tickDecimals=extraDec}}}}function setTicks(axis){var oticks=axis.options.ticks,ticks=[];if(oticks==null||typeof oticks=="number"&&oticks>0)ticks=axis.tickGenerator(axis);else if(oticks){if($.isFunction(oticks))ticks=oticks(axis);else ticks=oticks}var i,v;axis.ticks=[];for(i=0;i<ticks.length;++i){var label=null;var t=ticks[i];if(typeof t=="object"){v=+t[0];if(t.length>1)label=t[1]}else v=+t;if(label==null)label=axis.tickFormatter(v,axis);if(!isNaN(v))axis.ticks.push({v:v,label:label})}}function snapRangeToTicks(axis,ticks){if(axis.options.autoscaleMargin&&ticks.length>0){if(axis.options.min==null)axis.min=Math.min(axis.min,ticks[0].v);if(axis.options.max==null&&ticks.length>1)axis.max=Math.max(axis.max,ticks[ticks.length-1].v)}}function draw(){surface.clear();executeHooks(hooks.drawBackground,[ctx]);var grid=options.grid;if(grid.show&&grid.backgroundColor)drawBackground();if(grid.show&&!grid.aboveData){drawGrid()}for(var i=0;i<series.length;++i){executeHooks(hooks.drawSeries,[ctx,series[i]]);drawSeries(series[i])}executeHooks(hooks.draw,[ctx]);if(grid.show&&grid.aboveData){drawGrid()}surface.render();triggerRedrawOverlay()}function extractRange(ranges,coord){var axis,from,to,key,axes=allAxes();for(var i=0;i<axes.length;++i){axis=axes[i];if(axis.direction==coord){key=coord+axis.n+"axis";if(!ranges[key]&&axis.n==1)key=coord+"axis";if(ranges[key]){from=ranges[key].from;to=ranges[key].to;break}}}if(!ranges[key]){axis=coord=="x"?xaxes[0]:yaxes[0];from=ranges[coord+"1"];to=ranges[coord+"2"]}if(from!=null&&to!=null&&from>to){var tmp=from;from=to;to=tmp}return{from:from,to:to,axis:axis}}function drawBackground(){ctx.save();ctx.translate(plotOffset.left,plotOffset.top);ctx.fillStyle=getColorOrGradient(options.grid.backgroundColor,plotHeight,0,"rgba(255, 255, 255, 0)");ctx.fillRect(0,0,plotWidth,plotHeight);ctx.restore()}function drawGrid(){var i,axes,bw,bc;ctx.save();ctx.translate(plotOffset.left,plotOffset.top);var markings=options.grid.markings;if(markings){if($.isFunction(markings)){axes=plot.getAxes();axes.xmin=axes.xaxis.min;axes.xmax=axes.xaxis.max;axes.ymin=axes.yaxis.min;axes.ymax=axes.yaxis.max;markings=markings(axes)}for(i=0;i<markings.length;++i){var m=markings[i],xrange=extractRange(m,"x"),yrange=extractRange(m,"y");if(xrange.from==null)xrange.from=xrange.axis.min;if(xrange.to==null)xrange.to=xrange.axis.max;
8
+if(yrange.from==null)yrange.from=yrange.axis.min;if(yrange.to==null)yrange.to=yrange.axis.max;if(xrange.to<xrange.axis.min||xrange.from>xrange.axis.max||yrange.to<yrange.axis.min||yrange.from>yrange.axis.max)continue;xrange.from=Math.max(xrange.from,xrange.axis.min);xrange.to=Math.min(xrange.to,xrange.axis.max);yrange.from=Math.max(yrange.from,yrange.axis.min);yrange.to=Math.min(yrange.to,yrange.axis.max);var xequal=xrange.from===xrange.to,yequal=yrange.from===yrange.to;if(xequal&&yequal){continue}xrange.from=Math.floor(xrange.axis.p2c(xrange.from));xrange.to=Math.floor(xrange.axis.p2c(xrange.to));yrange.from=Math.floor(yrange.axis.p2c(yrange.from));yrange.to=Math.floor(yrange.axis.p2c(yrange.to));if(xequal||yequal){var lineWidth=m.lineWidth||options.grid.markingsLineWidth,subPixel=lineWidth%2?.5:0;ctx.beginPath();ctx.strokeStyle=m.color||options.grid.markingsColor;ctx.lineWidth=lineWidth;if(xequal){ctx.moveTo(xrange.to+subPixel,yrange.from);ctx.lineTo(xrange.to+subPixel,yrange.to)}else{ctx.moveTo(xrange.from,yrange.to+subPixel);ctx.lineTo(xrange.to,yrange.to+subPixel)}ctx.stroke()}else{ctx.fillStyle=m.color||options.grid.markingsColor;ctx.fillRect(xrange.from,yrange.to,xrange.to-xrange.from,yrange.from-yrange.to)}}}axes=allAxes();bw=options.grid.borderWidth;for(var j=0;j<axes.length;++j){var axis=axes[j],box=axis.box,t=axis.tickLength,x,y,xoff,yoff;if(!axis.show||axis.ticks.length==0)continue;ctx.lineWidth=1;if(axis.direction=="x"){x=0;if(t=="full")y=axis.position=="top"?0:plotHeight;else y=box.top-plotOffset.top+(axis.position=="top"?box.height:0)}else{y=0;if(t=="full")x=axis.position=="left"?0:plotWidth;else x=box.left-plotOffset.left+(axis.position=="left"?box.width:0)}if(!axis.innermost){ctx.strokeStyle=axis.options.color;ctx.beginPath();xoff=yoff=0;if(axis.direction=="x")xoff=plotWidth+1;else yoff=plotHeight+1;if(ctx.lineWidth==1){if(axis.direction=="x"){y=Math.floor(y)+.5}else{x=Math.floor(x)+.5}}ctx.moveTo(x,y);ctx.lineTo(x+xoff,y+yoff);ctx.stroke()}ctx.strokeStyle=axis.options.tickColor;ctx.beginPath();for(i=0;i<axis.ticks.length;++i){var v=axis.ticks[i].v;xoff=yoff=0;if(isNaN(v)||v<axis.min||v>axis.max||t=="full"&&(typeof bw=="object"&&bw[axis.position]>0||bw>0)&&(v==axis.min||v==axis.max))continue;if(axis.direction=="x"){x=axis.p2c(v);yoff=t=="full"?-plotHeight:t;if(axis.position=="top")yoff=-yoff}else{y=axis.p2c(v);xoff=t=="full"?-plotWidth:t;if(axis.position=="left")xoff=-xoff}if(ctx.lineWidth==1){if(axis.direction=="x")x=Math.floor(x)+.5;else y=Math.floor(y)+.5}ctx.moveTo(x,y);ctx.lineTo(x+xoff,y+yoff)}ctx.stroke()}if(bw){bc=options.grid.borderColor;if(typeof bw=="object"||typeof bc=="object"){if(typeof bw!=="object"){bw={top:bw,right:bw,bottom:bw,left:bw}}if(typeof bc!=="object"){bc={top:bc,right:bc,bottom:bc,left:bc}}if(bw.top>0){ctx.strokeStyle=bc.top;ctx.lineWidth=bw.top;ctx.beginPath();ctx.moveTo(0-bw.left,0-bw.top/2);ctx.lineTo(plotWidth,0-bw.top/2);ctx.stroke()}if(bw.right>0){ctx.strokeStyle=bc.right;ctx.lineWidth=bw.right;ctx.beginPath();ctx.moveTo(plotWidth+bw.right/2,0-bw.top);ctx.lineTo(plotWidth+bw.right/2,plotHeight);ctx.stroke()}if(bw.bottom>0){ctx.strokeStyle=bc.bottom;ctx.lineWidth=bw.bottom;ctx.beginPath();ctx.moveTo(plotWidth+bw.right,plotHeight+bw.bottom/2);ctx.lineTo(0,plotHeight+bw.bottom/2);ctx.stroke()}if(bw.left>0){ctx.strokeStyle=bc.left;ctx.lineWidth=bw.left;ctx.beginPath();ctx.moveTo(0-bw.left/2,plotHeight+bw.bottom);ctx.lineTo(0-bw.left/2,0);ctx.stroke()}}else{ctx.lineWidth=bw;ctx.strokeStyle=options.grid.borderColor;ctx.strokeRect(-bw/2,-bw/2,plotWidth+bw,plotHeight+bw)}}ctx.restore()}function drawAxisLabels(){$.each(allAxes(),function(_,axis){var box=axis.box,legacyStyles=axis.direction+"Axis "+axis.direction+axis.n+"Axis",layer="flot-"+axis.direction+"-axis flot-"+axis.direction+axis.n+"-axis "+legacyStyles,font=axis.options.font||"flot-tick-label tickLabel",tick,x,y,halign,valign;surface.removeText(layer);if(!axis.show||axis.ticks.length==0)return;for(var i=0;i<axis.ticks.length;++i){tick=axis.ticks[i];if(!tick.label||tick.v<axis.min||tick.v>axis.max)continue;if(axis.direction=="x"){halign="center";x=plotOffset.left+axis.p2c(tick.v);if(axis.position=="bottom"){y=box.top+box.padding}else{y=box.top+box.height-box.padding;valign="bottom"}}else{valign="middle";y=plotOffset.top+axis.p2c(tick.v);if(axis.position=="left"){x=box.left+box.width-box.padding;halign="right"}else{x=box.left+box.padding}}surface.addText(layer,x,y,tick.label,font,null,null,halign,valign)}})}function drawSeries(series){if(series.lines.show)drawSeriesLines(series);if(series.bars.show)drawSeriesBars(series);if(series.points.show)drawSeriesPoints(series)}function drawSeriesLines(series){function plotLine(datapoints,xoffset,yoffset,axisx,axisy){var points=datapoints.points,ps=datapoints.pointsize,prevx=null,prevy=null;ctx.beginPath();for(var i=ps;i<points.length;i+=ps){var x1=points[i-ps],y1=points[i-ps+1],x2=points[i],y2=points[i+1];if(x1==null||x2==null)continue;if(y1<=y2&&y1<axisy.min){if(y2<axisy.min)continue;x1=(axisy.min-y1)/(y2-y1)*(x2-x1)+x1;y1=axisy.min}else if(y2<=y1&&y2<axisy.min){if(y1<axisy.min)continue;x2=(axisy.min-y1)/(y2-y1)*(x2-x1)+x1;y2=axisy.min}if(y1>=y2&&y1>axisy.max){if(y2>axisy.max)continue;x1=(axisy.max-y1)/(y2-y1)*(x2-x1)+x1;y1=axisy.max}else if(y2>=y1&&y2>axisy.max){if(y1>axisy.max)continue;x2=(axisy.max-y1)/(y2-y1)*(x2-x1)+x1;y2=axisy.max}if(x1<=x2&&x1<axisx.min){if(x2<axisx.min)continue;y1=(axisx.min-x1)/(x2-x1)*(y2-y1)+y1;x1=axisx.min}else if(x2<=x1&&x2<axisx.min){if(x1<axisx.min)continue;y2=(axisx.min-x1)/(x2-x1)*(y2-y1)+y1;x2=axisx.min}if(x1>=x2&&x1>axisx.max){if(x2>axisx.max)continue;y1=(axisx.max-x1)/(x2-x1)*(y2-y1)+y1;x1=axisx.max}else if(x2>=x1&&x2>axisx.max){if(x1>axisx.max)continue;y2=(axisx.max-x1)/(x2-x1)*(y2-y1)+y1;x2=axisx.max}if(x1!=prevx||y1!=prevy)ctx.moveTo(axisx.p2c(x1)+xoffset,axisy.p2c(y1)+yoffset);prevx=x2;prevy=y2;ctx.lineTo(axisx.p2c(x2)+xoffset,axisy.p2c(y2)+yoffset)}ctx.stroke()}function plotLineArea(datapoints,axisx,axisy){var points=datapoints.points,ps=datapoints.pointsize,bottom=Math.min(Math.max(0,axisy.min),axisy.max),i=0,top,areaOpen=false,ypos=1,segmentStart=0,segmentEnd=0;while(true){if(ps>0&&i>points.length+ps)break;i+=ps;var x1=points[i-ps],y1=points[i-ps+ypos],x2=points[i],y2=points[i+ypos];if(areaOpen){if(ps>0&&x1!=null&&x2==null){segmentEnd=i;ps=-ps;ypos=2;continue}if(ps<0&&i==segmentStart+ps){ctx.fill();areaOpen=false;ps=-ps;ypos=1;i=segmentStart=segmentEnd+ps;continue}}if(x1==null||x2==null)continue;if(x1<=x2&&x1<axisx.min){if(x2<axisx.min)continue;y1=(axisx.min-x1)/(x2-x1)*(y2-y1)+y1;x1=axisx.min}else if(x2<=x1&&x2<axisx.min){if(x1<axisx.min)continue;y2=(axisx.min-x1)/(x2-x1)*(y2-y1)+y1;x2=axisx.min}if(x1>=x2&&x1>axisx.max){if(x2>axisx.max)continue;y1=(axisx.max-x1)/(x2-x1)*(y2-y1)+y1;x1=axisx.max}else if(x2>=x1&&x2>axisx.max){if(x1>axisx.max)continue;y2=(axisx.max-x1)/(x2-x1)*(y2-y1)+y1;x2=axisx.max}if(!areaOpen){ctx.beginPath();ctx.moveTo(axisx.p2c(x1),axisy.p2c(bottom));areaOpen=true}if(y1>=axisy.max&&y2>=axisy.max){ctx.lineTo(axisx.p2c(x1),axisy.p2c(axisy.max));ctx.lineTo(axisx.p2c(x2),axisy.p2c(axisy.max));continue}else if(y1<=axisy.min&&y2<=axisy.min){ctx.lineTo(axisx.p2c(x1),axisy.p2c(axisy.min));ctx.lineTo(axisx.p2c(x2),axisy.p2c(axisy.min));continue}var x1old=x1,x2old=x2;if(y1<=y2&&y1<axisy.min&&y2>=axisy.min){x1=(axisy.min-y1)/(y2-y1)*(x2-x1)+x1;y1=axisy.min}else if(y2<=y1&&y2<axisy.min&&y1>=axisy.min){x2=(axisy.min-y1)/(y2-y1)*(x2-x1)+x1;y2=axisy.min}if(y1>=y2&&y1>axisy.max&&y2<=axisy.max){x1=(axisy.max-y1)/(y2-y1)*(x2-x1)+x1;y1=axisy.max}else if(y2>=y1&&y2>axisy.max&&y1<=axisy.max){x2=(axisy.max-y1)/(y2-y1)*(x2-x1)+x1;y2=axisy.max}if(x1!=x1old){ctx.lineTo(axisx.p2c(x1old),axisy.p2c(y1))}ctx.lineTo(axisx.p2c(x1),axisy.p2c(y1));ctx.lineTo(axisx.p2c(x2),axisy.p2c(y2));if(x2!=x2old){ctx.lineTo(axisx.p2c(x2),axisy.p2c(y2));ctx.lineTo(axisx.p2c(x2old),axisy.p2c(y2))}}}ctx.save();ctx.translate(plotOffset.left,plotOffset.top);ctx.lineJoin="round";var lw=series.lines.lineWidth,sw=series.shadowSize;if(lw>0&&sw>0){ctx.lineWidth=sw;ctx.strokeStyle="rgba(0,0,0,0.1)";var angle=Math.PI/18;plotLine(series.datapoints,Math.sin(angle)*(lw/2+sw/2),Math.cos(angle)*(lw/2+sw/2),series.xaxis,series.yaxis);ctx.lineWidth=sw/2;plotLine(series.datapoints,Math.sin(angle)*(lw/2+sw/4),Math.cos(angle)*(lw/2+sw/4),series.xaxis,series.yaxis)}ctx.lineWidth=lw;ctx.strokeStyle=series.color;var fillStyle=getFillStyle(series.lines,series.color,0,plotHeight);if(fillStyle){ctx.fillStyle=fillStyle;plotLineArea(series.datapoints,series.xaxis,series.yaxis)}if(lw>0)plotLine(series.datapoints,0,0,series.xaxis,series.yaxis);ctx.restore()}function drawSeriesPoints(series){function plotPoints(datapoints,radius,fillStyle,offset,shadow,axisx,axisy,symbol){var points=datapoints.points,ps=datapoints.pointsize;for(var i=0;i<points.length;i+=ps){var x=points[i],y=points[i+1];if(x==null||x<axisx.min||x>axisx.max||y<axisy.min||y>axisy.max)continue;ctx.beginPath();x=axisx.p2c(x);y=axisy.p2c(y)+offset;if(symbol=="circle")ctx.arc(x,y,radius,0,shadow?Math.PI:Math.PI*2,false);else symbol(ctx,x,y,radius,shadow);ctx.closePath();if(fillStyle){ctx.fillStyle=fillStyle;ctx.fill()}ctx.stroke()}}ctx.save();ctx.translate(plotOffset.left,plotOffset.top);var lw=series.points.lineWidth,sw=series.shadowSize,radius=series.points.radius,symbol=series.points.symbol;if(lw==0)lw=1e-4;if(lw>0&&sw>0){var w=sw/2;ctx.lineWidth=w;ctx.strokeStyle="rgba(0,0,0,0.1)";plotPoints(series.datapoints,radius,null,w+w/2,true,series.xaxis,series.yaxis,symbol);ctx.strokeStyle="rgba(0,0,0,0.2)";plotPoints(series.datapoints,radius,null,w/2,true,series.xaxis,series.yaxis,symbol)}ctx.lineWidth=lw;ctx.strokeStyle=series.color;plotPoints(series.datapoints,radius,getFillStyle(series.points,series.color),0,false,series.xaxis,series.yaxis,symbol);ctx.restore()}function drawBar(x,y,b,barLeft,barRight,fillStyleCallback,axisx,axisy,c,horizontal,lineWidth){var left,right,bottom,top,drawLeft,drawRight,drawTop,drawBottom,tmp;if(horizontal){drawBottom=drawRight=drawTop=true;drawLeft=false;left=b;right=x;top=y+barLeft;bottom=y+barRight;if(right<left){tmp=right;right=left;left=tmp;drawLeft=true;drawRight=false}}else{drawLeft=drawRight=drawTop=true;drawBottom=false;left=x+barLeft;right=x+barRight;bottom=b;top=y;if(top<bottom){tmp=top;top=bottom;bottom=tmp;drawBottom=true;drawTop=false}}if(right<axisx.min||left>axisx.max||top<axisy.min||bottom>axisy.max)return;if(left<axisx.min){left=axisx.min;drawLeft=false}if(right>axisx.max){right=axisx.max;drawRight=false}if(bottom<axisy.min){bottom=axisy.min;drawBottom=false}if(top>axisy.max){top=axisy.max;drawTop=false}left=axisx.p2c(left);bottom=axisy.p2c(bottom);right=axisx.p2c(right);top=axisy.p2c(top);if(fillStyleCallback){c.fillStyle=fillStyleCallback(bottom,top);c.fillRect(left,top,right-left,bottom-top)}if(lineWidth>0&&(drawLeft||drawRight||drawTop||drawBottom)){c.beginPath();c.moveTo(left,bottom);if(drawLeft)c.lineTo(left,top);else c.moveTo(left,top);if(drawTop)c.lineTo(right,top);else c.moveTo(right,top);if(drawRight)c.lineTo(right,bottom);else c.moveTo(right,bottom);if(drawBottom)c.lineTo(left,bottom);else c.moveTo(left,bottom);c.stroke()}}function drawSeriesBars(series){function plotBars(datapoints,barLeft,barRight,fillStyleCallback,axisx,axisy){var points=datapoints.points,ps=datapoints.pointsize;for(var i=0;i<points.length;i+=ps){if(points[i]==null)continue;drawBar(points[i],points[i+1],points[i+2],barLeft,barRight,fillStyleCallback,axisx,axisy,ctx,series.bars.horizontal,series.bars.lineWidth)}}ctx.save();ctx.translate(plotOffset.left,plotOffset.top);ctx.lineWidth=series.bars.lineWidth;ctx.strokeStyle=series.color;var barLeft;switch(series.bars.align){case"left":barLeft=0;break;case"right":barLeft=-series.bars.barWidth;break;default:barLeft=-series.bars.barWidth/2}var fillStyleCallback=series.bars.fill?function(bottom,top){return getFillStyle(series.bars,series.color,bottom,top)}:null;plotBars(series.datapoints,barLeft,barLeft+series.bars.barWidth,fillStyleCallback,series.xaxis,series.yaxis);ctx.restore()}function getFillStyle(filloptions,seriesColor,bottom,top){var fill=filloptions.fill;if(!fill)return null;if(filloptions.fillColor)return getColorOrGradient(filloptions.fillColor,bottom,top,seriesColor);var c=$.color.parse(seriesColor);c.a=typeof fill=="number"?fill:.4;c.normalize();return c.toString()}function insertLegend(){if(options.legend.container!=null){$(options.legend.container).html("")}else{placeholder.find(".legend").remove()}if(!options.legend.show){return}var fragments=[],entries=[],rowStarted=false,lf=options.legend.labelFormatter,s,label;for(var i=0;i<series.length;++i){s=series[i];if(s.label){label=lf?lf(s.label,s):s.label;if(label){entries.push({label:label,color:s.color})}}}if(options.legend.sorted){if($.isFunction(options.legend.sorted)){entries.sort(options.legend.sorted)}else if(options.legend.sorted=="reverse"){entries.reverse()}else{var ascending=options.legend.sorted!="descending";entries.sort(function(a,b){return a.label==b.label?0:a.label<b.label!=ascending?1:-1})}}for(var i=0;i<entries.length;++i){var entry=entries[i];if(i%options.legend.noColumns==0){if(rowStarted)fragments.push("</tr>");fragments.push("<tr>");rowStarted=true}fragments.push('<td class="legendColorBox"><div style="border:1px solid '+options.legend.labelBoxBorderColor+';padding:1px"><div style="width:4px;height:0;border:5px solid '+entry.color+';overflow:hidden"></div></div></td>'+'<td class="legendLabel">'+entry.label+"</td>")}if(rowStarted)fragments.push("</tr>");if(fragments.length==0)return;var table='<table style="font-size:smaller;color:'+options.grid.color+'">'+fragments.join("")+"</table>";if(options.legend.container!=null)$(options.legend.container).html(table);else{var pos="",p=options.legend.position,m=options.legend.margin;if(m[0]==null)m=[m,m];if(p.charAt(0)=="n")pos+="top:"+(m[1]+plotOffset.top)+"px;";else if(p.charAt(0)=="s")pos+="bottom:"+(m[1]+plotOffset.bottom)+"px;";if(p.charAt(1)=="e")pos+="right:"+(m[0]+plotOffset.right)+"px;";else if(p.charAt(1)=="w")pos+="left:"+(m[0]+plotOffset.left)+"px;";var legend=$('<div class="legend">'+table.replace('style="','style="position:absolute;'+pos+";")+"</div>").appendTo(placeholder);if(options.legend.backgroundOpacity!=0){var c=options.legend.backgroundColor;if(c==null){c=options.grid.backgroundColor;if(c&&typeof c=="string")c=$.color.parse(c);else c=$.color.extract(legend,"background-color");c.a=1;c=c.toString()}var div=legend.children();$('<div style="position:absolute;width:'+div.width()+"px;height:"+div.height()+"px;"+pos+"background-color:"+c+';"> </div>').prependTo(legend).css("opacity",options.legend.backgroundOpacity)}}}var highlights=[],redrawTimeout=null;function findNearbyItem(mouseX,mouseY,seriesFilter){var maxDistance=options.grid.mouseActiveRadius,smallestDistance=maxDistance*maxDistance+1,item=null,foundPoint=false,i,j,ps;for(i=series.length-1;i>=0;--i){if(!seriesFilter(series[i]))continue;var s=series[i],axisx=s.xaxis,axisy=s.yaxis,points=s.datapoints.points,mx=axisx.c2p(mouseX),my=axisy.c2p(mouseY),maxx=maxDistance/axisx.scale,maxy=maxDistance/axisy.scale;ps=s.datapoints.pointsize;if(axisx.options.inverseTransform)maxx=Number.MAX_VALUE;if(axisy.options.inverseTransform)maxy=Number.MAX_VALUE;if(s.lines.show||s.points.show){for(j=0;j<points.length;j+=ps){var x=points[j],y=points[j+1];if(x==null)continue;if(x-mx>maxx||x-mx<-maxx||y-my>maxy||y-my<-maxy)continue;var dx=Math.abs(axisx.p2c(x)-mouseX),dy=Math.abs(axisy.p2c(y)-mouseY),dist=dx*dx+dy*dy;if(dist<smallestDistance){smallestDistance=dist;item=[i,j/ps]}}}if(s.bars.show&&!item){var barLeft,barRight;switch(s.bars.align){case"left":barLeft=0;break;case"right":barLeft=-s.bars.barWidth;break;default:barLeft=-s.bars.barWidth/2}barRight=barLeft+s.bars.barWidth;for(j=0;j<points.length;j+=ps){var x=points[j],y=points[j+1],b=points[j+2];if(x==null)continue;if(series[i].bars.horizontal?mx<=Math.max(b,x)&&mx>=Math.min(b,x)&&my>=y+barLeft&&my<=y+barRight:mx>=x+barLeft&&mx<=x+barRight&&my>=Math.min(b,y)&&my<=Math.max(b,y))item=[i,j/ps]}}}if(item){i=item[0];j=item[1];ps=series[i].datapoints.pointsize;return{datapoint:series[i].datapoints.points.slice(j*ps,(j+1)*ps),dataIndex:j,series:series[i],seriesIndex:i}}return null}function onMouseMove(e){if(options.grid.hoverable)triggerClickHoverEvent("plothover",e,function(s){return s["hoverable"]!=false})}function onMouseLeave(e){if(options.grid.hoverable)triggerClickHoverEvent("plothover",e,function(s){return false})}function onClick(e){triggerClickHoverEvent("plotclick",e,function(s){return s["clickable"]!=false})}function triggerClickHoverEvent(eventname,event,seriesFilter){var offset=eventHolder.offset(),canvasX=event.pageX-offset.left-plotOffset.left,canvasY=event.pageY-offset.top-plotOffset.top,pos=canvasToAxisCoords({left:canvasX,top:canvasY});pos.pageX=event.pageX;pos.pageY=event.pageY;var item=findNearbyItem(canvasX,canvasY,seriesFilter);if(item){item.pageX=parseInt(item.series.xaxis.p2c(item.datapoint[0])+offset.left+plotOffset.left,10);item.pageY=parseInt(item.series.yaxis.p2c(item.datapoint[1])+offset.top+plotOffset.top,10)}if(options.grid.autoHighlight){for(var i=0;i<highlights.length;++i){var h=highlights[i];if(h.auto==eventname&&!(item&&h.series==item.series&&h.point[0]==item.datapoint[0]&&h.point[1]==item.datapoint[1]))unhighlight(h.series,h.point)}if(item)highlight(item.series,item.datapoint,eventname)}placeholder.trigger(eventname,[pos,item])}function triggerRedrawOverlay(){var t=options.interaction.redrawOverlayInterval;if(t==-1){drawOverlay();return}if(!redrawTimeout)redrawTimeout=setTimeout(drawOverlay,t)}function drawOverlay(){redrawTimeout=null;octx.save();overlay.clear();octx.translate(plotOffset.left,plotOffset.top);var i,hi;for(i=0;i<highlights.length;++i){hi=highlights[i];if(hi.series.bars.show)drawBarHighlight(hi.series,hi.point);else drawPointHighlight(hi.series,hi.point)}octx.restore();executeHooks(hooks.drawOverlay,[octx])}function highlight(s,point,auto){if(typeof s=="number")s=series[s];if(typeof point=="number"){var ps=s.datapoints.pointsize;point=s.datapoints.points.slice(ps*point,ps*(point+1))}var i=indexOfHighlight(s,point);if(i==-1){highlights.push({series:s,point:point,auto:auto});triggerRedrawOverlay()}else if(!auto)highlights[i].auto=false}function unhighlight(s,point){if(s==null&&point==null){highlights=[];triggerRedrawOverlay();return}if(typeof s=="number")s=series[s];if(typeof point=="number"){var ps=s.datapoints.pointsize;point=s.datapoints.points.slice(ps*point,ps*(point+1))}var i=indexOfHighlight(s,point);if(i!=-1){highlights.splice(i,1);triggerRedrawOverlay()}}function indexOfHighlight(s,p){for(var i=0;i<highlights.length;++i){var h=highlights[i];if(h.series==s&&h.point[0]==p[0]&&h.point[1]==p[1])return i}return-1}function drawPointHighlight(series,point){var x=point[0],y=point[1],axisx=series.xaxis,axisy=series.yaxis,highlightColor=typeof series.highlightColor==="string"?series.highlightColor:$.color.parse(series.color).scale("a",.5).toString();if(x<axisx.min||x>axisx.max||y<axisy.min||y>axisy.max)return;var pointRadius=series.points.radius+series.points.lineWidth/2;octx.lineWidth=pointRadius;octx.strokeStyle=highlightColor;var radius=1.5*pointRadius;x=axisx.p2c(x);y=axisy.p2c(y);octx.beginPath();if(series.points.symbol=="circle")octx.arc(x,y,radius,0,2*Math.PI,false);else series.points.symbol(octx,x,y,radius,false);octx.closePath();octx.stroke()}function drawBarHighlight(series,point){var highlightColor=typeof series.highlightColor==="string"?series.highlightColor:$.color.parse(series.color).scale("a",.5).toString(),fillStyle=highlightColor,barLeft;switch(series.bars.align){case"left":barLeft=0;break;case"right":barLeft=-series.bars.barWidth;break;default:barLeft=-series.bars.barWidth/2}octx.lineWidth=series.bars.lineWidth;octx.strokeStyle=highlightColor;drawBar(point[0],point[1],point[2]||0,barLeft,barLeft+series.bars.barWidth,function(){return fillStyle},series.xaxis,series.yaxis,octx,series.bars.horizontal,series.bars.lineWidth)}function getColorOrGradient(spec,bottom,top,defaultColor){if(typeof spec=="string")return spec;else{var gradient=ctx.createLinearGradient(0,top,0,bottom);for(var i=0,l=spec.colors.length;i<l;++i){var c=spec.colors[i];if(typeof c!="string"){var co=$.color.parse(defaultColor);if(c.brightness!=null)co=co.scale("rgb",c.brightness);if(c.opacity!=null)co.a*=c.opacity;c=co.toString()}gradient.addColorStop(i/(l-1),c)}return gradient}}}$.plot=function(placeholder,data,options){var plot=new Plot($(placeholder),data,options,$.plot.plugins);return plot};$.plot.version="0.8.3";$.plot.plugins=[];$.fn.plot=function(data,options){return this.each(function(){$.plot(this,data,options)})};function floorInBase(n,base){return base*Math.floor(n/base)}})(jQuery);
0 9
\ No newline at end of file
... ...
@@ -0,0 +1,346 @@
1
+/* Flot plugin for adding the ability to pan and zoom the plot.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+The default behaviour is double click and scrollwheel up/down to zoom in, drag
7
+to pan. The plugin defines plot.zoom({ center }), plot.zoomOut() and
8
+plot.pan( offset ) so you easily can add custom controls. It also fires
9
+"plotpan" and "plotzoom" events, useful for synchronizing plots.
10
+
11
+The plugin supports these options:
12
+
13
+	zoom: {
14
+		interactive: false
15
+		trigger: "dblclick" // or "click" for single click
16
+		amount: 1.5         // 2 = 200% (zoom in), 0.5 = 50% (zoom out)
17
+	}
18
+
19
+	pan: {
20
+		interactive: false
21
+		cursor: "move"      // CSS mouse cursor value used when dragging, e.g. "pointer"
22
+		frameRate: 20
23
+	}
24
+
25
+	xaxis, yaxis, x2axis, y2axis: {
26
+		zoomRange: null  // or [ number, number ] (min range, max range) or false
27
+		panRange: null   // or [ number, number ] (min, max) or false
28
+	}
29
+
30
+"interactive" enables the built-in drag/click behaviour. If you enable
31
+interactive for pan, then you'll have a basic plot that supports moving
32
+around; the same for zoom.
33
+
34
+"amount" specifies the default amount to zoom in (so 1.5 = 150%) relative to
35
+the current viewport.
36
+
37
+"cursor" is a standard CSS mouse cursor string used for visual feedback to the
38
+user when dragging.
39
+
40
+"frameRate" specifies the maximum number of times per second the plot will
41
+update itself while the user is panning around on it (set to null to disable
42
+intermediate pans, the plot will then not update until the mouse button is
43
+released).
44
+
45
+"zoomRange" is the interval in which zooming can happen, e.g. with zoomRange:
46
+[1, 100] the zoom will never scale the axis so that the difference between min
47
+and max is smaller than 1 or larger than 100. You can set either end to null
48
+to ignore, e.g. [1, null]. If you set zoomRange to false, zooming on that axis
49
+will be disabled.
50
+
51
+"panRange" confines the panning to stay within a range, e.g. with panRange:
52
+[-10, 20] panning stops at -10 in one end and at 20 in the other. Either can
53
+be null, e.g. [-10, null]. If you set panRange to false, panning on that axis
54
+will be disabled.
55
+
56
+Example API usage:
57
+
58
+	plot = $.plot(...);
59
+
60
+	// zoom default amount in on the pixel ( 10, 20 )
61
+	plot.zoom({ center: { left: 10, top: 20 } });
62
+
63
+	// zoom out again
64
+	plot.zoomOut({ center: { left: 10, top: 20 } });
65
+
66
+	// zoom 200% in on the pixel (10, 20)
67
+	plot.zoom({ amount: 2, center: { left: 10, top: 20 } });
68
+
69
+	// pan 100 pixels to the left and 20 down
70
+	plot.pan({ left: -100, top: 20 })
71
+
72
+Here, "center" specifies where the center of the zooming should happen. Note
73
+that this is defined in pixel space, not the space of the data points (you can
74
+use the p2c helpers on the axes in Flot to help you convert between these).
75
+
76
+"amount" is the amount to zoom the viewport relative to the current range, so
77
+1 is 100% (i.e. no change), 1.5 is 150% (zoom in), 0.7 is 70% (zoom out). You
78
+can set the default in the options.
79
+
80
+*/
81
+
82
+// First two dependencies, jquery.event.drag.js and
83
+// jquery.mousewheel.js, we put them inline here to save people the
84
+// effort of downloading them.
85
+
86
+/*
87
+jquery.event.drag.js ~ v1.5 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)
88
+Licensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt
89
+*/
90
+(function(a){function e(h){var k,j=this,l=h.data||{};if(l.elem)j=h.dragTarget=l.elem,h.dragProxy=d.proxy||j,h.cursorOffsetX=l.pageX-l.left,h.cursorOffsetY=l.pageY-l.top,h.offsetX=h.pageX-h.cursorOffsetX,h.offsetY=h.pageY-h.cursorOffsetY;else if(d.dragging||l.which>0&&h.which!=l.which||a(h.target).is(l.not))return;switch(h.type){case"mousedown":return a.extend(l,a(j).offset(),{elem:j,target:h.target,pageX:h.pageX,pageY:h.pageY}),b.add(document,"mousemove mouseup",e,l),i(j,!1),d.dragging=null,!1;case!d.dragging&&"mousemove":if(g(h.pageX-l.pageX)+g(h.pageY-l.pageY)<l.distance)break;h.target=l.target,k=f(h,"dragstart",j),k!==!1&&(d.dragging=j,d.proxy=h.dragProxy=a(k||j)[0]);case"mousemove":if(d.dragging){if(k=f(h,"drag",j),c.drop&&(c.drop.allowed=k!==!1,c.drop.handler(h)),k!==!1)break;h.type="mouseup"}case"mouseup":b.remove(document,"mousemove mouseup",e),d.dragging&&(c.drop&&c.drop.handler(h),f(h,"dragend",j)),i(j,!0),d.dragging=d.proxy=l.elem=!1}return!0}function f(b,c,d){b.type=c;var e=a.event.dispatch.call(d,b);return e===!1?!1:e||b.result}function g(a){return Math.pow(a,2)}function h(){return d.dragging===!1}function i(a,b){a&&(a.unselectable=b?"off":"on",a.onselectstart=function(){return b},a.style&&(a.style.MozUserSelect=b?"":"none"))}a.fn.drag=function(a,b,c){return b&&this.bind("dragstart",a),c&&this.bind("dragend",c),a?this.bind("drag",b?b:a):this.trigger("drag")};var b=a.event,c=b.special,d=c.drag={not:":input",distance:0,which:1,dragging:!1,setup:function(c){c=a.extend({distance:d.distance,which:d.which,not:d.not},c||{}),c.distance=g(c.distance),b.add(this,"mousedown",e,c),this.attachEvent&&this.attachEvent("ondragstart",h)},teardown:function(){b.remove(this,"mousedown",e),this===d.dragging&&(d.dragging=d.proxy=!1),i(this,!0),this.detachEvent&&this.detachEvent("ondragstart",h)}};c.dragstart=c.dragend={setup:function(){},teardown:function(){}}})(jQuery);
91
+
92
+/* jquery.mousewheel.min.js
93
+ * Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
94
+ * Licensed under the MIT License (LICENSE.txt).
95
+ * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
96
+ * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
97
+ * Thanks to: Seamus Leahy for adding deltaX and deltaY
98
+ *
99
+ * Version: 3.0.6
100
+ *
101
+ * Requires: 1.2.2+
102
+ */
103
+(function(d){function e(a){var b=a||window.event,c=[].slice.call(arguments,1),f=0,e=0,g=0,a=d.event.fix(b);a.type="mousewheel";b.wheelDelta&&(f=b.wheelDelta/120);b.detail&&(f=-b.detail/3);g=f;void 0!==b.axis&&b.axis===b.HORIZONTAL_AXIS&&(g=0,e=-1*f);void 0!==b.wheelDeltaY&&(g=b.wheelDeltaY/120);void 0!==b.wheelDeltaX&&(e=-1*b.wheelDeltaX/120);c.unshift(a,f,e,g);return(d.event.dispatch||d.event.handle).apply(this,c)}var c=["DOMMouseScroll","mousewheel"];if(d.event.fixHooks)for(var h=c.length;h;)d.event.fixHooks[c[--h]]=d.event.mouseHooks;d.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=c.length;a;)this.addEventListener(c[--a],e,!1);else this.onmousewheel=e},teardown:function(){if(this.removeEventListener)for(var a=c.length;a;)this.removeEventListener(c[--a],e,!1);else this.onmousewheel=null}};d.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery);
104
+
105
+
106
+
107
+
108
+(function ($) {
109
+    var options = {
110
+        xaxis: {
111
+            zoomRange: null, // or [number, number] (min range, max range)
112
+            panRange: null // or [number, number] (min, max)
113
+        },
114
+        zoom: {
115
+            interactive: false,
116
+            trigger: "dblclick", // or "click" for single click
117
+            amount: 1.5 // how much to zoom relative to current position, 2 = 200% (zoom in), 0.5 = 50% (zoom out)
118
+        },
119
+        pan: {
120
+            interactive: false,
121
+            cursor: "move",
122
+            frameRate: 20
123
+        }
124
+    };
125
+
126
+    function init(plot) {
127
+        function onZoomClick(e, zoomOut) {
128
+            var c = plot.offset();
129
+            c.left = e.pageX - c.left;
130
+            c.top = e.pageY - c.top;
131
+            if (zoomOut)
132
+                plot.zoomOut({ center: c });
133
+            else
134
+                plot.zoom({ center: c });
135
+        }
136
+
137
+        function onMouseWheel(e, delta) {
138
+            e.preventDefault();
139
+            onZoomClick(e, delta < 0);
140
+            return false;
141
+        }
142
+        
143
+        var prevCursor = 'default', prevPageX = 0, prevPageY = 0,
144
+            panTimeout = null;
145
+
146
+        function onDragStart(e) {
147
+            if (e.which != 1)  // only accept left-click
148
+                return false;
149
+            var c = plot.getPlaceholder().css('cursor');
150
+            if (c)
151
+                prevCursor = c;
152
+            plot.getPlaceholder().css('cursor', plot.getOptions().pan.cursor);
153
+            prevPageX = e.pageX;
154
+            prevPageY = e.pageY;
155
+        }
156
+        
157
+        function onDrag(e) {
158
+            var frameRate = plot.getOptions().pan.frameRate;
159
+            if (panTimeout || !frameRate)
160
+                return;
161
+
162
+            panTimeout = setTimeout(function () {
163
+                plot.pan({ left: prevPageX - e.pageX,
164
+                           top: prevPageY - e.pageY });
165
+                prevPageX = e.pageX;
166
+                prevPageY = e.pageY;
167
+                                                    
168
+                panTimeout = null;
169
+            }, 1 / frameRate * 1000);
170
+        }
171
+
172
+        function onDragEnd(e) {
173
+            if (panTimeout) {
174
+                clearTimeout(panTimeout);
175
+                panTimeout = null;
176
+            }
177
+                    
178
+            plot.getPlaceholder().css('cursor', prevCursor);
179
+            plot.pan({ left: prevPageX - e.pageX,
180
+                       top: prevPageY - e.pageY });
181
+        }
182
+        
183
+        function bindEvents(plot, eventHolder) {
184
+            var o = plot.getOptions();
185
+            if (o.zoom.interactive) {
186
+                eventHolder[o.zoom.trigger](onZoomClick);
187
+                eventHolder.mousewheel(onMouseWheel);
188
+            }
189
+
190
+            if (o.pan.interactive) {
191
+                eventHolder.bind("dragstart", { distance: 10 }, onDragStart);
192
+                eventHolder.bind("drag", onDrag);
193
+                eventHolder.bind("dragend", onDragEnd);
194
+            }
195
+        }
196
+
197
+        plot.zoomOut = function (args) {
198
+            if (!args)
199
+                args = {};
200
+            
201
+            if (!args.amount)
202
+                args.amount = plot.getOptions().zoom.amount;
203
+
204
+            args.amount = 1 / args.amount;
205
+            plot.zoom(args);
206
+        };
207
+        
208
+        plot.zoom = function (args) {
209
+            if (!args)
210
+                args = {};
211
+            
212
+            var c = args.center,
213
+                amount = args.amount || plot.getOptions().zoom.amount,
214
+                w = plot.width(), h = plot.height();
215
+
216
+            if (!c)
217
+                c = { left: w / 2, top: h / 2 };
218
+                
219
+            var xf = c.left / w,
220
+                yf = c.top / h,
221
+                minmax = {
222
+                    x: {
223
+                        min: c.left - xf * w / amount,
224
+                        max: c.left + (1 - xf) * w / amount
225
+                    },
226
+                    y: {
227
+                        min: c.top - yf * h / amount,
228
+                        max: c.top + (1 - yf) * h / amount
229
+                    }
230
+                };
231
+
232
+            $.each(plot.getAxes(), function(_, axis) {
233
+                var opts = axis.options,
234
+                    min = minmax[axis.direction].min,
235
+                    max = minmax[axis.direction].max,
236
+                    zr = opts.zoomRange,
237
+                    pr = opts.panRange;
238
+
239
+                if (zr === false) // no zooming on this axis
240
+                    return;
241
+                    
242
+                min = axis.c2p(min);
243
+                max = axis.c2p(max);
244
+                if (min > max) {
245
+                    // make sure min < max
246
+                    var tmp = min;
247
+                    min = max;
248
+                    max = tmp;
249
+                }
250
+
251
+                //Check that we are in panRange
252
+                if (pr) {
253
+                    if (pr[0] != null && min < pr[0]) {
254
+                        min = pr[0];
255
+                    }
256
+                    if (pr[1] != null && max > pr[1]) {
257
+                        max = pr[1];
258
+                    }
259
+                }
260
+
261
+                var range = max - min;
262
+                if (zr &&
263
+                    ((zr[0] != null && range < zr[0] && amount >1) ||
264
+                     (zr[1] != null && range > zr[1] && amount <1)))
265
+                    return;
266
+            
267
+                opts.min = min;
268
+                opts.max = max;
269
+            });
270
+            
271
+            plot.setupGrid();
272
+            plot.draw();
273
+            
274
+            if (!args.preventEvent)
275
+                plot.getPlaceholder().trigger("plotzoom", [ plot, args ]);
276
+        };
277
+
278
+        plot.pan = function (args) {
279
+            var delta = {
280
+                x: +args.left,
281
+                y: +args.top
282
+            };
283
+
284
+            if (isNaN(delta.x))
285
+                delta.x = 0;
286
+            if (isNaN(delta.y))
287
+                delta.y = 0;
288
+
289
+            $.each(plot.getAxes(), function (_, axis) {
290
+                var opts = axis.options,
291
+                    min, max, d = delta[axis.direction];
292
+
293
+                min = axis.c2p(axis.p2c(axis.min) + d),
294
+                max = axis.c2p(axis.p2c(axis.max) + d);
295
+
296
+                var pr = opts.panRange;
297
+                if (pr === false) // no panning on this axis
298
+                    return;
299
+                
300
+                if (pr) {
301
+                    // check whether we hit the wall
302
+                    if (pr[0] != null && pr[0] > min) {
303
+                        d = pr[0] - min;
304
+                        min += d;
305
+                        max += d;
306
+                    }
307
+                    
308
+                    if (pr[1] != null && pr[1] < max) {
309
+                        d = pr[1] - max;
310
+                        min += d;
311
+                        max += d;
312
+                    }
313
+                }
314
+                
315
+                opts.min = min;
316
+                opts.max = max;
317
+            });
318
+            
319
+            plot.setupGrid();
320
+            plot.draw();
321
+            
322
+            if (!args.preventEvent)
323
+                plot.getPlaceholder().trigger("plotpan", [ plot, args ]);
324
+        };
325
+
326
+        function shutdown(plot, eventHolder) {
327
+            eventHolder.unbind(plot.getOptions().zoom.trigger, onZoomClick);
328
+            eventHolder.unbind("mousewheel", onMouseWheel);
329
+            eventHolder.unbind("dragstart", onDragStart);
330
+            eventHolder.unbind("drag", onDrag);
331
+            eventHolder.unbind("dragend", onDragEnd);
332
+            if (panTimeout)
333
+                clearTimeout(panTimeout);
334
+        }
335
+        
336
+        plot.hooks.bindEvents.push(bindEvents);
337
+        plot.hooks.shutdown.push(shutdown);
338
+    }
339
+    
340
+    $.plot.plugins.push({
341
+        init: init,
342
+        options: options,
343
+        name: 'navigate',
344
+        version: '1.3'
345
+    });
346
+})(jQuery);
... ...
@@ -0,0 +1,7 @@
1
+/* Javascript plotting library for jQuery, version 0.8.3.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+*/
7
+(function(a){function e(h){var k,j=this,l=h.data||{};if(l.elem)j=h.dragTarget=l.elem,h.dragProxy=d.proxy||j,h.cursorOffsetX=l.pageX-l.left,h.cursorOffsetY=l.pageY-l.top,h.offsetX=h.pageX-h.cursorOffsetX,h.offsetY=h.pageY-h.cursorOffsetY;else if(d.dragging||l.which>0&&h.which!=l.which||a(h.target).is(l.not))return;switch(h.type){case"mousedown":return a.extend(l,a(j).offset(),{elem:j,target:h.target,pageX:h.pageX,pageY:h.pageY}),b.add(document,"mousemove mouseup",e,l),i(j,!1),d.dragging=null,!1;case!d.dragging&&"mousemove":if(g(h.pageX-l.pageX)+g(h.pageY-l.pageY)<l.distance)break;h.target=l.target,k=f(h,"dragstart",j),k!==!1&&(d.dragging=j,d.proxy=h.dragProxy=a(k||j)[0]);case"mousemove":if(d.dragging){if(k=f(h,"drag",j),c.drop&&(c.drop.allowed=k!==!1,c.drop.handler(h)),k!==!1)break;h.type="mouseup"}case"mouseup":b.remove(document,"mousemove mouseup",e),d.dragging&&(c.drop&&c.drop.handler(h),f(h,"dragend",j)),i(j,!0),d.dragging=d.proxy=l.elem=!1}return!0}function f(b,c,d){b.type=c;var e=a.event.dispatch.call(d,b);return e===!1?!1:e||b.result}function g(a){return Math.pow(a,2)}function h(){return d.dragging===!1}function i(a,b){a&&(a.unselectable=b?"off":"on",a.onselectstart=function(){return b},a.style&&(a.style.MozUserSelect=b?"":"none"))}a.fn.drag=function(a,b,c){return b&&this.bind("dragstart",a),c&&this.bind("dragend",c),a?this.bind("drag",b?b:a):this.trigger("drag")};var b=a.event,c=b.special,d=c.drag={not:":input",distance:0,which:1,dragging:!1,setup:function(c){c=a.extend({distance:d.distance,which:d.which,not:d.not},c||{}),c.distance=g(c.distance),b.add(this,"mousedown",e,c),this.attachEvent&&this.attachEvent("ondragstart",h)},teardown:function(){b.remove(this,"mousedown",e),this===d.dragging&&(d.dragging=d.proxy=!1),i(this,!0),this.detachEvent&&this.detachEvent("ondragstart",h)}};c.dragstart=c.dragend={setup:function(){},teardown:function(){}}})(jQuery);(function(d){function e(a){var b=a||window.event,c=[].slice.call(arguments,1),f=0,e=0,g=0,a=d.event.fix(b);a.type="mousewheel";b.wheelDelta&&(f=b.wheelDelta/120);b.detail&&(f=-b.detail/3);g=f;void 0!==b.axis&&b.axis===b.HORIZONTAL_AXIS&&(g=0,e=-1*f);void 0!==b.wheelDeltaY&&(g=b.wheelDeltaY/120);void 0!==b.wheelDeltaX&&(e=-1*b.wheelDeltaX/120);c.unshift(a,f,e,g);return(d.event.dispatch||d.event.handle).apply(this,c)}var c=["DOMMouseScroll","mousewheel"];if(d.event.fixHooks)for(var h=c.length;h;)d.event.fixHooks[c[--h]]=d.event.mouseHooks;d.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=c.length;a;)this.addEventListener(c[--a],e,!1);else this.onmousewheel=e},teardown:function(){if(this.removeEventListener)for(var a=c.length;a;)this.removeEventListener(c[--a],e,!1);else this.onmousewheel=null}};d.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery);(function($){var options={xaxis:{zoomRange:null,panRange:null},zoom:{interactive:false,trigger:"dblclick",amount:1.5},pan:{interactive:false,cursor:"move",frameRate:20}};function init(plot){function onZoomClick(e,zoomOut){var c=plot.offset();c.left=e.pageX-c.left;c.top=e.pageY-c.top;if(zoomOut)plot.zoomOut({center:c});else plot.zoom({center:c})}function onMouseWheel(e,delta){e.preventDefault();onZoomClick(e,delta<0);return false}var prevCursor="default",prevPageX=0,prevPageY=0,panTimeout=null;function onDragStart(e){if(e.which!=1)return false;var c=plot.getPlaceholder().css("cursor");if(c)prevCursor=c;plot.getPlaceholder().css("cursor",plot.getOptions().pan.cursor);prevPageX=e.pageX;prevPageY=e.pageY}function onDrag(e){var frameRate=plot.getOptions().pan.frameRate;if(panTimeout||!frameRate)return;panTimeout=setTimeout(function(){plot.pan({left:prevPageX-e.pageX,top:prevPageY-e.pageY});prevPageX=e.pageX;prevPageY=e.pageY;panTimeout=null},1/frameRate*1e3)}function onDragEnd(e){if(panTimeout){clearTimeout(panTimeout);panTimeout=null}plot.getPlaceholder().css("cursor",prevCursor);plot.pan({left:prevPageX-e.pageX,top:prevPageY-e.pageY})}function bindEvents(plot,eventHolder){var o=plot.getOptions();if(o.zoom.interactive){eventHolder[o.zoom.trigger](onZoomClick);eventHolder.mousewheel(onMouseWheel)}if(o.pan.interactive){eventHolder.bind("dragstart",{distance:10},onDragStart);eventHolder.bind("drag",onDrag);eventHolder.bind("dragend",onDragEnd)}}plot.zoomOut=function(args){if(!args)args={};if(!args.amount)args.amount=plot.getOptions().zoom.amount;args.amount=1/args.amount;plot.zoom(args)};plot.zoom=function(args){if(!args)args={};var c=args.center,amount=args.amount||plot.getOptions().zoom.amount,w=plot.width(),h=plot.height();if(!c)c={left:w/2,top:h/2};var xf=c.left/w,yf=c.top/h,minmax={x:{min:c.left-xf*w/amount,max:c.left+(1-xf)*w/amount},y:{min:c.top-yf*h/amount,max:c.top+(1-yf)*h/amount}};$.each(plot.getAxes(),function(_,axis){var opts=axis.options,min=minmax[axis.direction].min,max=minmax[axis.direction].max,zr=opts.zoomRange,pr=opts.panRange;if(zr===false)return;min=axis.c2p(min);max=axis.c2p(max);if(min>max){var tmp=min;min=max;max=tmp}if(pr){if(pr[0]!=null&&min<pr[0]){min=pr[0]}if(pr[1]!=null&&max>pr[1]){max=pr[1]}}var range=max-min;if(zr&&(zr[0]!=null&&range<zr[0]&&amount>1||zr[1]!=null&&range>zr[1]&&amount<1))return;opts.min=min;opts.max=max});plot.setupGrid();plot.draw();if(!args.preventEvent)plot.getPlaceholder().trigger("plotzoom",[plot,args])};plot.pan=function(args){var delta={x:+args.left,y:+args.top};if(isNaN(delta.x))delta.x=0;if(isNaN(delta.y))delta.y=0;$.each(plot.getAxes(),function(_,axis){var opts=axis.options,min,max,d=delta[axis.direction];min=axis.c2p(axis.p2c(axis.min)+d),max=axis.c2p(axis.p2c(axis.max)+d);var pr=opts.panRange;if(pr===false)return;if(pr){if(pr[0]!=null&&pr[0]>min){d=pr[0]-min;min+=d;max+=d}if(pr[1]!=null&&pr[1]<max){d=pr[1]-max;min+=d;max+=d}}opts.min=min;opts.max=max});plot.setupGrid();plot.draw();if(!args.preventEvent)plot.getPlaceholder().trigger("plotpan",[plot,args])};function shutdown(plot,eventHolder){eventHolder.unbind(plot.getOptions().zoom.trigger,onZoomClick);eventHolder.unbind("mousewheel",onMouseWheel);eventHolder.unbind("dragstart",onDragStart);eventHolder.unbind("drag",onDrag);eventHolder.unbind("dragend",onDragEnd);if(panTimeout)clearTimeout(panTimeout)}plot.hooks.bindEvents.push(bindEvents);plot.hooks.shutdown.push(shutdown)}$.plot.plugins.push({init:init,options:options,name:"navigate",version:"1.3"})})(jQuery);
0 8
\ No newline at end of file
... ...
@@ -0,0 +1,820 @@
1
+/* Flot plugin for rendering pie charts.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+The plugin assumes that each series has a single data value, and that each
7
+value is a positive integer or zero.  Negative numbers don't make sense for a
8
+pie chart, and have unpredictable results.  The values do NOT need to be
9
+passed in as percentages; the plugin will calculate the total and per-slice
10
+percentages internally.
11
+
12
+* Created by Brian Medendorp
13
+
14
+* Updated with contributions from btburnett3, Anthony Aragues and Xavi Ivars
15
+
16
+The plugin supports these options:
17
+
18
+	series: {
19
+		pie: {
20
+			show: true/false
21
+			radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'
22
+			innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect
23
+			startAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result
24
+			tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)
25
+			offset: {
26
+				top: integer value to move the pie up or down
27
+				left: integer value to move the pie left or right, or 'auto'
28
+			},
29
+			stroke: {
30
+				color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF')
31
+				width: integer pixel width of the stroke
32
+			},
33
+			label: {
34
+				show: true/false, or 'auto'
35
+				formatter:  a user-defined function that modifies the text/style of the label text
36
+				radius: 0-1 for percentage of fullsize, or a specified pixel length
37
+				background: {
38
+					color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000')
39
+					opacity: 0-1
40
+				},
41
+				threshold: 0-1 for the percentage value at which to hide labels (if they're too small)
42
+			},
43
+			combine: {
44
+				threshold: 0-1 for the percentage value at which to combine slices (if they're too small)
45
+				color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined
46
+				label: any text value of what the combined slice should be labeled
47
+			}
48
+			highlight: {
49
+				opacity: 0-1
50
+			}
51
+		}
52
+	}
53
+
54
+More detail and specific examples can be found in the included HTML file.
55
+
56
+*/
57
+
58
+(function($) {
59
+
60
+	// Maximum redraw attempts when fitting labels within the plot
61
+
62
+	var REDRAW_ATTEMPTS = 10;
63
+
64
+	// Factor by which to shrink the pie when fitting labels within the plot
65
+
66
+	var REDRAW_SHRINK = 0.95;
67
+
68
+	function init(plot) {
69
+
70
+		var canvas = null,
71
+			target = null,
72
+			options = null,
73
+			maxRadius = null,
74
+			centerLeft = null,
75
+			centerTop = null,
76
+			processed = false,
77
+			ctx = null;
78
+
79
+		// interactive variables
80
+
81
+		var highlights = [];
82
+
83
+		// add hook to determine if pie plugin in enabled, and then perform necessary operations
84
+
85
+		plot.hooks.processOptions.push(function(plot, options) {
86
+			if (options.series.pie.show) {
87
+
88
+				options.grid.show = false;
89
+
90
+				// set labels.show
91
+
92
+				if (options.series.pie.label.show == "auto") {
93
+					if (options.legend.show) {
94
+						options.series.pie.label.show = false;
95
+					} else {
96
+						options.series.pie.label.show = true;
97
+					}
98
+				}
99
+
100
+				// set radius
101
+
102
+				if (options.series.pie.radius == "auto") {
103
+					if (options.series.pie.label.show) {
104
+						options.series.pie.radius = 3/4;
105
+					} else {
106
+						options.series.pie.radius = 1;
107
+					}
108
+				}
109
+
110
+				// ensure sane tilt
111
+
112
+				if (options.series.pie.tilt > 1) {
113
+					options.series.pie.tilt = 1;
114
+				} else if (options.series.pie.tilt < 0) {
115
+					options.series.pie.tilt = 0;
116
+				}
117
+			}
118
+		});
119
+
120
+		plot.hooks.bindEvents.push(function(plot, eventHolder) {
121
+			var options = plot.getOptions();
122
+			if (options.series.pie.show) {
123
+				if (options.grid.hoverable) {
124
+					eventHolder.unbind("mousemove").mousemove(onMouseMove);
125
+				}
126
+				if (options.grid.clickable) {
127
+					eventHolder.unbind("click").click(onClick);
128
+				}
129
+			}
130
+		});
131
+
132
+		plot.hooks.processDatapoints.push(function(plot, series, data, datapoints) {
133
+			var options = plot.getOptions();
134
+			if (options.series.pie.show) {
135
+				processDatapoints(plot, series, data, datapoints);
136
+			}
137
+		});
138
+
139
+		plot.hooks.drawOverlay.push(function(plot, octx) {
140
+			var options = plot.getOptions();
141
+			if (options.series.pie.show) {
142
+				drawOverlay(plot, octx);
143
+			}
144
+		});
145
+
146
+		plot.hooks.draw.push(function(plot, newCtx) {
147
+			var options = plot.getOptions();
148
+			if (options.series.pie.show) {
149
+				draw(plot, newCtx);
150
+			}
151
+		});
152
+
153
+		function processDatapoints(plot, series, datapoints) {
154
+			if (!processed)	{
155
+				processed = true;
156
+				canvas = plot.getCanvas();
157
+				target = $(canvas).parent();
158
+				options = plot.getOptions();
159
+				plot.setData(combine(plot.getData()));
160
+			}
161
+		}
162
+
163
+		function combine(data) {
164
+
165
+			var total = 0,
166
+				combined = 0,
167
+				numCombined = 0,
168
+				color = options.series.pie.combine.color,
169
+				newdata = [];
170
+
171
+			// Fix up the raw data from Flot, ensuring the data is numeric
172
+
173
+			for (var i = 0; i < data.length; ++i) {
174
+
175
+				var value = data[i].data;
176
+
177
+				// If the data is an array, we'll assume that it's a standard
178
+				// Flot x-y pair, and are concerned only with the second value.
179
+
180
+				// Note how we use the original array, rather than creating a
181
+				// new one; this is more efficient and preserves any extra data
182
+				// that the user may have stored in higher indexes.
183
+
184
+				if ($.isArray(value) && value.length == 1) {
185
+    				value = value[0];
186
+				}
187
+
188
+				if ($.isArray(value)) {
189
+					// Equivalent to $.isNumeric() but compatible with jQuery < 1.7
190
+					if (!isNaN(parseFloat(value[1])) && isFinite(value[1])) {
191
+						value[1] = +value[1];
192
+					} else {
193
+						value[1] = 0;
194
+					}
195
+				} else if (!isNaN(parseFloat(value)) && isFinite(value)) {
196
+					value = [1, +value];
197
+				} else {
198
+					value = [1, 0];
199
+				}
200
+
201
+				data[i].data = [value];
202
+			}
203
+
204
+			// Sum up all the slices, so we can calculate percentages for each
205
+
206
+			for (var i = 0; i < data.length; ++i) {
207
+				total += data[i].data[0][1];
208
+			}
209
+
210
+			// Count the number of slices with percentages below the combine
211
+			// threshold; if it turns out to be just one, we won't combine.
212
+
213
+			for (var i = 0; i < data.length; ++i) {
214
+				var value = data[i].data[0][1];
215
+				if (value / total <= options.series.pie.combine.threshold) {
216
+					combined += value;
217
+					numCombined++;
218
+					if (!color) {
219
+						color = data[i].color;
220
+					}
221
+				}
222
+			}
223
+
224
+			for (var i = 0; i < data.length; ++i) {
225
+				var value = data[i].data[0][1];
226
+				if (numCombined < 2 || value / total > options.series.pie.combine.threshold) {
227
+					newdata.push(
228
+						$.extend(data[i], {     /* extend to allow keeping all other original data values
229
+						                           and using them e.g. in labelFormatter. */
230
+							data: [[1, value]],
231
+							color: data[i].color,
232
+							label: data[i].label,
233
+							angle: value * Math.PI * 2 / total,
234
+							percent: value / (total / 100)
235
+						})
236
+					);
237
+				}
238
+			}
239
+
240
+			if (numCombined > 1) {
241
+				newdata.push({
242
+					data: [[1, combined]],
243
+					color: color,
244
+					label: options.series.pie.combine.label,
245
+					angle: combined * Math.PI * 2 / total,
246
+					percent: combined / (total / 100)
247
+				});
248
+			}
249
+
250
+			return newdata;
251
+		}
252
+
253
+		function draw(plot, newCtx) {
254
+
255
+			if (!target) {
256
+				return; // if no series were passed
257
+			}
258
+
259
+			var canvasWidth = plot.getPlaceholder().width(),
260
+				canvasHeight = plot.getPlaceholder().height(),
261
+				legendWidth = target.children().filter(".legend").children().width() || 0;
262
+
263
+			ctx = newCtx;
264
+
265
+			// WARNING: HACK! REWRITE THIS CODE AS SOON AS POSSIBLE!
266
+
267
+			// When combining smaller slices into an 'other' slice, we need to
268
+			// add a new series.  Since Flot gives plugins no way to modify the
269
+			// list of series, the pie plugin uses a hack where the first call
270
+			// to processDatapoints results in a call to setData with the new
271
+			// list of series, then subsequent processDatapoints do nothing.
272
+
273
+			// The plugin-global 'processed' flag is used to control this hack;
274
+			// it starts out false, and is set to true after the first call to
275
+			// processDatapoints.
276
+
277
+			// Unfortunately this turns future setData calls into no-ops; they
278
+			// call processDatapoints, the flag is true, and nothing happens.
279
+
280
+			// To fix this we'll set the flag back to false here in draw, when
281
+			// all series have been processed, so the next sequence of calls to
282
+			// processDatapoints once again starts out with a slice-combine.
283
+			// This is really a hack; in 0.9 we need to give plugins a proper
284
+			// way to modify series before any processing begins.
285
+
286
+			processed = false;
287
+
288
+			// calculate maximum radius and center point
289
+
290
+			maxRadius =  Math.min(canvasWidth, canvasHeight / options.series.pie.tilt) / 2;
291
+			centerTop = canvasHeight / 2 + options.series.pie.offset.top;
292
+			centerLeft = canvasWidth / 2;
293
+
294
+			if (options.series.pie.offset.left == "auto") {
295
+				if (options.legend.position.match("w")) {
296
+					centerLeft += legendWidth / 2;
297
+				} else {
298
+					centerLeft -= legendWidth / 2;
299
+				}
300
+				if (centerLeft < maxRadius) {
301
+					centerLeft = maxRadius;
302
+				} else if (centerLeft > canvasWidth - maxRadius) {
303
+					centerLeft = canvasWidth - maxRadius;
304
+				}
305
+			} else {
306
+				centerLeft += options.series.pie.offset.left;
307
+			}
308
+
309
+			var slices = plot.getData(),
310
+				attempts = 0;
311
+
312
+			// Keep shrinking the pie's radius until drawPie returns true,
313
+			// indicating that all the labels fit, or we try too many times.
314
+
315
+			do {
316
+				if (attempts > 0) {
317
+					maxRadius *= REDRAW_SHRINK;
318
+				}
319
+				attempts += 1;
320
+				clear();
321
+				if (options.series.pie.tilt <= 0.8) {
322
+					drawShadow();
323
+				}
324
+			} while (!drawPie() && attempts < REDRAW_ATTEMPTS)
325
+
326
+			if (attempts >= REDRAW_ATTEMPTS) {
327
+				clear();
328
+				target.prepend("<div class='error'>Could not draw pie with labels contained inside canvas</div>");
329
+			}
330
+
331
+			if (plot.setSeries && plot.insertLegend) {
332
+				plot.setSeries(slices);
333
+				plot.insertLegend();
334
+			}
335
+
336
+			// we're actually done at this point, just defining internal functions at this point
337
+
338
+			function clear() {
339
+				ctx.clearRect(0, 0, canvasWidth, canvasHeight);
340
+				target.children().filter(".pieLabel, .pieLabelBackground").remove();
341
+			}
342
+
343
+			function drawShadow() {
344
+
345
+				var shadowLeft = options.series.pie.shadow.left;
346
+				var shadowTop = options.series.pie.shadow.top;
347
+				var edge = 10;
348
+				var alpha = options.series.pie.shadow.alpha;
349
+				var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
350
+
351
+				if (radius >= canvasWidth / 2 - shadowLeft || radius * options.series.pie.tilt >= canvasHeight / 2 - shadowTop || radius <= edge) {
352
+					return;	// shadow would be outside canvas, so don't draw it
353
+				}
354
+
355
+				ctx.save();
356
+				ctx.translate(shadowLeft,shadowTop);
357
+				ctx.globalAlpha = alpha;
358
+				ctx.fillStyle = "#000";
359
+
360
+				// center and rotate to starting position
361
+
362
+				ctx.translate(centerLeft,centerTop);
363
+				ctx.scale(1, options.series.pie.tilt);
364
+
365
+				//radius -= edge;
366
+
367
+				for (var i = 1; i <= edge; i++) {
368
+					ctx.beginPath();
369
+					ctx.arc(0, 0, radius, 0, Math.PI * 2, false);
370
+					ctx.fill();
371
+					radius -= i;
372
+				}
373
+
374
+				ctx.restore();
375
+			}
376
+
377
+			function drawPie() {
378
+
379
+				var startAngle = Math.PI * options.series.pie.startAngle;
380
+				var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
381
+
382
+				// center and rotate to starting position
383
+
384
+				ctx.save();
385
+				ctx.translate(centerLeft,centerTop);
386
+				ctx.scale(1, options.series.pie.tilt);
387
+				//ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera
388
+
389
+				// draw slices
390
+
391
+				ctx.save();
392
+				var currentAngle = startAngle;
393
+				for (var i = 0; i < slices.length; ++i) {
394
+					slices[i].startAngle = currentAngle;
395
+					drawSlice(slices[i].angle, slices[i].color, true);
396
+				}
397
+				ctx.restore();
398
+
399
+				// draw slice outlines
400
+
401
+				if (options.series.pie.stroke.width > 0) {
402
+					ctx.save();
403
+					ctx.lineWidth = options.series.pie.stroke.width;
404
+					currentAngle = startAngle;
405
+					for (var i = 0; i < slices.length; ++i) {
406
+						drawSlice(slices[i].angle, options.series.pie.stroke.color, false);
407
+					}
408
+					ctx.restore();
409
+				}
410
+
411
+				// draw donut hole
412
+
413
+				drawDonutHole(ctx);
414
+
415
+				ctx.restore();
416
+
417
+				// Draw the labels, returning true if they fit within the plot
418
+
419
+				if (options.series.pie.label.show) {
420
+					return drawLabels();
421
+				} else return true;
422
+
423
+				function drawSlice(angle, color, fill) {
424
+
425
+					if (angle <= 0 || isNaN(angle)) {
426
+						return;
427
+					}
428
+
429
+					if (fill) {
430
+						ctx.fillStyle = color;
431
+					} else {
432
+						ctx.strokeStyle = color;
433
+						ctx.lineJoin = "round";
434
+					}
435
+
436
+					ctx.beginPath();
437
+					if (Math.abs(angle - Math.PI * 2) > 0.000000001) {
438
+						ctx.moveTo(0, 0); // Center of the pie
439
+					}
440
+
441
+					//ctx.arc(0, 0, radius, 0, angle, false); // This doesn't work properly in Opera
442
+					ctx.arc(0, 0, radius,currentAngle, currentAngle + angle / 2, false);
443
+					ctx.arc(0, 0, radius,currentAngle + angle / 2, currentAngle + angle, false);
444
+					ctx.closePath();
445
+					//ctx.rotate(angle); // This doesn't work properly in Opera
446
+					currentAngle += angle;
447
+
448
+					if (fill) {
449
+						ctx.fill();
450
+					} else {
451
+						ctx.stroke();
452
+					}
453
+				}
454
+
455
+				function drawLabels() {
456
+
457
+					var currentAngle = startAngle;
458
+					var radius = options.series.pie.label.radius > 1 ? options.series.pie.label.radius : maxRadius * options.series.pie.label.radius;
459
+
460
+					for (var i = 0; i < slices.length; ++i) {
461
+						if (slices[i].percent >= options.series.pie.label.threshold * 100) {
462
+							if (!drawLabel(slices[i], currentAngle, i)) {
463
+								return false;
464
+							}
465
+						}
466
+						currentAngle += slices[i].angle;
467
+					}
468
+
469
+					return true;
470
+
471
+					function drawLabel(slice, startAngle, index) {
472
+
473
+						if (slice.data[0][1] == 0) {
474
+							return true;
475
+						}
476
+
477
+						// format label text
478
+
479
+						var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter;
480
+
481
+						if (lf) {
482
+							text = lf(slice.label, slice);
483
+						} else {
484
+							text = slice.label;
485
+						}
486
+
487
+						if (plf) {
488
+							text = plf(text, slice);
489
+						}
490
+
491
+						var halfAngle = ((startAngle + slice.angle) + startAngle) / 2;
492
+						var x = centerLeft + Math.round(Math.cos(halfAngle) * radius);
493
+						var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt;
494
+
495
+						var html = "<span class='pieLabel' id='pieLabel" + index + "' style='position:absolute;top:" + y + "px;left:" + x + "px;'>" + text + "</span>";
496
+						target.append(html);
497
+
498
+						var label = target.children("#pieLabel" + index);
499
+						var labelTop = (y - label.height() / 2);
500
+						var labelLeft = (x - label.width() / 2);
501
+
502
+						label.css("top", labelTop);
503
+						label.css("left", labelLeft);
504
+
505
+						// check to make sure that the label is not outside the canvas
506
+
507
+						if (0 - labelTop > 0 || 0 - labelLeft > 0 || canvasHeight - (labelTop + label.height()) < 0 || canvasWidth - (labelLeft + label.width()) < 0) {
508
+							return false;
509
+						}
510
+
511
+						if (options.series.pie.label.background.opacity != 0) {
512
+
513
+							// put in the transparent background separately to avoid blended labels and label boxes
514
+
515
+							var c = options.series.pie.label.background.color;
516
+
517
+							if (c == null) {
518
+								c = slice.color;
519
+							}
520
+
521
+							var pos = "top:" + labelTop + "px;left:" + labelLeft + "px;";
522
+							$("<div class='pieLabelBackground' style='position:absolute;width:" + label.width() + "px;height:" + label.height() + "px;" + pos + "background-color:" + c + ";'></div>")
523
+								.css("opacity", options.series.pie.label.background.opacity)
524
+								.insertBefore(label);
525
+						}
526
+
527
+						return true;
528
+					} // end individual label function
529
+				} // end drawLabels function
530
+			} // end drawPie function
531
+		} // end draw function
532
+
533
+		// Placed here because it needs to be accessed from multiple locations
534
+
535
+		function drawDonutHole(layer) {
536
+			if (options.series.pie.innerRadius > 0) {
537
+
538
+				// subtract the center
539
+
540
+				layer.save();
541
+				var innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius;
542
+				layer.globalCompositeOperation = "destination-out"; // this does not work with excanvas, but it will fall back to using the stroke color
543
+				layer.beginPath();
544
+				layer.fillStyle = options.series.pie.stroke.color;
545
+				layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);
546
+				layer.fill();
547
+				layer.closePath();
548
+				layer.restore();
549
+
550
+				// add inner stroke
551
+
552
+				layer.save();
553
+				layer.beginPath();
554
+				layer.strokeStyle = options.series.pie.stroke.color;
555
+				layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);
556
+				layer.stroke();
557
+				layer.closePath();
558
+				layer.restore();
559
+
560
+				// TODO: add extra shadow inside hole (with a mask) if the pie is tilted.
561
+			}
562
+		}
563
+
564
+		//-- Additional Interactive related functions --
565
+
566
+		function isPointInPoly(poly, pt) {
567
+			for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
568
+				((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1]))
569
+				&& (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])
570
+				&& (c = !c);
571
+			return c;
572
+		}
573
+
574
+		function findNearbySlice(mouseX, mouseY) {
575
+
576
+			var slices = plot.getData(),
577
+				options = plot.getOptions(),
578
+				radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius,
579
+				x, y;
580
+
581
+			for (var i = 0; i < slices.length; ++i) {
582
+
583
+				var s = slices[i];
584
+
585
+				if (s.pie.show) {
586
+
587
+					ctx.save();
588
+					ctx.beginPath();
589
+					ctx.moveTo(0, 0); // Center of the pie
590
+					//ctx.scale(1, options.series.pie.tilt);	// this actually seems to break everything when here.
591
+					ctx.arc(0, 0, radius, s.startAngle, s.startAngle + s.angle / 2, false);
592
+					ctx.arc(0, 0, radius, s.startAngle + s.angle / 2, s.startAngle + s.angle, false);
593
+					ctx.closePath();
594
+					x = mouseX - centerLeft;
595
+					y = mouseY - centerTop;
596
+
597
+					if (ctx.isPointInPath) {
598
+						if (ctx.isPointInPath(mouseX - centerLeft, mouseY - centerTop)) {
599
+							ctx.restore();
600
+							return {
601
+								datapoint: [s.percent, s.data],
602
+								dataIndex: 0,
603
+								series: s,
604
+								seriesIndex: i
605
+							};
606
+						}
607
+					} else {
608
+
609
+						// excanvas for IE doesn;t support isPointInPath, this is a workaround.
610
+
611
+						var p1X = radius * Math.cos(s.startAngle),
612
+							p1Y = radius * Math.sin(s.startAngle),
613
+							p2X = radius * Math.cos(s.startAngle + s.angle / 4),
614
+							p2Y = radius * Math.sin(s.startAngle + s.angle / 4),
615
+							p3X = radius * Math.cos(s.startAngle + s.angle / 2),
616
+							p3Y = radius * Math.sin(s.startAngle + s.angle / 2),
617
+							p4X = radius * Math.cos(s.startAngle + s.angle / 1.5),
618
+							p4Y = radius * Math.sin(s.startAngle + s.angle / 1.5),
619
+							p5X = radius * Math.cos(s.startAngle + s.angle),
620
+							p5Y = radius * Math.sin(s.startAngle + s.angle),
621
+							arrPoly = [[0, 0], [p1X, p1Y], [p2X, p2Y], [p3X, p3Y], [p4X, p4Y], [p5X, p5Y]],
622
+							arrPoint = [x, y];
623
+
624
+						// TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?
625
+
626
+						if (isPointInPoly(arrPoly, arrPoint)) {
627
+							ctx.restore();
628
+							return {
629
+								datapoint: [s.percent, s.data],
630
+								dataIndex: 0,
631
+								series: s,
632
+								seriesIndex: i
633
+							};
634
+						}
635
+					}
636
+
637
+					ctx.restore();
638
+				}
639
+			}
640
+
641
+			return null;
642
+		}
643
+
644
+		function onMouseMove(e) {
645
+			triggerClickHoverEvent("plothover", e);
646
+		}
647
+
648
+		function onClick(e) {
649
+			triggerClickHoverEvent("plotclick", e);
650
+		}
651
+
652
+		// trigger click or hover event (they send the same parameters so we share their code)
653
+
654
+		function triggerClickHoverEvent(eventname, e) {
655
+
656
+			var offset = plot.offset();
657
+			var canvasX = parseInt(e.pageX - offset.left);
658
+			var canvasY =  parseInt(e.pageY - offset.top);
659
+			var item = findNearbySlice(canvasX, canvasY);
660
+
661
+			if (options.grid.autoHighlight) {
662
+
663
+				// clear auto-highlights
664
+
665
+				for (var i = 0; i < highlights.length; ++i) {
666
+					var h = highlights[i];
667
+					if (h.auto == eventname && !(item && h.series == item.series)) {
668
+						unhighlight(h.series);
669
+					}
670
+				}
671
+			}
672
+
673
+			// highlight the slice
674
+
675
+			if (item) {
676
+				highlight(item.series, eventname);
677
+			}
678
+
679
+			// trigger any hover bind events
680
+
681
+			var pos = { pageX: e.pageX, pageY: e.pageY };
682
+			target.trigger(eventname, [pos, item]);
683
+		}
684
+
685
+		function highlight(s, auto) {
686
+			//if (typeof s == "number") {
687
+			//	s = series[s];
688
+			//}
689
+
690
+			var i = indexOfHighlight(s);
691
+
692
+			if (i == -1) {
693
+				highlights.push({ series: s, auto: auto });
694
+				plot.triggerRedrawOverlay();
695
+			} else if (!auto) {
696
+				highlights[i].auto = false;
697
+			}
698
+		}
699
+
700
+		function unhighlight(s) {
701
+			if (s == null) {
702
+				highlights = [];
703
+				plot.triggerRedrawOverlay();
704
+			}
705
+
706
+			//if (typeof s == "number") {
707
+			//	s = series[s];
708
+			//}
709
+
710
+			var i = indexOfHighlight(s);
711
+
712
+			if (i != -1) {
713
+				highlights.splice(i, 1);
714
+				plot.triggerRedrawOverlay();
715
+			}
716
+		}
717
+
718
+		function indexOfHighlight(s) {
719
+			for (var i = 0; i < highlights.length; ++i) {
720
+				var h = highlights[i];
721
+				if (h.series == s)
722
+					return i;
723
+			}
724
+			return -1;
725
+		}
726
+
727
+		function drawOverlay(plot, octx) {
728
+
729
+			var options = plot.getOptions();
730
+
731
+			var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
732
+
733
+			octx.save();
734
+			octx.translate(centerLeft, centerTop);
735
+			octx.scale(1, options.series.pie.tilt);
736
+
737
+			for (var i = 0; i < highlights.length; ++i) {
738
+				drawHighlight(highlights[i].series);
739
+			}
740
+
741
+			drawDonutHole(octx);
742
+
743
+			octx.restore();
744
+
745
+			function drawHighlight(series) {
746
+
747
+				if (series.angle <= 0 || isNaN(series.angle)) {
748
+					return;
749
+				}
750
+
751
+				//octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();
752
+				octx.fillStyle = "rgba(255, 255, 255, " + options.series.pie.highlight.opacity + ")"; // this is temporary until we have access to parseColor
753
+				octx.beginPath();
754
+				if (Math.abs(series.angle - Math.PI * 2) > 0.000000001) {
755
+					octx.moveTo(0, 0); // Center of the pie
756
+				}
757
+				octx.arc(0, 0, radius, series.startAngle, series.startAngle + series.angle / 2, false);
758
+				octx.arc(0, 0, radius, series.startAngle + series.angle / 2, series.startAngle + series.angle, false);
759
+				octx.closePath();
760
+				octx.fill();
761
+			}
762
+		}
763
+	} // end init (plugin body)
764
+
765
+	// define pie specific options and their default values
766
+
767
+	var options = {
768
+		series: {
769
+			pie: {
770
+				show: false,
771
+				radius: "auto",	// actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)
772
+				innerRadius: 0, /* for donut */
773
+				startAngle: 3/2,
774
+				tilt: 1,
775
+				shadow: {
776
+					left: 5,	// shadow left offset
777
+					top: 15,	// shadow top offset
778
+					alpha: 0.02	// shadow alpha
779
+				},
780
+				offset: {
781
+					top: 0,
782
+					left: "auto"
783
+				},
784
+				stroke: {
785
+					color: "#fff",
786
+					width: 1
787
+				},
788
+				label: {
789
+					show: "auto",
790
+					formatter: function(label, slice) {
791
+						return "<div style='font-size:x-small;text-align:center;padding:2px;color:" + slice.color + ";'>" + label + "<br/>" + Math.round(slice.percent) + "%</div>";
792
+					},	// formatter function
793
+					radius: 1,	// radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)
794
+					background: {
795
+						color: null,
796
+						opacity: 0
797
+					},
798
+					threshold: 0	// percentage at which to hide the label (i.e. the slice is too narrow)
799
+				},
800
+				combine: {
801
+					threshold: -1,	// percentage at which to combine little slices into one larger slice
802
+					color: null,	// color to give the new slice (auto-generated if null)
803
+					label: "Other"	// label to give the new slice
804
+				},
805
+				highlight: {
806
+					//color: "#fff",		// will add this functionality once parseColor is available
807
+					opacity: 0.5
808
+				}
809
+			}
810
+		}
811
+	};
812
+
813
+	$.plot.plugins.push({
814
+		init: init,
815
+		options: options,
816
+		name: "pie",
817
+		version: "1.1"
818
+	});
819
+
820
+})(jQuery);
... ...
@@ -0,0 +1,7 @@
1
+/* Javascript plotting library for jQuery, version 0.8.3.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+*/
7
+(function($){var REDRAW_ATTEMPTS=10;var REDRAW_SHRINK=.95;function init(plot){var canvas=null,target=null,options=null,maxRadius=null,centerLeft=null,centerTop=null,processed=false,ctx=null;var highlights=[];plot.hooks.processOptions.push(function(plot,options){if(options.series.pie.show){options.grid.show=false;if(options.series.pie.label.show=="auto"){if(options.legend.show){options.series.pie.label.show=false}else{options.series.pie.label.show=true}}if(options.series.pie.radius=="auto"){if(options.series.pie.label.show){options.series.pie.radius=3/4}else{options.series.pie.radius=1}}if(options.series.pie.tilt>1){options.series.pie.tilt=1}else if(options.series.pie.tilt<0){options.series.pie.tilt=0}}});plot.hooks.bindEvents.push(function(plot,eventHolder){var options=plot.getOptions();if(options.series.pie.show){if(options.grid.hoverable){eventHolder.unbind("mousemove").mousemove(onMouseMove)}if(options.grid.clickable){eventHolder.unbind("click").click(onClick)}}});plot.hooks.processDatapoints.push(function(plot,series,data,datapoints){var options=plot.getOptions();if(options.series.pie.show){processDatapoints(plot,series,data,datapoints)}});plot.hooks.drawOverlay.push(function(plot,octx){var options=plot.getOptions();if(options.series.pie.show){drawOverlay(plot,octx)}});plot.hooks.draw.push(function(plot,newCtx){var options=plot.getOptions();if(options.series.pie.show){draw(plot,newCtx)}});function processDatapoints(plot,series,datapoints){if(!processed){processed=true;canvas=plot.getCanvas();target=$(canvas).parent();options=plot.getOptions();plot.setData(combine(plot.getData()))}}function combine(data){var total=0,combined=0,numCombined=0,color=options.series.pie.combine.color,newdata=[];for(var i=0;i<data.length;++i){var value=data[i].data;if($.isArray(value)&&value.length==1){value=value[0]}if($.isArray(value)){if(!isNaN(parseFloat(value[1]))&&isFinite(value[1])){value[1]=+value[1]}else{value[1]=0}}else if(!isNaN(parseFloat(value))&&isFinite(value)){value=[1,+value]}else{value=[1,0]}data[i].data=[value]}for(var i=0;i<data.length;++i){total+=data[i].data[0][1]}for(var i=0;i<data.length;++i){var value=data[i].data[0][1];if(value/total<=options.series.pie.combine.threshold){combined+=value;numCombined++;if(!color){color=data[i].color}}}for(var i=0;i<data.length;++i){var value=data[i].data[0][1];if(numCombined<2||value/total>options.series.pie.combine.threshold){newdata.push($.extend(data[i],{data:[[1,value]],color:data[i].color,label:data[i].label,angle:value*Math.PI*2/total,percent:value/(total/100)}))}}if(numCombined>1){newdata.push({data:[[1,combined]],color:color,label:options.series.pie.combine.label,angle:combined*Math.PI*2/total,percent:combined/(total/100)})}return newdata}function draw(plot,newCtx){if(!target){return}var canvasWidth=plot.getPlaceholder().width(),canvasHeight=plot.getPlaceholder().height(),legendWidth=target.children().filter(".legend").children().width()||0;ctx=newCtx;processed=false;maxRadius=Math.min(canvasWidth,canvasHeight/options.series.pie.tilt)/2;centerTop=canvasHeight/2+options.series.pie.offset.top;centerLeft=canvasWidth/2;if(options.series.pie.offset.left=="auto"){if(options.legend.position.match("w")){centerLeft+=legendWidth/2}else{centerLeft-=legendWidth/2}if(centerLeft<maxRadius){centerLeft=maxRadius}else if(centerLeft>canvasWidth-maxRadius){centerLeft=canvasWidth-maxRadius}}else{centerLeft+=options.series.pie.offset.left}var slices=plot.getData(),attempts=0;do{if(attempts>0){maxRadius*=REDRAW_SHRINK}attempts+=1;clear();if(options.series.pie.tilt<=.8){drawShadow()}}while(!drawPie()&&attempts<REDRAW_ATTEMPTS);if(attempts>=REDRAW_ATTEMPTS){clear();target.prepend("<div class='error'>Could not draw pie with labels contained inside canvas</div>")}if(plot.setSeries&&plot.insertLegend){plot.setSeries(slices);plot.insertLegend()}function clear(){ctx.clearRect(0,0,canvasWidth,canvasHeight);target.children().filter(".pieLabel, .pieLabelBackground").remove()}function drawShadow(){var shadowLeft=options.series.pie.shadow.left;var shadowTop=options.series.pie.shadow.top;var edge=10;var alpha=options.series.pie.shadow.alpha;var radius=options.series.pie.radius>1?options.series.pie.radius:maxRadius*options.series.pie.radius;if(radius>=canvasWidth/2-shadowLeft||radius*options.series.pie.tilt>=canvasHeight/2-shadowTop||radius<=edge){return}ctx.save();ctx.translate(shadowLeft,shadowTop);ctx.globalAlpha=alpha;ctx.fillStyle="#000";ctx.translate(centerLeft,centerTop);ctx.scale(1,options.series.pie.tilt);for(var i=1;i<=edge;i++){ctx.beginPath();ctx.arc(0,0,radius,0,Math.PI*2,false);ctx.fill();radius-=i}ctx.restore()}function drawPie(){var startAngle=Math.PI*options.series.pie.startAngle;var radius=options.series.pie.radius>1?options.series.pie.radius:maxRadius*options.series.pie.radius;ctx.save();ctx.translate(centerLeft,centerTop);ctx.scale(1,options.series.pie.tilt);ctx.save();var currentAngle=startAngle;for(var i=0;i<slices.length;++i){slices[i].startAngle=currentAngle;drawSlice(slices[i].angle,slices[i].color,true)}ctx.restore();if(options.series.pie.stroke.width>0){ctx.save();ctx.lineWidth=options.series.pie.stroke.width;currentAngle=startAngle;for(var i=0;i<slices.length;++i){drawSlice(slices[i].angle,options.series.pie.stroke.color,false)}ctx.restore()}drawDonutHole(ctx);ctx.restore();if(options.series.pie.label.show){return drawLabels()}else return true;function drawSlice(angle,color,fill){if(angle<=0||isNaN(angle)){return}if(fill){ctx.fillStyle=color}else{ctx.strokeStyle=color;ctx.lineJoin="round"}ctx.beginPath();if(Math.abs(angle-Math.PI*2)>1e-9){ctx.moveTo(0,0)}ctx.arc(0,0,radius,currentAngle,currentAngle+angle/2,false);ctx.arc(0,0,radius,currentAngle+angle/2,currentAngle+angle,false);ctx.closePath();currentAngle+=angle;if(fill){ctx.fill()}else{ctx.stroke()}}function drawLabels(){var currentAngle=startAngle;var radius=options.series.pie.label.radius>1?options.series.pie.label.radius:maxRadius*options.series.pie.label.radius;for(var i=0;i<slices.length;++i){if(slices[i].percent>=options.series.pie.label.threshold*100){if(!drawLabel(slices[i],currentAngle,i)){return false}}currentAngle+=slices[i].angle}return true;function drawLabel(slice,startAngle,index){if(slice.data[0][1]==0){return true}var lf=options.legend.labelFormatter,text,plf=options.series.pie.label.formatter;if(lf){text=lf(slice.label,slice)}else{text=slice.label}if(plf){text=plf(text,slice)}var halfAngle=(startAngle+slice.angle+startAngle)/2;var x=centerLeft+Math.round(Math.cos(halfAngle)*radius);var y=centerTop+Math.round(Math.sin(halfAngle)*radius)*options.series.pie.tilt;var html="<span class='pieLabel' id='pieLabel"+index+"' style='position:absolute;top:"+y+"px;left:"+x+"px;'>"+text+"</span>";target.append(html);var label=target.children("#pieLabel"+index);var labelTop=y-label.height()/2;var labelLeft=x-label.width()/2;label.css("top",labelTop);label.css("left",labelLeft);if(0-labelTop>0||0-labelLeft>0||canvasHeight-(labelTop+label.height())<0||canvasWidth-(labelLeft+label.width())<0){return false}if(options.series.pie.label.background.opacity!=0){var c=options.series.pie.label.background.color;if(c==null){c=slice.color}var pos="top:"+labelTop+"px;left:"+labelLeft+"px;";$("<div class='pieLabelBackground' style='position:absolute;width:"+label.width()+"px;height:"+label.height()+"px;"+pos+"background-color:"+c+";'></div>").css("opacity",options.series.pie.label.background.opacity).insertBefore(label)}return true}}}}function drawDonutHole(layer){if(options.series.pie.innerRadius>0){layer.save();var innerRadius=options.series.pie.innerRadius>1?options.series.pie.innerRadius:maxRadius*options.series.pie.innerRadius;layer.globalCompositeOperation="destination-out";layer.beginPath();layer.fillStyle=options.series.pie.stroke.color;layer.arc(0,0,innerRadius,0,Math.PI*2,false);layer.fill();layer.closePath();layer.restore();layer.save();layer.beginPath();layer.strokeStyle=options.series.pie.stroke.color;layer.arc(0,0,innerRadius,0,Math.PI*2,false);layer.stroke();layer.closePath();layer.restore()}}function isPointInPoly(poly,pt){for(var c=false,i=-1,l=poly.length,j=l-1;++i<l;j=i)(poly[i][1]<=pt[1]&&pt[1]<poly[j][1]||poly[j][1]<=pt[1]&&pt[1]<poly[i][1])&&pt[0]<(poly[j][0]-poly[i][0])*(pt[1]-poly[i][1])/(poly[j][1]-poly[i][1])+poly[i][0]&&(c=!c);return c}function findNearbySlice(mouseX,mouseY){var slices=plot.getData(),options=plot.getOptions(),radius=options.series.pie.radius>1?options.series.pie.radius:maxRadius*options.series.pie.radius,x,y;for(var i=0;i<slices.length;++i){var s=slices[i];if(s.pie.show){ctx.save();ctx.beginPath();ctx.moveTo(0,0);ctx.arc(0,0,radius,s.startAngle,s.startAngle+s.angle/2,false);ctx.arc(0,0,radius,s.startAngle+s.angle/2,s.startAngle+s.angle,false);ctx.closePath();x=mouseX-centerLeft;y=mouseY-centerTop;if(ctx.isPointInPath){if(ctx.isPointInPath(mouseX-centerLeft,mouseY-centerTop)){ctx.restore();return{datapoint:[s.percent,s.data],dataIndex:0,series:s,seriesIndex:i}}}else{var p1X=radius*Math.cos(s.startAngle),p1Y=radius*Math.sin(s.startAngle),p2X=radius*Math.cos(s.startAngle+s.angle/4),p2Y=radius*Math.sin(s.startAngle+s.angle/4),p3X=radius*Math.cos(s.startAngle+s.angle/2),p3Y=radius*Math.sin(s.startAngle+s.angle/2),p4X=radius*Math.cos(s.startAngle+s.angle/1.5),p4Y=radius*Math.sin(s.startAngle+s.angle/1.5),p5X=radius*Math.cos(s.startAngle+s.angle),p5Y=radius*Math.sin(s.startAngle+s.angle),arrPoly=[[0,0],[p1X,p1Y],[p2X,p2Y],[p3X,p3Y],[p4X,p4Y],[p5X,p5Y]],arrPoint=[x,y];if(isPointInPoly(arrPoly,arrPoint)){ctx.restore();return{datapoint:[s.percent,s.data],dataIndex:0,series:s,seriesIndex:i}}}ctx.restore()}}return null}function onMouseMove(e){triggerClickHoverEvent("plothover",e)}function onClick(e){triggerClickHoverEvent("plotclick",e)}function triggerClickHoverEvent(eventname,e){var offset=plot.offset();var canvasX=parseInt(e.pageX-offset.left);var canvasY=parseInt(e.pageY-offset.top);var item=findNearbySlice(canvasX,canvasY);if(options.grid.autoHighlight){for(var i=0;i<highlights.length;++i){var h=highlights[i];if(h.auto==eventname&&!(item&&h.series==item.series)){unhighlight(h.series)}}}if(item){highlight(item.series,eventname)}var pos={pageX:e.pageX,pageY:e.pageY};target.trigger(eventname,[pos,item])}function highlight(s,auto){var i=indexOfHighlight(s);if(i==-1){highlights.push({series:s,auto:auto});plot.triggerRedrawOverlay()}else if(!auto){highlights[i].auto=false}}function unhighlight(s){if(s==null){highlights=[];plot.triggerRedrawOverlay()}var i=indexOfHighlight(s);if(i!=-1){highlights.splice(i,1);plot.triggerRedrawOverlay()}}function indexOfHighlight(s){for(var i=0;i<highlights.length;++i){var h=highlights[i];if(h.series==s)return i}return-1}function drawOverlay(plot,octx){var options=plot.getOptions();var radius=options.series.pie.radius>1?options.series.pie.radius:maxRadius*options.series.pie.radius;octx.save();octx.translate(centerLeft,centerTop);octx.scale(1,options.series.pie.tilt);for(var i=0;i<highlights.length;++i){drawHighlight(highlights[i].series)}drawDonutHole(octx);octx.restore();function drawHighlight(series){if(series.angle<=0||isNaN(series.angle)){return}octx.fillStyle="rgba(255, 255, 255, "+options.series.pie.highlight.opacity+")";octx.beginPath();if(Math.abs(series.angle-Math.PI*2)>1e-9){octx.moveTo(0,0)}octx.arc(0,0,radius,series.startAngle,series.startAngle+series.angle/2,false);octx.arc(0,0,radius,series.startAngle+series.angle/2,series.startAngle+series.angle,false);octx.closePath();octx.fill()}}}var options={series:{pie:{show:false,radius:"auto",innerRadius:0,startAngle:3/2,tilt:1,shadow:{left:5,top:15,alpha:.02},offset:{top:0,left:"auto"},stroke:{color:"#fff",width:1},label:{show:"auto",formatter:function(label,slice){return"<div style='font-size:x-small;text-align:center;padding:2px;color:"+slice.color+";'>"+label+"<br/>"+Math.round(slice.percent)+"%</div>"},radius:1,background:{color:null,opacity:0},threshold:0},combine:{threshold:-1,color:null,label:"Other"},highlight:{opacity:.5}}}};$.plot.plugins.push({init:init,options:options,name:"pie",version:"1.1"})})(jQuery);
0 8
\ No newline at end of file
... ...
@@ -0,0 +1,59 @@
1
+/* Flot plugin for automatically redrawing plots as the placeholder resizes.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+It works by listening for changes on the placeholder div (through the jQuery
7
+resize event plugin) - if the size changes, it will redraw the plot.
8
+
9
+There are no options. If you need to disable the plugin for some plots, you
10
+can just fix the size of their placeholders.
11
+
12
+*/
13
+
14
+/* Inline dependency:
15
+ * jQuery resize event - v1.1 - 3/14/2010
16
+ * http://benalman.com/projects/jquery-resize-plugin/
17
+ *
18
+ * Copyright (c) 2010 "Cowboy" Ben Alman
19
+ * Dual licensed under the MIT and GPL licenses.
20
+ * http://benalman.com/about/license/
21
+ */
22
+(function($,e,t){"$:nomunge";var i=[],n=$.resize=$.extend($.resize,{}),a,r=false,s="setTimeout",u="resize",m=u+"-special-event",o="pendingDelay",l="activeDelay",f="throttleWindow";n[o]=200;n[l]=20;n[f]=true;$.event.special[u]={setup:function(){if(!n[f]&&this[s]){return false}var e=$(this);i.push(this);e.data(m,{w:e.width(),h:e.height()});if(i.length===1){a=t;h()}},teardown:function(){if(!n[f]&&this[s]){return false}var e=$(this);for(var t=i.length-1;t>=0;t--){if(i[t]==this){i.splice(t,1);break}}e.removeData(m);if(!i.length){if(r){cancelAnimationFrame(a)}else{clearTimeout(a)}a=null}},add:function(e){if(!n[f]&&this[s]){return false}var i;function a(e,n,a){var r=$(this),s=r.data(m)||{};s.w=n!==t?n:r.width();s.h=a!==t?a:r.height();i.apply(this,arguments)}if($.isFunction(e)){i=e;return a}else{i=e.handler;e.handler=a}}};function h(t){if(r===true){r=t||1}for(var s=i.length-1;s>=0;s--){var l=$(i[s]);if(l[0]==e||l.is(":visible")){var f=l.width(),c=l.height(),d=l.data(m);if(d&&(f!==d.w||c!==d.h)){l.trigger(u,[d.w=f,d.h=c]);r=t||true}}else{d=l.data(m);d.w=0;d.h=0}}if(a!==null){if(r&&(t==null||t-r<1e3)){a=e.requestAnimationFrame(h)}else{a=setTimeout(h,n[o]);r=false}}}if(!e.requestAnimationFrame){e.requestAnimationFrame=function(){return e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(t,i){return e.setTimeout(function(){t((new Date).getTime())},n[l])}}()}if(!e.cancelAnimationFrame){e.cancelAnimationFrame=function(){return e.webkitCancelRequestAnimationFrame||e.mozCancelRequestAnimationFrame||e.oCancelRequestAnimationFrame||e.msCancelRequestAnimationFrame||clearTimeout}()}})(jQuery,this);
23
+
24
+(function ($) {
25
+    var options = { }; // no options
26
+
27
+    function init(plot) {
28
+        function onResize() {
29
+            var placeholder = plot.getPlaceholder();
30
+
31
+            // somebody might have hidden us and we can't plot
32
+            // when we don't have the dimensions
33
+            if (placeholder.width() == 0 || placeholder.height() == 0)
34
+                return;
35
+
36
+            plot.resize();
37
+            plot.setupGrid();
38
+            plot.draw();
39
+        }
40
+        
41
+        function bindEvents(plot, eventHolder) {
42
+            plot.getPlaceholder().resize(onResize);
43
+        }
44
+
45
+        function shutdown(plot, eventHolder) {
46
+            plot.getPlaceholder().unbind("resize", onResize);
47
+        }
48
+        
49
+        plot.hooks.bindEvents.push(bindEvents);
50
+        plot.hooks.shutdown.push(shutdown);
51
+    }
52
+    
53
+    $.plot.plugins.push({
54
+        init: init,
55
+        options: options,
56
+        name: 'resize',
57
+        version: '1.0'
58
+    });
59
+})(jQuery);
... ...
@@ -0,0 +1,7 @@
1
+/* Javascript plotting library for jQuery, version 0.8.3.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+*/
7
+(function($,e,t){"$:nomunge";var i=[],n=$.resize=$.extend($.resize,{}),a,r=false,s="setTimeout",u="resize",m=u+"-special-event",o="pendingDelay",l="activeDelay",f="throttleWindow";n[o]=200;n[l]=20;n[f]=true;$.event.special[u]={setup:function(){if(!n[f]&&this[s]){return false}var e=$(this);i.push(this);e.data(m,{w:e.width(),h:e.height()});if(i.length===1){a=t;h()}},teardown:function(){if(!n[f]&&this[s]){return false}var e=$(this);for(var t=i.length-1;t>=0;t--){if(i[t]==this){i.splice(t,1);break}}e.removeData(m);if(!i.length){if(r){cancelAnimationFrame(a)}else{clearTimeout(a)}a=null}},add:function(e){if(!n[f]&&this[s]){return false}var i;function a(e,n,a){var r=$(this),s=r.data(m)||{};s.w=n!==t?n:r.width();s.h=a!==t?a:r.height();i.apply(this,arguments)}if($.isFunction(e)){i=e;return a}else{i=e.handler;e.handler=a}}};function h(t){if(r===true){r=t||1}for(var s=i.length-1;s>=0;s--){var l=$(i[s]);if(l[0]==e||l.is(":visible")){var f=l.width(),c=l.height(),d=l.data(m);if(d&&(f!==d.w||c!==d.h)){l.trigger(u,[d.w=f,d.h=c]);r=t||true}}else{d=l.data(m);d.w=0;d.h=0}}if(a!==null){if(r&&(t==null||t-r<1e3)){a=e.requestAnimationFrame(h)}else{a=setTimeout(h,n[o]);r=false}}}if(!e.requestAnimationFrame){e.requestAnimationFrame=function(){return e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(t,i){return e.setTimeout(function(){t((new Date).getTime())},n[l])}}()}if(!e.cancelAnimationFrame){e.cancelAnimationFrame=function(){return e.webkitCancelRequestAnimationFrame||e.mozCancelRequestAnimationFrame||e.oCancelRequestAnimationFrame||e.msCancelRequestAnimationFrame||clearTimeout}()}})(jQuery,this);(function($){var options={};function init(plot){function onResize(){var placeholder=plot.getPlaceholder();if(placeholder.width()==0||placeholder.height()==0)return;plot.resize();plot.setupGrid();plot.draw()}function bindEvents(plot,eventHolder){plot.getPlaceholder().resize(onResize)}function shutdown(plot,eventHolder){plot.getPlaceholder().unbind("resize",onResize)}plot.hooks.bindEvents.push(bindEvents);plot.hooks.shutdown.push(shutdown)}$.plot.plugins.push({init:init,options:options,name:"resize",version:"1.0"})})(jQuery);
0 8
\ No newline at end of file
... ...
@@ -0,0 +1,360 @@
1
+/* Flot plugin for selecting regions of a plot.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+The plugin supports these options:
7
+
8
+selection: {
9
+	mode: null or "x" or "y" or "xy",
10
+	color: color,
11
+	shape: "round" or "miter" or "bevel",
12
+	minSize: number of pixels
13
+}
14
+
15
+Selection support is enabled by setting the mode to one of "x", "y" or "xy".
16
+In "x" mode, the user will only be able to specify the x range, similarly for
17
+"y" mode. For "xy", the selection becomes a rectangle where both ranges can be
18
+specified. "color" is color of the selection (if you need to change the color
19
+later on, you can get to it with plot.getOptions().selection.color). "shape"
20
+is the shape of the corners of the selection.
21
+
22
+"minSize" is the minimum size a selection can be in pixels. This value can
23
+be customized to determine the smallest size a selection can be and still
24
+have the selection rectangle be displayed. When customizing this value, the
25
+fact that it refers to pixels, not axis units must be taken into account.
26
+Thus, for example, if there is a bar graph in time mode with BarWidth set to 1
27
+minute, setting "minSize" to 1 will not make the minimum selection size 1
28
+minute, but rather 1 pixel. Note also that setting "minSize" to 0 will prevent
29
+"plotunselected" events from being fired when the user clicks the mouse without
30
+dragging.
31
+
32
+When selection support is enabled, a "plotselected" event will be emitted on
33
+the DOM element you passed into the plot function. The event handler gets a
34
+parameter with the ranges selected on the axes, like this:
35
+
36
+	placeholder.bind( "plotselected", function( event, ranges ) {
37
+		alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to)
38
+		// similar for yaxis - with multiple axes, the extra ones are in
39
+		// x2axis, x3axis, ...
40
+	});
41
+
42
+The "plotselected" event is only fired when the user has finished making the
43
+selection. A "plotselecting" event is fired during the process with the same
44
+parameters as the "plotselected" event, in case you want to know what's
45
+happening while it's happening,
46
+
47
+A "plotunselected" event with no arguments is emitted when the user clicks the
48
+mouse to remove the selection. As stated above, setting "minSize" to 0 will
49
+destroy this behavior.
50
+
51
+The plugin allso adds the following methods to the plot object:
52
+
53
+- setSelection( ranges, preventEvent )
54
+
55
+  Set the selection rectangle. The passed in ranges is on the same form as
56
+  returned in the "plotselected" event. If the selection mode is "x", you
57
+  should put in either an xaxis range, if the mode is "y" you need to put in
58
+  an yaxis range and both xaxis and yaxis if the selection mode is "xy", like
59
+  this:
60
+
61
+	setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });
62
+
63
+  setSelection will trigger the "plotselected" event when called. If you don't
64
+  want that to happen, e.g. if you're inside a "plotselected" handler, pass
65
+  true as the second parameter. If you are using multiple axes, you can
66
+  specify the ranges on any of those, e.g. as x2axis/x3axis/... instead of
67
+  xaxis, the plugin picks the first one it sees.
68
+
69
+- clearSelection( preventEvent )
70
+
71
+  Clear the selection rectangle. Pass in true to avoid getting a
72
+  "plotunselected" event.
73
+
74
+- getSelection()
75
+
76
+  Returns the current selection in the same format as the "plotselected"
77
+  event. If there's currently no selection, the function returns null.
78
+
79
+*/
80
+
81
+(function ($) {
82
+    function init(plot) {
83
+        var selection = {
84
+                first: { x: -1, y: -1}, second: { x: -1, y: -1},
85
+                show: false,
86
+                active: false
87
+            };
88
+
89
+        // FIXME: The drag handling implemented here should be
90
+        // abstracted out, there's some similar code from a library in
91
+        // the navigation plugin, this should be massaged a bit to fit
92
+        // the Flot cases here better and reused. Doing this would
93
+        // make this plugin much slimmer.
94
+        var savedhandlers = {};
95
+
96
+        var mouseUpHandler = null;
97
+        
98
+        function onMouseMove(e) {
99
+            if (selection.active) {
100
+                updateSelection(e);
101
+                
102
+                plot.getPlaceholder().trigger("plotselecting", [ getSelection() ]);
103
+            }
104
+        }
105
+
106
+        function onMouseDown(e) {
107
+            if (e.which != 1)  // only accept left-click
108
+                return;
109
+            
110
+            // cancel out any text selections
111
+            document.body.focus();
112
+
113
+            // prevent text selection and drag in old-school browsers
114
+            if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) {
115
+                savedhandlers.onselectstart = document.onselectstart;
116
+                document.onselectstart = function () { return false; };
117
+            }
118
+            if (document.ondrag !== undefined && savedhandlers.ondrag == null) {
119
+                savedhandlers.ondrag = document.ondrag;
120
+                document.ondrag = function () { return false; };
121
+            }
122
+
123
+            setSelectionPos(selection.first, e);
124
+
125
+            selection.active = true;
126
+
127
+            // this is a bit silly, but we have to use a closure to be
128
+            // able to whack the same handler again
129
+            mouseUpHandler = function (e) { onMouseUp(e); };
130
+            
131
+            $(document).one("mouseup", mouseUpHandler);
132
+        }
133
+
134
+        function onMouseUp(e) {
135
+            mouseUpHandler = null;
136
+            
137
+            // revert drag stuff for old-school browsers
138
+            if (document.onselectstart !== undefined)
139
+                document.onselectstart = savedhandlers.onselectstart;
140
+            if (document.ondrag !== undefined)
141
+                document.ondrag = savedhandlers.ondrag;
142
+
143
+            // no more dragging
144
+            selection.active = false;
145
+            updateSelection(e);
146
+
147
+            if (selectionIsSane())
148
+                triggerSelectedEvent();
149
+            else {
150
+                // this counts as a clear
151
+                plot.getPlaceholder().trigger("plotunselected", [ ]);
152
+                plot.getPlaceholder().trigger("plotselecting", [ null ]);
153
+            }
154
+
155
+            return false;
156
+        }
157
+
158
+        function getSelection() {
159
+            if (!selectionIsSane())
160
+                return null;
161
+            
162
+            if (!selection.show) return null;
163
+
164
+            var r = {}, c1 = selection.first, c2 = selection.second;
165
+            $.each(plot.getAxes(), function (name, axis) {
166
+                if (axis.used) {
167
+                    var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]); 
168
+                    r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) };
169
+                }
170
+            });
171
+            return r;
172
+        }
173
+
174
+        function triggerSelectedEvent() {
175
+            var r = getSelection();
176
+
177
+            plot.getPlaceholder().trigger("plotselected", [ r ]);
178
+
179
+            // backwards-compat stuff, to be removed in future
180
+            if (r.xaxis && r.yaxis)
181
+                plot.getPlaceholder().trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]);
182
+        }
183
+
184
+        function clamp(min, value, max) {
185
+            return value < min ? min: (value > max ? max: value);
186
+        }
187
+
188
+        function setSelectionPos(pos, e) {
189
+            var o = plot.getOptions();
190
+            var offset = plot.getPlaceholder().offset();
191
+            var plotOffset = plot.getPlotOffset();
192
+            pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width());
193
+            pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height());
194
+
195
+            if (o.selection.mode == "y")
196
+                pos.x = pos == selection.first ? 0 : plot.width();
197
+
198
+            if (o.selection.mode == "x")
199
+                pos.y = pos == selection.first ? 0 : plot.height();
200
+        }
201
+
202
+        function updateSelection(pos) {
203
+            if (pos.pageX == null)
204
+                return;
205
+
206
+            setSelectionPos(selection.second, pos);
207
+            if (selectionIsSane()) {
208
+                selection.show = true;
209
+                plot.triggerRedrawOverlay();
210
+            }
211
+            else
212
+                clearSelection(true);
213
+        }
214
+
215
+        function clearSelection(preventEvent) {
216
+            if (selection.show) {
217
+                selection.show = false;
218
+                plot.triggerRedrawOverlay();
219
+                if (!preventEvent)
220
+                    plot.getPlaceholder().trigger("plotunselected", [ ]);
221
+            }
222
+        }
223
+
224
+        // function taken from markings support in Flot
225
+        function extractRange(ranges, coord) {
226
+            var axis, from, to, key, axes = plot.getAxes();
227
+
228
+            for (var k in axes) {
229
+                axis = axes[k];
230
+                if (axis.direction == coord) {
231
+                    key = coord + axis.n + "axis";
232
+                    if (!ranges[key] && axis.n == 1)
233
+                        key = coord + "axis"; // support x1axis as xaxis
234
+                    if (ranges[key]) {
235
+                        from = ranges[key].from;
236
+                        to = ranges[key].to;
237
+                        break;
238
+                    }
239
+                }
240
+            }
241
+
242
+            // backwards-compat stuff - to be removed in future
243
+            if (!ranges[key]) {
244
+                axis = coord == "x" ? plot.getXAxes()[0] : plot.getYAxes()[0];
245
+                from = ranges[coord + "1"];
246
+                to = ranges[coord + "2"];
247
+            }
248
+
249
+            // auto-reverse as an added bonus
250
+            if (from != null && to != null && from > to) {
251
+                var tmp = from;
252
+                from = to;
253
+                to = tmp;
254
+            }
255
+            
256
+            return { from: from, to: to, axis: axis };
257
+        }
258
+        
259
+        function setSelection(ranges, preventEvent) {
260
+            var axis, range, o = plot.getOptions();
261
+
262
+            if (o.selection.mode == "y") {
263
+                selection.first.x = 0;
264
+                selection.second.x = plot.width();
265
+            }
266
+            else {
267
+                range = extractRange(ranges, "x");
268
+
269
+                selection.first.x = range.axis.p2c(range.from);
270
+                selection.second.x = range.axis.p2c(range.to);
271
+            }
272
+
273
+            if (o.selection.mode == "x") {
274
+                selection.first.y = 0;
275
+                selection.second.y = plot.height();
276
+            }
277
+            else {
278
+                range = extractRange(ranges, "y");
279
+
280
+                selection.first.y = range.axis.p2c(range.from);
281
+                selection.second.y = range.axis.p2c(range.to);
282
+            }
283
+
284
+            selection.show = true;
285
+            plot.triggerRedrawOverlay();
286
+            if (!preventEvent && selectionIsSane())
287
+                triggerSelectedEvent();
288
+        }
289
+
290
+        function selectionIsSane() {
291
+            var minSize = plot.getOptions().selection.minSize;
292
+            return Math.abs(selection.second.x - selection.first.x) >= minSize &&
293
+                Math.abs(selection.second.y - selection.first.y) >= minSize;
294
+        }
295
+
296
+        plot.clearSelection = clearSelection;
297
+        plot.setSelection = setSelection;
298
+        plot.getSelection = getSelection;
299
+
300
+        plot.hooks.bindEvents.push(function(plot, eventHolder) {
301
+            var o = plot.getOptions();
302
+            if (o.selection.mode != null) {
303
+                eventHolder.mousemove(onMouseMove);
304
+                eventHolder.mousedown(onMouseDown);
305
+            }
306
+        });
307
+
308
+
309
+        plot.hooks.drawOverlay.push(function (plot, ctx) {
310
+            // draw selection
311
+            if (selection.show && selectionIsSane()) {
312
+                var plotOffset = plot.getPlotOffset();
313
+                var o = plot.getOptions();
314
+
315
+                ctx.save();
316
+                ctx.translate(plotOffset.left, plotOffset.top);
317
+
318
+                var c = $.color.parse(o.selection.color);
319
+
320
+                ctx.strokeStyle = c.scale('a', 0.8).toString();
321
+                ctx.lineWidth = 1;
322
+                ctx.lineJoin = o.selection.shape;
323
+                ctx.fillStyle = c.scale('a', 0.4).toString();
324
+
325
+                var x = Math.min(selection.first.x, selection.second.x) + 0.5,
326
+                    y = Math.min(selection.first.y, selection.second.y) + 0.5,
327
+                    w = Math.abs(selection.second.x - selection.first.x) - 1,
328
+                    h = Math.abs(selection.second.y - selection.first.y) - 1;
329
+
330
+                ctx.fillRect(x, y, w, h);
331
+                ctx.strokeRect(x, y, w, h);
332
+
333
+                ctx.restore();
334
+            }
335
+        });
336
+        
337
+        plot.hooks.shutdown.push(function (plot, eventHolder) {
338
+            eventHolder.unbind("mousemove", onMouseMove);
339
+            eventHolder.unbind("mousedown", onMouseDown);
340
+            
341
+            if (mouseUpHandler)
342
+                $(document).unbind("mouseup", mouseUpHandler);
343
+        });
344
+
345
+    }
346
+
347
+    $.plot.plugins.push({
348
+        init: init,
349
+        options: {
350
+            selection: {
351
+                mode: null, // one of null, "x", "y" or "xy"
352
+                color: "#e8cfac",
353
+                shape: "round", // one of "round", "miter", or "bevel"
354
+                minSize: 5 // minimum number of pixels
355
+            }
356
+        },
357
+        name: 'selection',
358
+        version: '1.1'
359
+    });
360
+})(jQuery);
... ...
@@ -0,0 +1,7 @@
1
+/* Javascript plotting library for jQuery, version 0.8.3.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+*/
7
+(function($){function init(plot){var selection={first:{x:-1,y:-1},second:{x:-1,y:-1},show:false,active:false};var savedhandlers={};var mouseUpHandler=null;function onMouseMove(e){if(selection.active){updateSelection(e);plot.getPlaceholder().trigger("plotselecting",[getSelection()])}}function onMouseDown(e){if(e.which!=1)return;document.body.focus();if(document.onselectstart!==undefined&&savedhandlers.onselectstart==null){savedhandlers.onselectstart=document.onselectstart;document.onselectstart=function(){return false}}if(document.ondrag!==undefined&&savedhandlers.ondrag==null){savedhandlers.ondrag=document.ondrag;document.ondrag=function(){return false}}setSelectionPos(selection.first,e);selection.active=true;mouseUpHandler=function(e){onMouseUp(e)};$(document).one("mouseup",mouseUpHandler)}function onMouseUp(e){mouseUpHandler=null;if(document.onselectstart!==undefined)document.onselectstart=savedhandlers.onselectstart;if(document.ondrag!==undefined)document.ondrag=savedhandlers.ondrag;selection.active=false;updateSelection(e);if(selectionIsSane())triggerSelectedEvent();else{plot.getPlaceholder().trigger("plotunselected",[]);plot.getPlaceholder().trigger("plotselecting",[null])}return false}function getSelection(){if(!selectionIsSane())return null;if(!selection.show)return null;var r={},c1=selection.first,c2=selection.second;$.each(plot.getAxes(),function(name,axis){if(axis.used){var p1=axis.c2p(c1[axis.direction]),p2=axis.c2p(c2[axis.direction]);r[name]={from:Math.min(p1,p2),to:Math.max(p1,p2)}}});return r}function triggerSelectedEvent(){var r=getSelection();plot.getPlaceholder().trigger("plotselected",[r]);if(r.xaxis&&r.yaxis)plot.getPlaceholder().trigger("selected",[{x1:r.xaxis.from,y1:r.yaxis.from,x2:r.xaxis.to,y2:r.yaxis.to}])}function clamp(min,value,max){return value<min?min:value>max?max:value}function setSelectionPos(pos,e){var o=plot.getOptions();var offset=plot.getPlaceholder().offset();var plotOffset=plot.getPlotOffset();pos.x=clamp(0,e.pageX-offset.left-plotOffset.left,plot.width());pos.y=clamp(0,e.pageY-offset.top-plotOffset.top,plot.height());if(o.selection.mode=="y")pos.x=pos==selection.first?0:plot.width();if(o.selection.mode=="x")pos.y=pos==selection.first?0:plot.height()}function updateSelection(pos){if(pos.pageX==null)return;setSelectionPos(selection.second,pos);if(selectionIsSane()){selection.show=true;plot.triggerRedrawOverlay()}else clearSelection(true)}function clearSelection(preventEvent){if(selection.show){selection.show=false;plot.triggerRedrawOverlay();if(!preventEvent)plot.getPlaceholder().trigger("plotunselected",[])}}function extractRange(ranges,coord){var axis,from,to,key,axes=plot.getAxes();for(var k in axes){axis=axes[k];if(axis.direction==coord){key=coord+axis.n+"axis";if(!ranges[key]&&axis.n==1)key=coord+"axis";if(ranges[key]){from=ranges[key].from;to=ranges[key].to;break}}}if(!ranges[key]){axis=coord=="x"?plot.getXAxes()[0]:plot.getYAxes()[0];from=ranges[coord+"1"];to=ranges[coord+"2"]}if(from!=null&&to!=null&&from>to){var tmp=from;from=to;to=tmp}return{from:from,to:to,axis:axis}}function setSelection(ranges,preventEvent){var axis,range,o=plot.getOptions();if(o.selection.mode=="y"){selection.first.x=0;selection.second.x=plot.width()}else{range=extractRange(ranges,"x");selection.first.x=range.axis.p2c(range.from);selection.second.x=range.axis.p2c(range.to)}if(o.selection.mode=="x"){selection.first.y=0;selection.second.y=plot.height()}else{range=extractRange(ranges,"y");selection.first.y=range.axis.p2c(range.from);selection.second.y=range.axis.p2c(range.to)}selection.show=true;plot.triggerRedrawOverlay();if(!preventEvent&&selectionIsSane())triggerSelectedEvent()}function selectionIsSane(){var minSize=plot.getOptions().selection.minSize;return Math.abs(selection.second.x-selection.first.x)>=minSize&&Math.abs(selection.second.y-selection.first.y)>=minSize}plot.clearSelection=clearSelection;plot.setSelection=setSelection;plot.getSelection=getSelection;plot.hooks.bindEvents.push(function(plot,eventHolder){var o=plot.getOptions();if(o.selection.mode!=null){eventHolder.mousemove(onMouseMove);eventHolder.mousedown(onMouseDown)}});plot.hooks.drawOverlay.push(function(plot,ctx){if(selection.show&&selectionIsSane()){var plotOffset=plot.getPlotOffset();var o=plot.getOptions();ctx.save();ctx.translate(plotOffset.left,plotOffset.top);var c=$.color.parse(o.selection.color);ctx.strokeStyle=c.scale("a",.8).toString();ctx.lineWidth=1;ctx.lineJoin=o.selection.shape;ctx.fillStyle=c.scale("a",.4).toString();var x=Math.min(selection.first.x,selection.second.x)+.5,y=Math.min(selection.first.y,selection.second.y)+.5,w=Math.abs(selection.second.x-selection.first.x)-1,h=Math.abs(selection.second.y-selection.first.y)-1;ctx.fillRect(x,y,w,h);ctx.strokeRect(x,y,w,h);ctx.restore()}});plot.hooks.shutdown.push(function(plot,eventHolder){eventHolder.unbind("mousemove",onMouseMove);eventHolder.unbind("mousedown",onMouseDown);if(mouseUpHandler)$(document).unbind("mouseup",mouseUpHandler)})}$.plot.plugins.push({init:init,options:{selection:{mode:null,color:"#e8cfac",shape:"round",minSize:5}},name:"selection",version:"1.1"})})(jQuery);
0 8
\ No newline at end of file
... ...
@@ -0,0 +1,188 @@
1
+/* Flot plugin for stacking data sets rather than overlyaing them.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+The plugin assumes the data is sorted on x (or y if stacking horizontally).
7
+For line charts, it is assumed that if a line has an undefined gap (from a
8
+null point), then the line above it should have the same gap - insert zeros
9
+instead of "null" if you want another behaviour. This also holds for the start
10
+and end of the chart. Note that stacking a mix of positive and negative values
11
+in most instances doesn't make sense (so it looks weird).
12
+
13
+Two or more series are stacked when their "stack" attribute is set to the same
14
+key (which can be any number or string or just "true"). To specify the default
15
+stack, you can set the stack option like this:
16
+
17
+	series: {
18
+		stack: null/false, true, or a key (number/string)
19
+	}
20
+
21
+You can also specify it for a single series, like this:
22
+
23
+	$.plot( $("#placeholder"), [{
24
+		data: [ ... ],
25
+		stack: true
26
+	}])
27
+
28
+The stacking order is determined by the order of the data series in the array
29
+(later series end up on top of the previous).
30
+
31
+Internally, the plugin modifies the datapoints in each series, adding an
32
+offset to the y value. For line series, extra data points are inserted through
33
+interpolation. If there's a second y value, it's also adjusted (e.g for bar
34
+charts or filled areas).
35
+
36
+*/
37
+
38
+(function ($) {
39
+    var options = {
40
+        series: { stack: null } // or number/string
41
+    };
42
+    
43
+    function init(plot) {
44
+        function findMatchingSeries(s, allseries) {
45
+            var res = null;
46
+            for (var i = 0; i < allseries.length; ++i) {
47
+                if (s == allseries[i])
48
+                    break;
49
+                
50
+                if (allseries[i].stack == s.stack)
51
+                    res = allseries[i];
52
+            }
53
+            
54
+            return res;
55
+        }
56
+        
57
+        function stackData(plot, s, datapoints) {
58
+            if (s.stack == null || s.stack === false)
59
+                return;
60
+
61
+            var other = findMatchingSeries(s, plot.getData());
62
+            if (!other)
63
+                return;
64
+
65
+            var ps = datapoints.pointsize,
66
+                points = datapoints.points,
67
+                otherps = other.datapoints.pointsize,
68
+                otherpoints = other.datapoints.points,
69
+                newpoints = [],
70
+                px, py, intery, qx, qy, bottom,
71
+                withlines = s.lines.show,
72
+                horizontal = s.bars.horizontal,
73
+                withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y),
74
+                withsteps = withlines && s.lines.steps,
75
+                fromgap = true,
76
+                keyOffset = horizontal ? 1 : 0,
77
+                accumulateOffset = horizontal ? 0 : 1,
78
+                i = 0, j = 0, l, m;
79
+
80
+            while (true) {
81
+                if (i >= points.length)
82
+                    break;
83
+
84
+                l = newpoints.length;
85
+
86
+                if (points[i] == null) {
87
+                    // copy gaps
88
+                    for (m = 0; m < ps; ++m)
89
+                        newpoints.push(points[i + m]);
90
+                    i += ps;
91
+                }
92
+                else if (j >= otherpoints.length) {
93
+                    // for lines, we can't use the rest of the points
94
+                    if (!withlines) {
95
+                        for (m = 0; m < ps; ++m)
96
+                            newpoints.push(points[i + m]);
97
+                    }
98
+                    i += ps;
99
+                }
100
+                else if (otherpoints[j] == null) {
101
+                    // oops, got a gap
102
+                    for (m = 0; m < ps; ++m)
103
+                        newpoints.push(null);
104
+                    fromgap = true;
105
+                    j += otherps;
106
+                }
107
+                else {
108
+                    // cases where we actually got two points
109
+                    px = points[i + keyOffset];
110
+                    py = points[i + accumulateOffset];
111
+                    qx = otherpoints[j + keyOffset];
112
+                    qy = otherpoints[j + accumulateOffset];
113
+                    bottom = 0;
114
+
115
+                    if (px == qx) {
116
+                        for (m = 0; m < ps; ++m)
117
+                            newpoints.push(points[i + m]);
118
+
119
+                        newpoints[l + accumulateOffset] += qy;
120
+                        bottom = qy;
121
+                        
122
+                        i += ps;
123
+                        j += otherps;
124
+                    }
125
+                    else if (px > qx) {
126
+                        // we got past point below, might need to
127
+                        // insert interpolated extra point
128
+                        if (withlines && i > 0 && points[i - ps] != null) {
129
+                            intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px);
130
+                            newpoints.push(qx);
131
+                            newpoints.push(intery + qy);
132
+                            for (m = 2; m < ps; ++m)
133
+                                newpoints.push(points[i + m]);
134
+                            bottom = qy; 
135
+                        }
136
+
137
+                        j += otherps;
138
+                    }
139
+                    else { // px < qx
140
+                        if (fromgap && withlines) {
141
+                            // if we come from a gap, we just skip this point
142
+                            i += ps;
143
+                            continue;
144
+                        }
145
+                            
146
+                        for (m = 0; m < ps; ++m)
147
+                            newpoints.push(points[i + m]);
148
+                        
149
+                        // we might be able to interpolate a point below,
150
+                        // this can give us a better y
151
+                        if (withlines && j > 0 && otherpoints[j - otherps] != null)
152
+                            bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx);
153
+
154
+                        newpoints[l + accumulateOffset] += bottom;
155
+                        
156
+                        i += ps;
157
+                    }
158
+
159
+                    fromgap = false;
160
+                    
161
+                    if (l != newpoints.length && withbottom)
162
+                        newpoints[l + 2] += bottom;
163
+                }
164
+
165
+                // maintain the line steps invariant
166
+                if (withsteps && l != newpoints.length && l > 0
167
+                    && newpoints[l] != null
168
+                    && newpoints[l] != newpoints[l - ps]
169
+                    && newpoints[l + 1] != newpoints[l - ps + 1]) {
170
+                    for (m = 0; m < ps; ++m)
171
+                        newpoints[l + ps + m] = newpoints[l + m];
172
+                    newpoints[l + 1] = newpoints[l - ps + 1];
173
+                }
174
+            }
175
+
176
+            datapoints.points = newpoints;
177
+        }
178
+        
179
+        plot.hooks.processDatapoints.push(stackData);
180
+    }
181
+    
182
+    $.plot.plugins.push({
183
+        init: init,
184
+        options: options,
185
+        name: 'stack',
186
+        version: '1.2'
187
+    });
188
+})(jQuery);
... ...
@@ -0,0 +1,7 @@
1
+/* Javascript plotting library for jQuery, version 0.8.3.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+*/
7
+(function($){var options={series:{stack:null}};function init(plot){function findMatchingSeries(s,allseries){var res=null;for(var i=0;i<allseries.length;++i){if(s==allseries[i])break;if(allseries[i].stack==s.stack)res=allseries[i]}return res}function stackData(plot,s,datapoints){if(s.stack==null||s.stack===false)return;var other=findMatchingSeries(s,plot.getData());if(!other)return;var ps=datapoints.pointsize,points=datapoints.points,otherps=other.datapoints.pointsize,otherpoints=other.datapoints.points,newpoints=[],px,py,intery,qx,qy,bottom,withlines=s.lines.show,horizontal=s.bars.horizontal,withbottom=ps>2&&(horizontal?datapoints.format[2].x:datapoints.format[2].y),withsteps=withlines&&s.lines.steps,fromgap=true,keyOffset=horizontal?1:0,accumulateOffset=horizontal?0:1,i=0,j=0,l,m;while(true){if(i>=points.length)break;l=newpoints.length;if(points[i]==null){for(m=0;m<ps;++m)newpoints.push(points[i+m]);i+=ps}else if(j>=otherpoints.length){if(!withlines){for(m=0;m<ps;++m)newpoints.push(points[i+m])}i+=ps}else if(otherpoints[j]==null){for(m=0;m<ps;++m)newpoints.push(null);fromgap=true;j+=otherps}else{px=points[i+keyOffset];py=points[i+accumulateOffset];qx=otherpoints[j+keyOffset];qy=otherpoints[j+accumulateOffset];bottom=0;if(px==qx){for(m=0;m<ps;++m)newpoints.push(points[i+m]);newpoints[l+accumulateOffset]+=qy;bottom=qy;i+=ps;j+=otherps}else if(px>qx){if(withlines&&i>0&&points[i-ps]!=null){intery=py+(points[i-ps+accumulateOffset]-py)*(qx-px)/(points[i-ps+keyOffset]-px);newpoints.push(qx);newpoints.push(intery+qy);for(m=2;m<ps;++m)newpoints.push(points[i+m]);bottom=qy}j+=otherps}else{if(fromgap&&withlines){i+=ps;continue}for(m=0;m<ps;++m)newpoints.push(points[i+m]);if(withlines&&j>0&&otherpoints[j-otherps]!=null)bottom=qy+(otherpoints[j-otherps+accumulateOffset]-qy)*(px-qx)/(otherpoints[j-otherps+keyOffset]-qx);newpoints[l+accumulateOffset]+=bottom;i+=ps}fromgap=false;if(l!=newpoints.length&&withbottom)newpoints[l+2]+=bottom}if(withsteps&&l!=newpoints.length&&l>0&&newpoints[l]!=null&&newpoints[l]!=newpoints[l-ps]&&newpoints[l+1]!=newpoints[l-ps+1]){for(m=0;m<ps;++m)newpoints[l+ps+m]=newpoints[l+m];newpoints[l+1]=newpoints[l-ps+1]}}datapoints.points=newpoints}plot.hooks.processDatapoints.push(stackData)}$.plot.plugins.push({init:init,options:options,name:"stack",version:"1.2"})})(jQuery);
0 8
\ No newline at end of file
... ...
@@ -0,0 +1,71 @@
1
+/* Flot plugin that adds some extra symbols for plotting points.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+The symbols are accessed as strings through the standard symbol options:
7
+
8
+	series: {
9
+		points: {
10
+			symbol: "square" // or "diamond", "triangle", "cross"
11
+		}
12
+	}
13
+
14
+*/
15
+
16
+(function ($) {
17
+    function processRawData(plot, series, datapoints) {
18
+        // we normalize the area of each symbol so it is approximately the
19
+        // same as a circle of the given radius
20
+
21
+        var handlers = {
22
+            square: function (ctx, x, y, radius, shadow) {
23
+                // pi * r^2 = (2s)^2  =>  s = r * sqrt(pi)/2
24
+                var size = radius * Math.sqrt(Math.PI) / 2;
25
+                ctx.rect(x - size, y - size, size + size, size + size);
26
+            },
27
+            diamond: function (ctx, x, y, radius, shadow) {
28
+                // pi * r^2 = 2s^2  =>  s = r * sqrt(pi/2)
29
+                var size = radius * Math.sqrt(Math.PI / 2);
30
+                ctx.moveTo(x - size, y);
31
+                ctx.lineTo(x, y - size);
32
+                ctx.lineTo(x + size, y);
33
+                ctx.lineTo(x, y + size);
34
+                ctx.lineTo(x - size, y);
35
+            },
36
+            triangle: function (ctx, x, y, radius, shadow) {
37
+                // pi * r^2 = 1/2 * s^2 * sin (pi / 3)  =>  s = r * sqrt(2 * pi / sin(pi / 3))
38
+                var size = radius * Math.sqrt(2 * Math.PI / Math.sin(Math.PI / 3));
39
+                var height = size * Math.sin(Math.PI / 3);
40
+                ctx.moveTo(x - size/2, y + height/2);
41
+                ctx.lineTo(x + size/2, y + height/2);
42
+                if (!shadow) {
43
+                    ctx.lineTo(x, y - height/2);
44
+                    ctx.lineTo(x - size/2, y + height/2);
45
+                }
46
+            },
47
+            cross: function (ctx, x, y, radius, shadow) {
48
+                // pi * r^2 = (2s)^2  =>  s = r * sqrt(pi)/2
49
+                var size = radius * Math.sqrt(Math.PI) / 2;
50
+                ctx.moveTo(x - size, y - size);
51
+                ctx.lineTo(x + size, y + size);
52
+                ctx.moveTo(x - size, y + size);
53
+                ctx.lineTo(x + size, y - size);
54
+            }
55
+        };
56
+
57
+        var s = series.points.symbol;
58
+        if (handlers[s])
59
+            series.points.symbol = handlers[s];
60
+    }
61
+    
62
+    function init(plot) {
63
+        plot.hooks.processDatapoints.push(processRawData);
64
+    }
65
+    
66
+    $.plot.plugins.push({
67
+        init: init,
68
+        name: 'symbols',
69
+        version: '1.0'
70
+    });
71
+})(jQuery);
... ...
@@ -0,0 +1,7 @@
1
+/* Javascript plotting library for jQuery, version 0.8.3.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+*/
7
+(function($){function processRawData(plot,series,datapoints){var handlers={square:function(ctx,x,y,radius,shadow){var size=radius*Math.sqrt(Math.PI)/2;ctx.rect(x-size,y-size,size+size,size+size)},diamond:function(ctx,x,y,radius,shadow){var size=radius*Math.sqrt(Math.PI/2);ctx.moveTo(x-size,y);ctx.lineTo(x,y-size);ctx.lineTo(x+size,y);ctx.lineTo(x,y+size);ctx.lineTo(x-size,y)},triangle:function(ctx,x,y,radius,shadow){var size=radius*Math.sqrt(2*Math.PI/Math.sin(Math.PI/3));var height=size*Math.sin(Math.PI/3);ctx.moveTo(x-size/2,y+height/2);ctx.lineTo(x+size/2,y+height/2);if(!shadow){ctx.lineTo(x,y-height/2);ctx.lineTo(x-size/2,y+height/2)}},cross:function(ctx,x,y,radius,shadow){var size=radius*Math.sqrt(Math.PI)/2;ctx.moveTo(x-size,y-size);ctx.lineTo(x+size,y+size);ctx.moveTo(x-size,y+size);ctx.lineTo(x+size,y-size)}};var s=series.points.symbol;if(handlers[s])series.points.symbol=handlers[s]}function init(plot){plot.hooks.processDatapoints.push(processRawData)}$.plot.plugins.push({init:init,name:"symbols",version:"1.0"})})(jQuery);
0 8
\ No newline at end of file
... ...
@@ -0,0 +1,142 @@
1
+/* Flot plugin for thresholding data.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+The plugin supports these options:
7
+
8
+	series: {
9
+		threshold: {
10
+			below: number
11
+			color: colorspec
12
+		}
13
+	}
14
+
15
+It can also be applied to a single series, like this:
16
+
17
+	$.plot( $("#placeholder"), [{
18
+		data: [ ... ],
19
+		threshold: { ... }
20
+	}])
21
+
22
+An array can be passed for multiple thresholding, like this:
23
+
24
+	threshold: [{
25
+		below: number1
26
+		color: color1
27
+	},{
28
+		below: number2
29
+		color: color2
30
+	}]
31
+
32
+These multiple threshold objects can be passed in any order since they are
33
+sorted by the processing function.
34
+
35
+The data points below "below" are drawn with the specified color. This makes
36
+it easy to mark points below 0, e.g. for budget data.
37
+
38
+Internally, the plugin works by splitting the data into two series, above and
39
+below the threshold. The extra series below the threshold will have its label
40
+cleared and the special "originSeries" attribute set to the original series.
41
+You may need to check for this in hover events.
42
+
43
+*/
44
+
45
+(function ($) {
46
+    var options = {
47
+        series: { threshold: null } // or { below: number, color: color spec}
48
+    };
49
+    
50
+    function init(plot) {
51
+        function thresholdData(plot, s, datapoints, below, color) {
52
+            var ps = datapoints.pointsize, i, x, y, p, prevp,
53
+                thresholded = $.extend({}, s); // note: shallow copy
54
+
55
+            thresholded.datapoints = { points: [], pointsize: ps, format: datapoints.format };
56
+            thresholded.label = null;
57
+            thresholded.color = color;
58
+            thresholded.threshold = null;
59
+            thresholded.originSeries = s;
60
+            thresholded.data = [];
61
+ 
62
+            var origpoints = datapoints.points,
63
+                addCrossingPoints = s.lines.show;
64
+
65
+            var threspoints = [];
66
+            var newpoints = [];
67
+            var m;
68
+
69
+            for (i = 0; i < origpoints.length; i += ps) {
70
+                x = origpoints[i];
71
+                y = origpoints[i + 1];
72
+
73
+                prevp = p;
74
+                if (y < below)
75
+                    p = threspoints;
76
+                else
77
+                    p = newpoints;
78
+
79
+                if (addCrossingPoints && prevp != p && x != null
80
+                    && i > 0 && origpoints[i - ps] != null) {
81
+                    var interx = x + (below - y) * (x - origpoints[i - ps]) / (y - origpoints[i - ps + 1]);
82
+                    prevp.push(interx);
83
+                    prevp.push(below);
84
+                    for (m = 2; m < ps; ++m)
85
+                        prevp.push(origpoints[i + m]);
86
+                    
87
+                    p.push(null); // start new segment
88
+                    p.push(null);
89
+                    for (m = 2; m < ps; ++m)
90
+                        p.push(origpoints[i + m]);
91
+                    p.push(interx);
92
+                    p.push(below);
93
+                    for (m = 2; m < ps; ++m)
94
+                        p.push(origpoints[i + m]);
95
+                }
96
+
97
+                p.push(x);
98
+                p.push(y);
99
+                for (m = 2; m < ps; ++m)
100
+                    p.push(origpoints[i + m]);
101
+            }
102
+
103
+            datapoints.points = newpoints;
104
+            thresholded.datapoints.points = threspoints;
105
+            
106
+            if (thresholded.datapoints.points.length > 0) {
107
+                var origIndex = $.inArray(s, plot.getData());
108
+                // Insert newly-generated series right after original one (to prevent it from becoming top-most)
109
+                plot.getData().splice(origIndex + 1, 0, thresholded);
110
+            }
111
+                
112
+            // FIXME: there are probably some edge cases left in bars
113
+        }
114
+        
115
+        function processThresholds(plot, s, datapoints) {
116
+            if (!s.threshold)
117
+                return;
118
+            
119
+            if (s.threshold instanceof Array) {
120
+                s.threshold.sort(function(a, b) {
121
+                    return a.below - b.below;
122
+                });
123
+                
124
+                $(s.threshold).each(function(i, th) {
125
+                    thresholdData(plot, s, datapoints, th.below, th.color);
126
+                });
127
+            }
128
+            else {
129
+                thresholdData(plot, s, datapoints, s.threshold.below, s.threshold.color);
130
+            }
131
+        }
132
+        
133
+        plot.hooks.processDatapoints.push(processThresholds);
134
+    }
135
+    
136
+    $.plot.plugins.push({
137
+        init: init,
138
+        options: options,
139
+        name: 'threshold',
140
+        version: '1.2'
141
+    });
142
+})(jQuery);
... ...
@@ -0,0 +1,7 @@
1
+/* Javascript plotting library for jQuery, version 0.8.3.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+*/
7
+(function($){var options={series:{threshold:null}};function init(plot){function thresholdData(plot,s,datapoints,below,color){var ps=datapoints.pointsize,i,x,y,p,prevp,thresholded=$.extend({},s);thresholded.datapoints={points:[],pointsize:ps,format:datapoints.format};thresholded.label=null;thresholded.color=color;thresholded.threshold=null;thresholded.originSeries=s;thresholded.data=[];var origpoints=datapoints.points,addCrossingPoints=s.lines.show;var threspoints=[];var newpoints=[];var m;for(i=0;i<origpoints.length;i+=ps){x=origpoints[i];y=origpoints[i+1];prevp=p;if(y<below)p=threspoints;else p=newpoints;if(addCrossingPoints&&prevp!=p&&x!=null&&i>0&&origpoints[i-ps]!=null){var interx=x+(below-y)*(x-origpoints[i-ps])/(y-origpoints[i-ps+1]);prevp.push(interx);prevp.push(below);for(m=2;m<ps;++m)prevp.push(origpoints[i+m]);p.push(null);p.push(null);for(m=2;m<ps;++m)p.push(origpoints[i+m]);p.push(interx);p.push(below);for(m=2;m<ps;++m)p.push(origpoints[i+m])}p.push(x);p.push(y);for(m=2;m<ps;++m)p.push(origpoints[i+m])}datapoints.points=newpoints;thresholded.datapoints.points=threspoints;if(thresholded.datapoints.points.length>0){var origIndex=$.inArray(s,plot.getData());plot.getData().splice(origIndex+1,0,thresholded)}}function processThresholds(plot,s,datapoints){if(!s.threshold)return;if(s.threshold instanceof Array){s.threshold.sort(function(a,b){return a.below-b.below});$(s.threshold).each(function(i,th){thresholdData(plot,s,datapoints,th.below,th.color)})}else{thresholdData(plot,s,datapoints,s.threshold.below,s.threshold.color)}}plot.hooks.processDatapoints.push(processThresholds)}$.plot.plugins.push({init:init,options:options,name:"threshold",version:"1.2"})})(jQuery);
0 8
\ No newline at end of file
... ...
@@ -0,0 +1,432 @@
1
+/* Pretty handling of time axes.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+Set axis.mode to "time" to enable. See the section "Time series data" in
7
+API.txt for details.
8
+
9
+*/
10
+
11
+(function($) {
12
+
13
+	var options = {
14
+		xaxis: {
15
+			timezone: null,		// "browser" for local to the client or timezone for timezone-js
16
+			timeformat: null,	// format string to use
17
+			twelveHourClock: false,	// 12 or 24 time in time mode
18
+			monthNames: null	// list of names of months
19
+		}
20
+	};
21
+
22
+	// round to nearby lower multiple of base
23
+
24
+	function floorInBase(n, base) {
25
+		return base * Math.floor(n / base);
26
+	}
27
+
28
+	// Returns a string with the date d formatted according to fmt.
29
+	// A subset of the Open Group's strftime format is supported.
30
+
31
+	function formatDate(d, fmt, monthNames, dayNames) {
32
+
33
+		if (typeof d.strftime == "function") {
34
+			return d.strftime(fmt);
35
+		}
36
+
37
+		var leftPad = function(n, pad) {
38
+			n = "" + n;
39
+			pad = "" + (pad == null ? "0" : pad);
40
+			return n.length == 1 ? pad + n : n;
41
+		};
42
+
43
+		var r = [];
44
+		var escape = false;
45
+		var hours = d.getHours();
46
+		var isAM = hours < 12;
47
+
48
+		if (monthNames == null) {
49
+			monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
50
+		}
51
+
52
+		if (dayNames == null) {
53
+			dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
54
+		}
55
+
56
+		var hours12;
57
+
58
+		if (hours > 12) {
59
+			hours12 = hours - 12;
60
+		} else if (hours == 0) {
61
+			hours12 = 12;
62
+		} else {
63
+			hours12 = hours;
64
+		}
65
+
66
+		for (var i = 0; i < fmt.length; ++i) {
67
+
68
+			var c = fmt.charAt(i);
69
+
70
+			if (escape) {
71
+				switch (c) {
72
+					case 'a': c = "" + dayNames[d.getDay()]; break;
73
+					case 'b': c = "" + monthNames[d.getMonth()]; break;
74
+					case 'd': c = leftPad(d.getDate()); break;
75
+					case 'e': c = leftPad(d.getDate(), " "); break;
76
+					case 'h':	// For back-compat with 0.7; remove in 1.0
77
+					case 'H': c = leftPad(hours); break;
78
+					case 'I': c = leftPad(hours12); break;
79
+					case 'l': c = leftPad(hours12, " "); break;
80
+					case 'm': c = leftPad(d.getMonth() + 1); break;
81
+					case 'M': c = leftPad(d.getMinutes()); break;
82
+					// quarters not in Open Group's strftime specification
83
+					case 'q':
84
+						c = "" + (Math.floor(d.getMonth() / 3) + 1); break;
85
+					case 'S': c = leftPad(d.getSeconds()); break;
86
+					case 'y': c = leftPad(d.getFullYear() % 100); break;
87
+					case 'Y': c = "" + d.getFullYear(); break;
88
+					case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break;
89
+					case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break;
90
+					case 'w': c = "" + d.getDay(); break;
91
+				}
92
+				r.push(c);
93
+				escape = false;
94
+			} else {
95
+				if (c == "%") {
96
+					escape = true;
97
+				} else {
98
+					r.push(c);
99
+				}
100
+			}
101
+		}
102
+
103
+		return r.join("");
104
+	}
105
+
106
+	// To have a consistent view of time-based data independent of which time
107
+	// zone the client happens to be in we need a date-like object independent
108
+	// of time zones.  This is done through a wrapper that only calls the UTC
109
+	// versions of the accessor methods.
110
+
111
+	function makeUtcWrapper(d) {
112
+
113
+		function addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) {
114
+			sourceObj[sourceMethod] = function() {
115
+				return targetObj[targetMethod].apply(targetObj, arguments);
116
+			};
117
+		};
118
+
119
+		var utc = {
120
+			date: d
121
+		};
122
+
123
+		// support strftime, if found
124
+
125
+		if (d.strftime != undefined) {
126
+			addProxyMethod(utc, "strftime", d, "strftime");
127
+		}
128
+
129
+		addProxyMethod(utc, "getTime", d, "getTime");
130
+		addProxyMethod(utc, "setTime", d, "setTime");
131
+
132
+		var props = ["Date", "Day", "FullYear", "Hours", "Milliseconds", "Minutes", "Month", "Seconds"];
133
+
134
+		for (var p = 0; p < props.length; p++) {
135
+			addProxyMethod(utc, "get" + props[p], d, "getUTC" + props[p]);
136
+			addProxyMethod(utc, "set" + props[p], d, "setUTC" + props[p]);
137
+		}
138
+
139
+		return utc;
140
+	};
141
+
142
+	// select time zone strategy.  This returns a date-like object tied to the
143
+	// desired timezone
144
+
145
+	function dateGenerator(ts, opts) {
146
+		if (opts.timezone == "browser") {
147
+			return new Date(ts);
148
+		} else if (!opts.timezone || opts.timezone == "utc") {
149
+			return makeUtcWrapper(new Date(ts));
150
+		} else if (typeof timezoneJS != "undefined" && typeof timezoneJS.Date != "undefined") {
151
+			var d = new timezoneJS.Date();
152
+			// timezone-js is fickle, so be sure to set the time zone before
153
+			// setting the time.
154
+			d.setTimezone(opts.timezone);
155
+			d.setTime(ts);
156
+			return d;
157
+		} else {
158
+			return makeUtcWrapper(new Date(ts));
159
+		}
160
+	}
161
+	
162
+	// map of app. size of time units in milliseconds
163
+
164
+	var timeUnitSize = {
165
+		"second": 1000,
166
+		"minute": 60 * 1000,
167
+		"hour": 60 * 60 * 1000,
168
+		"day": 24 * 60 * 60 * 1000,
169
+		"month": 30 * 24 * 60 * 60 * 1000,
170
+		"quarter": 3 * 30 * 24 * 60 * 60 * 1000,
171
+		"year": 365.2425 * 24 * 60 * 60 * 1000
172
+	};
173
+
174
+	// the allowed tick sizes, after 1 year we use
175
+	// an integer algorithm
176
+
177
+	var baseSpec = [
178
+		[1, "second"], [2, "second"], [5, "second"], [10, "second"],
179
+		[30, "second"], 
180
+		[1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"],
181
+		[30, "minute"], 
182
+		[1, "hour"], [2, "hour"], [4, "hour"],
183
+		[8, "hour"], [12, "hour"],
184
+		[1, "day"], [2, "day"], [3, "day"],
185
+		[0.25, "month"], [0.5, "month"], [1, "month"],
186
+		[2, "month"]
187
+	];
188
+
189
+	// we don't know which variant(s) we'll need yet, but generating both is
190
+	// cheap
191
+
192
+	var specMonths = baseSpec.concat([[3, "month"], [6, "month"],
193
+		[1, "year"]]);
194
+	var specQuarters = baseSpec.concat([[1, "quarter"], [2, "quarter"],
195
+		[1, "year"]]);
196
+
197
+	function init(plot) {
198
+		plot.hooks.processOptions.push(function (plot, options) {
199
+			$.each(plot.getAxes(), function(axisName, axis) {
200
+
201
+				var opts = axis.options;
202
+
203
+				if (opts.mode == "time") {
204
+					axis.tickGenerator = function(axis) {
205
+
206
+						var ticks = [];
207
+						var d = dateGenerator(axis.min, opts);
208
+						var minSize = 0;
209
+
210
+						// make quarter use a possibility if quarters are
211
+						// mentioned in either of these options
212
+
213
+						var spec = (opts.tickSize && opts.tickSize[1] ===
214
+							"quarter") ||
215
+							(opts.minTickSize && opts.minTickSize[1] ===
216
+							"quarter") ? specQuarters : specMonths;
217
+
218
+						if (opts.minTickSize != null) {
219
+							if (typeof opts.tickSize == "number") {
220
+								minSize = opts.tickSize;
221
+							} else {
222
+								minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]];
223
+							}
224
+						}
225
+
226
+						for (var i = 0; i < spec.length - 1; ++i) {
227
+							if (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]]
228
+											  + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2
229
+								&& spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) {
230
+								break;
231
+							}
232
+						}
233
+
234
+						var size = spec[i][0];
235
+						var unit = spec[i][1];
236
+
237
+						// special-case the possibility of several years
238
+
239
+						if (unit == "year") {
240
+
241
+							// if given a minTickSize in years, just use it,
242
+							// ensuring that it's an integer
243
+
244
+							if (opts.minTickSize != null && opts.minTickSize[1] == "year") {
245
+								size = Math.floor(opts.minTickSize[0]);
246
+							} else {
247
+
248
+								var magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10));
249
+								var norm = (axis.delta / timeUnitSize.year) / magn;
250
+
251
+								if (norm < 1.5) {
252
+									size = 1;
253
+								} else if (norm < 3) {
254
+									size = 2;
255
+								} else if (norm < 7.5) {
256
+									size = 5;
257
+								} else {
258
+									size = 10;
259
+								}
260
+
261
+								size *= magn;
262
+							}
263
+
264
+							// minimum size for years is 1
265
+
266
+							if (size < 1) {
267
+								size = 1;
268
+							}
269
+						}
270
+
271
+						axis.tickSize = opts.tickSize || [size, unit];
272
+						var tickSize = axis.tickSize[0];
273
+						unit = axis.tickSize[1];
274
+
275
+						var step = tickSize * timeUnitSize[unit];
276
+
277
+						if (unit == "second") {
278
+							d.setSeconds(floorInBase(d.getSeconds(), tickSize));
279
+						} else if (unit == "minute") {
280
+							d.setMinutes(floorInBase(d.getMinutes(), tickSize));
281
+						} else if (unit == "hour") {
282
+							d.setHours(floorInBase(d.getHours(), tickSize));
283
+						} else if (unit == "month") {
284
+							d.setMonth(floorInBase(d.getMonth(), tickSize));
285
+						} else if (unit == "quarter") {
286
+							d.setMonth(3 * floorInBase(d.getMonth() / 3,
287
+								tickSize));
288
+						} else if (unit == "year") {
289
+							d.setFullYear(floorInBase(d.getFullYear(), tickSize));
290
+						}
291
+
292
+						// reset smaller components
293
+
294
+						d.setMilliseconds(0);
295
+
296
+						if (step >= timeUnitSize.minute) {
297
+							d.setSeconds(0);
298
+						}
299
+						if (step >= timeUnitSize.hour) {
300
+							d.setMinutes(0);
301
+						}
302
+						if (step >= timeUnitSize.day) {
303
+							d.setHours(0);
304
+						}
305
+						if (step >= timeUnitSize.day * 4) {
306
+							d.setDate(1);
307
+						}
308
+						if (step >= timeUnitSize.month * 2) {
309
+							d.setMonth(floorInBase(d.getMonth(), 3));
310
+						}
311
+						if (step >= timeUnitSize.quarter * 2) {
312
+							d.setMonth(floorInBase(d.getMonth(), 6));
313
+						}
314
+						if (step >= timeUnitSize.year) {
315
+							d.setMonth(0);
316
+						}
317
+
318
+						var carry = 0;
319
+						var v = Number.NaN;
320
+						var prev;
321
+
322
+						do {
323
+
324
+							prev = v;
325
+							v = d.getTime();
326
+							ticks.push(v);
327
+
328
+							if (unit == "month" || unit == "quarter") {
329
+								if (tickSize < 1) {
330
+
331
+									// a bit complicated - we'll divide the
332
+									// month/quarter up but we need to take
333
+									// care of fractions so we don't end up in
334
+									// the middle of a day
335
+
336
+									d.setDate(1);
337
+									var start = d.getTime();
338
+									d.setMonth(d.getMonth() +
339
+										(unit == "quarter" ? 3 : 1));
340
+									var end = d.getTime();
341
+									d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);
342
+									carry = d.getHours();
343
+									d.setHours(0);
344
+								} else {
345
+									d.setMonth(d.getMonth() +
346
+										tickSize * (unit == "quarter" ? 3 : 1));
347
+								}
348
+							} else if (unit == "year") {
349
+								d.setFullYear(d.getFullYear() + tickSize);
350
+							} else {
351
+								d.setTime(v + step);
352
+							}
353
+						} while (v < axis.max && v != prev);
354
+
355
+						return ticks;
356
+					};
357
+
358
+					axis.tickFormatter = function (v, axis) {
359
+
360
+						var d = dateGenerator(v, axis.options);
361
+
362
+						// first check global format
363
+
364
+						if (opts.timeformat != null) {
365
+							return formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames);
366
+						}
367
+
368
+						// possibly use quarters if quarters are mentioned in
369
+						// any of these places
370
+
371
+						var useQuarters = (axis.options.tickSize &&
372
+								axis.options.tickSize[1] == "quarter") ||
373
+							(axis.options.minTickSize &&
374
+								axis.options.minTickSize[1] == "quarter");
375
+
376
+						var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];
377
+						var span = axis.max - axis.min;
378
+						var suffix = (opts.twelveHourClock) ? " %p" : "";
379
+						var hourCode = (opts.twelveHourClock) ? "%I" : "%H";
380
+						var fmt;
381
+
382
+						if (t < timeUnitSize.minute) {
383
+							fmt = hourCode + ":%M:%S" + suffix;
384
+						} else if (t < timeUnitSize.day) {
385
+							if (span < 2 * timeUnitSize.day) {
386
+								fmt = hourCode + ":%M" + suffix;
387
+							} else {
388
+								fmt = "%b %d " + hourCode + ":%M" + suffix;
389
+							}
390
+						} else if (t < timeUnitSize.month) {
391
+							fmt = "%b %d";
392
+						} else if ((useQuarters && t < timeUnitSize.quarter) ||
393
+							(!useQuarters && t < timeUnitSize.year)) {
394
+							if (span < timeUnitSize.year) {
395
+								fmt = "%b";
396
+							} else {
397
+								fmt = "%b %Y";
398
+							}
399
+						} else if (useQuarters && t < timeUnitSize.year) {
400
+							if (span < timeUnitSize.year) {
401
+								fmt = "Q%q";
402
+							} else {
403
+								fmt = "Q%q %Y";
404
+							}
405
+						} else {
406
+							fmt = "%Y";
407
+						}
408
+
409
+						var rt = formatDate(d, fmt, opts.monthNames, opts.dayNames);
410
+
411
+						return rt;
412
+					};
413
+				}
414
+			});
415
+		});
416
+	}
417
+
418
+	$.plot.plugins.push({
419
+		init: init,
420
+		options: options,
421
+		name: 'time',
422
+		version: '1.0'
423
+	});
424
+
425
+	// Time-axis support used to be in Flot core, which exposed the
426
+	// formatDate function on the plot object.  Various plugins depend
427
+	// on the function, so we need to re-expose it here.
428
+
429
+	$.plot.formatDate = formatDate;
430
+	$.plot.dateGenerator = dateGenerator;
431
+
432
+})(jQuery);
... ...
@@ -0,0 +1,7 @@
1
+/* Javascript plotting library for jQuery, version 0.8.3.
2
+
3
+Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+Licensed under the MIT license.
5
+
6
+*/
7
+(function($){var options={xaxis:{timezone:null,timeformat:null,twelveHourClock:false,monthNames:null}};function floorInBase(n,base){return base*Math.floor(n/base)}function formatDate(d,fmt,monthNames,dayNames){if(typeof d.strftime=="function"){return d.strftime(fmt)}var leftPad=function(n,pad){n=""+n;pad=""+(pad==null?"0":pad);return n.length==1?pad+n:n};var r=[];var escape=false;var hours=d.getHours();var isAM=hours<12;if(monthNames==null){monthNames=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]}if(dayNames==null){dayNames=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]}var hours12;if(hours>12){hours12=hours-12}else if(hours==0){hours12=12}else{hours12=hours}for(var i=0;i<fmt.length;++i){var c=fmt.charAt(i);if(escape){switch(c){case"a":c=""+dayNames[d.getDay()];break;case"b":c=""+monthNames[d.getMonth()];break;case"d":c=leftPad(d.getDate());break;case"e":c=leftPad(d.getDate()," ");break;case"h":case"H":c=leftPad(hours);break;case"I":c=leftPad(hours12);break;case"l":c=leftPad(hours12," ");break;case"m":c=leftPad(d.getMonth()+1);break;case"M":c=leftPad(d.getMinutes());break;case"q":c=""+(Math.floor(d.getMonth()/3)+1);break;case"S":c=leftPad(d.getSeconds());break;case"y":c=leftPad(d.getFullYear()%100);break;case"Y":c=""+d.getFullYear();break;case"p":c=isAM?""+"am":""+"pm";break;case"P":c=isAM?""+"AM":""+"PM";break;case"w":c=""+d.getDay();break}r.push(c);escape=false}else{if(c=="%"){escape=true}else{r.push(c)}}}return r.join("")}function makeUtcWrapper(d){function addProxyMethod(sourceObj,sourceMethod,targetObj,targetMethod){sourceObj[sourceMethod]=function(){return targetObj[targetMethod].apply(targetObj,arguments)}}var utc={date:d};if(d.strftime!=undefined){addProxyMethod(utc,"strftime",d,"strftime")}addProxyMethod(utc,"getTime",d,"getTime");addProxyMethod(utc,"setTime",d,"setTime");var props=["Date","Day","FullYear","Hours","Milliseconds","Minutes","Month","Seconds"];for(var p=0;p<props.length;p++){addProxyMethod(utc,"get"+props[p],d,"getUTC"+props[p]);addProxyMethod(utc,"set"+props[p],d,"setUTC"+props[p])}return utc}function dateGenerator(ts,opts){if(opts.timezone=="browser"){return new Date(ts)}else if(!opts.timezone||opts.timezone=="utc"){return makeUtcWrapper(new Date(ts))}else if(typeof timezoneJS!="undefined"&&typeof timezoneJS.Date!="undefined"){var d=new timezoneJS.Date;d.setTimezone(opts.timezone);d.setTime(ts);return d}else{return makeUtcWrapper(new Date(ts))}}var timeUnitSize={second:1e3,minute:60*1e3,hour:60*60*1e3,day:24*60*60*1e3,month:30*24*60*60*1e3,quarter:3*30*24*60*60*1e3,year:365.2425*24*60*60*1e3};var baseSpec=[[1,"second"],[2,"second"],[5,"second"],[10,"second"],[30,"second"],[1,"minute"],[2,"minute"],[5,"minute"],[10,"minute"],[30,"minute"],[1,"hour"],[2,"hour"],[4,"hour"],[8,"hour"],[12,"hour"],[1,"day"],[2,"day"],[3,"day"],[.25,"month"],[.5,"month"],[1,"month"],[2,"month"]];var specMonths=baseSpec.concat([[3,"month"],[6,"month"],[1,"year"]]);var specQuarters=baseSpec.concat([[1,"quarter"],[2,"quarter"],[1,"year"]]);function init(plot){plot.hooks.processOptions.push(function(plot,options){$.each(plot.getAxes(),function(axisName,axis){var opts=axis.options;if(opts.mode=="time"){axis.tickGenerator=function(axis){var ticks=[];var d=dateGenerator(axis.min,opts);var minSize=0;var spec=opts.tickSize&&opts.tickSize[1]==="quarter"||opts.minTickSize&&opts.minTickSize[1]==="quarter"?specQuarters:specMonths;if(opts.minTickSize!=null){if(typeof opts.tickSize=="number"){minSize=opts.tickSize}else{minSize=opts.minTickSize[0]*timeUnitSize[opts.minTickSize[1]]}}for(var i=0;i<spec.length-1;++i){if(axis.delta<(spec[i][0]*timeUnitSize[spec[i][1]]+spec[i+1][0]*timeUnitSize[spec[i+1][1]])/2&&spec[i][0]*timeUnitSize[spec[i][1]]>=minSize){break}}var size=spec[i][0];var unit=spec[i][1];if(unit=="year"){if(opts.minTickSize!=null&&opts.minTickSize[1]=="year"){size=Math.floor(opts.minTickSize[0])}else{var magn=Math.pow(10,Math.floor(Math.log(axis.delta/timeUnitSize.year)/Math.LN10));var norm=axis.delta/timeUnitSize.year/magn;if(norm<1.5){size=1}else if(norm<3){size=2}else if(norm<7.5){size=5}else{size=10}size*=magn}if(size<1){size=1}}axis.tickSize=opts.tickSize||[size,unit];var tickSize=axis.tickSize[0];unit=axis.tickSize[1];var step=tickSize*timeUnitSize[unit];if(unit=="second"){d.setSeconds(floorInBase(d.getSeconds(),tickSize))}else if(unit=="minute"){d.setMinutes(floorInBase(d.getMinutes(),tickSize))}else if(unit=="hour"){d.setHours(floorInBase(d.getHours(),tickSize))}else if(unit=="month"){d.setMonth(floorInBase(d.getMonth(),tickSize))}else if(unit=="quarter"){d.setMonth(3*floorInBase(d.getMonth()/3,tickSize))}else if(unit=="year"){d.setFullYear(floorInBase(d.getFullYear(),tickSize))}d.setMilliseconds(0);if(step>=timeUnitSize.minute){d.setSeconds(0)}if(step>=timeUnitSize.hour){d.setMinutes(0)}if(step>=timeUnitSize.day){d.setHours(0)}if(step>=timeUnitSize.day*4){d.setDate(1)}if(step>=timeUnitSize.month*2){d.setMonth(floorInBase(d.getMonth(),3))}if(step>=timeUnitSize.quarter*2){d.setMonth(floorInBase(d.getMonth(),6))}if(step>=timeUnitSize.year){d.setMonth(0)}var carry=0;var v=Number.NaN;var prev;do{prev=v;v=d.getTime();ticks.push(v);if(unit=="month"||unit=="quarter"){if(tickSize<1){d.setDate(1);var start=d.getTime();d.setMonth(d.getMonth()+(unit=="quarter"?3:1));var end=d.getTime();d.setTime(v+carry*timeUnitSize.hour+(end-start)*tickSize);carry=d.getHours();d.setHours(0)}else{d.setMonth(d.getMonth()+tickSize*(unit=="quarter"?3:1))}}else if(unit=="year"){d.setFullYear(d.getFullYear()+tickSize)}else{d.setTime(v+step)}}while(v<axis.max&&v!=prev);return ticks};axis.tickFormatter=function(v,axis){var d=dateGenerator(v,axis.options);if(opts.timeformat!=null){return formatDate(d,opts.timeformat,opts.monthNames,opts.dayNames)}var useQuarters=axis.options.tickSize&&axis.options.tickSize[1]=="quarter"||axis.options.minTickSize&&axis.options.minTickSize[1]=="quarter";var t=axis.tickSize[0]*timeUnitSize[axis.tickSize[1]];var span=axis.max-axis.min;var suffix=opts.twelveHourClock?" %p":"";var hourCode=opts.twelveHourClock?"%I":"%H";var fmt;if(t<timeUnitSize.minute){fmt=hourCode+":%M:%S"+suffix}else if(t<timeUnitSize.day){if(span<2*timeUnitSize.day){fmt=hourCode+":%M"+suffix}else{fmt="%b %d "+hourCode+":%M"+suffix}}else if(t<timeUnitSize.month){fmt="%b %d"}else if(useQuarters&&t<timeUnitSize.quarter||!useQuarters&&t<timeUnitSize.year){if(span<timeUnitSize.year){fmt="%b"}else{fmt="%b %Y"}}else if(useQuarters&&t<timeUnitSize.year){if(span<timeUnitSize.year){fmt="Q%q"}else{fmt="Q%q %Y"}}else{fmt="%Y"}var rt=formatDate(d,fmt,opts.monthNames,opts.dayNames);return rt}}})})}$.plot.plugins.push({init:init,options:options,name:"time",version:"1.0"});$.plot.formatDate=formatDate;$.plot.dateGenerator=dateGenerator})(jQuery);
0 8
\ No newline at end of file
... ...
@@ -0,0 +1,9472 @@
1
+/*!
2
+ * jQuery JavaScript Library v1.8.3
3
+ * http://jquery.com/
4
+ *
5
+ * Includes Sizzle.js
6
+ * http://sizzlejs.com/
7
+ *
8
+ * Copyright 2012 jQuery Foundation and other contributors
9
+ * Released under the MIT license
10
+ * http://jquery.org/license
11
+ *
12
+ * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time)
13
+ */
14
+(function( window, undefined ) {
15
+var
16
+	// A central reference to the root jQuery(document)
17
+	rootjQuery,
18
+
19
+	// The deferred used on DOM ready
20
+	readyList,
21
+
22
+	// Use the correct document accordingly with window argument (sandbox)
23
+	document = window.document,
24
+	location = window.location,
25
+	navigator = window.navigator,
26
+
27
+	// Map over jQuery in case of overwrite
28
+	_jQuery = window.jQuery,
29
+
30
+	// Map over the $ in case of overwrite
31
+	_$ = window.$,
32
+
33
+	// Save a reference to some core methods
34
+	core_push = Array.prototype.push,
35
+	core_slice = Array.prototype.slice,
36
+	core_indexOf = Array.prototype.indexOf,
37
+	core_toString = Object.prototype.toString,
38
+	core_hasOwn = Object.prototype.hasOwnProperty,
39
+	core_trim = String.prototype.trim,
40
+
41
+	// Define a local copy of jQuery
42
+	jQuery = function( selector, context ) {
43
+		// The jQuery object is actually just the init constructor 'enhanced'
44
+		return new jQuery.fn.init( selector, context, rootjQuery );
45
+	},
46
+
47
+	// Used for matching numbers
48
+	core_pnum = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,
49
+
50
+	// Used for detecting and trimming whitespace
51
+	core_rnotwhite = /\S/,
52
+	core_rspace = /\s+/,
53
+
54
+	// Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
55
+	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
56
+
57
+	// A simple way to check for HTML strings
58
+	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
59
+	rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
60
+
61
+	// Match a standalone tag
62
+	rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
63
+
64
+	// JSON RegExp
65
+	rvalidchars = /^[\],:{}\s]*$/,
66
+	rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
67
+	rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,
68
+	rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,
69
+
70
+	// Matches dashed string for camelizing
71
+	rmsPrefix = /^-ms-/,
72
+	rdashAlpha = /-([\da-z])/gi,
73
+
74
+	// Used by jQuery.camelCase as callback to replace()
75
+	fcamelCase = function( all, letter ) {
76
+		return ( letter + "" ).toUpperCase();
77
+	},
78
+
79
+	// The ready event handler and self cleanup method
80
+	DOMContentLoaded = function() {
81
+		if ( document.addEventListener ) {
82
+			document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
83
+			jQuery.ready();
84
+		} else if ( document.readyState === "complete" ) {
85
+			// we're here because readyState === "complete" in oldIE
86
+			// which is good enough for us to call the dom ready!
87
+			document.detachEvent( "onreadystatechange", DOMContentLoaded );
88
+			jQuery.ready();
89
+		}
90
+	},
91
+
92
+	// [[Class]] -> type pairs
93
+	class2type = {};
94
+
95
+jQuery.fn = jQuery.prototype = {
96
+	constructor: jQuery,
97
+	init: function( selector, context, rootjQuery ) {
98
+		var match, elem, ret, doc;
99
+
100
+		// Handle $(""), $(null), $(undefined), $(false)
101
+		if ( !selector ) {
102
+			return this;
103
+		}
104
+
105
+		// Handle $(DOMElement)
106
+		if ( selector.nodeType ) {
107
+			this.context = this[0] = selector;
108
+			this.length = 1;
109
+			return this;
110
+		}
111
+
112
+		// Handle HTML strings
113
+		if ( typeof selector === "string" ) {
114
+			if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
115
+				// Assume that strings that start and end with <> are HTML and skip the regex check
116
+				match = [ null, selector, null ];
117
+
118
+			} else {
119
+				match = rquickExpr.exec( selector );
120
+			}
121
+
122
+			// Match html or make sure no context is specified for #id
123
+			if ( match && (match[1] || !context) ) {
124
+
125
+				// HANDLE: $(html) -> $(array)
126
+				if ( match[1] ) {
127
+					context = context instanceof jQuery ? context[0] : context;
128
+					doc = ( context && context.nodeType ? context.ownerDocument || context : document );
129
+
130
+					// scripts is true for back-compat
131
+					selector = jQuery.parseHTML( match[1], doc, true );
132
+					if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
133
+						this.attr.call( selector, context, true );
134
+					}
135
+
136
+					return jQuery.merge( this, selector );
137
+
138
+				// HANDLE: $(#id)
139
+				} else {
140
+					elem = document.getElementById( match[2] );
141
+
142
+					// Check parentNode to catch when Blackberry 4.6 returns
143
+					// nodes that are no longer in the document #6963
144
+					if ( elem && elem.parentNode ) {
145
+						// Handle the case where IE and Opera return items
146
+						// by name instead of ID
147
+						if ( elem.id !== match[2] ) {
148
+							return rootjQuery.find( selector );
149
+						}
150
+
151
+						// Otherwise, we inject the element directly into the jQuery object
152
+						this.length = 1;
153
+						this[0] = elem;
154
+					}
155
+
156
+					this.context = document;
157
+					this.selector = selector;
158
+					return this;
159
+				}
160
+
161
+			// HANDLE: $(expr, $(...))
162
+			} else if ( !context || context.jquery ) {
163
+				return ( context || rootjQuery ).find( selector );
164
+
165
+			// HANDLE: $(expr, context)
166
+			// (which is just equivalent to: $(context).find(expr)
167
+			} else {
168
+				return this.constructor( context ).find( selector );
169
+			}
170
+
171
+		// HANDLE: $(function)
172
+		// Shortcut for document ready
173
+		} else if ( jQuery.isFunction( selector ) ) {
174
+			return rootjQuery.ready( selector );
175
+		}
176
+
177
+		if ( selector.selector !== undefined ) {
178
+			this.selector = selector.selector;
179
+			this.context = selector.context;
180
+		}
181
+
182
+		return jQuery.makeArray( selector, this );
183
+	},
184
+
185
+	// Start with an empty selector
186
+	selector: "",
187
+
188
+	// The current version of jQuery being used
189
+	jquery: "1.8.3",
190
+
191
+	// The default length of a jQuery object is 0
192
+	length: 0,
193
+
194
+	// The number of elements contained in the matched element set
195
+	size: function() {
196
+		return this.length;
197
+	},
198
+
199
+	toArray: function() {
200
+		return core_slice.call( this );
201
+	},
202
+
203
+	// Get the Nth element in the matched element set OR
204
+	// Get the whole matched element set as a clean array
205
+	get: function( num ) {
206
+		return num == null ?
207
+
208
+			// Return a 'clean' array
209
+			this.toArray() :
210
+
211
+			// Return just the object
212
+			( num < 0 ? this[ this.length + num ] : this[ num ] );
213
+	},
214
+
215
+	// Take an array of elements and push it onto the stack
216
+	// (returning the new matched element set)
217
+	pushStack: function( elems, name, selector ) {
218
+
219
+		// Build a new jQuery matched element set
220
+		var ret = jQuery.merge( this.constructor(), elems );
221
+
222
+		// Add the old object onto the stack (as a reference)
223
+		ret.prevObject = this;
224
+
225
+		ret.context = this.context;
226
+
227
+		if ( name === "find" ) {
228
+			ret.selector = this.selector + ( this.selector ? " " : "" ) + selector;
229
+		} else if ( name ) {
230
+			ret.selector = this.selector + "." + name + "(" + selector + ")";
231
+		}
232
+
233
+		// Return the newly-formed element set
234
+		return ret;
235
+	},
236
+
237
+	// Execute a callback for every element in the matched set.
238
+	// (You can seed the arguments with an array of args, but this is
239
+	// only used internally.)
240
+	each: function( callback, args ) {
241
+		return jQuery.each( this, callback, args );
242
+	},
243
+
244
+	ready: function( fn ) {
245
+		// Add the callback
246
+		jQuery.ready.promise().done( fn );
247
+
248
+		return this;
249
+	},
250
+
251
+	eq: function( i ) {
252
+		i = +i;
253
+		return i === -1 ?
254
+			this.slice( i ) :
255
+			this.slice( i, i + 1 );
256
+	},
257
+
258
+	first: function() {
259
+		return this.eq( 0 );
260
+	},
261
+
262
+	last: function() {
263
+		return this.eq( -1 );
264
+	},
265
+
266
+	slice: function() {
267
+		return this.pushStack( core_slice.apply( this, arguments ),
268
+			"slice", core_slice.call(arguments).join(",") );
269
+	},
270
+
271
+	map: function( callback ) {
272
+		return this.pushStack( jQuery.map(this, function( elem, i ) {
273
+			return callback.call( elem, i, elem );
274
+		}));
275
+	},
276
+
277
+	end: function() {
278
+		return this.prevObject || this.constructor(null);
279
+	},
280
+
281
+	// For internal use only.
282
+	// Behaves like an Array's method, not like a jQuery method.
283
+	push: core_push,
284
+	sort: [].sort,
285
+	splice: [].splice
286
+};
287
+
288
+// Give the init function the jQuery prototype for later instantiation
289
+jQuery.fn.init.prototype = jQuery.fn;
290
+
291
+jQuery.extend = jQuery.fn.extend = function() {
292
+	var options, name, src, copy, copyIsArray, clone,
293
+		target = arguments[0] || {},
294
+		i = 1,
295
+		length = arguments.length,
296
+		deep = false;
297
+
298
+	// Handle a deep copy situation
299
+	if ( typeof target === "boolean" ) {
300
+		deep = target;
301
+		target = arguments[1] || {};
302
+		// skip the boolean and the target
303
+		i = 2;
304
+	}
305
+
306
+	// Handle case when target is a string or something (possible in deep copy)
307
+	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
308
+		target = {};
309
+	}
310
+
311
+	// extend jQuery itself if only one argument is passed
312
+	if ( length === i ) {
313
+		target = this;
314
+		--i;
315
+	}
316
+
317
+	for ( ; i < length; i++ ) {
318
+		// Only deal with non-null/undefined values
319
+		if ( (options = arguments[ i ]) != null ) {
320
+			// Extend the base object
321
+			for ( name in options ) {
322
+				src = target[ name ];
323
+				copy = options[ name ];
324
+
325
+				// Prevent never-ending loop
326
+				if ( target === copy ) {
327
+					continue;
328
+				}
329
+
330
+				// Recurse if we're merging plain objects or arrays
331
+				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
332
+					if ( copyIsArray ) {
333
+						copyIsArray = false;
334
+						clone = src && jQuery.isArray(src) ? src : [];
335
+
336
+					} else {
337
+						clone = src && jQuery.isPlainObject(src) ? src : {};
338
+					}
339
+
340
+					// Never move original objects, clone them
341
+					target[ name ] = jQuery.extend( deep, clone, copy );
342
+
343
+				// Don't bring in undefined values
344
+				} else if ( copy !== undefined ) {
345
+					target[ name ] = copy;
346
+				}
347
+			}
348
+		}
349
+	}
350
+
351
+	// Return the modified object
352
+	return target;
353
+};
354
+
355
+jQuery.extend({
356
+	noConflict: function( deep ) {
357
+		if ( window.$ === jQuery ) {
358
+			window.$ = _$;
359
+		}
360
+
361
+		if ( deep && window.jQuery === jQuery ) {
362
+			window.jQuery = _jQuery;
363
+		}
364
+
365
+		return jQuery;
366
+	},
367
+
368
+	// Is the DOM ready to be used? Set to true once it occurs.
369
+	isReady: false,
370
+
371
+	// A counter to track how many items to wait for before
372
+	// the ready event fires. See #6781
373
+	readyWait: 1,
374
+
375
+	// Hold (or release) the ready event
376
+	holdReady: function( hold ) {
377
+		if ( hold ) {
378
+			jQuery.readyWait++;
379
+		} else {
380
+			jQuery.ready( true );
381
+		}
382
+	},
383
+
384
+	// Handle when the DOM is ready
385
+	ready: function( wait ) {
386
+
387
+		// Abort if there are pending holds or we're already ready
388
+		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
389
+			return;
390
+		}
391
+
392
+		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
393
+		if ( !document.body ) {
394
+			return setTimeout( jQuery.ready, 1 );
395
+		}
396
+
397
+		// Remember that the DOM is ready
398
+		jQuery.isReady = true;
399
+
400
+		// If a normal DOM Ready event fired, decrement, and wait if need be
401
+		if ( wait !== true && --jQuery.readyWait > 0 ) {
402
+			return;
403
+		}
404
+
405
+		// If there are functions bound, to execute
406
+		readyList.resolveWith( document, [ jQuery ] );
407
+
408
+		// Trigger any bound ready events
409
+		if ( jQuery.fn.trigger ) {
410
+			jQuery( document ).trigger("ready").off("ready");
411
+		}
412
+	},
413
+
414
+	// See test/unit/core.js for details concerning isFunction.
415
+	// Since version 1.3, DOM methods and functions like alert
416
+	// aren't supported. They return false on IE (#2968).
417
+	isFunction: function( obj ) {
418
+		return jQuery.type(obj) === "function";
419
+	},
420
+
421
+	isArray: Array.isArray || function( obj ) {
422
+		return jQuery.type(obj) === "array";
423
+	},
424
+
425
+	isWindow: function( obj ) {
426
+		return obj != null && obj == obj.window;
427
+	},
428
+
429
+	isNumeric: function( obj ) {
430
+		return !isNaN( parseFloat(obj) ) && isFinite( obj );
431
+	},
432
+
433
+	type: function( obj ) {
434
+		return obj == null ?
435
+			String( obj ) :
436
+			class2type[ core_toString.call(obj) ] || "object";
437
+	},
438
+
439
+	isPlainObject: function( obj ) {
440
+		// Must be an Object.
441
+		// Because of IE, we also have to check the presence of the constructor property.
442
+		// Make sure that DOM nodes and window objects don't pass through, as well
443
+		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
444
+			return false;
445
+		}
446
+
447
+		try {
448
+			// Not own constructor property must be Object
449
+			if ( obj.constructor &&
450
+				!core_hasOwn.call(obj, "constructor") &&
451
+				!core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
452
+				return false;
453
+			}
454
+		} catch ( e ) {
455
+			// IE8,9 Will throw exceptions on certain host objects #9897
456
+			return false;
457
+		}
458
+
459
+		// Own properties are enumerated firstly, so to speed up,
460
+		// if last one is own, then all properties are own.
461
+
462
+		var key;
463
+		for ( key in obj ) {}
464
+
465
+		return key === undefined || core_hasOwn.call( obj, key );
466
+	},
467
+
468
+	isEmptyObject: function( obj ) {
469
+		var name;
470
+		for ( name in obj ) {
471
+			return false;
472
+		}
473
+		return true;
474
+	},
475
+
476
+	error: function( msg ) {
477
+		throw new Error( msg );
478
+	},
479
+
480
+	// data: string of html
481
+	// context (optional): If specified, the fragment will be created in this context, defaults to document
482
+	// scripts (optional): If true, will include scripts passed in the html string
483
+	parseHTML: function( data, context, scripts ) {
484
+		var parsed;
485
+		if ( !data || typeof data !== "string" ) {
486
+			return null;
487
+		}
488
+		if ( typeof context === "boolean" ) {
489
+			scripts = context;
490
+			context = 0;
491
+		}
492
+		context = context || document;
493
+
494
+		// Single tag
495
+		if ( (parsed = rsingleTag.exec( data )) ) {
496
+			return [ context.createElement( parsed[1] ) ];
497
+		}
498
+
499
+		parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] );
500
+		return jQuery.merge( [],
501
+			(parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes );
502
+	},
503
+
504
+	parseJSON: function( data ) {
505
+		if ( !data || typeof data !== "string") {
506
+			return null;
507
+		}
508
+
509
+		// Make sure leading/trailing whitespace is removed (IE can't handle it)
510
+		data = jQuery.trim( data );
511
+
512
+		// Attempt to parse using the native JSON parser first
513
+		if ( window.JSON && window.JSON.parse ) {
514
+			return window.JSON.parse( data );
515
+		}
516
+
517
+		// Make sure the incoming data is actual JSON
518
+		// Logic borrowed from http://json.org/json2.js
519
+		if ( rvalidchars.test( data.replace( rvalidescape, "@" )
520
+			.replace( rvalidtokens, "]" )
521
+			.replace( rvalidbraces, "")) ) {
522
+
523
+			return ( new Function( "return " + data ) )();
524
+
525
+		}
526
+		jQuery.error( "Invalid JSON: " + data );
527
+	},
528
+
529
+	// Cross-browser xml parsing
530
+	parseXML: function( data ) {
531
+		var xml, tmp;
532
+		if ( !data || typeof data !== "string" ) {
533
+			return null;
534
+		}
535
+		try {
536
+			if ( window.DOMParser ) { // Standard
537
+				tmp = new DOMParser();
538
+				xml = tmp.parseFromString( data , "text/xml" );
539
+			} else { // IE
540
+				xml = new ActiveXObject( "Microsoft.XMLDOM" );
541
+				xml.async = "false";
542
+				xml.loadXML( data );
543
+			}
544
+		} catch( e ) {
545
+			xml = undefined;
546
+		}
547
+		if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
548
+			jQuery.error( "Invalid XML: " + data );
549
+		}
550
+		return xml;
551
+	},
552
+
553
+	noop: function() {},
554
+
555
+	// Evaluates a script in a global context
556
+	// Workarounds based on findings by Jim Driscoll
557
+	// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
558
+	globalEval: function( data ) {
559
+		if ( data && core_rnotwhite.test( data ) ) {
560
+			// We use execScript on Internet Explorer
561
+			// We use an anonymous function so that context is window
562
+			// rather than jQuery in Firefox
563
+			( window.execScript || function( data ) {
564
+				window[ "eval" ].call( window, data );
565
+			} )( data );
566
+		}
567
+	},
568
+
569
+	// Convert dashed to camelCase; used by the css and data modules
570
+	// Microsoft forgot to hump their vendor prefix (#9572)
571
+	camelCase: function( string ) {
572
+		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
573
+	},
574
+
575
+	nodeName: function( elem, name ) {
576
+		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
577
+	},
578
+
579
+	// args is for internal usage only
580
+	each: function( obj, callback, args ) {
581
+		var name,
582
+			i = 0,
583
+			length = obj.length,
584
+			isObj = length === undefined || jQuery.isFunction( obj );
585
+
586
+		if ( args ) {
587
+			if ( isObj ) {
588
+				for ( name in obj ) {
589
+					if ( callback.apply( obj[ name ], args ) === false ) {
590
+						break;
591
+					}
592
+				}
593
+			} else {
594
+				for ( ; i < length; ) {
595
+					if ( callback.apply( obj[ i++ ], args ) === false ) {
596
+						break;
597
+					}
598
+				}
599
+			}
600
+
601
+		// A special, fast, case for the most common use of each
602
+		} else {
603
+			if ( isObj ) {
604
+				for ( name in obj ) {
605
+					if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) {
606
+						break;
607
+					}
608
+				}
609
+			} else {
610
+				for ( ; i < length; ) {
611
+					if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) {
612
+						break;
613
+					}
614
+				}
615
+			}
616
+		}
617
+
618
+		return obj;
619
+	},
620
+
621
+	// Use native String.trim function wherever possible
622
+	trim: core_trim && !core_trim.call("\uFEFF\xA0") ?
623
+		function( text ) {
624
+			return text == null ?
625
+				"" :
626
+				core_trim.call( text );
627
+		} :
628
+
629
+		// Otherwise use our own trimming functionality
630
+		function( text ) {
631
+			return text == null ?
632
+				"" :
633
+				( text + "" ).replace( rtrim, "" );
634
+		},
635
+
636
+	// results is for internal usage only
637
+	makeArray: function( arr, results ) {
638
+		var type,
639
+			ret = results || [];
640
+
641
+		if ( arr != null ) {
642
+			// The window, strings (and functions) also have 'length'
643
+			// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
644
+			type = jQuery.type( arr );
645
+
646
+			if ( arr.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( arr ) ) {
647
+				core_push.call( ret, arr );
648
+			} else {
649
+				jQuery.merge( ret, arr );
650
+			}
651
+		}
652
+
653
+		return ret;
654
+	},
655
+
656
+	inArray: function( elem, arr, i ) {
657
+		var len;
658
+
659
+		if ( arr ) {
660
+			if ( core_indexOf ) {
661
+				return core_indexOf.call( arr, elem, i );
662
+			}
663
+
664
+			len = arr.length;
665
+			i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
666
+
667
+			for ( ; i < len; i++ ) {
668
+				// Skip accessing in sparse arrays
669
+				if ( i in arr && arr[ i ] === elem ) {
670
+					return i;
671
+				}
672
+			}
673
+		}
674
+
675
+		return -1;
676
+	},
677
+
678
+	merge: function( first, second ) {
679
+		var l = second.length,
680
+			i = first.length,
681
+			j = 0;
682
+
683
+		if ( typeof l === "number" ) {
684
+			for ( ; j < l; j++ ) {
685
+				first[ i++ ] = second[ j ];
686
+			}
687
+
688
+		} else {
689
+			while ( second[j] !== undefined ) {
690
+				first[ i++ ] = second[ j++ ];
691
+			}
692
+		}
693
+
694
+		first.length = i;
695
+
696
+		return first;
697
+	},
698
+
699
+	grep: function( elems, callback, inv ) {
700
+		var retVal,
701
+			ret = [],
702
+			i = 0,
703
+			length = elems.length;
704
+		inv = !!inv;
705
+
706
+		// Go through the array, only saving the items
707
+		// that pass the validator function
708
+		for ( ; i < length; i++ ) {
709
+			retVal = !!callback( elems[ i ], i );
710
+			if ( inv !== retVal ) {
711
+				ret.push( elems[ i ] );
712
+			}
713
+		}
714
+
715
+		return ret;
716
+	},
717
+
718
+	// arg is for internal usage only
719
+	map: function( elems, callback, arg ) {
720
+		var value, key,
721
+			ret = [],
722
+			i = 0,
723
+			length = elems.length,
724
+			// jquery objects are treated as arrays
725
+			isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
726
+
727
+		// Go through the array, translating each of the items to their
728
+		if ( isArray ) {
729
+			for ( ; i < length; i++ ) {
730
+				value = callback( elems[ i ], i, arg );
731
+
732
+				if ( value != null ) {
733
+					ret[ ret.length ] = value;
734
+				}
735
+			}
736
+
737
+		// Go through every key on the object,
738
+		} else {
739
+			for ( key in elems ) {
740
+				value = callback( elems[ key ], key, arg );
741
+
742
+				if ( value != null ) {
743
+					ret[ ret.length ] = value;
744
+				}
745
+			}
746
+		}
747
+
748
+		// Flatten any nested arrays
749
+		return ret.concat.apply( [], ret );
750
+	},
751
+
752
+	// A global GUID counter for objects
753
+	guid: 1,
754
+
755
+	// Bind a function to a context, optionally partially applying any
756
+	// arguments.
757
+	proxy: function( fn, context ) {
758
+		var tmp, args, proxy;
759
+
760
+		if ( typeof context === "string" ) {
761
+			tmp = fn[ context ];
762
+			context = fn;
763
+			fn = tmp;
764
+		}
765
+
766
+		// Quick check to determine if target is callable, in the spec
767
+		// this throws a TypeError, but we will just return undefined.
768
+		if ( !jQuery.isFunction( fn ) ) {
769
+			return undefined;
770
+		}
771
+
772
+		// Simulated bind
773
+		args = core_slice.call( arguments, 2 );
774
+		proxy = function() {
775
+			return fn.apply( context, args.concat( core_slice.call( arguments ) ) );
776
+		};
777
+
778
+		// Set the guid of unique handler to the same of original handler, so it can be removed
779
+		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
780
+
781
+		return proxy;
782
+	},
783
+
784
+	// Multifunctional method to get and set values of a collection
785
+	// The value/s can optionally be executed if it's a function
786
+	access: function( elems, fn, key, value, chainable, emptyGet, pass ) {
787
+		var exec,
788
+			bulk = key == null,
789
+			i = 0,
790
+			length = elems.length;
791
+
792
+		// Sets many values
793
+		if ( key && typeof key === "object" ) {
794
+			for ( i in key ) {
795
+				jQuery.access( elems, fn, i, key[i], 1, emptyGet, value );
796
+			}
797
+			chainable = 1;
798
+
799
+		// Sets one value
800
+		} else if ( value !== undefined ) {
801
+			// Optionally, function values get executed if exec is true
802
+			exec = pass === undefined && jQuery.isFunction( value );
803
+
804
+			if ( bulk ) {
805
+				// Bulk operations only iterate when executing function values
806
+				if ( exec ) {
807
+					exec = fn;
808
+					fn = function( elem, key, value ) {
809
+						return exec.call( jQuery( elem ), value );
810
+					};
811
+
812
+				// Otherwise they run against the entire set
813
+				} else {
814
+					fn.call( elems, value );
815
+					fn = null;
816
+				}
817
+			}
818
+
819
+			if ( fn ) {
820
+				for (; i < length; i++ ) {
821
+					fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
822
+				}
823
+			}
824
+
825
+			chainable = 1;
826
+		}
827
+
828
+		return chainable ?
829
+			elems :
830
+
831
+			// Gets
832
+			bulk ?
833
+				fn.call( elems ) :
834
+				length ? fn( elems[0], key ) : emptyGet;
835
+	},
836
+
837
+	now: function() {
838
+		return ( new Date() ).getTime();
839
+	}
840
+});
841
+
842
+jQuery.ready.promise = function( obj ) {
843
+	if ( !readyList ) {
844
+
845
+		readyList = jQuery.Deferred();
846
+
847
+		// Catch cases where $(document).ready() is called after the browser event has already occurred.
848
+		// we once tried to use readyState "interactive" here, but it caused issues like the one
849
+		// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
850
+		if ( document.readyState === "complete" ) {
851
+			// Handle it asynchronously to allow scripts the opportunity to delay ready
852
+			setTimeout( jQuery.ready, 1 );
853
+
854
+		// Standards-based browsers support DOMContentLoaded
855
+		} else if ( document.addEventListener ) {
856
+			// Use the handy event callback
857
+			document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
858
+
859
+			// A fallback to window.onload, that will always work
860
+			window.addEventListener( "load", jQuery.ready, false );
861
+
862
+		// If IE event model is used
863
+		} else {
864
+			// Ensure firing before onload, maybe late but safe also for iframes
865
+			document.attachEvent( "onreadystatechange", DOMContentLoaded );
866
+
867
+			// A fallback to window.onload, that will always work
868
+			window.attachEvent( "onload", jQuery.ready );
869
+
870
+			// If IE and not a frame
871
+			// continually check to see if the document is ready
872
+			var top = false;
873
+
874
+			try {
875
+				top = window.frameElement == null && document.documentElement;
876
+			} catch(e) {}
877
+
878
+			if ( top && top.doScroll ) {
879
+				(function doScrollCheck() {
880
+					if ( !jQuery.isReady ) {
881
+
882
+						try {
883
+							// Use the trick by Diego Perini
884
+							// http://javascript.nwbox.com/IEContentLoaded/
885
+							top.doScroll("left");
886
+						} catch(e) {
887
+							return setTimeout( doScrollCheck, 50 );
888
+						}
889
+
890
+						// and execute any waiting functions
891
+						jQuery.ready();
892
+					}
893
+				})();
894
+			}
895
+		}
896
+	}
897
+	return readyList.promise( obj );
898
+};
899
+
900
+// Populate the class2type map
901
+jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
902
+	class2type[ "[object " + name + "]" ] = name.toLowerCase();
903
+});
904
+
905
+// All jQuery objects should point back to these
906
+rootjQuery = jQuery(document);
907
+// String to Object options format cache
908
+var optionsCache = {};
909
+
910
+// Convert String-formatted options into Object-formatted ones and store in cache
911
+function createOptions( options ) {
912
+	var object = optionsCache[ options ] = {};
913
+	jQuery.each( options.split( core_rspace ), function( _, flag ) {
914
+		object[ flag ] = true;
915
+	});
916
+	return object;
917
+}
918
+
919
+/*
920
+ * Create a callback list using the following parameters:
921
+ *
922
+ *	options: an optional list of space-separated options that will change how
923
+ *			the callback list behaves or a more traditional option object
924
+ *
925
+ * By default a callback list will act like an event callback list and can be
926
+ * "fired" multiple times.
927
+ *
928
+ * Possible options:
929
+ *
930
+ *	once:			will ensure the callback list can only be fired once (like a Deferred)
931
+ *
932
+ *	memory:			will keep track of previous values and will call any callback added
933
+ *					after the list has been fired right away with the latest "memorized"
934
+ *					values (like a Deferred)
935
+ *
936
+ *	unique:			will ensure a callback can only be added once (no duplicate in the list)
937
+ *
938
+ *	stopOnFalse:	interrupt callings when a callback returns false
939
+ *
940
+ */
941
+jQuery.Callbacks = function( options ) {
942
+
943
+	// Convert options from String-formatted to Object-formatted if needed
944
+	// (we check in cache first)
945
+	options = typeof options === "string" ?
946
+		( optionsCache[ options ] || createOptions( options ) ) :
947
+		jQuery.extend( {}, options );
948
+
949
+	var // Last fire value (for non-forgettable lists)
950
+		memory,
951
+		// Flag to know if list was already fired
952
+		fired,
953
+		// Flag to know if list is currently firing
954
+		firing,
955
+		// First callback to fire (used internally by add and fireWith)
956
+		firingStart,
957
+		// End of the loop when firing
958
+		firingLength,
959
+		// Index of currently firing callback (modified by remove if needed)
960
+		firingIndex,
961
+		// Actual callback list
962
+		list = [],
963
+		// Stack of fire calls for repeatable lists
964
+		stack = !options.once && [],
965
+		// Fire callbacks
966
+		fire = function( data ) {
967
+			memory = options.memory && data;
968
+			fired = true;
969
+			firingIndex = firingStart || 0;
970
+			firingStart = 0;
971
+			firingLength = list.length;
972
+			firing = true;
973
+			for ( ; list && firingIndex < firingLength; firingIndex++ ) {
974
+				if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
975
+					memory = false; // To prevent further calls using add
976
+					break;
977
+				}
978
+			}
979
+			firing = false;
980
+			if ( list ) {
981
+				if ( stack ) {
982
+					if ( stack.length ) {
983
+						fire( stack.shift() );
984
+					}
985
+				} else if ( memory ) {
986
+					list = [];
987
+				} else {
988
+					self.disable();
989
+				}
990
+			}
991
+		},
992
+		// Actual Callbacks object
993
+		self = {
994
+			// Add a callback or a collection of callbacks to the list
995
+			add: function() {
996
+				if ( list ) {
997
+					// First, we save the current length
998
+					var start = list.length;
999
+					(function add( args ) {
1000
+						jQuery.each( args, function( _, arg ) {
1001
+							var type = jQuery.type( arg );
1002
+							if ( type === "function" ) {
1003
+								if ( !options.unique || !self.has( arg ) ) {
1004
+									list.push( arg );
1005
+								}
1006
+							} else if ( arg && arg.length && type !== "string" ) {
1007
+								// Inspect recursively
1008
+								add( arg );
1009
+							}
1010
+						});
1011
+					})( arguments );
1012
+					// Do we need to add the callbacks to the
1013
+					// current firing batch?
1014
+					if ( firing ) {
1015
+						firingLength = list.length;
1016
+					// With memory, if we're not firing then
1017
+					// we should call right away
1018
+					} else if ( memory ) {
1019
+						firingStart = start;
1020
+						fire( memory );
1021
+					}
1022
+				}
1023
+				return this;
1024
+			},
1025
+			// Remove a callback from the list
1026
+			remove: function() {
1027
+				if ( list ) {
1028
+					jQuery.each( arguments, function( _, arg ) {
1029
+						var index;
1030
+						while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
1031
+							list.splice( index, 1 );
1032
+							// Handle firing indexes
1033
+							if ( firing ) {
1034
+								if ( index <= firingLength ) {
1035
+									firingLength--;
1036
+								}
1037
+								if ( index <= firingIndex ) {
1038
+									firingIndex--;
1039
+								}
1040
+							}
1041
+						}
1042
+					});
1043
+				}
1044
+				return this;
1045
+			},
1046
+			// Control if a given callback is in the list
1047
+			has: function( fn ) {
1048
+				return jQuery.inArray( fn, list ) > -1;
1049
+			},
1050
+			// Remove all callbacks from the list
1051
+			empty: function() {
1052
+				list = [];
1053
+				return this;
1054
+			},
1055
+			// Have the list do nothing anymore
1056
+			disable: function() {
1057
+				list = stack = memory = undefined;
1058
+				return this;
1059
+			},
1060
+			// Is it disabled?
1061
+			disabled: function() {
1062
+				return !list;
1063
+			},
1064
+			// Lock the list in its current state
1065
+			lock: function() {
1066
+				stack = undefined;
1067
+				if ( !memory ) {
1068
+					self.disable();
1069
+				}
1070
+				return this;
1071
+			},
1072
+			// Is it locked?
1073
+			locked: function() {
1074
+				return !stack;
1075
+			},
1076
+			// Call all callbacks with the given context and arguments
1077
+			fireWith: function( context, args ) {
1078
+				args = args || [];
1079
+				args = [ context, args.slice ? args.slice() : args ];
1080
+				if ( list && ( !fired || stack ) ) {
1081
+					if ( firing ) {
1082
+						stack.push( args );
1083
+					} else {
1084
+						fire( args );
1085
+					}
1086
+				}
1087
+				return this;
1088
+			},
1089
+			// Call all the callbacks with the given arguments
1090
+			fire: function() {
1091
+				self.fireWith( this, arguments );
1092
+				return this;
1093
+			},
1094
+			// To know if the callbacks have already been called at least once
1095
+			fired: function() {
1096
+				return !!fired;
1097
+			}
1098
+		};
1099
+
1100
+	return self;
1101
+};
1102
+jQuery.extend({
1103
+
1104
+	Deferred: function( func ) {
1105
+		var tuples = [
1106
+				// action, add listener, listener list, final state
1107
+				[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
1108
+				[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
1109
+				[ "notify", "progress", jQuery.Callbacks("memory") ]
1110
+			],
1111
+			state = "pending",
1112
+			promise = {
1113
+				state: function() {
1114
+					return state;
1115
+				},
1116
+				always: function() {
1117
+					deferred.done( arguments ).fail( arguments );
1118
+					return this;
1119
+				},
1120
+				then: function( /* fnDone, fnFail, fnProgress */ ) {
1121
+					var fns = arguments;
1122
+					return jQuery.Deferred(function( newDefer ) {
1123
+						jQuery.each( tuples, function( i, tuple ) {
1124
+							var action = tuple[ 0 ],
1125
+								fn = fns[ i ];
1126
+							// deferred[ done | fail | progress ] for forwarding actions to newDefer
1127
+							deferred[ tuple[1] ]( jQuery.isFunction( fn ) ?
1128
+								function() {
1129
+									var returned = fn.apply( this, arguments );
1130
+									if ( returned && jQuery.isFunction( returned.promise ) ) {
1131
+										returned.promise()
1132
+											.done( newDefer.resolve )
1133
+											.fail( newDefer.reject )
1134
+											.progress( newDefer.notify );
1135
+									} else {
1136
+										newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
1137
+									}
1138
+								} :
1139
+								newDefer[ action ]
1140
+							);
1141
+						});
1142
+						fns = null;
1143
+					}).promise();
1144
+				},
1145
+				// Get a promise for this deferred
1146
+				// If obj is provided, the promise aspect is added to the object
1147
+				promise: function( obj ) {
1148
+					return obj != null ? jQuery.extend( obj, promise ) : promise;
1149
+				}
1150
+			},
1151
+			deferred = {};
1152
+
1153
+		// Keep pipe for back-compat
1154
+		promise.pipe = promise.then;
1155
+
1156
+		// Add list-specific methods
1157
+		jQuery.each( tuples, function( i, tuple ) {
1158
+			var list = tuple[ 2 ],
1159
+				stateString = tuple[ 3 ];
1160
+
1161
+			// promise[ done | fail | progress ] = list.add
1162
+			promise[ tuple[1] ] = list.add;
1163
+
1164
+			// Handle state
1165
+			if ( stateString ) {
1166
+				list.add(function() {
1167
+					// state = [ resolved | rejected ]
1168
+					state = stateString;
1169
+
1170
+				// [ reject_list | resolve_list ].disable; progress_list.lock
1171
+				}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
1172
+			}
1173
+
1174
+			// deferred[ resolve | reject | notify ] = list.fire
1175
+			deferred[ tuple[0] ] = list.fire;
1176
+			deferred[ tuple[0] + "With" ] = list.fireWith;
1177
+		});
1178
+
1179
+		// Make the deferred a promise
1180
+		promise.promise( deferred );
1181
+
1182
+		// Call given func if any
1183
+		if ( func ) {
1184
+			func.call( deferred, deferred );
1185
+		}
1186
+
1187
+		// All done!
1188
+		return deferred;
1189
+	},
1190
+
1191
+	// Deferred helper
1192
+	when: function( subordinate /* , ..., subordinateN */ ) {
1193
+		var i = 0,
1194
+			resolveValues = core_slice.call( arguments ),
1195
+			length = resolveValues.length,
1196
+
1197
+			// the count of uncompleted subordinates
1198
+			remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
1199
+
1200
+			// the master Deferred. If resolveValues consist of only a single Deferred, just use that.
1201
+			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
1202
+
1203
+			// Update function for both resolve and progress values
1204
+			updateFunc = function( i, contexts, values ) {
1205
+				return function( value ) {
1206
+					contexts[ i ] = this;
1207
+					values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
1208
+					if( values === progressValues ) {
1209
+						deferred.notifyWith( contexts, values );
1210
+					} else if ( !( --remaining ) ) {
1211
+						deferred.resolveWith( contexts, values );
1212
+					}
1213
+				};
1214
+			},
1215
+
1216
+			progressValues, progressContexts, resolveContexts;
1217
+
1218
+		// add listeners to Deferred subordinates; treat others as resolved
1219
+		if ( length > 1 ) {
1220
+			progressValues = new Array( length );
1221
+			progressContexts = new Array( length );
1222
+			resolveContexts = new Array( length );
1223
+			for ( ; i < length; i++ ) {
1224
+				if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
1225
+					resolveValues[ i ].promise()
1226
+						.done( updateFunc( i, resolveContexts, resolveValues ) )
1227
+						.fail( deferred.reject )
1228
+						.progress( updateFunc( i, progressContexts, progressValues ) );
1229
+				} else {
1230
+					--remaining;
1231
+				}
1232
+			}
1233
+		}
1234
+
1235
+		// if we're not waiting on anything, resolve the master
1236
+		if ( !remaining ) {
1237
+			deferred.resolveWith( resolveContexts, resolveValues );
1238
+		}
1239
+
1240
+		return deferred.promise();
1241
+	}
1242
+});
1243
+jQuery.support = (function() {
1244
+
1245
+	var support,
1246
+		all,
1247
+		a,
1248
+		select,
1249
+		opt,
1250
+		input,
1251
+		fragment,
1252
+		eventName,
1253
+		i,
1254
+		isSupported,
1255
+		clickFn,
1256
+		div = document.createElement("div");
1257
+
1258
+	// Setup
1259
+	div.setAttribute( "className", "t" );
1260
+	div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
1261
+
1262
+	// Support tests won't run in some limited or non-browser environments
1263
+	all = div.getElementsByTagName("*");
1264
+	a = div.getElementsByTagName("a")[ 0 ];
1265
+	if ( !all || !a || !all.length ) {
1266
+		return {};
1267
+	}
1268
+
1269
+	// First batch of tests
1270
+	select = document.createElement("select");
1271
+	opt = select.appendChild( document.createElement("option") );
1272
+	input = div.getElementsByTagName("input")[ 0 ];
1273
+
1274
+	a.style.cssText = "top:1px;float:left;opacity:.5";
1275
+	support = {
1276
+		// IE strips leading whitespace when .innerHTML is used
1277
+		leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1278
+
1279
+		// Make sure that tbody elements aren't automatically inserted
1280
+		// IE will insert them into empty tables
1281
+		tbody: !div.getElementsByTagName("tbody").length,
1282
+
1283
+		// Make sure that link elements get serialized correctly by innerHTML
1284
+		// This requires a wrapper element in IE
1285
+		htmlSerialize: !!div.getElementsByTagName("link").length,
1286
+
1287
+		// Get the style information from getAttribute
1288
+		// (IE uses .cssText instead)
1289
+		style: /top/.test( a.getAttribute("style") ),
1290
+
1291
+		// Make sure that URLs aren't manipulated
1292
+		// (IE normalizes it by default)
1293
+		hrefNormalized: ( a.getAttribute("href") === "/a" ),
1294
+
1295
+		// Make sure that element opacity exists
1296
+		// (IE uses filter instead)
1297
+		// Use a regex to work around a WebKit issue. See #5145
1298
+		opacity: /^0.5/.test( a.style.opacity ),
1299
+
1300
+		// Verify style float existence
1301
+		// (IE uses styleFloat instead of cssFloat)
1302
+		cssFloat: !!a.style.cssFloat,
1303
+
1304
+		// Make sure that if no value is specified for a checkbox
1305
+		// that it defaults to "on".
1306
+		// (WebKit defaults to "" instead)
1307
+		checkOn: ( input.value === "on" ),
1308
+
1309
+		// Make sure that a selected-by-default option has a working selected property.
1310
+		// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1311
+		optSelected: opt.selected,
1312
+
1313
+		// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1314
+		getSetAttribute: div.className !== "t",
1315
+
1316
+		// Tests for enctype support on a form (#6743)
1317
+		enctype: !!document.createElement("form").enctype,
1318
+
1319
+		// Makes sure cloning an html5 element does not cause problems
1320
+		// Where outerHTML is undefined, this still works
1321
+		html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>",
1322
+
1323
+		// jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode
1324
+		boxModel: ( document.compatMode === "CSS1Compat" ),
1325
+
1326
+		// Will be defined later
1327
+		submitBubbles: true,
1328
+		changeBubbles: true,
1329
+		focusinBubbles: false,
1330
+		deleteExpando: true,
1331
+		noCloneEvent: true,
1332
+		inlineBlockNeedsLayout: false,
1333
+		shrinkWrapBlocks: false,
1334
+		reliableMarginRight: true,
1335
+		boxSizingReliable: true,
1336
+		pixelPosition: false
1337
+	};
1338
+
1339
+	// Make sure checked status is properly cloned
1340
+	input.checked = true;
1341
+	support.noCloneChecked = input.cloneNode( true ).checked;
1342
+
1343
+	// Make sure that the options inside disabled selects aren't marked as disabled
1344
+	// (WebKit marks them as disabled)
1345
+	select.disabled = true;
1346
+	support.optDisabled = !opt.disabled;
1347
+
1348
+	// Test to see if it's possible to delete an expando from an element
1349
+	// Fails in Internet Explorer
1350
+	try {
1351
+		delete div.test;
1352
+	} catch( e ) {
1353
+		support.deleteExpando = false;
1354
+	}
1355
+
1356
+	if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1357
+		div.attachEvent( "onclick", clickFn = function() {
1358
+			// Cloning a node shouldn't copy over any
1359
+			// bound event handlers (IE does this)
1360
+			support.noCloneEvent = false;
1361
+		});
1362
+		div.cloneNode( true ).fireEvent("onclick");
1363
+		div.detachEvent( "onclick", clickFn );
1364
+	}
1365
+
1366
+	// Check if a radio maintains its value
1367
+	// after being appended to the DOM
1368
+	input = document.createElement("input");
1369
+	input.value = "t";
1370
+	input.setAttribute( "type", "radio" );
1371
+	support.radioValue = input.value === "t";
1372
+
1373
+	input.setAttribute( "checked", "checked" );
1374
+
1375
+	// #11217 - WebKit loses check when the name is after the checked attribute
1376
+	input.setAttribute( "name", "t" );
1377
+
1378
+	div.appendChild( input );
1379
+	fragment = document.createDocumentFragment();
1380
+	fragment.appendChild( div.lastChild );
1381
+
1382
+	// WebKit doesn't clone checked state correctly in fragments
1383
+	support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1384
+
1385
+	// Check if a disconnected checkbox will retain its checked
1386
+	// value of true after appended to the DOM (IE6/7)
1387
+	support.appendChecked = input.checked;
1388
+
1389
+	fragment.removeChild( input );
1390
+	fragment.appendChild( div );
1391
+
1392
+	// Technique from Juriy Zaytsev
1393
+	// http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
1394
+	// We only care about the case where non-standard event systems
1395
+	// are used, namely in IE. Short-circuiting here helps us to
1396
+	// avoid an eval call (in setAttribute) which can cause CSP
1397
+	// to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1398
+	if ( div.attachEvent ) {
1399
+		for ( i in {
1400
+			submit: true,
1401
+			change: true,
1402
+			focusin: true
1403
+		}) {
1404
+			eventName = "on" + i;
1405
+			isSupported = ( eventName in div );
1406
+			if ( !isSupported ) {
1407
+				div.setAttribute( eventName, "return;" );
1408
+				isSupported = ( typeof div[ eventName ] === "function" );
1409
+			}
1410
+			support[ i + "Bubbles" ] = isSupported;
1411
+		}
1412
+	}
1413
+
1414
+	// Run tests that need a body at doc ready
1415
+	jQuery(function() {
1416
+		var container, div, tds, marginDiv,
1417
+			divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;",
1418
+			body = document.getElementsByTagName("body")[0];
1419
+
1420
+		if ( !body ) {
1421
+			// Return for frameset docs that don't have a body
1422
+			return;
1423
+		}
1424
+
1425
+		container = document.createElement("div");
1426
+		container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px";
1427
+		body.insertBefore( container, body.firstChild );
1428
+
1429
+		// Construct the test element
1430
+		div = document.createElement("div");
1431
+		container.appendChild( div );
1432
+
1433
+		// Check if table cells still have offsetWidth/Height when they are set
1434
+		// to display:none and there are still other visible table cells in a
1435
+		// table row; if so, offsetWidth/Height are not reliable for use when
1436
+		// determining if an element has been hidden directly using
1437
+		// display:none (it is still safe to use offsets if a parent element is
1438
+		// hidden; don safety goggles and see bug #4512 for more information).
1439
+		// (only IE 8 fails this test)
1440
+		div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
1441
+		tds = div.getElementsByTagName("td");
1442
+		tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none";
1443
+		isSupported = ( tds[ 0 ].offsetHeight === 0 );
1444
+
1445
+		tds[ 0 ].style.display = "";
1446
+		tds[ 1 ].style.display = "none";
1447
+
1448
+		// Check if empty table cells still have offsetWidth/Height
1449
+		// (IE <= 8 fail this test)
1450
+		support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1451
+
1452
+		// Check box-sizing and margin behavior
1453
+		div.innerHTML = "";
1454
+		div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";
1455
+		support.boxSizing = ( div.offsetWidth === 4 );
1456
+		support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );
1457
+
1458
+		// NOTE: To any future maintainer, we've window.getComputedStyle
1459
+		// because jsdom on node.js will break without it.
1460
+		if ( window.getComputedStyle ) {
1461
+			support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
1462
+			support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
1463
+
1464
+			// Check if div with explicit width and no margin-right incorrectly
1465
+			// gets computed margin-right based on width of container. For more
1466
+			// info see bug #3333
1467
+			// Fails in WebKit before Feb 2011 nightlies
1468
+			// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1469
+			marginDiv = document.createElement("div");
1470
+			marginDiv.style.cssText = div.style.cssText = divReset;
1471
+			marginDiv.style.marginRight = marginDiv.style.width = "0";
1472
+			div.style.width = "1px";
1473
+			div.appendChild( marginDiv );
1474
+			support.reliableMarginRight =
1475
+				!parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
1476
+		}
1477
+
1478
+		if ( typeof div.style.zoom !== "undefined" ) {
1479
+			// Check if natively block-level elements act like inline-block
1480
+			// elements when setting their display to 'inline' and giving
1481
+			// them layout
1482
+			// (IE < 8 does this)
1483
+			div.innerHTML = "";
1484
+			div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1";
1485
+			support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
1486
+
1487
+			// Check if elements with layout shrink-wrap their children
1488
+			// (IE 6 does this)
1489
+			div.style.display = "block";
1490
+			div.style.overflow = "visible";
1491
+			div.innerHTML = "<div></div>";
1492
+			div.firstChild.style.width = "5px";
1493
+			support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
1494
+
1495
+			container.style.zoom = 1;
1496
+		}
1497
+
1498
+		// Null elements to avoid leaks in IE
1499
+		body.removeChild( container );
1500
+		container = div = tds = marginDiv = null;
1501
+	});
1502
+
1503
+	// Null elements to avoid leaks in IE
1504
+	fragment.removeChild( div );
1505
+	all = a = select = opt = input = fragment = div = null;
1506
+
1507
+	return support;
1508
+})();
1509
+var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
1510
+	rmultiDash = /([A-Z])/g;
1511
+
1512
+jQuery.extend({
1513
+	cache: {},
1514
+
1515
+	deletedIds: [],
1516
+
1517
+	// Remove at next major release (1.9/2.0)
1518
+	uuid: 0,
1519
+
1520
+	// Unique for each copy of jQuery on the page
1521
+	// Non-digits removed to match rinlinejQuery
1522
+	expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1523
+
1524
+	// The following elements throw uncatchable exceptions if you
1525
+	// attempt to add expando properties to them.
1526
+	noData: {
1527
+		"embed": true,
1528
+		// Ban all objects except for Flash (which handle expandos)
1529
+		"object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1530
+		"applet": true
1531
+	},
1532
+
1533
+	hasData: function( elem ) {
1534
+		elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1535
+		return !!elem && !isEmptyDataObject( elem );
1536
+	},
1537
+
1538
+	data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1539
+		if ( !jQuery.acceptData( elem ) ) {
1540
+			return;
1541
+		}
1542
+
1543
+		var thisCache, ret,
1544
+			internalKey = jQuery.expando,
1545
+			getByName = typeof name === "string",
1546
+
1547
+			// We have to handle DOM nodes and JS objects differently because IE6-7
1548
+			// can't GC object references properly across the DOM-JS boundary
1549
+			isNode = elem.nodeType,
1550
+
1551
+			// Only DOM nodes need the global jQuery cache; JS object data is
1552
+			// attached directly to the object so GC can occur automatically
1553
+			cache = isNode ? jQuery.cache : elem,
1554
+
1555
+			// Only defining an ID for JS objects if its cache already exists allows
1556
+			// the code to shortcut on the same path as a DOM node with no cache
1557
+			id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
1558
+
1559
+		// Avoid doing any more work than we need to when trying to get data on an
1560
+		// object that has no data at all
1561
+		if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) {
1562
+			return;
1563
+		}
1564
+
1565
+		if ( !id ) {
1566
+			// Only DOM nodes need a new unique ID for each element since their data
1567
+			// ends up in the global cache
1568
+			if ( isNode ) {
1569
+				elem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++;
1570
+			} else {
1571
+				id = internalKey;
1572
+			}
1573
+		}
1574
+
1575
+		if ( !cache[ id ] ) {
1576
+			cache[ id ] = {};
1577
+
1578
+			// Avoids exposing jQuery metadata on plain JS objects when the object
1579
+			// is serialized using JSON.stringify
1580
+			if ( !isNode ) {
1581
+				cache[ id ].toJSON = jQuery.noop;
1582
+			}
1583
+		}
1584
+
1585
+		// An object can be passed to jQuery.data instead of a key/value pair; this gets
1586
+		// shallow copied over onto the existing cache
1587
+		if ( typeof name === "object" || typeof name === "function" ) {
1588
+			if ( pvt ) {
1589
+				cache[ id ] = jQuery.extend( cache[ id ], name );
1590
+			} else {
1591
+				cache[ id ].data = jQuery.extend( cache[ id ].data, name );
1592
+			}
1593
+		}
1594
+
1595
+		thisCache = cache[ id ];
1596
+
1597
+		// jQuery data() is stored in a separate object inside the object's internal data
1598
+		// cache in order to avoid key collisions between internal data and user-defined
1599
+		// data.
1600
+		if ( !pvt ) {
1601
+			if ( !thisCache.data ) {
1602
+				thisCache.data = {};
1603
+			}
1604
+
1605
+			thisCache = thisCache.data;
1606
+		}
1607
+
1608
+		if ( data !== undefined ) {
1609
+			thisCache[ jQuery.camelCase( name ) ] = data;
1610
+		}
1611
+
1612
+		// Check for both converted-to-camel and non-converted data property names
1613
+		// If a data property was specified
1614
+		if ( getByName ) {
1615
+
1616
+			// First Try to find as-is property data
1617
+			ret = thisCache[ name ];
1618
+
1619
+			// Test for null|undefined property data
1620
+			if ( ret == null ) {
1621
+
1622
+				// Try to find the camelCased property
1623
+				ret = thisCache[ jQuery.camelCase( name ) ];
1624
+			}
1625
+		} else {
1626
+			ret = thisCache;
1627
+		}
1628
+
1629
+		return ret;
1630
+	},
1631
+
1632
+	removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1633
+		if ( !jQuery.acceptData( elem ) ) {
1634
+			return;
1635
+		}
1636
+
1637
+		var thisCache, i, l,
1638
+
1639
+			isNode = elem.nodeType,
1640
+
1641
+			// See jQuery.data for more information
1642
+			cache = isNode ? jQuery.cache : elem,
1643
+			id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
1644
+
1645
+		// If there is already no cache entry for this object, there is no
1646
+		// purpose in continuing
1647
+		if ( !cache[ id ] ) {
1648
+			return;
1649
+		}
1650
+
1651
+		if ( name ) {
1652
+
1653
+			thisCache = pvt ? cache[ id ] : cache[ id ].data;
1654
+
1655
+			if ( thisCache ) {
1656
+
1657
+				// Support array or space separated string names for data keys
1658
+				if ( !jQuery.isArray( name ) ) {
1659
+
1660
+					// try the string as a key before any manipulation
1661
+					if ( name in thisCache ) {
1662
+						name = [ name ];
1663
+					} else {
1664
+
1665
+						// split the camel cased version by spaces unless a key with the spaces exists
1666
+						name = jQuery.camelCase( name );
1667
+						if ( name in thisCache ) {
1668
+							name = [ name ];
1669
+						} else {
1670
+							name = name.split(" ");
1671
+						}
1672
+					}
1673
+				}
1674
+
1675
+				for ( i = 0, l = name.length; i < l; i++ ) {
1676
+					delete thisCache[ name[i] ];
1677
+				}
1678
+
1679
+				// If there is no data left in the cache, we want to continue
1680
+				// and let the cache object itself get destroyed
1681
+				if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {
1682
+					return;
1683
+				}
1684
+			}
1685
+		}
1686
+
1687
+		// See jQuery.data for more information
1688
+		if ( !pvt ) {
1689
+			delete cache[ id ].data;
1690
+
1691
+			// Don't destroy the parent cache unless the internal data object
1692
+			// had been the only thing left in it
1693
+			if ( !isEmptyDataObject( cache[ id ] ) ) {
1694
+				return;
1695
+			}
1696
+		}
1697
+
1698
+		// Destroy the cache
1699
+		if ( isNode ) {
1700
+			jQuery.cleanData( [ elem ], true );
1701
+
1702
+		// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
1703
+		} else if ( jQuery.support.deleteExpando || cache != cache.window ) {
1704
+			delete cache[ id ];
1705
+
1706
+		// When all else fails, null
1707
+		} else {
1708
+			cache[ id ] = null;
1709
+		}
1710
+	},
1711
+
1712
+	// For internal use only.
1713
+	_data: function( elem, name, data ) {
1714
+		return jQuery.data( elem, name, data, true );
1715
+	},
1716
+
1717
+	// A method for determining if a DOM node can handle the data expando
1718
+	acceptData: function( elem ) {
1719
+		var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];
1720
+
1721
+		// nodes accept data unless otherwise specified; rejection can be conditional
1722
+		return !noData || noData !== true && elem.getAttribute("classid") === noData;
1723
+	}
1724
+});
1725
+
1726
+jQuery.fn.extend({
1727
+	data: function( key, value ) {
1728
+		var parts, part, attr, name, l,
1729
+			elem = this[0],
1730
+			i = 0,
1731
+			data = null;
1732
+
1733
+		// Gets all values
1734
+		if ( key === undefined ) {
1735
+			if ( this.length ) {
1736
+				data = jQuery.data( elem );
1737
+
1738
+				if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
1739
+					attr = elem.attributes;
1740
+					for ( l = attr.length; i < l; i++ ) {
1741
+						name = attr[i].name;
1742
+
1743
+						if ( !name.indexOf( "data-" ) ) {
1744
+							name = jQuery.camelCase( name.substring(5) );
1745
+
1746
+							dataAttr( elem, name, data[ name ] );
1747
+						}
1748
+					}
1749
+					jQuery._data( elem, "parsedAttrs", true );
1750
+				}
1751
+			}
1752
+
1753
+			return data;
1754
+		}
1755
+
1756
+		// Sets multiple values
1757
+		if ( typeof key === "object" ) {
1758
+			return this.each(function() {
1759
+				jQuery.data( this, key );
1760
+			});
1761
+		}
1762
+
1763
+		parts = key.split( ".", 2 );
1764
+		parts[1] = parts[1] ? "." + parts[1] : "";
1765
+		part = parts[1] + "!";
1766
+
1767
+		return jQuery.access( this, function( value ) {
1768
+
1769
+			if ( value === undefined ) {
1770
+				data = this.triggerHandler( "getData" + part, [ parts[0] ] );
1771
+
1772
+				// Try to fetch any internally stored data first
1773
+				if ( data === undefined && elem ) {
1774
+					data = jQuery.data( elem, key );
1775
+					data = dataAttr( elem, key, data );
1776
+				}
1777
+
1778
+				return data === undefined && parts[1] ?
1779
+					this.data( parts[0] ) :
1780
+					data;
1781
+			}
1782
+
1783
+			parts[1] = value;
1784
+			this.each(function() {
1785
+				var self = jQuery( this );
1786
+
1787
+				self.triggerHandler( "setData" + part, parts );
1788
+				jQuery.data( this, key, value );
1789
+				self.triggerHandler( "changeData" + part, parts );
1790
+			});
1791
+		}, null, value, arguments.length > 1, null, false );
1792
+	},
1793
+
1794
+	removeData: function( key ) {
1795
+		return this.each(function() {
1796
+			jQuery.removeData( this, key );
1797
+		});
1798
+	}
1799
+});
1800
+
1801
+function dataAttr( elem, key, data ) {
1802
+	// If nothing was found internally, try to fetch any
1803
+	// data from the HTML5 data-* attribute
1804
+	if ( data === undefined && elem.nodeType === 1 ) {
1805
+
1806
+		var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
1807
+
1808
+		data = elem.getAttribute( name );
1809
+
1810
+		if ( typeof data === "string" ) {
1811
+			try {
1812
+				data = data === "true" ? true :
1813
+				data === "false" ? false :
1814
+				data === "null" ? null :
1815
+				// Only convert to a number if it doesn't change the string
1816
+				+data + "" === data ? +data :
1817
+				rbrace.test( data ) ? jQuery.parseJSON( data ) :
1818
+					data;
1819
+			} catch( e ) {}
1820
+
1821
+			// Make sure we set the data so it isn't changed later
1822
+			jQuery.data( elem, key, data );
1823
+
1824
+		} else {
1825
+			data = undefined;
1826
+		}
1827
+	}
1828
+
1829
+	return data;
1830
+}
1831
+
1832
+// checks a cache object for emptiness
1833
+function isEmptyDataObject( obj ) {
1834
+	var name;
1835
+	for ( name in obj ) {
1836
+
1837
+		// if the public data object is empty, the private is still empty
1838
+		if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
1839
+			continue;
1840
+		}
1841
+		if ( name !== "toJSON" ) {
1842
+			return false;
1843
+		}
1844
+	}
1845
+
1846
+	return true;
1847
+}
1848
+jQuery.extend({
1849
+	queue: function( elem, type, data ) {
1850
+		var queue;
1851
+
1852
+		if ( elem ) {
1853
+			type = ( type || "fx" ) + "queue";
1854
+			queue = jQuery._data( elem, type );
1855
+
1856
+			// Speed up dequeue by getting out quickly if this is just a lookup
1857
+			if ( data ) {
1858
+				if ( !queue || jQuery.isArray(data) ) {
1859
+					queue = jQuery._data( elem, type, jQuery.makeArray(data) );
1860
+				} else {
1861
+					queue.push( data );
1862
+				}
1863
+			}
1864
+			return queue || [];
1865
+		}
1866
+	},
1867
+
1868
+	dequeue: function( elem, type ) {
1869
+		type = type || "fx";
1870
+
1871
+		var queue = jQuery.queue( elem, type ),
1872
+			startLength = queue.length,
1873
+			fn = queue.shift(),
1874
+			hooks = jQuery._queueHooks( elem, type ),
1875
+			next = function() {
1876
+				jQuery.dequeue( elem, type );
1877
+			};
1878
+
1879
+		// If the fx queue is dequeued, always remove the progress sentinel
1880
+		if ( fn === "inprogress" ) {
1881
+			fn = queue.shift();
1882
+			startLength--;
1883
+		}
1884
+
1885
+		if ( fn ) {
1886
+
1887
+			// Add a progress sentinel to prevent the fx queue from being
1888
+			// automatically dequeued
1889
+			if ( type === "fx" ) {
1890
+				queue.unshift( "inprogress" );
1891
+			}
1892
+
1893
+			// clear up the last queue stop function
1894
+			delete hooks.stop;
1895
+			fn.call( elem, next, hooks );
1896
+		}
1897
+
1898
+		if ( !startLength && hooks ) {
1899
+			hooks.empty.fire();
1900
+		}
1901
+	},
1902
+
1903
+	// not intended for public consumption - generates a queueHooks object, or returns the current one
1904
+	_queueHooks: function( elem, type ) {
1905
+		var key = type + "queueHooks";
1906
+		return jQuery._data( elem, key ) || jQuery._data( elem, key, {
1907
+			empty: jQuery.Callbacks("once memory").add(function() {
1908
+				jQuery.removeData( elem, type + "queue", true );
1909
+				jQuery.removeData( elem, key, true );
1910
+			})
1911
+		});
1912
+	}
1913
+});
1914
+
1915
+jQuery.fn.extend({
1916
+	queue: function( type, data ) {
1917
+		var setter = 2;
1918
+
1919
+		if ( typeof type !== "string" ) {
1920
+			data = type;
1921
+			type = "fx";
1922
+			setter--;
1923
+		}
1924
+
1925
+		if ( arguments.length < setter ) {
1926
+			return jQuery.queue( this[0], type );
1927
+		}
1928
+
1929
+		return data === undefined ?
1930
+			this :
1931
+			this.each(function() {
1932
+				var queue = jQuery.queue( this, type, data );
1933
+
1934
+				// ensure a hooks for this queue
1935
+				jQuery._queueHooks( this, type );
1936
+
1937
+				if ( type === "fx" && queue[0] !== "inprogress" ) {
1938
+					jQuery.dequeue( this, type );
1939
+				}
1940
+			});
1941
+	},
1942
+	dequeue: function( type ) {
1943
+		return this.each(function() {
1944
+			jQuery.dequeue( this, type );
1945
+		});
1946
+	},
1947
+	// Based off of the plugin by Clint Helfers, with permission.
1948
+	// http://blindsignals.com/index.php/2009/07/jquery-delay/
1949
+	delay: function( time, type ) {
1950
+		time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
1951
+		type = type || "fx";
1952
+
1953
+		return this.queue( type, function( next, hooks ) {
1954
+			var timeout = setTimeout( next, time );
1955
+			hooks.stop = function() {
1956
+				clearTimeout( timeout );
1957
+			};
1958
+		});
1959
+	},
1960
+	clearQueue: function( type ) {
1961
+		return this.queue( type || "fx", [] );
1962
+	},
1963
+	// Get a promise resolved when queues of a certain type
1964
+	// are emptied (fx is the type by default)
1965
+	promise: function( type, obj ) {
1966
+		var tmp,
1967
+			count = 1,
1968
+			defer = jQuery.Deferred(),
1969
+			elements = this,
1970
+			i = this.length,
1971
+			resolve = function() {
1972
+				if ( !( --count ) ) {
1973
+					defer.resolveWith( elements, [ elements ] );
1974
+				}
1975
+			};
1976
+
1977
+		if ( typeof type !== "string" ) {
1978
+			obj = type;
1979
+			type = undefined;
1980
+		}
1981
+		type = type || "fx";
1982
+
1983
+		while( i-- ) {
1984
+			tmp = jQuery._data( elements[ i ], type + "queueHooks" );
1985
+			if ( tmp && tmp.empty ) {
1986
+				count++;
1987
+				tmp.empty.add( resolve );
1988
+			}
1989
+		}
1990
+		resolve();
1991
+		return defer.promise( obj );
1992
+	}
1993
+});
1994
+var nodeHook, boolHook, fixSpecified,
1995
+	rclass = /[\t\r\n]/g,
1996
+	rreturn = /\r/g,
1997
+	rtype = /^(?:button|input)$/i,
1998
+	rfocusable = /^(?:button|input|object|select|textarea)$/i,
1999
+	rclickable = /^a(?:rea|)$/i,
2000
+	rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
2001
+	getSetAttribute = jQuery.support.getSetAttribute;
2002
+
2003
+jQuery.fn.extend({
2004
+	attr: function( name, value ) {
2005
+		return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
2006
+	},
2007
+
2008
+	removeAttr: function( name ) {
2009
+		return this.each(function() {
2010
+			jQuery.removeAttr( this, name );
2011
+		});
2012
+	},
2013
+
2014
+	prop: function( name, value ) {
2015
+		return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
2016
+	},
2017
+
2018
+	removeProp: function( name ) {
2019
+		name = jQuery.propFix[ name ] || name;
2020
+		return this.each(function() {
2021
+			// try/catch handles cases where IE balks (such as removing a property on window)
2022
+			try {
2023
+				this[ name ] = undefined;
2024
+				delete this[ name ];
2025
+			} catch( e ) {}
2026
+		});
2027
+	},
2028
+
2029
+	addClass: function( value ) {
2030
+		var classNames, i, l, elem,
2031
+			setClass, c, cl;
2032
+
2033
+		if ( jQuery.isFunction( value ) ) {
2034
+			return this.each(function( j ) {
2035
+				jQuery( this ).addClass( value.call(this, j, this.className) );
2036
+			});
2037
+		}
2038
+
2039
+		if ( value && typeof value === "string" ) {
2040
+			classNames = value.split( core_rspace );
2041
+
2042
+			for ( i = 0, l = this.length; i < l; i++ ) {
2043
+				elem = this[ i ];
2044
+
2045
+				if ( elem.nodeType === 1 ) {
2046
+					if ( !elem.className && classNames.length === 1 ) {
2047
+						elem.className = value;
2048
+
2049
+					} else {
2050
+						setClass = " " + elem.className + " ";
2051
+
2052
+						for ( c = 0, cl = classNames.length; c < cl; c++ ) {
2053
+							if ( setClass.indexOf( " " + classNames[ c ] + " " ) < 0 ) {
2054
+								setClass += classNames[ c ] + " ";
2055
+							}
2056
+						}
2057
+						elem.className = jQuery.trim( setClass );
2058
+					}
2059
+				}
2060
+			}
2061
+		}
2062
+
2063
+		return this;
2064
+	},
2065
+
2066
+	removeClass: function( value ) {
2067
+		var removes, className, elem, c, cl, i, l;
2068
+
2069
+		if ( jQuery.isFunction( value ) ) {
2070
+			return this.each(function( j ) {
2071
+				jQuery( this ).removeClass( value.call(this, j, this.className) );
2072
+			});
2073
+		}
2074
+		if ( (value && typeof value === "string") || value === undefined ) {
2075
+			removes = ( value || "" ).split( core_rspace );
2076
+
2077
+			for ( i = 0, l = this.length; i < l; i++ ) {
2078
+				elem = this[ i ];
2079
+				if ( elem.nodeType === 1 && elem.className ) {
2080
+
2081
+					className = (" " + elem.className + " ").replace( rclass, " " );
2082
+
2083
+					// loop over each item in the removal list
2084
+					for ( c = 0, cl = removes.length; c < cl; c++ ) {
2085
+						// Remove until there is nothing to remove,
2086
+						while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) {
2087
+							className = className.replace( " " + removes[ c ] + " " , " " );
2088
+						}
2089
+					}
2090
+					elem.className = value ? jQuery.trim( className ) : "";
2091
+				}
2092
+			}
2093
+		}
2094
+
2095
+		return this;
2096
+	},
2097
+
2098
+	toggleClass: function( value, stateVal ) {
2099
+		var type = typeof value,
2100
+			isBool = typeof stateVal === "boolean";
2101
+
2102
+		if ( jQuery.isFunction( value ) ) {
2103
+			return this.each(function( i ) {
2104
+				jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
2105
+			});
2106
+		}
2107
+
2108
+		return this.each(function() {
2109
+			if ( type === "string" ) {
2110
+				// toggle individual class names
2111
+				var className,
2112
+					i = 0,
2113
+					self = jQuery( this ),
2114
+					state = stateVal,
2115
+					classNames = value.split( core_rspace );
2116
+
2117
+				while ( (className = classNames[ i++ ]) ) {
2118
+					// check each className given, space separated list
2119
+					state = isBool ? state : !self.hasClass( className );
2120
+					self[ state ? "addClass" : "removeClass" ]( className );
2121
+				}
2122
+
2123
+			} else if ( type === "undefined" || type === "boolean" ) {
2124
+				if ( this.className ) {
2125
+					// store className if set
2126
+					jQuery._data( this, "__className__", this.className );
2127
+				}
2128
+
2129
+				// toggle whole className
2130
+				this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2131
+			}
2132
+		});
2133
+	},
2134
+
2135
+	hasClass: function( selector ) {
2136
+		var className = " " + selector + " ",
2137
+			i = 0,
2138
+			l = this.length;
2139
+		for ( ; i < l; i++ ) {
2140
+			if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
2141
+				return true;
2142
+			}
2143
+		}
2144
+
2145
+		return false;
2146
+	},
2147
+
2148
+	val: function( value ) {
2149
+		var hooks, ret, isFunction,
2150
+			elem = this[0];
2151
+
2152
+		if ( !arguments.length ) {
2153
+			if ( elem ) {
2154
+				hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
2155
+
2156
+				if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2157
+					return ret;
2158
+				}
2159
+
2160
+				ret = elem.value;
2161
+
2162
+				return typeof ret === "string" ?
2163
+					// handle most common string cases
2164
+					ret.replace(rreturn, "") :
2165
+					// handle cases where value is null/undef or number
2166
+					ret == null ? "" : ret;
2167
+			}
2168
+
2169
+			return;
2170
+		}
2171
+
2172
+		isFunction = jQuery.isFunction( value );
2173
+
2174
+		return this.each(function( i ) {
2175
+			var val,
2176
+				self = jQuery(this);
2177
+
2178
+			if ( this.nodeType !== 1 ) {
2179
+				return;
2180
+			}
2181
+
2182
+			if ( isFunction ) {
2183
+				val = value.call( this, i, self.val() );
2184
+			} else {
2185
+				val = value;
2186
+			}
2187
+
2188
+			// Treat null/undefined as ""; convert numbers to string
2189
+			if ( val == null ) {
2190
+				val = "";
2191
+			} else if ( typeof val === "number" ) {
2192
+				val += "";
2193
+			} else if ( jQuery.isArray( val ) ) {
2194
+				val = jQuery.map(val, function ( value ) {
2195
+					return value == null ? "" : value + "";
2196
+				});
2197
+			}
2198
+
2199
+			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
2200
+
2201
+			// If set returns undefined, fall back to normal setting
2202
+			if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2203
+				this.value = val;
2204
+			}
2205
+		});
2206
+	}
2207
+});
2208
+
2209
+jQuery.extend({
2210
+	valHooks: {
2211
+		option: {
2212
+			get: function( elem ) {
2213
+				// attributes.value is undefined in Blackberry 4.7 but
2214
+				// uses .value. See #6932
2215
+				var val = elem.attributes.value;
2216
+				return !val || val.specified ? elem.value : elem.text;
2217
+			}
2218
+		},
2219
+		select: {
2220
+			get: function( elem ) {
2221
+				var value, option,
2222
+					options = elem.options,
2223
+					index = elem.selectedIndex,
2224
+					one = elem.type === "select-one" || index < 0,
2225
+					values = one ? null : [],
2226
+					max = one ? index + 1 : options.length,
2227
+					i = index < 0 ?
2228
+						max :
2229
+						one ? index : 0;
2230
+
2231
+				// Loop through all the selected options
2232
+				for ( ; i < max; i++ ) {
2233
+					option = options[ i ];
2234
+
2235
+					// oldIE doesn't update selected after form reset (#2551)
2236
+					if ( ( option.selected || i === index ) &&
2237
+							// Don't return options that are disabled or in a disabled optgroup
2238
+							( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
2239
+							( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
2240
+
2241
+						// Get the specific value for the option
2242
+						value = jQuery( option ).val();
2243
+
2244
+						// We don't need an array for one selects
2245
+						if ( one ) {
2246
+							return value;
2247
+						}
2248
+
2249
+						// Multi-Selects return an array
2250
+						values.push( value );
2251
+					}
2252
+				}
2253
+
2254
+				return values;
2255
+			},
2256
+
2257
+			set: function( elem, value ) {
2258
+				var values = jQuery.makeArray( value );
2259
+
2260
+				jQuery(elem).find("option").each(function() {
2261
+					this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2262
+				});
2263
+
2264
+				if ( !values.length ) {
2265
+					elem.selectedIndex = -1;
2266
+				}
2267
+				return values;
2268
+			}
2269
+		}
2270
+	},
2271
+
2272
+	// Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9
2273
+	attrFn: {},
2274
+
2275
+	attr: function( elem, name, value, pass ) {
2276
+		var ret, hooks, notxml,
2277
+			nType = elem.nodeType;
2278
+
2279
+		// don't get/set attributes on text, comment and attribute nodes
2280
+		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2281
+			return;
2282
+		}
2283
+
2284
+		if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) {
2285
+			return jQuery( elem )[ name ]( value );
2286
+		}
2287
+
2288
+		// Fallback to prop when attributes are not supported
2289
+		if ( typeof elem.getAttribute === "undefined" ) {
2290
+			return jQuery.prop( elem, name, value );
2291
+		}
2292
+
2293
+		notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2294
+
2295
+		// All attributes are lowercase
2296
+		// Grab necessary hook if one is defined
2297
+		if ( notxml ) {
2298
+			name = name.toLowerCase();
2299
+			hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
2300
+		}
2301
+
2302
+		if ( value !== undefined ) {
2303
+
2304
+			if ( value === null ) {
2305
+				jQuery.removeAttr( elem, name );
2306
+				return;
2307
+
2308
+			} else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2309
+				return ret;
2310
+
2311
+			} else {
2312
+				elem.setAttribute( name, value + "" );
2313
+				return value;
2314
+			}
2315
+
2316
+		} else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
2317
+			return ret;
2318
+
2319
+		} else {
2320
+
2321
+			ret = elem.getAttribute( name );
2322
+
2323
+			// Non-existent attributes return null, we normalize to undefined
2324
+			return ret === null ?
2325
+				undefined :
2326
+				ret;
2327
+		}
2328
+	},
2329
+
2330
+	removeAttr: function( elem, value ) {
2331
+		var propName, attrNames, name, isBool,
2332
+			i = 0;
2333
+
2334
+		if ( value && elem.nodeType === 1 ) {
2335
+
2336
+			attrNames = value.split( core_rspace );
2337
+
2338
+			for ( ; i < attrNames.length; i++ ) {
2339
+				name = attrNames[ i ];
2340
+
2341
+				if ( name ) {
2342
+					propName = jQuery.propFix[ name ] || name;
2343
+					isBool = rboolean.test( name );
2344
+
2345
+					// See #9699 for explanation of this approach (setting first, then removal)
2346
+					// Do not do this for boolean attributes (see #10870)
2347
+					if ( !isBool ) {
2348
+						jQuery.attr( elem, name, "" );
2349
+					}
2350
+					elem.removeAttribute( getSetAttribute ? name : propName );
2351
+
2352
+					// Set corresponding property to false for boolean attributes
2353
+					if ( isBool && propName in elem ) {
2354
+						elem[ propName ] = false;
2355
+					}
2356
+				}
2357
+			}
2358
+		}
2359
+	},
2360
+
2361
+	attrHooks: {
2362
+		type: {
2363
+			set: function( elem, value ) {
2364
+				// We can't allow the type property to be changed (since it causes problems in IE)
2365
+				if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2366
+					jQuery.error( "type property can't be changed" );
2367
+				} else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2368
+					// Setting the type on a radio button after the value resets the value in IE6-9
2369
+					// Reset value to it's default in case type is set after value
2370
+					// This is for element creation
2371
+					var val = elem.value;
2372
+					elem.setAttribute( "type", value );
2373
+					if ( val ) {
2374
+						elem.value = val;
2375
+					}
2376
+					return value;
2377
+				}
2378
+			}
2379
+		},
2380
+		// Use the value property for back compat
2381
+		// Use the nodeHook for button elements in IE6/7 (#1954)
2382
+		value: {
2383
+			get: function( elem, name ) {
2384
+				if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2385
+					return nodeHook.get( elem, name );
2386
+				}
2387
+				return name in elem ?
2388
+					elem.value :
2389
+					null;
2390
+			},
2391
+			set: function( elem, value, name ) {
2392
+				if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2393
+					return nodeHook.set( elem, value, name );
2394
+				}
2395
+				// Does not return so that setAttribute is also used
2396
+				elem.value = value;
2397
+			}
2398
+		}
2399
+	},
2400
+
2401
+	propFix: {
2402
+		tabindex: "tabIndex",
2403
+		readonly: "readOnly",
2404
+		"for": "htmlFor",
2405
+		"class": "className",
2406
+		maxlength: "maxLength",
2407
+		cellspacing: "cellSpacing",
2408
+		cellpadding: "cellPadding",
2409
+		rowspan: "rowSpan",
2410
+		colspan: "colSpan",
2411
+		usemap: "useMap",
2412
+		frameborder: "frameBorder",
2413
+		contenteditable: "contentEditable"
2414
+	},
2415
+
2416
+	prop: function( elem, name, value ) {
2417
+		var ret, hooks, notxml,
2418
+			nType = elem.nodeType;
2419
+
2420
+		// don't get/set properties on text, comment and attribute nodes
2421
+		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2422
+			return;
2423
+		}
2424
+
2425
+		notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2426
+
2427
+		if ( notxml ) {
2428
+			// Fix name and attach hooks
2429
+			name = jQuery.propFix[ name ] || name;
2430
+			hooks = jQuery.propHooks[ name ];
2431
+		}
2432
+
2433
+		if ( value !== undefined ) {
2434
+			if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2435
+				return ret;
2436
+
2437
+			} else {
2438
+				return ( elem[ name ] = value );
2439
+			}
2440
+
2441
+		} else {
2442
+			if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
2443
+				return ret;
2444
+
2445
+			} else {
2446
+				return elem[ name ];
2447
+			}
2448
+		}
2449
+	},
2450
+
2451
+	propHooks: {
2452
+		tabIndex: {
2453
+			get: function( elem ) {
2454
+				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2455
+				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2456
+				var attributeNode = elem.getAttributeNode("tabindex");
2457
+
2458
+				return attributeNode && attributeNode.specified ?
2459
+					parseInt( attributeNode.value, 10 ) :
2460
+					rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2461
+						0 :
2462
+						undefined;
2463
+			}
2464
+		}
2465
+	}
2466
+});
2467
+
2468
+// Hook for boolean attributes
2469
+boolHook = {
2470
+	get: function( elem, name ) {
2471
+		// Align boolean attributes with corresponding properties
2472
+		// Fall back to attribute presence where some booleans are not supported
2473
+		var attrNode,
2474
+			property = jQuery.prop( elem, name );
2475
+		return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
2476
+			name.toLowerCase() :
2477
+			undefined;
2478
+	},
2479
+	set: function( elem, value, name ) {
2480
+		var propName;
2481
+		if ( value === false ) {
2482
+			// Remove boolean attributes when set to false
2483
+			jQuery.removeAttr( elem, name );
2484
+		} else {
2485
+			// value is true since we know at this point it's type boolean and not false
2486
+			// Set boolean attributes to the same name and set the DOM property
2487
+			propName = jQuery.propFix[ name ] || name;
2488
+			if ( propName in elem ) {
2489
+				// Only set the IDL specifically if it already exists on the element
2490
+				elem[ propName ] = true;
2491
+			}
2492
+
2493
+			elem.setAttribute( name, name.toLowerCase() );
2494
+		}
2495
+		return name;
2496
+	}
2497
+};
2498
+
2499
+// IE6/7 do not support getting/setting some attributes with get/setAttribute
2500
+if ( !getSetAttribute ) {
2501
+
2502
+	fixSpecified = {
2503
+		name: true,
2504
+		id: true,
2505
+		coords: true
2506
+	};
2507
+
2508
+	// Use this for any attribute in IE6/7
2509
+	// This fixes almost every IE6/7 issue
2510
+	nodeHook = jQuery.valHooks.button = {
2511
+		get: function( elem, name ) {
2512
+			var ret;
2513
+			ret = elem.getAttributeNode( name );
2514
+			return ret && ( fixSpecified[ name ] ? ret.value !== "" : ret.specified ) ?
2515
+				ret.value :
2516
+				undefined;
2517
+		},
2518
+		set: function( elem, value, name ) {
2519
+			// Set the existing or create a new attribute node
2520
+			var ret = elem.getAttributeNode( name );
2521
+			if ( !ret ) {
2522
+				ret = document.createAttribute( name );
2523
+				elem.setAttributeNode( ret );
2524
+			}
2525
+			return ( ret.value = value + "" );
2526
+		}
2527
+	};
2528
+
2529
+	// Set width and height to auto instead of 0 on empty string( Bug #8150 )
2530
+	// This is for removals
2531
+	jQuery.each([ "width", "height" ], function( i, name ) {
2532
+		jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2533
+			set: function( elem, value ) {
2534
+				if ( value === "" ) {
2535
+					elem.setAttribute( name, "auto" );
2536
+					return value;
2537
+				}
2538
+			}
2539
+		});
2540
+	});
2541
+
2542
+	// Set contenteditable to false on removals(#10429)
2543
+	// Setting to empty string throws an error as an invalid value
2544
+	jQuery.attrHooks.contenteditable = {
2545
+		get: nodeHook.get,
2546
+		set: function( elem, value, name ) {
2547
+			if ( value === "" ) {
2548
+				value = "false";
2549
+			}
2550
+			nodeHook.set( elem, value, name );
2551
+		}
2552
+	};
2553
+}
2554
+
2555
+
2556
+// Some attributes require a special call on IE
2557
+if ( !jQuery.support.hrefNormalized ) {
2558
+	jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2559
+		jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2560
+			get: function( elem ) {
2561
+				var ret = elem.getAttribute( name, 2 );
2562
+				return ret === null ? undefined : ret;
2563
+			}
2564
+		});
2565
+	});
2566
+}
2567
+
2568
+if ( !jQuery.support.style ) {
2569
+	jQuery.attrHooks.style = {
2570
+		get: function( elem ) {
2571
+			// Return undefined in the case of empty string
2572
+			// Normalize to lowercase since IE uppercases css property names
2573
+			return elem.style.cssText.toLowerCase() || undefined;
2574
+		},
2575
+		set: function( elem, value ) {
2576
+			return ( elem.style.cssText = value + "" );
2577
+		}
2578
+	};
2579
+}
2580
+
2581
+// Safari mis-reports the default selected property of an option
2582
+// Accessing the parent's selectedIndex property fixes it
2583
+if ( !jQuery.support.optSelected ) {
2584
+	jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2585
+		get: function( elem ) {
2586
+			var parent = elem.parentNode;
2587
+
2588
+			if ( parent ) {
2589
+				parent.selectedIndex;
2590
+
2591
+				// Make sure that it also works with optgroups, see #5701
2592
+				if ( parent.parentNode ) {
2593
+					parent.parentNode.selectedIndex;
2594
+				}
2595
+			}
2596
+			return null;
2597
+		}
2598
+	});
2599
+}
2600
+
2601
+// IE6/7 call enctype encoding
2602
+if ( !jQuery.support.enctype ) {
2603
+	jQuery.propFix.enctype = "encoding";
2604
+}
2605
+
2606
+// Radios and checkboxes getter/setter
2607
+if ( !jQuery.support.checkOn ) {
2608
+	jQuery.each([ "radio", "checkbox" ], function() {
2609
+		jQuery.valHooks[ this ] = {
2610
+			get: function( elem ) {
2611
+				// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2612
+				return elem.getAttribute("value") === null ? "on" : elem.value;
2613
+			}
2614
+		};
2615
+	});
2616
+}
2617
+jQuery.each([ "radio", "checkbox" ], function() {
2618
+	jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2619
+		set: function( elem, value ) {
2620
+			if ( jQuery.isArray( value ) ) {
2621
+				return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
2622
+			}
2623
+		}
2624
+	});
2625
+});
2626
+var rformElems = /^(?:textarea|input|select)$/i,
2627
+	rtypenamespace = /^([^\.]*|)(?:\.(.+)|)$/,
2628
+	rhoverHack = /(?:^|\s)hover(\.\S+|)\b/,
2629
+	rkeyEvent = /^key/,
2630
+	rmouseEvent = /^(?:mouse|contextmenu)|click/,
2631
+	rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
2632
+	hoverHack = function( events ) {
2633
+		return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
2634
+	};
2635
+
2636
+/*
2637
+ * Helper functions for managing events -- not part of the public interface.
2638
+ * Props to Dean Edwards' addEvent library for many of the ideas.
2639
+ */
2640
+jQuery.event = {
2641
+
2642
+	add: function( elem, types, handler, data, selector ) {
2643
+
2644
+		var elemData, eventHandle, events,
2645
+			t, tns, type, namespaces, handleObj,
2646
+			handleObjIn, handlers, special;
2647
+
2648
+		// Don't attach events to noData or text/comment nodes (allow plain objects tho)
2649
+		if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {
2650
+			return;
2651
+		}
2652
+
2653
+		// Caller can pass in an object of custom data in lieu of the handler
2654
+		if ( handler.handler ) {
2655
+			handleObjIn = handler;
2656
+			handler = handleObjIn.handler;
2657
+			selector = handleObjIn.selector;
2658
+		}
2659
+
2660
+		// Make sure that the handler has a unique ID, used to find/remove it later
2661
+		if ( !handler.guid ) {
2662
+			handler.guid = jQuery.guid++;
2663
+		}
2664
+
2665
+		// Init the element's event structure and main handler, if this is the first
2666
+		events = elemData.events;
2667
+		if ( !events ) {
2668
+			elemData.events = events = {};
2669
+		}
2670
+		eventHandle = elemData.handle;
2671
+		if ( !eventHandle ) {
2672
+			elemData.handle = eventHandle = function( e ) {
2673
+				// Discard the second event of a jQuery.event.trigger() and
2674
+				// when an event is called after a page has unloaded
2675
+				return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2676
+					jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
2677
+					undefined;
2678
+			};
2679
+			// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
2680
+			eventHandle.elem = elem;
2681
+		}
2682
+
2683
+		// Handle multiple events separated by a space
2684
+		// jQuery(...).bind("mouseover mouseout", fn);
2685
+		types = jQuery.trim( hoverHack(types) ).split( " " );
2686
+		for ( t = 0; t < types.length; t++ ) {
2687
+
2688
+			tns = rtypenamespace.exec( types[t] ) || [];
2689
+			type = tns[1];
2690
+			namespaces = ( tns[2] || "" ).split( "." ).sort();
2691
+
2692
+			// If event changes its type, use the special event handlers for the changed type
2693
+			special = jQuery.event.special[ type ] || {};
2694
+
2695
+			// If selector defined, determine special event api type, otherwise given type
2696
+			type = ( selector ? special.delegateType : special.bindType ) || type;
2697
+
2698
+			// Update special based on newly reset type
2699
+			special = jQuery.event.special[ type ] || {};
2700
+
2701
+			// handleObj is passed to all event handlers
2702
+			handleObj = jQuery.extend({
2703
+				type: type,
2704
+				origType: tns[1],
2705
+				data: data,
2706
+				handler: handler,
2707
+				guid: handler.guid,
2708
+				selector: selector,
2709
+				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
2710
+				namespace: namespaces.join(".")
2711
+			}, handleObjIn );
2712
+
2713
+			// Init the event handler queue if we're the first
2714
+			handlers = events[ type ];
2715
+			if ( !handlers ) {
2716
+				handlers = events[ type ] = [];
2717
+				handlers.delegateCount = 0;
2718
+
2719
+				// Only use addEventListener/attachEvent if the special events handler returns false
2720
+				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2721
+					// Bind the global event handler to the element
2722
+					if ( elem.addEventListener ) {
2723
+						elem.addEventListener( type, eventHandle, false );
2724
+
2725
+					} else if ( elem.attachEvent ) {
2726
+						elem.attachEvent( "on" + type, eventHandle );
2727
+					}
2728
+				}
2729
+			}
2730
+
2731
+			if ( special.add ) {
2732
+				special.add.call( elem, handleObj );
2733
+
2734
+				if ( !handleObj.handler.guid ) {
2735
+					handleObj.handler.guid = handler.guid;
2736
+				}
2737
+			}
2738
+
2739
+			// Add to the element's handler list, delegates in front
2740
+			if ( selector ) {
2741
+				handlers.splice( handlers.delegateCount++, 0, handleObj );
2742
+			} else {
2743
+				handlers.push( handleObj );
2744
+			}
2745
+
2746
+			// Keep track of which events have ever been used, for event optimization
2747
+			jQuery.event.global[ type ] = true;
2748
+		}
2749
+
2750
+		// Nullify elem to prevent memory leaks in IE
2751
+		elem = null;
2752
+	},
2753
+
2754
+	global: {},
2755
+
2756
+	// Detach an event or set of events from an element
2757
+	remove: function( elem, types, handler, selector, mappedTypes ) {
2758
+
2759
+		var t, tns, type, origType, namespaces, origCount,
2760
+			j, events, special, eventType, handleObj,
2761
+			elemData = jQuery.hasData( elem ) && jQuery._data( elem );
2762
+
2763
+		if ( !elemData || !(events = elemData.events) ) {
2764
+			return;
2765
+		}
2766
+
2767
+		// Once for each type.namespace in types; type may be omitted
2768
+		types = jQuery.trim( hoverHack( types || "" ) ).split(" ");
2769
+		for ( t = 0; t < types.length; t++ ) {
2770
+			tns = rtypenamespace.exec( types[t] ) || [];
2771
+			type = origType = tns[1];
2772
+			namespaces = tns[2];
2773
+
2774
+			// Unbind all events (on this namespace, if provided) for the element
2775
+			if ( !type ) {
2776
+				for ( type in events ) {
2777
+					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
2778
+				}
2779
+				continue;
2780
+			}
2781
+
2782
+			special = jQuery.event.special[ type ] || {};
2783
+			type = ( selector? special.delegateType : special.bindType ) || type;
2784
+			eventType = events[ type ] || [];
2785
+			origCount = eventType.length;
2786
+			namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null;
2787
+
2788
+			// Remove matching events
2789
+			for ( j = 0; j < eventType.length; j++ ) {
2790
+				handleObj = eventType[ j ];
2791
+
2792
+				if ( ( mappedTypes || origType === handleObj.origType ) &&
2793
+					 ( !handler || handler.guid === handleObj.guid ) &&
2794
+					 ( !namespaces || namespaces.test( handleObj.namespace ) ) &&
2795
+					 ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
2796
+					eventType.splice( j--, 1 );
2797
+
2798
+					if ( handleObj.selector ) {
2799
+						eventType.delegateCount--;
2800
+					}
2801
+					if ( special.remove ) {
2802
+						special.remove.call( elem, handleObj );
2803
+					}
2804
+				}
2805
+			}
2806
+
2807
+			// Remove generic event handler if we removed something and no more handlers exist
2808
+			// (avoids potential for endless recursion during removal of special event handlers)
2809
+			if ( eventType.length === 0 && origCount !== eventType.length ) {
2810
+				if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
2811
+					jQuery.removeEvent( elem, type, elemData.handle );
2812
+				}
2813
+
2814
+				delete events[ type ];
2815
+			}
2816
+		}
2817
+
2818
+		// Remove the expando if it's no longer used
2819
+		if ( jQuery.isEmptyObject( events ) ) {
2820
+			delete elemData.handle;
2821
+
2822
+			// removeData also checks for emptiness and clears the expando if empty
2823
+			// so use it instead of delete
2824
+			jQuery.removeData( elem, "events", true );
2825
+		}
2826
+	},
2827
+
2828
+	// Events that are safe to short-circuit if no handlers are attached.
2829
+	// Native DOM events should not be added, they may have inline handlers.
2830
+	customEvent: {
2831
+		"getData": true,
2832
+		"setData": true,
2833
+		"changeData": true
2834
+	},
2835
+
2836
+	trigger: function( event, data, elem, onlyHandlers ) {
2837
+		// Don't do events on text and comment nodes
2838
+		if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {
2839
+			return;
2840
+		}
2841
+
2842
+		// Event object or event type
2843
+		var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType,
2844
+			type = event.type || event,
2845
+			namespaces = [];
2846
+
2847
+		// focus/blur morphs to focusin/out; ensure we're not firing them right now
2848
+		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
2849
+			return;
2850
+		}
2851
+
2852
+		if ( type.indexOf( "!" ) >= 0 ) {
2853
+			// Exclusive events trigger only for the exact event (no namespaces)
2854
+			type = type.slice(0, -1);
2855
+			exclusive = true;
2856
+		}
2857
+
2858
+		if ( type.indexOf( "." ) >= 0 ) {
2859
+			// Namespaced trigger; create a regexp to match event type in handle()
2860
+			namespaces = type.split(".");
2861
+			type = namespaces.shift();
2862
+			namespaces.sort();
2863
+		}
2864
+
2865
+		if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
2866
+			// No jQuery handlers for this event type, and it can't have inline handlers
2867
+			return;
2868
+		}
2869
+
2870
+		// Caller can pass in an Event, Object, or just an event type string
2871
+		event = typeof event === "object" ?
2872
+			// jQuery.Event object
2873
+			event[ jQuery.expando ] ? event :
2874
+			// Object literal
2875
+			new jQuery.Event( type, event ) :
2876
+			// Just the event type (string)
2877
+			new jQuery.Event( type );
2878
+
2879
+		event.type = type;
2880
+		event.isTrigger = true;
2881
+		event.exclusive = exclusive;
2882
+		event.namespace = namespaces.join( "." );
2883
+		event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null;
2884
+		ontype = type.indexOf( ":" ) < 0 ? "on" + type : "";
2885
+
2886
+		// Handle a global trigger
2887
+		if ( !elem ) {
2888
+
2889
+			// TODO: Stop taunting the data cache; remove global events and always attach to document
2890
+			cache = jQuery.cache;
2891
+			for ( i in cache ) {
2892
+				if ( cache[ i ].events && cache[ i ].events[ type ] ) {
2893
+					jQuery.event.trigger( event, data, cache[ i ].handle.elem, true );
2894
+				}
2895
+			}
2896
+			return;
2897
+		}
2898
+
2899
+		// Clean up the event in case it is being reused
2900
+		event.result = undefined;
2901
+		if ( !event.target ) {
2902
+			event.target = elem;
2903
+		}
2904
+
2905
+		// Clone any incoming data and prepend the event, creating the handler arg list
2906
+		data = data != null ? jQuery.makeArray( data ) : [];
2907
+		data.unshift( event );
2908
+
2909
+		// Allow special events to draw outside the lines
2910
+		special = jQuery.event.special[ type ] || {};
2911
+		if ( special.trigger && special.trigger.apply( elem, data ) === false ) {
2912
+			return;
2913
+		}
2914
+
2915
+		// Determine event propagation path in advance, per W3C events spec (#9951)
2916
+		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
2917
+		eventPath = [[ elem, special.bindType || type ]];
2918
+		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
2919
+
2920
+			bubbleType = special.delegateType || type;
2921
+			cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode;
2922
+			for ( old = elem; cur; cur = cur.parentNode ) {
2923
+				eventPath.push([ cur, bubbleType ]);
2924
+				old = cur;
2925
+			}
2926
+
2927
+			// Only add window if we got to document (e.g., not plain obj or detached DOM)
2928
+			if ( old === (elem.ownerDocument || document) ) {
2929
+				eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);
2930
+			}
2931
+		}
2932
+
2933
+		// Fire handlers on the event path
2934
+		for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) {
2935
+
2936
+			cur = eventPath[i][0];
2937
+			event.type = eventPath[i][1];
2938
+
2939
+			handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
2940
+			if ( handle ) {
2941
+				handle.apply( cur, data );
2942
+			}
2943
+			// Note that this is a bare JS function and not a jQuery handler
2944
+			handle = ontype && cur[ ontype ];
2945
+			if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
2946
+				event.preventDefault();
2947
+			}
2948
+		}
2949
+		event.type = type;
2950
+
2951
+		// If nobody prevented the default action, do it now
2952
+		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
2953
+
2954
+			if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&
2955
+				!(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
2956
+
2957
+				// Call a native DOM method on the target with the same name name as the event.
2958
+				// Can't use an .isFunction() check here because IE6/7 fails that test.
2959
+				// Don't do default actions on window, that's where global variables be (#6170)
2960
+				// IE<9 dies on focus/blur to hidden element (#1486)
2961
+				if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {
2962
+
2963
+					// Don't re-trigger an onFOO event when we call its FOO() method
2964
+					old = elem[ ontype ];
2965
+
2966
+					if ( old ) {
2967
+						elem[ ontype ] = null;
2968
+					}
2969
+
2970
+					// Prevent re-triggering of the same event, since we already bubbled it above
2971
+					jQuery.event.triggered = type;
2972
+					elem[ type ]();
2973
+					jQuery.event.triggered = undefined;
2974
+
2975
+					if ( old ) {
2976
+						elem[ ontype ] = old;
2977
+					}
2978
+				}
2979
+			}
2980
+		}
2981
+
2982
+		return event.result;
2983
+	},
2984
+
2985
+	dispatch: function( event ) {
2986
+
2987
+		// Make a writable jQuery.Event from the native event object
2988
+		event = jQuery.event.fix( event || window.event );
2989
+
2990
+		var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related,
2991
+			handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []),
2992
+			delegateCount = handlers.delegateCount,
2993
+			args = core_slice.call( arguments ),
2994
+			run_all = !event.exclusive && !event.namespace,
2995
+			special = jQuery.event.special[ event.type ] || {},
2996
+			handlerQueue = [];
2997
+
2998
+		// Use the fix-ed jQuery.Event rather than the (read-only) native event
2999
+		args[0] = event;
3000
+		event.delegateTarget = this;
3001
+
3002
+		// Call the preDispatch hook for the mapped type, and let it bail if desired
3003
+		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
3004
+			return;
3005
+		}
3006
+
3007
+		// Determine handlers that should run if there are delegated events
3008
+		// Avoid non-left-click bubbling in Firefox (#3861)
3009
+		if ( delegateCount && !(event.button && event.type === "click") ) {
3010
+
3011
+			for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {
3012
+
3013
+				// Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764)
3014
+				if ( cur.disabled !== true || event.type !== "click" ) {
3015
+					selMatch = {};
3016
+					matches = [];
3017
+					for ( i = 0; i < delegateCount; i++ ) {
3018
+						handleObj = handlers[ i ];
3019
+						sel = handleObj.selector;
3020
+
3021
+						if ( selMatch[ sel ] === undefined ) {
3022
+							selMatch[ sel ] = handleObj.needsContext ?
3023
+								jQuery( sel, this ).index( cur ) >= 0 :
3024
+								jQuery.find( sel, this, null, [ cur ] ).length;
3025
+						}
3026
+						if ( selMatch[ sel ] ) {
3027
+							matches.push( handleObj );
3028
+						}
3029
+					}
3030
+					if ( matches.length ) {
3031
+						handlerQueue.push({ elem: cur, matches: matches });
3032
+					}
3033
+				}
3034
+			}
3035
+		}
3036
+
3037
+		// Add the remaining (directly-bound) handlers
3038
+		if ( handlers.length > delegateCount ) {
3039
+			handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });
3040
+		}
3041
+
3042
+		// Run delegates first; they may want to stop propagation beneath us
3043
+		for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {
3044
+			matched = handlerQueue[ i ];
3045
+			event.currentTarget = matched.elem;
3046
+
3047
+			for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {
3048
+				handleObj = matched.matches[ j ];
3049
+
3050
+				// Triggered event must either 1) be non-exclusive and have no namespace, or
3051
+				// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
3052
+				if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {
3053
+
3054
+					event.data = handleObj.data;
3055
+					event.handleObj = handleObj;
3056
+
3057
+					ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
3058
+							.apply( matched.elem, args );
3059
+
3060
+					if ( ret !== undefined ) {
3061
+						event.result = ret;
3062
+						if ( ret === false ) {
3063
+							event.preventDefault();
3064
+							event.stopPropagation();
3065
+						}
3066
+					}
3067
+				}
3068
+			}
3069
+		}
3070
+
3071
+		// Call the postDispatch hook for the mapped type
3072
+		if ( special.postDispatch ) {
3073
+			special.postDispatch.call( this, event );
3074
+		}
3075
+
3076
+		return event.result;
3077
+	},
3078
+
3079
+	// Includes some event props shared by KeyEvent and MouseEvent
3080
+	// *** attrChange attrName relatedNode srcElement  are not normalized, non-W3C, deprecated, will be removed in 1.8 ***
3081
+	props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
3082
+
3083
+	fixHooks: {},
3084
+
3085
+	keyHooks: {
3086
+		props: "char charCode key keyCode".split(" "),
3087
+		filter: function( event, original ) {
3088
+
3089
+			// Add which for key events
3090
+			if ( event.which == null ) {
3091
+				event.which = original.charCode != null ? original.charCode : original.keyCode;
3092
+			}
3093
+
3094
+			return event;
3095
+		}
3096
+	},
3097
+
3098
+	mouseHooks: {
3099
+		props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
3100
+		filter: function( event, original ) {
3101
+			var eventDoc, doc, body,
3102
+				button = original.button,
3103
+				fromElement = original.fromElement;
3104
+
3105
+			// Calculate pageX/Y if missing and clientX/Y available
3106
+			if ( event.pageX == null && original.clientX != null ) {
3107
+				eventDoc = event.target.ownerDocument || document;
3108
+				doc = eventDoc.documentElement;
3109
+				body = eventDoc.body;
3110
+
3111
+				event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
3112
+				event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
3113
+			}
3114
+
3115
+			// Add relatedTarget, if necessary
3116
+			if ( !event.relatedTarget && fromElement ) {
3117
+				event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
3118
+			}
3119
+
3120
+			// Add which for click: 1 === left; 2 === middle; 3 === right
3121
+			// Note: button is not normalized, so don't use it
3122
+			if ( !event.which && button !== undefined ) {
3123
+				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
3124
+			}
3125
+
3126
+			return event;
3127
+		}
3128
+	},
3129
+
3130
+	fix: function( event ) {
3131
+		if ( event[ jQuery.expando ] ) {
3132
+			return event;
3133
+		}
3134
+
3135
+		// Create a writable copy of the event object and normalize some properties
3136
+		var i, prop,
3137
+			originalEvent = event,
3138
+			fixHook = jQuery.event.fixHooks[ event.type ] || {},
3139
+			copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
3140
+
3141
+		event = jQuery.Event( originalEvent );
3142
+
3143
+		for ( i = copy.length; i; ) {
3144
+			prop = copy[ --i ];
3145
+			event[ prop ] = originalEvent[ prop ];
3146
+		}
3147
+
3148
+		// Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)
3149
+		if ( !event.target ) {
3150
+			event.target = originalEvent.srcElement || document;
3151
+		}
3152
+
3153
+		// Target should not be a text node (#504, Safari)
3154
+		if ( event.target.nodeType === 3 ) {
3155
+			event.target = event.target.parentNode;
3156
+		}
3157
+
3158
+		// For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8)
3159
+		event.metaKey = !!event.metaKey;
3160
+
3161
+		return fixHook.filter? fixHook.filter( event, originalEvent ) : event;
3162
+	},
3163
+
3164
+	special: {
3165
+		load: {
3166
+			// Prevent triggered image.load events from bubbling to window.load
3167
+			noBubble: true
3168
+		},
3169
+
3170
+		focus: {
3171
+			delegateType: "focusin"
3172
+		},
3173
+		blur: {
3174
+			delegateType: "focusout"
3175
+		},
3176
+
3177
+		beforeunload: {
3178
+			setup: function( data, namespaces, eventHandle ) {
3179
+				// We only want to do this special case on windows
3180
+				if ( jQuery.isWindow( this ) ) {
3181
+					this.onbeforeunload = eventHandle;
3182
+				}
3183
+			},
3184
+
3185
+			teardown: function( namespaces, eventHandle ) {
3186
+				if ( this.onbeforeunload === eventHandle ) {
3187
+					this.onbeforeunload = null;
3188
+				}
3189
+			}
3190
+		}
3191
+	},
3192
+
3193
+	simulate: function( type, elem, event, bubble ) {
3194
+		// Piggyback on a donor event to simulate a different one.
3195
+		// Fake originalEvent to avoid donor's stopPropagation, but if the
3196
+		// simulated event prevents default then we do the same on the donor.
3197
+		var e = jQuery.extend(
3198
+			new jQuery.Event(),
3199
+			event,
3200
+			{ type: type,
3201
+				isSimulated: true,
3202
+				originalEvent: {}
3203
+			}
3204
+		);
3205
+		if ( bubble ) {
3206
+			jQuery.event.trigger( e, null, elem );
3207
+		} else {
3208
+			jQuery.event.dispatch.call( elem, e );
3209
+		}
3210
+		if ( e.isDefaultPrevented() ) {
3211
+			event.preventDefault();
3212
+		}
3213
+	}
3214
+};
3215
+
3216
+// Some plugins are using, but it's undocumented/deprecated and will be removed.
3217
+// The 1.7 special event interface should provide all the hooks needed now.
3218
+jQuery.event.handle = jQuery.event.dispatch;
3219
+
3220
+jQuery.removeEvent = document.removeEventListener ?
3221
+	function( elem, type, handle ) {
3222
+		if ( elem.removeEventListener ) {
3223
+			elem.removeEventListener( type, handle, false );
3224
+		}
3225
+	} :
3226
+	function( elem, type, handle ) {
3227
+		var name = "on" + type;
3228
+
3229
+		if ( elem.detachEvent ) {
3230
+
3231
+			// #8545, #7054, preventing memory leaks for custom events in IE6-8
3232
+			// detachEvent needed property on element, by name of that event, to properly expose it to GC
3233
+			if ( typeof elem[ name ] === "undefined" ) {
3234
+				elem[ name ] = null;
3235
+			}
3236
+
3237
+			elem.detachEvent( name, handle );
3238
+		}
3239
+	};
3240
+
3241
+jQuery.Event = function( src, props ) {
3242
+	// Allow instantiation without the 'new' keyword
3243
+	if ( !(this instanceof jQuery.Event) ) {
3244
+		return new jQuery.Event( src, props );
3245
+	}
3246
+
3247
+	// Event object
3248
+	if ( src && src.type ) {
3249
+		this.originalEvent = src;
3250
+		this.type = src.type;
3251
+
3252
+		// Events bubbling up the document may have been marked as prevented
3253
+		// by a handler lower down the tree; reflect the correct value.
3254
+		this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
3255
+			src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
3256
+
3257
+	// Event type
3258
+	} else {
3259
+		this.type = src;
3260
+	}
3261
+
3262
+	// Put explicitly provided properties onto the event object
3263
+	if ( props ) {
3264
+		jQuery.extend( this, props );
3265
+	}
3266
+
3267
+	// Create a timestamp if incoming event doesn't have one
3268
+	this.timeStamp = src && src.timeStamp || jQuery.now();
3269
+
3270
+	// Mark it as fixed
3271
+	this[ jQuery.expando ] = true;
3272
+};
3273
+
3274
+function returnFalse() {
3275
+	return false;
3276
+}
3277
+function returnTrue() {
3278
+	return true;
3279
+}
3280
+
3281
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3282
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3283
+jQuery.Event.prototype = {
3284
+	preventDefault: function() {
3285
+		this.isDefaultPrevented = returnTrue;
3286
+
3287
+		var e = this.originalEvent;
3288
+		if ( !e ) {
3289
+			return;
3290
+		}
3291
+
3292
+		// if preventDefault exists run it on the original event
3293
+		if ( e.preventDefault ) {
3294
+			e.preventDefault();
3295
+
3296
+		// otherwise set the returnValue property of the original event to false (IE)
3297
+		} else {
3298
+			e.returnValue = false;
3299
+		}
3300
+	},
3301
+	stopPropagation: function() {
3302
+		this.isPropagationStopped = returnTrue;
3303
+
3304
+		var e = this.originalEvent;
3305
+		if ( !e ) {
3306
+			return;
3307
+		}
3308
+		// if stopPropagation exists run it on the original event
3309
+		if ( e.stopPropagation ) {
3310
+			e.stopPropagation();
3311
+		}
3312
+		// otherwise set the cancelBubble property of the original event to true (IE)
3313
+		e.cancelBubble = true;
3314
+	},
3315
+	stopImmediatePropagation: function() {
3316
+		this.isImmediatePropagationStopped = returnTrue;
3317
+		this.stopPropagation();
3318
+	},
3319
+	isDefaultPrevented: returnFalse,
3320
+	isPropagationStopped: returnFalse,
3321
+	isImmediatePropagationStopped: returnFalse
3322
+};
3323
+
3324
+// Create mouseenter/leave events using mouseover/out and event-time checks
3325
+jQuery.each({
3326
+	mouseenter: "mouseover",
3327
+	mouseleave: "mouseout"
3328
+}, function( orig, fix ) {
3329
+	jQuery.event.special[ orig ] = {
3330
+		delegateType: fix,
3331
+		bindType: fix,
3332
+
3333
+		handle: function( event ) {
3334
+			var ret,
3335
+				target = this,
3336
+				related = event.relatedTarget,
3337
+				handleObj = event.handleObj,
3338
+				selector = handleObj.selector;
3339
+
3340
+			// For mousenter/leave call the handler if related is outside the target.
3341
+			// NB: No relatedTarget if the mouse left/entered the browser window
3342
+			if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
3343
+				event.type = handleObj.origType;
3344
+				ret = handleObj.handler.apply( this, arguments );
3345
+				event.type = fix;
3346
+			}
3347
+			return ret;
3348
+		}
3349
+	};
3350
+});
3351
+
3352
+// IE submit delegation
3353
+if ( !jQuery.support.submitBubbles ) {
3354
+
3355
+	jQuery.event.special.submit = {
3356
+		setup: function() {
3357
+			// Only need this for delegated form submit events
3358
+			if ( jQuery.nodeName( this, "form" ) ) {
3359
+				return false;
3360
+			}
3361
+
3362
+			// Lazy-add a submit handler when a descendant form may potentially be submitted
3363
+			jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
3364
+				// Node name check avoids a VML-related crash in IE (#9807)
3365
+				var elem = e.target,
3366
+					form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
3367
+				if ( form && !jQuery._data( form, "_submit_attached" ) ) {
3368
+					jQuery.event.add( form, "submit._submit", function( event ) {
3369
+						event._submit_bubble = true;
3370
+					});
3371
+					jQuery._data( form, "_submit_attached", true );
3372
+				}
3373
+			});
3374
+			// return undefined since we don't need an event listener
3375
+		},
3376
+
3377
+		postDispatch: function( event ) {
3378
+			// If form was submitted by the user, bubble the event up the tree
3379
+			if ( event._submit_bubble ) {
3380
+				delete event._submit_bubble;
3381
+				if ( this.parentNode && !event.isTrigger ) {
3382
+					jQuery.event.simulate( "submit", this.parentNode, event, true );
3383
+				}
3384
+			}
3385
+		},
3386
+
3387
+		teardown: function() {
3388
+			// Only need this for delegated form submit events
3389
+			if ( jQuery.nodeName( this, "form" ) ) {
3390
+				return false;
3391
+			}
3392
+
3393
+			// Remove delegated handlers; cleanData eventually reaps submit handlers attached above
3394
+			jQuery.event.remove( this, "._submit" );
3395
+		}
3396
+	};
3397
+}
3398
+
3399
+// IE change delegation and checkbox/radio fix
3400
+if ( !jQuery.support.changeBubbles ) {
3401
+
3402
+	jQuery.event.special.change = {
3403
+
3404
+		setup: function() {
3405
+
3406
+			if ( rformElems.test( this.nodeName ) ) {
3407
+				// IE doesn't fire change on a check/radio until blur; trigger it on click
3408
+				// after a propertychange. Eat the blur-change in special.change.handle.
3409
+				// This still fires onchange a second time for check/radio after blur.
3410
+				if ( this.type === "checkbox" || this.type === "radio" ) {
3411
+					jQuery.event.add( this, "propertychange._change", function( event ) {
3412
+						if ( event.originalEvent.propertyName === "checked" ) {
3413
+							this._just_changed = true;
3414
+						}
3415
+					});
3416
+					jQuery.event.add( this, "click._change", function( event ) {
3417
+						if ( this._just_changed && !event.isTrigger ) {
3418
+							this._just_changed = false;
3419
+						}
3420
+						// Allow triggered, simulated change events (#11500)
3421
+						jQuery.event.simulate( "change", this, event, true );
3422
+					});
3423
+				}
3424
+				return false;
3425
+			}
3426
+			// Delegated event; lazy-add a change handler on descendant inputs
3427
+			jQuery.event.add( this, "beforeactivate._change", function( e ) {
3428
+				var elem = e.target;
3429
+
3430
+				if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "_change_attached" ) ) {
3431
+					jQuery.event.add( elem, "change._change", function( event ) {
3432
+						if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
3433
+							jQuery.event.simulate( "change", this.parentNode, event, true );
3434
+						}
3435
+					});
3436
+					jQuery._data( elem, "_change_attached", true );
3437
+				}
3438
+			});
3439
+		},
3440
+
3441
+		handle: function( event ) {
3442
+			var elem = event.target;
3443
+
3444
+			// Swallow native change events from checkbox/radio, we already triggered them above
3445
+			if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
3446
+				return event.handleObj.handler.apply( this, arguments );
3447
+			}
3448
+		},
3449
+
3450
+		teardown: function() {
3451
+			jQuery.event.remove( this, "._change" );
3452
+
3453
+			return !rformElems.test( this.nodeName );
3454
+		}
3455
+	};
3456
+}
3457
+
3458
+// Create "bubbling" focus and blur events
3459
+if ( !jQuery.support.focusinBubbles ) {
3460
+	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3461
+
3462
+		// Attach a single capturing handler while someone wants focusin/focusout
3463
+		var attaches = 0,
3464
+			handler = function( event ) {
3465
+				jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
3466
+			};
3467
+
3468
+		jQuery.event.special[ fix ] = {
3469
+			setup: function() {
3470
+				if ( attaches++ === 0 ) {
3471
+					document.addEventListener( orig, handler, true );
3472
+				}
3473
+			},
3474
+			teardown: function() {
3475
+				if ( --attaches === 0 ) {
3476
+					document.removeEventListener( orig, handler, true );
3477
+				}
3478
+			}
3479
+		};
3480
+	});
3481
+}
3482
+
3483
+jQuery.fn.extend({
3484
+
3485
+	on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
3486
+		var origFn, type;
3487
+
3488
+		// Types can be a map of types/handlers
3489
+		if ( typeof types === "object" ) {
3490
+			// ( types-Object, selector, data )
3491
+			if ( typeof selector !== "string" ) { // && selector != null
3492
+				// ( types-Object, data )
3493
+				data = data || selector;
3494
+				selector = undefined;
3495
+			}
3496
+			for ( type in types ) {
3497
+				this.on( type, selector, data, types[ type ], one );
3498
+			}
3499
+			return this;
3500
+		}
3501
+
3502
+		if ( data == null && fn == null ) {
3503
+			// ( types, fn )
3504
+			fn = selector;
3505
+			data = selector = undefined;
3506
+		} else if ( fn == null ) {
3507
+			if ( typeof selector === "string" ) {
3508
+				// ( types, selector, fn )
3509
+				fn = data;
3510
+				data = undefined;
3511
+			} else {
3512
+				// ( types, data, fn )
3513
+				fn = data;
3514
+				data = selector;
3515
+				selector = undefined;
3516
+			}
3517
+		}
3518
+		if ( fn === false ) {
3519
+			fn = returnFalse;
3520
+		} else if ( !fn ) {
3521
+			return this;
3522
+		}
3523
+
3524
+		if ( one === 1 ) {
3525
+			origFn = fn;
3526
+			fn = function( event ) {
3527
+				// Can use an empty set, since event contains the info
3528
+				jQuery().off( event );
3529
+				return origFn.apply( this, arguments );
3530
+			};
3531
+			// Use same guid so caller can remove using origFn
3532
+			fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
3533
+		}
3534
+		return this.each( function() {
3535
+			jQuery.event.add( this, types, fn, data, selector );
3536
+		});
3537
+	},
3538
+	one: function( types, selector, data, fn ) {
3539
+		return this.on( types, selector, data, fn, 1 );
3540
+	},
3541
+	off: function( types, selector, fn ) {
3542
+		var handleObj, type;
3543
+		if ( types && types.preventDefault && types.handleObj ) {
3544
+			// ( event )  dispatched jQuery.Event
3545
+			handleObj = types.handleObj;
3546
+			jQuery( types.delegateTarget ).off(
3547
+				handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
3548
+				handleObj.selector,
3549
+				handleObj.handler
3550
+			);
3551
+			return this;
3552
+		}
3553
+		if ( typeof types === "object" ) {
3554
+			// ( types-object [, selector] )
3555
+			for ( type in types ) {
3556
+				this.off( type, selector, types[ type ] );
3557
+			}
3558
+			return this;
3559
+		}
3560
+		if ( selector === false || typeof selector === "function" ) {
3561
+			// ( types [, fn] )
3562
+			fn = selector;
3563
+			selector = undefined;
3564
+		}
3565
+		if ( fn === false ) {
3566
+			fn = returnFalse;
3567
+		}
3568
+		return this.each(function() {
3569
+			jQuery.event.remove( this, types, fn, selector );
3570
+		});
3571
+	},
3572
+
3573
+	bind: function( types, data, fn ) {
3574
+		return this.on( types, null, data, fn );
3575
+	},
3576
+	unbind: function( types, fn ) {
3577
+		return this.off( types, null, fn );
3578
+	},
3579
+
3580
+	live: function( types, data, fn ) {
3581
+		jQuery( this.context ).on( types, this.selector, data, fn );
3582
+		return this;
3583
+	},
3584
+	die: function( types, fn ) {
3585
+		jQuery( this.context ).off( types, this.selector || "**", fn );
3586
+		return this;
3587
+	},
3588
+
3589
+	delegate: function( selector, types, data, fn ) {
3590
+		return this.on( types, selector, data, fn );
3591
+	},
3592
+	undelegate: function( selector, types, fn ) {
3593
+		// ( namespace ) or ( selector, types [, fn] )
3594
+		return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
3595
+	},
3596
+
3597
+	trigger: function( type, data ) {
3598
+		return this.each(function() {
3599
+			jQuery.event.trigger( type, data, this );
3600
+		});
3601
+	},
3602
+	triggerHandler: function( type, data ) {
3603
+		if ( this[0] ) {
3604
+			return jQuery.event.trigger( type, data, this[0], true );
3605
+		}
3606
+	},
3607
+
3608
+	toggle: function( fn ) {
3609
+		// Save reference to arguments for access in closure
3610
+		var args = arguments,
3611
+			guid = fn.guid || jQuery.guid++,
3612
+			i = 0,
3613
+			toggler = function( event ) {
3614
+				// Figure out which function to execute
3615
+				var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3616
+				jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3617
+
3618
+				// Make sure that clicks stop
3619
+				event.preventDefault();
3620
+
3621
+				// and execute the function
3622
+				return args[ lastToggle ].apply( this, arguments ) || false;
3623
+			};
3624
+
3625
+		// link all the functions, so any of them can unbind this click handler
3626
+		toggler.guid = guid;
3627
+		while ( i < args.length ) {
3628
+			args[ i++ ].guid = guid;
3629
+		}
3630
+
3631
+		return this.click( toggler );
3632
+	},
3633
+
3634
+	hover: function( fnOver, fnOut ) {
3635
+		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3636
+	}
3637
+});
3638
+
3639
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3640
+	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3641
+	"change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
3642
+
3643
+	// Handle event binding
3644
+	jQuery.fn[ name ] = function( data, fn ) {
3645
+		if ( fn == null ) {
3646
+			fn = data;
3647
+			data = null;
3648
+		}
3649
+
3650
+		return arguments.length > 0 ?
3651
+			this.on( name, null, data, fn ) :
3652
+			this.trigger( name );
3653
+	};
3654
+
3655
+	if ( rkeyEvent.test( name ) ) {
3656
+		jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;
3657
+	}
3658
+
3659
+	if ( rmouseEvent.test( name ) ) {
3660
+		jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;
3661
+	}
3662
+});
3663
+/*!
3664
+ * Sizzle CSS Selector Engine
3665
+ * Copyright 2012 jQuery Foundation and other contributors
3666
+ * Released under the MIT license
3667
+ * http://sizzlejs.com/
3668
+ */
3669
+(function( window, undefined ) {
3670
+
3671
+var cachedruns,
3672
+	assertGetIdNotName,
3673
+	Expr,
3674
+	getText,
3675
+	isXML,
3676
+	contains,
3677
+	compile,
3678
+	sortOrder,
3679
+	hasDuplicate,
3680
+	outermostContext,
3681
+
3682
+	baseHasDuplicate = true,
3683
+	strundefined = "undefined",
3684
+
3685
+	expando = ( "sizcache" + Math.random() ).replace( ".", "" ),
3686
+
3687
+	Token = String,
3688
+	document = window.document,
3689
+	docElem = document.documentElement,
3690
+	dirruns = 0,
3691
+	done = 0,
3692
+	pop = [].pop,
3693
+	push = [].push,
3694
+	slice = [].slice,
3695
+	// Use a stripped-down indexOf if a native one is unavailable
3696
+	indexOf = [].indexOf || function( elem ) {
3697
+		var i = 0,
3698
+			len = this.length;
3699
+		for ( ; i < len; i++ ) {
3700
+			if ( this[i] === elem ) {
3701
+				return i;
3702
+			}
3703
+		}
3704
+		return -1;
3705
+	},
3706
+
3707
+	// Augment a function for special use by Sizzle
3708
+	markFunction = function( fn, value ) {
3709
+		fn[ expando ] = value == null || value;
3710
+		return fn;
3711
+	},
3712
+
3713
+	createCache = function() {
3714
+		var cache = {},
3715
+			keys = [];
3716
+
3717
+		return markFunction(function( key, value ) {
3718
+			// Only keep the most recent entries
3719
+			if ( keys.push( key ) > Expr.cacheLength ) {
3720
+				delete cache[ keys.shift() ];
3721
+			}
3722
+
3723
+			// Retrieve with (key + " ") to avoid collision with native Object.prototype properties (see Issue #157)
3724
+			return (cache[ key + " " ] = value);
3725
+		}, cache );
3726
+	},
3727
+
3728
+	classCache = createCache(),
3729
+	tokenCache = createCache(),
3730
+	compilerCache = createCache(),
3731
+
3732
+	// Regex
3733
+
3734
+	// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
3735
+	whitespace = "[\\x20\\t\\r\\n\\f]",
3736
+	// http://www.w3.org/TR/css3-syntax/#characters
3737
+	characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",
3738
+
3739
+	// Loosely modeled on CSS identifier characters
3740
+	// An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors)
3741
+	// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
3742
+	identifier = characterEncoding.replace( "w", "w#" ),
3743
+
3744
+	// Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
3745
+	operators = "([*^$|!~]?=)",
3746
+	attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
3747
+		"*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
3748
+
3749
+	// Prefer arguments not in parens/brackets,
3750
+	//   then attribute selectors and non-pseudos (denoted by :),
3751
+	//   then anything else
3752
+	// These preferences are here to reduce the number of selectors
3753
+	//   needing tokenize in the PSEUDO preFilter
3754
+	pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)",
3755
+
3756
+	// For matchExpr.POS and matchExpr.needsContext
3757
+	pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
3758
+		"*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)",
3759
+
3760
+	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
3761
+	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
3762
+
3763
+	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
3764
+	rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ),
3765
+	rpseudo = new RegExp( pseudos ),
3766
+
3767
+	// Easily-parseable/retrievable ID or TAG or CLASS selectors
3768
+	rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,
3769
+
3770
+	rnot = /^:not/,
3771
+	rsibling = /[\x20\t\r\n\f]*[+~]/,
3772
+	rendsWithNot = /:not\($/,
3773
+
3774
+	rheader = /h\d/i,
3775
+	rinputs = /input|select|textarea|button/i,
3776
+
3777
+	rbackslash = /\\(?!\\)/g,
3778
+
3779
+	matchExpr = {
3780
+		"ID": new RegExp( "^#(" + characterEncoding + ")" ),
3781
+		"CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
3782
+		"NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ),
3783
+		"TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
3784
+		"ATTR": new RegExp( "^" + attributes ),
3785
+		"PSEUDO": new RegExp( "^" + pseudos ),
3786
+		"POS": new RegExp( pos, "i" ),
3787
+		"CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace +
3788
+			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
3789
+			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
3790
+		// For use in libraries implementing .is()
3791
+		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" )
3792
+	},
3793
+
3794
+	// Support
3795
+
3796
+	// Used for testing something on an element
3797
+	assert = function( fn ) {
3798
+		var div = document.createElement("div");
3799
+
3800
+		try {
3801
+			return fn( div );
3802
+		} catch (e) {
3803
+			return false;
3804
+		} finally {
3805
+			// release memory in IE
3806
+			div = null;
3807
+		}
3808
+	},
3809
+
3810
+	// Check if getElementsByTagName("*") returns only elements
3811
+	assertTagNameNoComments = assert(function( div ) {
3812
+		div.appendChild( document.createComment("") );
3813
+		return !div.getElementsByTagName("*").length;
3814
+	}),
3815
+
3816
+	// Check if getAttribute returns normalized href attributes
3817
+	assertHrefNotNormalized = assert(function( div ) {
3818
+		div.innerHTML = "<a href='#'></a>";
3819
+		return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&
3820
+			div.firstChild.getAttribute("href") === "#";
3821
+	}),
3822
+
3823
+	// Check if attributes should be retrieved by attribute nodes
3824
+	assertAttributes = assert(function( div ) {
3825
+		div.innerHTML = "<select></select>";
3826
+		var type = typeof div.lastChild.getAttribute("multiple");
3827
+		// IE8 returns a string for some attributes even when not present
3828
+		return type !== "boolean" && type !== "string";
3829
+	}),
3830
+
3831
+	// Check if getElementsByClassName can be trusted
3832
+	assertUsableClassName = assert(function( div ) {
3833
+		// Opera can't find a second classname (in 9.6)
3834
+		div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
3835
+		if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) {
3836
+			return false;
3837
+		}
3838
+
3839
+		// Safari 3.2 caches class attributes and doesn't catch changes
3840
+		div.lastChild.className = "e";
3841
+		return div.getElementsByClassName("e").length === 2;
3842
+	}),
3843
+
3844
+	// Check if getElementById returns elements by name
3845
+	// Check if getElementsByName privileges form controls or returns elements by ID
3846
+	assertUsableName = assert(function( div ) {
3847
+		// Inject content
3848
+		div.id = expando + 0;
3849
+		div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>";
3850
+		docElem.insertBefore( div, docElem.firstChild );
3851
+
3852
+		// Test
3853
+		var pass = document.getElementsByName &&
3854
+			// buggy browsers will return fewer than the correct 2
3855
+			document.getElementsByName( expando ).length === 2 +
3856
+			// buggy browsers will return more than the correct 0
3857
+			document.getElementsByName( expando + 0 ).length;
3858
+		assertGetIdNotName = !document.getElementById( expando );
3859
+
3860
+		// Cleanup
3861
+		docElem.removeChild( div );
3862
+
3863
+		return pass;
3864
+	});
3865
+
3866
+// If slice is not available, provide a backup
3867
+try {
3868
+	slice.call( docElem.childNodes, 0 )[0].nodeType;
3869
+} catch ( e ) {
3870
+	slice = function( i ) {
3871
+		var elem,
3872
+			results = [];
3873
+		for ( ; (elem = this[i]); i++ ) {
3874
+			results.push( elem );
3875
+		}
3876
+		return results;
3877
+	};
3878
+}
3879
+
3880
+function Sizzle( selector, context, results, seed ) {
3881
+	results = results || [];
3882
+	context = context || document;
3883
+	var match, elem, xml, m,
3884
+		nodeType = context.nodeType;
3885
+
3886
+	if ( !selector || typeof selector !== "string" ) {
3887
+		return results;
3888
+	}
3889
+
3890
+	if ( nodeType !== 1 && nodeType !== 9 ) {
3891
+		return [];
3892
+	}
3893
+
3894
+	xml = isXML( context );
3895
+
3896
+	if ( !xml && !seed ) {
3897
+		if ( (match = rquickExpr.exec( selector )) ) {
3898
+			// Speed-up: Sizzle("#ID")
3899
+			if ( (m = match[1]) ) {
3900
+				if ( nodeType === 9 ) {
3901
+					elem = context.getElementById( m );
3902
+					// Check parentNode to catch when Blackberry 4.6 returns
3903
+					// nodes that are no longer in the document #6963
3904
+					if ( elem && elem.parentNode ) {
3905
+						// Handle the case where IE, Opera, and Webkit return items
3906
+						// by name instead of ID
3907
+						if ( elem.id === m ) {
3908
+							results.push( elem );
3909
+							return results;
3910
+						}
3911
+					} else {
3912
+						return results;
3913
+					}
3914
+				} else {
3915
+					// Context is not a document
3916
+					if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
3917
+						contains( context, elem ) && elem.id === m ) {
3918
+						results.push( elem );
3919
+						return results;
3920
+					}
3921
+				}
3922
+
3923
+			// Speed-up: Sizzle("TAG")
3924
+			} else if ( match[2] ) {
3925
+				push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) );
3926
+				return results;
3927
+
3928
+			// Speed-up: Sizzle(".CLASS")
3929
+			} else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) {
3930
+				push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
3931
+				return results;
3932
+			}
3933
+		}
3934
+	}
3935
+
3936
+	// All others
3937
+	return select( selector.replace( rtrim, "$1" ), context, results, seed, xml );
3938
+}
3939
+
3940
+Sizzle.matches = function( expr, elements ) {
3941
+	return Sizzle( expr, null, null, elements );
3942
+};
3943
+
3944
+Sizzle.matchesSelector = function( elem, expr ) {
3945
+	return Sizzle( expr, null, null, [ elem ] ).length > 0;
3946
+};
3947
+
3948
+// Returns a function to use in pseudos for input types
3949
+function createInputPseudo( type ) {
3950
+	return function( elem ) {
3951
+		var name = elem.nodeName.toLowerCase();
3952
+		return name === "input" && elem.type === type;
3953
+	};
3954
+}
3955
+
3956
+// Returns a function to use in pseudos for buttons
3957
+function createButtonPseudo( type ) {
3958
+	return function( elem ) {
3959
+		var name = elem.nodeName.toLowerCase();
3960
+		return (name === "input" || name === "button") && elem.type === type;
3961
+	};
3962
+}
3963
+
3964
+// Returns a function to use in pseudos for positionals
3965
+function createPositionalPseudo( fn ) {
3966
+	return markFunction(function( argument ) {
3967
+		argument = +argument;
3968
+		return markFunction(function( seed, matches ) {
3969
+			var j,
3970
+				matchIndexes = fn( [], seed.length, argument ),
3971
+				i = matchIndexes.length;
3972
+
3973
+			// Match elements found at the specified indexes
3974
+			while ( i-- ) {
3975
+				if ( seed[ (j = matchIndexes[i]) ] ) {
3976
+					seed[j] = !(matches[j] = seed[j]);
3977
+				}
3978
+			}
3979
+		});
3980
+	});
3981
+}
3982
+
3983
+/**
3984
+ * Utility function for retrieving the text value of an array of DOM nodes
3985
+ * @param {Array|Element} elem
3986
+ */
3987
+getText = Sizzle.getText = function( elem ) {
3988
+	var node,
3989
+		ret = "",
3990
+		i = 0,
3991
+		nodeType = elem.nodeType;
3992
+
3993
+	if ( nodeType ) {
3994
+		if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
3995
+			// Use textContent for elements
3996
+			// innerText usage removed for consistency of new lines (see #11153)
3997
+			if ( typeof elem.textContent === "string" ) {
3998
+				return elem.textContent;
3999
+			} else {
4000
+				// Traverse its children
4001
+				for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
4002
+					ret += getText( elem );
4003
+				}
4004
+			}
4005
+		} else if ( nodeType === 3 || nodeType === 4 ) {
4006
+			return elem.nodeValue;
4007
+		}
4008
+		// Do not include comment or processing instruction nodes
4009
+	} else {
4010
+
4011
+		// If no nodeType, this is expected to be an array
4012
+		for ( ; (node = elem[i]); i++ ) {
4013
+			// Do not traverse comment nodes
4014
+			ret += getText( node );
4015
+		}
4016
+	}
4017
+	return ret;
4018
+};
4019
+
4020
+isXML = Sizzle.isXML = function( elem ) {
4021
+	// documentElement is verified for cases where it doesn't yet exist
4022
+	// (such as loading iframes in IE - #4833)
4023
+	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
4024
+	return documentElement ? documentElement.nodeName !== "HTML" : false;
4025
+};
4026
+
4027
+// Element contains another
4028
+contains = Sizzle.contains = docElem.contains ?
4029
+	function( a, b ) {
4030
+		var adown = a.nodeType === 9 ? a.documentElement : a,
4031
+			bup = b && b.parentNode;
4032
+		return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) );
4033
+	} :
4034
+	docElem.compareDocumentPosition ?
4035
+	function( a, b ) {
4036
+		return b && !!( a.compareDocumentPosition( b ) & 16 );
4037
+	} :
4038
+	function( a, b ) {
4039
+		while ( (b = b.parentNode) ) {
4040
+			if ( b === a ) {
4041
+				return true;
4042
+			}
4043
+		}
4044
+		return false;
4045
+	};
4046
+
4047
+Sizzle.attr = function( elem, name ) {
4048
+	var val,
4049
+		xml = isXML( elem );
4050
+
4051
+	if ( !xml ) {
4052
+		name = name.toLowerCase();
4053
+	}
4054
+	if ( (val = Expr.attrHandle[ name ]) ) {
4055
+		return val( elem );
4056
+	}
4057
+	if ( xml || assertAttributes ) {
4058
+		return elem.getAttribute( name );
4059
+	}
4060
+	val = elem.getAttributeNode( name );
4061
+	return val ?
4062
+		typeof elem[ name ] === "boolean" ?
4063
+			elem[ name ] ? name : null :
4064
+			val.specified ? val.value : null :
4065
+		null;
4066
+};
4067
+
4068
+Expr = Sizzle.selectors = {
4069
+
4070
+	// Can be adjusted by the user
4071
+	cacheLength: 50,
4072
+
4073
+	createPseudo: markFunction,
4074
+
4075
+	match: matchExpr,
4076
+
4077
+	// IE6/7 return a modified href
4078
+	attrHandle: assertHrefNotNormalized ?
4079
+		{} :
4080
+		{
4081
+			"href": function( elem ) {
4082
+				return elem.getAttribute( "href", 2 );
4083
+			},
4084
+			"type": function( elem ) {
4085
+				return elem.getAttribute("type");
4086
+			}
4087
+		},
4088
+
4089
+	find: {
4090
+		"ID": assertGetIdNotName ?
4091
+			function( id, context, xml ) {
4092
+				if ( typeof context.getElementById !== strundefined && !xml ) {
4093
+					var m = context.getElementById( id );
4094
+					// Check parentNode to catch when Blackberry 4.6 returns
4095
+					// nodes that are no longer in the document #6963
4096
+					return m && m.parentNode ? [m] : [];
4097
+				}
4098
+			} :
4099
+			function( id, context, xml ) {
4100
+				if ( typeof context.getElementById !== strundefined && !xml ) {
4101
+					var m = context.getElementById( id );
4102
+
4103
+					return m ?
4104
+						m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ?
4105
+							[m] :
4106
+							undefined :
4107
+						[];
4108
+				}
4109
+			},
4110
+
4111
+		"TAG": assertTagNameNoComments ?
4112
+			function( tag, context ) {
4113
+				if ( typeof context.getElementsByTagName !== strundefined ) {
4114
+					return context.getElementsByTagName( tag );
4115
+				}
4116
+			} :
4117
+			function( tag, context ) {
4118
+				var results = context.getElementsByTagName( tag );
4119
+
4120
+				// Filter out possible comments
4121
+				if ( tag === "*" ) {
4122
+					var elem,
4123
+						tmp = [],
4124
+						i = 0;
4125
+
4126
+					for ( ; (elem = results[i]); i++ ) {
4127
+						if ( elem.nodeType === 1 ) {
4128
+							tmp.push( elem );
4129
+						}
4130
+					}
4131
+
4132
+					return tmp;
4133
+				}
4134
+				return results;
4135
+			},
4136
+
4137
+		"NAME": assertUsableName && function( tag, context ) {
4138
+			if ( typeof context.getElementsByName !== strundefined ) {
4139
+				return context.getElementsByName( name );
4140
+			}
4141
+		},
4142
+
4143
+		"CLASS": assertUsableClassName && function( className, context, xml ) {
4144
+			if ( typeof context.getElementsByClassName !== strundefined && !xml ) {
4145
+				return context.getElementsByClassName( className );
4146
+			}
4147
+		}
4148
+	},
4149
+
4150
+	relative: {
4151
+		">": { dir: "parentNode", first: true },
4152
+		" ": { dir: "parentNode" },
4153
+		"+": { dir: "previousSibling", first: true },
4154
+		"~": { dir: "previousSibling" }
4155
+	},
4156
+
4157
+	preFilter: {
4158
+		"ATTR": function( match ) {
4159
+			match[1] = match[1].replace( rbackslash, "" );
4160
+
4161
+			// Move the given value to match[3] whether quoted or unquoted
4162
+			match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" );
4163
+
4164
+			if ( match[2] === "~=" ) {
4165
+				match[3] = " " + match[3] + " ";
4166
+			}
4167
+
4168
+			return match.slice( 0, 4 );
4169
+		},
4170
+
4171
+		"CHILD": function( match ) {
4172
+			/* matches from matchExpr["CHILD"]
4173
+				1 type (only|nth|...)
4174
+				2 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
4175
+				3 xn-component of xn+y argument ([+-]?\d*n|)
4176
+				4 sign of xn-component
4177
+				5 x of xn-component
4178
+				6 sign of y-component
4179
+				7 y of y-component
4180
+			*/
4181
+			match[1] = match[1].toLowerCase();
4182
+
4183
+			if ( match[1] === "nth" ) {
4184
+				// nth-child requires argument
4185
+				if ( !match[2] ) {
4186
+					Sizzle.error( match[0] );
4187
+				}
4188
+
4189
+				// numeric x and y parameters for Expr.filter.CHILD
4190
+				// remember that false/true cast respectively to 0/1
4191
+				match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) );
4192
+				match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" );
4193
+
4194
+			// other types prohibit arguments
4195
+			} else if ( match[2] ) {
4196
+				Sizzle.error( match[0] );
4197
+			}
4198
+
4199
+			return match;
4200
+		},
4201
+
4202
+		"PSEUDO": function( match ) {
4203
+			var unquoted, excess;
4204
+			if ( matchExpr["CHILD"].test( match[0] ) ) {
4205
+				return null;
4206
+			}
4207
+
4208
+			if ( match[3] ) {
4209
+				match[2] = match[3];
4210
+			} else if ( (unquoted = match[4]) ) {
4211
+				// Only check arguments that contain a pseudo
4212
+				if ( rpseudo.test(unquoted) &&
4213
+					// Get excess from tokenize (recursively)
4214
+					(excess = tokenize( unquoted, true )) &&
4215
+					// advance to the next closing parenthesis
4216
+					(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
4217
+
4218
+					// excess is a negative index
4219
+					unquoted = unquoted.slice( 0, excess );
4220
+					match[0] = match[0].slice( 0, excess );
4221
+				}
4222
+				match[2] = unquoted;
4223
+			}
4224
+
4225
+			// Return only captures needed by the pseudo filter method (type and argument)
4226
+			return match.slice( 0, 3 );
4227
+		}
4228
+	},
4229
+
4230
+	filter: {
4231
+		"ID": assertGetIdNotName ?
4232
+			function( id ) {
4233
+				id = id.replace( rbackslash, "" );
4234
+				return function( elem ) {
4235
+					return elem.getAttribute("id") === id;
4236
+				};
4237
+			} :
4238
+			function( id ) {
4239
+				id = id.replace( rbackslash, "" );
4240
+				return function( elem ) {
4241
+					var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
4242
+					return node && node.value === id;
4243
+				};
4244
+			},
4245
+
4246
+		"TAG": function( nodeName ) {
4247
+			if ( nodeName === "*" ) {
4248
+				return function() { return true; };
4249
+			}
4250
+			nodeName = nodeName.replace( rbackslash, "" ).toLowerCase();
4251
+
4252
+			return function( elem ) {
4253
+				return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
4254
+			};
4255
+		},
4256
+
4257
+		"CLASS": function( className ) {
4258
+			var pattern = classCache[ expando ][ className + " " ];
4259
+
4260
+			return pattern ||
4261
+				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
4262
+				classCache( className, function( elem ) {
4263
+					return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" );
4264
+				});
4265
+		},
4266
+
4267
+		"ATTR": function( name, operator, check ) {
4268
+			return function( elem, context ) {
4269
+				var result = Sizzle.attr( elem, name );
4270
+
4271
+				if ( result == null ) {
4272
+					return operator === "!=";
4273
+				}
4274
+				if ( !operator ) {
4275
+					return true;
4276
+				}
4277
+
4278
+				result += "";
4279
+
4280
+				return operator === "=" ? result === check :
4281
+					operator === "!=" ? result !== check :
4282
+					operator === "^=" ? check && result.indexOf( check ) === 0 :
4283
+					operator === "*=" ? check && result.indexOf( check ) > -1 :
4284
+					operator === "$=" ? check && result.substr( result.length - check.length ) === check :
4285
+					operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
4286
+					operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" :
4287
+					false;
4288
+			};
4289
+		},
4290
+
4291
+		"CHILD": function( type, argument, first, last ) {
4292
+
4293
+			if ( type === "nth" ) {
4294
+				return function( elem ) {
4295
+					var node, diff,
4296
+						parent = elem.parentNode;
4297
+
4298
+					if ( first === 1 && last === 0 ) {
4299
+						return true;
4300
+					}
4301
+
4302
+					if ( parent ) {
4303
+						diff = 0;
4304
+						for ( node = parent.firstChild; node; node = node.nextSibling ) {
4305
+							if ( node.nodeType === 1 ) {
4306
+								diff++;
4307
+								if ( elem === node ) {
4308
+									break;
4309
+								}
4310
+							}
4311
+						}
4312
+					}
4313
+
4314
+					// Incorporate the offset (or cast to NaN), then check against cycle size
4315
+					diff -= last;
4316
+					return diff === first || ( diff % first === 0 && diff / first >= 0 );
4317
+				};
4318
+			}
4319
+
4320
+			return function( elem ) {
4321
+				var node = elem;
4322
+
4323
+				switch ( type ) {
4324
+					case "only":
4325
+					case "first":
4326
+						while ( (node = node.previousSibling) ) {
4327
+							if ( node.nodeType === 1 ) {
4328
+								return false;
4329
+							}
4330
+						}
4331
+
4332
+						if ( type === "first" ) {
4333
+							return true;
4334
+						}
4335
+
4336
+						node = elem;
4337
+
4338
+						/* falls through */
4339
+					case "last":
4340
+						while ( (node = node.nextSibling) ) {
4341
+							if ( node.nodeType === 1 ) {
4342
+								return false;
4343
+							}
4344
+						}
4345
+
4346
+						return true;
4347
+				}
4348
+			};
4349
+		},
4350
+
4351
+		"PSEUDO": function( pseudo, argument ) {
4352
+			// pseudo-class names are case-insensitive
4353
+			// http://www.w3.org/TR/selectors/#pseudo-classes
4354
+			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
4355
+			// Remember that setFilters inherits from pseudos
4356
+			var args,
4357
+				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
4358
+					Sizzle.error( "unsupported pseudo: " + pseudo );
4359
+
4360
+			// The user may use createPseudo to indicate that
4361
+			// arguments are needed to create the filter function
4362
+			// just as Sizzle does
4363
+			if ( fn[ expando ] ) {
4364
+				return fn( argument );
4365
+			}
4366
+
4367
+			// But maintain support for old signatures
4368
+			if ( fn.length > 1 ) {
4369
+				args = [ pseudo, pseudo, "", argument ];
4370
+				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
4371
+					markFunction(function( seed, matches ) {
4372
+						var idx,
4373
+							matched = fn( seed, argument ),
4374
+							i = matched.length;
4375
+						while ( i-- ) {
4376
+							idx = indexOf.call( seed, matched[i] );
4377
+							seed[ idx ] = !( matches[ idx ] = matched[i] );
4378
+						}
4379
+					}) :
4380
+					function( elem ) {
4381
+						return fn( elem, 0, args );
4382
+					};
4383
+			}
4384
+
4385
+			return fn;
4386
+		}
4387
+	},
4388
+
4389
+	pseudos: {
4390
+		"not": markFunction(function( selector ) {
4391
+			// Trim the selector passed to compile
4392
+			// to avoid treating leading and trailing
4393
+			// spaces as combinators
4394
+			var input = [],
4395
+				results = [],
4396
+				matcher = compile( selector.replace( rtrim, "$1" ) );
4397
+
4398
+			return matcher[ expando ] ?
4399
+				markFunction(function( seed, matches, context, xml ) {
4400
+					var elem,
4401
+						unmatched = matcher( seed, null, xml, [] ),
4402
+						i = seed.length;
4403
+
4404
+					// Match elements unmatched by `matcher`
4405
+					while ( i-- ) {
4406
+						if ( (elem = unmatched[i]) ) {
4407
+							seed[i] = !(matches[i] = elem);
4408
+						}
4409
+					}
4410
+				}) :
4411
+				function( elem, context, xml ) {
4412
+					input[0] = elem;
4413
+					matcher( input, null, xml, results );
4414
+					return !results.pop();
4415
+				};
4416
+		}),
4417
+
4418
+		"has": markFunction(function( selector ) {
4419
+			return function( elem ) {
4420
+				return Sizzle( selector, elem ).length > 0;
4421
+			};
4422
+		}),
4423
+
4424
+		"contains": markFunction(function( text ) {
4425
+			return function( elem ) {
4426
+				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
4427
+			};
4428
+		}),
4429
+
4430
+		"enabled": function( elem ) {
4431
+			return elem.disabled === false;
4432
+		},
4433
+
4434
+		"disabled": function( elem ) {
4435
+			return elem.disabled === true;
4436
+		},
4437
+
4438
+		"checked": function( elem ) {
4439
+			// In CSS3, :checked should return both checked and selected elements
4440
+			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
4441
+			var nodeName = elem.nodeName.toLowerCase();
4442
+			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
4443
+		},
4444
+
4445
+		"selected": function( elem ) {
4446
+			// Accessing this property makes selected-by-default
4447
+			// options in Safari work properly
4448
+			if ( elem.parentNode ) {
4449
+				elem.parentNode.selectedIndex;
4450
+			}
4451
+
4452
+			return elem.selected === true;
4453
+		},
4454
+
4455
+		"parent": function( elem ) {
4456
+			return !Expr.pseudos["empty"]( elem );
4457
+		},
4458
+
4459
+		"empty": function( elem ) {
4460
+			// http://www.w3.org/TR/selectors/#empty-pseudo
4461
+			// :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
4462
+			//   not comment, processing instructions, or others
4463
+			// Thanks to Diego Perini for the nodeName shortcut
4464
+			//   Greater than "@" means alpha characters (specifically not starting with "#" or "?")
4465
+			var nodeType;
4466
+			elem = elem.firstChild;
4467
+			while ( elem ) {
4468
+				if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) {
4469
+					return false;
4470
+				}
4471
+				elem = elem.nextSibling;
4472
+			}
4473
+			return true;
4474
+		},
4475
+
4476
+		"header": function( elem ) {
4477
+			return rheader.test( elem.nodeName );
4478
+		},
4479
+
4480
+		"text": function( elem ) {
4481
+			var type, attr;
4482
+			// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
4483
+			// use getAttribute instead to test this case
4484
+			return elem.nodeName.toLowerCase() === "input" &&
4485
+				(type = elem.type) === "text" &&
4486
+				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type );
4487
+		},
4488
+
4489
+		// Input types
4490
+		"radio": createInputPseudo("radio"),
4491
+		"checkbox": createInputPseudo("checkbox"),
4492
+		"file": createInputPseudo("file"),
4493
+		"password": createInputPseudo("password"),
4494
+		"image": createInputPseudo("image"),
4495
+
4496
+		"submit": createButtonPseudo("submit"),
4497
+		"reset": createButtonPseudo("reset"),
4498
+
4499
+		"button": function( elem ) {
4500
+			var name = elem.nodeName.toLowerCase();
4501
+			return name === "input" && elem.type === "button" || name === "button";
4502
+		},
4503
+
4504
+		"input": function( elem ) {
4505
+			return rinputs.test( elem.nodeName );
4506
+		},
4507
+
4508
+		"focus": function( elem ) {
4509
+			var doc = elem.ownerDocument;
4510
+			return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
4511
+		},
4512
+
4513
+		"active": function( elem ) {
4514
+			return elem === elem.ownerDocument.activeElement;
4515
+		},
4516
+
4517
+		// Positional types
4518
+		"first": createPositionalPseudo(function() {
4519
+			return [ 0 ];
4520
+		}),
4521
+
4522
+		"last": createPositionalPseudo(function( matchIndexes, length ) {
4523
+			return [ length - 1 ];
4524
+		}),
4525
+
4526
+		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
4527
+			return [ argument < 0 ? argument + length : argument ];
4528
+		}),
4529
+
4530
+		"even": createPositionalPseudo(function( matchIndexes, length ) {
4531
+			for ( var i = 0; i < length; i += 2 ) {
4532
+				matchIndexes.push( i );
4533
+			}
4534
+			return matchIndexes;
4535
+		}),
4536
+
4537
+		"odd": createPositionalPseudo(function( matchIndexes, length ) {
4538
+			for ( var i = 1; i < length; i += 2 ) {
4539
+				matchIndexes.push( i );
4540
+			}
4541
+			return matchIndexes;
4542
+		}),
4543
+
4544
+		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
4545
+			for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) {
4546
+				matchIndexes.push( i );
4547
+			}
4548
+			return matchIndexes;
4549
+		}),
4550
+
4551
+		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
4552
+			for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) {
4553
+				matchIndexes.push( i );
4554
+			}
4555
+			return matchIndexes;
4556
+		})
4557
+	}
4558
+};
4559
+
4560
+function siblingCheck( a, b, ret ) {
4561
+	if ( a === b ) {
4562
+		return ret;
4563
+	}
4564
+
4565
+	var cur = a.nextSibling;
4566
+
4567
+	while ( cur ) {
4568
+		if ( cur === b ) {
4569
+			return -1;
4570
+		}
4571
+
4572
+		cur = cur.nextSibling;
4573
+	}
4574
+
4575
+	return 1;
4576
+}
4577
+
4578
+sortOrder = docElem.compareDocumentPosition ?
4579
+	function( a, b ) {
4580
+		if ( a === b ) {
4581
+			hasDuplicate = true;
4582
+			return 0;
4583
+		}
4584
+
4585
+		return ( !a.compareDocumentPosition || !b.compareDocumentPosition ?
4586
+			a.compareDocumentPosition :
4587
+			a.compareDocumentPosition(b) & 4
4588
+		) ? -1 : 1;
4589
+	} :
4590
+	function( a, b ) {
4591
+		// The nodes are identical, we can exit early
4592
+		if ( a === b ) {
4593
+			hasDuplicate = true;
4594
+			return 0;
4595
+
4596
+		// Fallback to using sourceIndex (in IE) if it's available on both nodes
4597
+		} else if ( a.sourceIndex && b.sourceIndex ) {
4598
+			return a.sourceIndex - b.sourceIndex;
4599
+		}
4600
+
4601
+		var al, bl,
4602
+			ap = [],
4603
+			bp = [],
4604
+			aup = a.parentNode,
4605
+			bup = b.parentNode,
4606
+			cur = aup;
4607
+
4608
+		// If the nodes are siblings (or identical) we can do a quick check
4609
+		if ( aup === bup ) {
4610
+			return siblingCheck( a, b );
4611
+
4612
+		// If no parents were found then the nodes are disconnected
4613
+		} else if ( !aup ) {
4614
+			return -1;
4615
+
4616
+		} else if ( !bup ) {
4617
+			return 1;
4618
+		}
4619
+
4620
+		// Otherwise they're somewhere else in the tree so we need
4621
+		// to build up a full list of the parentNodes for comparison
4622
+		while ( cur ) {
4623
+			ap.unshift( cur );
4624
+			cur = cur.parentNode;
4625
+		}
4626
+
4627
+		cur = bup;
4628
+
4629
+		while ( cur ) {
4630
+			bp.unshift( cur );
4631
+			cur = cur.parentNode;
4632
+		}
4633
+
4634
+		al = ap.length;
4635
+		bl = bp.length;
4636
+
4637
+		// Start walking down the tree looking for a discrepancy
4638
+		for ( var i = 0; i < al && i < bl; i++ ) {
4639
+			if ( ap[i] !== bp[i] ) {
4640
+				return siblingCheck( ap[i], bp[i] );
4641
+			}
4642
+		}
4643
+
4644
+		// We ended someplace up the tree so do a sibling check
4645
+		return i === al ?
4646
+			siblingCheck( a, bp[i], -1 ) :
4647
+			siblingCheck( ap[i], b, 1 );
4648
+	};
4649
+
4650
+// Always assume the presence of duplicates if sort doesn't
4651
+// pass them to our comparison function (as in Google Chrome).
4652
+[0, 0].sort( sortOrder );
4653
+baseHasDuplicate = !hasDuplicate;
4654
+
4655
+// Document sorting and removing duplicates
4656
+Sizzle.uniqueSort = function( results ) {
4657
+	var elem,
4658
+		duplicates = [],
4659
+		i = 1,
4660
+		j = 0;
4661
+
4662
+	hasDuplicate = baseHasDuplicate;
4663
+	results.sort( sortOrder );
4664
+
4665
+	if ( hasDuplicate ) {
4666
+		for ( ; (elem = results[i]); i++ ) {
4667
+			if ( elem === results[ i - 1 ] ) {
4668
+				j = duplicates.push( i );
4669
+			}
4670
+		}
4671
+		while ( j-- ) {
4672
+			results.splice( duplicates[ j ], 1 );
4673
+		}
4674
+	}
4675
+
4676
+	return results;
4677
+};
4678
+
4679
+Sizzle.error = function( msg ) {
4680
+	throw new Error( "Syntax error, unrecognized expression: " + msg );
4681
+};
4682
+
4683
+function tokenize( selector, parseOnly ) {
4684
+	var matched, match, tokens, type,
4685
+		soFar, groups, preFilters,
4686
+		cached = tokenCache[ expando ][ selector + " " ];
4687
+
4688
+	if ( cached ) {
4689
+		return parseOnly ? 0 : cached.slice( 0 );
4690
+	}
4691
+
4692
+	soFar = selector;
4693
+	groups = [];
4694
+	preFilters = Expr.preFilter;
4695
+
4696
+	while ( soFar ) {
4697
+
4698
+		// Comma and first run
4699
+		if ( !matched || (match = rcomma.exec( soFar )) ) {
4700
+			if ( match ) {
4701
+				// Don't consume trailing commas as valid
4702
+				soFar = soFar.slice( match[0].length ) || soFar;
4703
+			}
4704
+			groups.push( tokens = [] );
4705
+		}
4706
+
4707
+		matched = false;
4708
+
4709
+		// Combinators
4710
+		if ( (match = rcombinators.exec( soFar )) ) {
4711
+			tokens.push( matched = new Token( match.shift() ) );
4712
+			soFar = soFar.slice( matched.length );
4713
+
4714
+			// Cast descendant combinators to space
4715
+			matched.type = match[0].replace( rtrim, " " );
4716
+		}
4717
+
4718
+		// Filters
4719
+		for ( type in Expr.filter ) {
4720
+			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
4721
+				(match = preFilters[ type ]( match ))) ) {
4722
+
4723
+				tokens.push( matched = new Token( match.shift() ) );
4724
+				soFar = soFar.slice( matched.length );
4725
+				matched.type = type;
4726
+				matched.matches = match;
4727
+			}
4728
+		}
4729
+
4730
+		if ( !matched ) {
4731
+			break;
4732
+		}
4733
+	}
4734
+
4735
+	// Return the length of the invalid excess
4736
+	// if we're just parsing
4737
+	// Otherwise, throw an error or return tokens
4738
+	return parseOnly ?
4739
+		soFar.length :
4740
+		soFar ?
4741
+			Sizzle.error( selector ) :
4742
+			// Cache the tokens
4743
+			tokenCache( selector, groups ).slice( 0 );
4744
+}
4745
+
4746
+function addCombinator( matcher, combinator, base ) {
4747
+	var dir = combinator.dir,
4748
+		checkNonElements = base && combinator.dir === "parentNode",
4749
+		doneName = done++;
4750
+
4751
+	return combinator.first ?
4752
+		// Check against closest ancestor/preceding element
4753
+		function( elem, context, xml ) {
4754
+			while ( (elem = elem[ dir ]) ) {
4755
+				if ( checkNonElements || elem.nodeType === 1  ) {
4756
+					return matcher( elem, context, xml );
4757
+				}
4758
+			}
4759
+		} :
4760
+
4761
+		// Check against all ancestor/preceding elements
4762
+		function( elem, context, xml ) {
4763
+			// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
4764
+			if ( !xml ) {
4765
+				var cache,
4766
+					dirkey = dirruns + " " + doneName + " ",
4767
+					cachedkey = dirkey + cachedruns;
4768
+				while ( (elem = elem[ dir ]) ) {
4769
+					if ( checkNonElements || elem.nodeType === 1 ) {
4770
+						if ( (cache = elem[ expando ]) === cachedkey ) {
4771
+							return elem.sizset;
4772
+						} else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {
4773
+							if ( elem.sizset ) {
4774
+								return elem;
4775
+							}
4776
+						} else {
4777
+							elem[ expando ] = cachedkey;
4778
+							if ( matcher( elem, context, xml ) ) {
4779
+								elem.sizset = true;
4780
+								return elem;
4781
+							}
4782
+							elem.sizset = false;
4783
+						}
4784
+					}
4785
+				}
4786
+			} else {
4787
+				while ( (elem = elem[ dir ]) ) {
4788
+					if ( checkNonElements || elem.nodeType === 1 ) {
4789
+						if ( matcher( elem, context, xml ) ) {
4790
+							return elem;
4791
+						}
4792
+					}
4793
+				}
4794
+			}
4795
+		};
4796
+}
4797
+
4798
+function elementMatcher( matchers ) {
4799
+	return matchers.length > 1 ?
4800
+		function( elem, context, xml ) {
4801
+			var i = matchers.length;
4802
+			while ( i-- ) {
4803
+				if ( !matchers[i]( elem, context, xml ) ) {
4804
+					return false;
4805
+				}
4806
+			}
4807
+			return true;
4808
+		} :
4809
+		matchers[0];
4810
+}
4811
+
4812
+function condense( unmatched, map, filter, context, xml ) {
4813
+	var elem,
4814
+		newUnmatched = [],
4815
+		i = 0,
4816
+		len = unmatched.length,
4817
+		mapped = map != null;
4818
+
4819
+	for ( ; i < len; i++ ) {
4820
+		if ( (elem = unmatched[i]) ) {
4821
+			if ( !filter || filter( elem, context, xml ) ) {
4822
+				newUnmatched.push( elem );
4823
+				if ( mapped ) {
4824
+					map.push( i );
4825
+				}
4826
+			}
4827
+		}
4828
+	}
4829
+
4830
+	return newUnmatched;
4831
+}
4832
+
4833
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
4834
+	if ( postFilter && !postFilter[ expando ] ) {
4835
+		postFilter = setMatcher( postFilter );
4836
+	}
4837
+	if ( postFinder && !postFinder[ expando ] ) {
4838
+		postFinder = setMatcher( postFinder, postSelector );
4839
+	}
4840
+	return markFunction(function( seed, results, context, xml ) {
4841
+		var temp, i, elem,
4842
+			preMap = [],
4843
+			postMap = [],
4844
+			preexisting = results.length,
4845
+
4846
+			// Get initial elements from seed or context
4847
+			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
4848
+
4849
+			// Prefilter to get matcher input, preserving a map for seed-results synchronization
4850
+			matcherIn = preFilter && ( seed || !selector ) ?
4851
+				condense( elems, preMap, preFilter, context, xml ) :
4852
+				elems,
4853
+
4854
+			matcherOut = matcher ?
4855
+				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
4856
+				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
4857
+
4858
+					// ...intermediate processing is necessary
4859
+					[] :
4860
+
4861
+					// ...otherwise use results directly
4862
+					results :
4863
+				matcherIn;
4864
+
4865
+		// Find primary matches
4866
+		if ( matcher ) {
4867
+			matcher( matcherIn, matcherOut, context, xml );
4868
+		}
4869
+
4870
+		// Apply postFilter
4871
+		if ( postFilter ) {
4872
+			temp = condense( matcherOut, postMap );
4873
+			postFilter( temp, [], context, xml );
4874
+
4875
+			// Un-match failing elements by moving them back to matcherIn
4876
+			i = temp.length;
4877
+			while ( i-- ) {
4878
+				if ( (elem = temp[i]) ) {
4879
+					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
4880
+				}
4881
+			}
4882
+		}
4883
+
4884
+		if ( seed ) {
4885
+			if ( postFinder || preFilter ) {
4886
+				if ( postFinder ) {
4887
+					// Get the final matcherOut by condensing this intermediate into postFinder contexts
4888
+					temp = [];
4889
+					i = matcherOut.length;
4890
+					while ( i-- ) {
4891
+						if ( (elem = matcherOut[i]) ) {
4892
+							// Restore matcherIn since elem is not yet a final match
4893
+							temp.push( (matcherIn[i] = elem) );
4894
+						}
4895
+					}
4896
+					postFinder( null, (matcherOut = []), temp, xml );
4897
+				}
4898
+
4899
+				// Move matched elements from seed to results to keep them synchronized
4900
+				i = matcherOut.length;
4901
+				while ( i-- ) {
4902
+					if ( (elem = matcherOut[i]) &&
4903
+						(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
4904
+
4905
+						seed[temp] = !(results[temp] = elem);
4906
+					}
4907
+				}
4908
+			}
4909
+
4910
+		// Add elements to results, through postFinder if defined
4911
+		} else {
4912
+			matcherOut = condense(
4913
+				matcherOut === results ?
4914
+					matcherOut.splice( preexisting, matcherOut.length ) :
4915
+					matcherOut
4916
+			);
4917
+			if ( postFinder ) {
4918
+				postFinder( null, results, matcherOut, xml );
4919
+			} else {
4920
+				push.apply( results, matcherOut );
4921
+			}
4922
+		}
4923
+	});
4924
+}
4925
+
4926
+function matcherFromTokens( tokens ) {
4927
+	var checkContext, matcher, j,
4928
+		len = tokens.length,
4929
+		leadingRelative = Expr.relative[ tokens[0].type ],
4930
+		implicitRelative = leadingRelative || Expr.relative[" "],
4931
+		i = leadingRelative ? 1 : 0,
4932
+
4933
+		// The foundational matcher ensures that elements are reachable from top-level context(s)
4934
+		matchContext = addCombinator( function( elem ) {
4935
+			return elem === checkContext;
4936
+		}, implicitRelative, true ),
4937
+		matchAnyContext = addCombinator( function( elem ) {
4938
+			return indexOf.call( checkContext, elem ) > -1;
4939
+		}, implicitRelative, true ),
4940
+		matchers = [ function( elem, context, xml ) {
4941
+			return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
4942
+				(checkContext = context).nodeType ?
4943
+					matchContext( elem, context, xml ) :
4944
+					matchAnyContext( elem, context, xml ) );
4945
+		} ];
4946
+
4947
+	for ( ; i < len; i++ ) {
4948
+		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
4949
+			matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
4950
+		} else {
4951
+			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
4952
+
4953
+			// Return special upon seeing a positional matcher
4954
+			if ( matcher[ expando ] ) {
4955
+				// Find the next relative operator (if any) for proper handling
4956
+				j = ++i;
4957
+				for ( ; j < len; j++ ) {
4958
+					if ( Expr.relative[ tokens[j].type ] ) {
4959
+						break;
4960
+					}
4961
+				}
4962
+				return setMatcher(
4963
+					i > 1 && elementMatcher( matchers ),
4964
+					i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ),
4965
+					matcher,
4966
+					i < j && matcherFromTokens( tokens.slice( i, j ) ),
4967
+					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
4968
+					j < len && tokens.join("")
4969
+				);
4970
+			}
4971
+			matchers.push( matcher );
4972
+		}
4973
+	}
4974
+
4975
+	return elementMatcher( matchers );
4976
+}
4977
+
4978
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
4979
+	var bySet = setMatchers.length > 0,
4980
+		byElement = elementMatchers.length > 0,
4981
+		superMatcher = function( seed, context, xml, results, expandContext ) {
4982
+			var elem, j, matcher,
4983
+				setMatched = [],
4984
+				matchedCount = 0,
4985
+				i = "0",
4986
+				unmatched = seed && [],
4987
+				outermost = expandContext != null,
4988
+				contextBackup = outermostContext,
4989
+				// We must always have either seed elements or context
4990
+				elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),
4991
+				// Nested matchers should use non-integer dirruns
4992
+				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E);
4993
+
4994
+			if ( outermost ) {
4995
+				outermostContext = context !== document && context;
4996
+				cachedruns = superMatcher.el;
4997
+			}
4998
+
4999
+			// Add elements passing elementMatchers directly to results
5000
+			for ( ; (elem = elems[i]) != null; i++ ) {
5001
+				if ( byElement && elem ) {
5002
+					for ( j = 0; (matcher = elementMatchers[j]); j++ ) {
5003
+						if ( matcher( elem, context, xml ) ) {
5004
+							results.push( elem );
5005
+							break;
5006
+						}
5007
+					}
5008
+					if ( outermost ) {
5009
+						dirruns = dirrunsUnique;
5010
+						cachedruns = ++superMatcher.el;
5011
+					}
5012
+				}
5013
+
5014
+				// Track unmatched elements for set filters
5015
+				if ( bySet ) {
5016
+					// They will have gone through all possible matchers
5017
+					if ( (elem = !matcher && elem) ) {
5018
+						matchedCount--;
5019
+					}
5020
+
5021
+					// Lengthen the array for every element, matched or not
5022
+					if ( seed ) {
5023
+						unmatched.push( elem );
5024
+					}
5025
+				}
5026
+			}
5027
+
5028
+			// Apply set filters to unmatched elements
5029
+			matchedCount += i;
5030
+			if ( bySet && i !== matchedCount ) {
5031
+				for ( j = 0; (matcher = setMatchers[j]); j++ ) {
5032
+					matcher( unmatched, setMatched, context, xml );
5033
+				}
5034
+
5035
+				if ( seed ) {
5036
+					// Reintegrate element matches to eliminate the need for sorting
5037
+					if ( matchedCount > 0 ) {
5038
+						while ( i-- ) {
5039
+							if ( !(unmatched[i] || setMatched[i]) ) {
5040
+								setMatched[i] = pop.call( results );
5041
+							}
5042
+						}
5043
+					}
5044
+
5045
+					// Discard index placeholder values to get only actual matches
5046
+					setMatched = condense( setMatched );
5047
+				}
5048
+
5049
+				// Add matches to results
5050
+				push.apply( results, setMatched );
5051
+
5052
+				// Seedless set matches succeeding multiple successful matchers stipulate sorting
5053
+				if ( outermost && !seed && setMatched.length > 0 &&
5054
+					( matchedCount + setMatchers.length ) > 1 ) {
5055
+
5056
+					Sizzle.uniqueSort( results );
5057
+				}
5058
+			}
5059
+
5060
+			// Override manipulation of globals by nested matchers
5061
+			if ( outermost ) {
5062
+				dirruns = dirrunsUnique;
5063
+				outermostContext = contextBackup;
5064
+			}
5065
+
5066
+			return unmatched;
5067
+		};
5068
+
5069
+	superMatcher.el = 0;
5070
+	return bySet ?
5071
+		markFunction( superMatcher ) :
5072
+		superMatcher;
5073
+}
5074
+
5075
+compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
5076
+	var i,
5077
+		setMatchers = [],
5078
+		elementMatchers = [],
5079
+		cached = compilerCache[ expando ][ selector + " " ];
5080
+
5081
+	if ( !cached ) {
5082
+		// Generate a function of recursive functions that can be used to check each element
5083
+		if ( !group ) {
5084
+			group = tokenize( selector );
5085
+		}
5086
+		i = group.length;
5087
+		while ( i-- ) {
5088
+			cached = matcherFromTokens( group[i] );
5089
+			if ( cached[ expando ] ) {
5090
+				setMatchers.push( cached );
5091
+			} else {
5092
+				elementMatchers.push( cached );
5093
+			}
5094
+		}
5095
+
5096
+		// Cache the compiled function
5097
+		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
5098
+	}
5099
+	return cached;
5100
+};
5101
+
5102
+function multipleContexts( selector, contexts, results ) {
5103
+	var i = 0,
5104
+		len = contexts.length;
5105
+	for ( ; i < len; i++ ) {
5106
+		Sizzle( selector, contexts[i], results );
5107
+	}
5108
+	return results;
5109
+}
5110
+
5111
+function select( selector, context, results, seed, xml ) {
5112
+	var i, tokens, token, type, find,
5113
+		match = tokenize( selector ),
5114
+		j = match.length;
5115
+
5116
+	if ( !seed ) {
5117
+		// Try to minimize operations if there is only one group
5118
+		if ( match.length === 1 ) {
5119
+
5120
+			// Take a shortcut and set the context if the root selector is an ID
5121
+			tokens = match[0] = match[0].slice( 0 );
5122
+			if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
5123
+					context.nodeType === 9 && !xml &&
5124
+					Expr.relative[ tokens[1].type ] ) {
5125
+
5126
+				context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0];
5127
+				if ( !context ) {
5128
+					return results;
5129
+				}
5130
+
5131
+				selector = selector.slice( tokens.shift().length );
5132
+			}
5133
+
5134
+			// Fetch a seed set for right-to-left matching
5135
+			for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) {
5136
+				token = tokens[i];
5137
+
5138
+				// Abort if we hit a combinator
5139
+				if ( Expr.relative[ (type = token.type) ] ) {
5140
+					break;
5141
+				}
5142
+				if ( (find = Expr.find[ type ]) ) {
5143
+					// Search, expanding context for leading sibling combinators
5144
+					if ( (seed = find(
5145
+						token.matches[0].replace( rbackslash, "" ),
5146
+						rsibling.test( tokens[0].type ) && context.parentNode || context,
5147
+						xml
5148
+					)) ) {
5149
+
5150
+						// If seed is empty or no tokens remain, we can return early
5151
+						tokens.splice( i, 1 );
5152
+						selector = seed.length && tokens.join("");
5153
+						if ( !selector ) {
5154
+							push.apply( results, slice.call( seed, 0 ) );
5155
+							return results;
5156
+						}
5157
+
5158
+						break;
5159
+					}
5160
+				}
5161
+			}
5162
+		}
5163
+	}
5164
+
5165
+	// Compile and execute a filtering function
5166
+	// Provide `match` to avoid retokenization if we modified the selector above
5167
+	compile( selector, match )(
5168
+		seed,
5169
+		context,
5170
+		xml,
5171
+		results,
5172
+		rsibling.test( selector )
5173
+	);
5174
+	return results;
5175
+}
5176
+
5177
+if ( document.querySelectorAll ) {
5178
+	(function() {
5179
+		var disconnectedMatch,
5180
+			oldSelect = select,
5181
+			rescape = /'|\\/g,
5182
+			rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,
5183
+
5184
+			// qSa(:focus) reports false when true (Chrome 21), no need to also add to buggyMatches since matches checks buggyQSA
5185
+			// A support test would require too much code (would include document ready)
5186
+			rbuggyQSA = [ ":focus" ],
5187
+
5188
+			// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
5189
+			// A support test would require too much code (would include document ready)
5190
+			// just skip matchesSelector for :active
5191
+			rbuggyMatches = [ ":active" ],
5192
+			matches = docElem.matchesSelector ||
5193
+				docElem.mozMatchesSelector ||
5194
+				docElem.webkitMatchesSelector ||
5195
+				docElem.oMatchesSelector ||
5196
+				docElem.msMatchesSelector;
5197
+
5198
+		// Build QSA regex
5199
+		// Regex strategy adopted from Diego Perini
5200
+		assert(function( div ) {
5201
+			// Select is set to empty string on purpose
5202
+			// This is to test IE's treatment of not explictly
5203
+			// setting a boolean content attribute,
5204
+			// since its presence should be enough
5205
+			// http://bugs.jquery.com/ticket/12359
5206
+			div.innerHTML = "<select><option selected=''></option></select>";
5207
+
5208
+			// IE8 - Some boolean attributes are not treated correctly
5209
+			if ( !div.querySelectorAll("[selected]").length ) {
5210
+				rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" );
5211
+			}
5212
+
5213
+			// Webkit/Opera - :checked should return selected option elements
5214
+			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
5215
+			// IE8 throws error here (do not put tests after this one)
5216
+			if ( !div.querySelectorAll(":checked").length ) {
5217
+				rbuggyQSA.push(":checked");
5218
+			}
5219
+		});
5220
+
5221
+		assert(function( div ) {
5222
+
5223
+			// Opera 10-12/IE9 - ^= $= *= and empty values
5224
+			// Should not select anything
5225
+			div.innerHTML = "<p test=''></p>";
5226
+			if ( div.querySelectorAll("[test^='']").length ) {
5227
+				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" );
5228
+			}
5229
+
5230
+			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
5231
+			// IE8 throws error here (do not put tests after this one)
5232
+			div.innerHTML = "<input type='hidden'/>";
5233
+			if ( !div.querySelectorAll(":enabled").length ) {
5234
+				rbuggyQSA.push(":enabled", ":disabled");
5235
+			}
5236
+		});
5237
+
5238
+		// rbuggyQSA always contains :focus, so no need for a length check
5239
+		rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") );
5240
+
5241
+		select = function( selector, context, results, seed, xml ) {
5242
+			// Only use querySelectorAll when not filtering,
5243
+			// when this is not xml,
5244
+			// and when no QSA bugs apply
5245
+			if ( !seed && !xml && !rbuggyQSA.test( selector ) ) {
5246
+				var groups, i,
5247
+					old = true,
5248
+					nid = expando,
5249
+					newContext = context,
5250
+					newSelector = context.nodeType === 9 && selector;
5251
+
5252
+				// qSA works strangely on Element-rooted queries
5253
+				// We can work around this by specifying an extra ID on the root
5254
+				// and working up from there (Thanks to Andrew Dupont for the technique)
5255
+				// IE 8 doesn't work on object elements
5256
+				if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
5257
+					groups = tokenize( selector );
5258
+
5259
+					if ( (old = context.getAttribute("id")) ) {
5260
+						nid = old.replace( rescape, "\\$&" );
5261
+					} else {
5262
+						context.setAttribute( "id", nid );
5263
+					}
5264
+					nid = "[id='" + nid + "'] ";
5265
+
5266
+					i = groups.length;
5267
+					while ( i-- ) {
5268
+						groups[i] = nid + groups[i].join("");
5269
+					}
5270
+					newContext = rsibling.test( selector ) && context.parentNode || context;
5271
+					newSelector = groups.join(",");
5272
+				}
5273
+
5274
+				if ( newSelector ) {
5275
+					try {
5276
+						push.apply( results, slice.call( newContext.querySelectorAll(
5277
+							newSelector
5278
+						), 0 ) );
5279
+						return results;
5280
+					} catch(qsaError) {
5281
+					} finally {
5282
+						if ( !old ) {
5283
+							context.removeAttribute("id");
5284
+						}
5285
+					}
5286
+				}
5287
+			}
5288
+
5289
+			return oldSelect( selector, context, results, seed, xml );
5290
+		};
5291
+
5292
+		if ( matches ) {
5293
+			assert(function( div ) {
5294
+				// Check to see if it's possible to do matchesSelector
5295
+				// on a disconnected node (IE 9)
5296
+				disconnectedMatch = matches.call( div, "div" );
5297
+
5298
+				// This should fail with an exception
5299
+				// Gecko does not error, returns false instead
5300
+				try {
5301
+					matches.call( div, "[test!='']:sizzle" );
5302
+					rbuggyMatches.push( "!=", pseudos );
5303
+				} catch ( e ) {}
5304
+			});
5305
+
5306
+			// rbuggyMatches always contains :active and :focus, so no need for a length check
5307
+			rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") );
5308
+
5309
+			Sizzle.matchesSelector = function( elem, expr ) {
5310
+				// Make sure that attribute selectors are quoted
5311
+				expr = expr.replace( rattributeQuotes, "='$1']" );
5312
+
5313
+				// rbuggyMatches always contains :active, so no need for an existence check
5314
+				if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && !rbuggyQSA.test( expr ) ) {
5315
+					try {
5316
+						var ret = matches.call( elem, expr );
5317
+
5318
+						// IE 9's matchesSelector returns false on disconnected nodes
5319
+						if ( ret || disconnectedMatch ||
5320
+								// As well, disconnected nodes are said to be in a document
5321
+								// fragment in IE 9
5322
+								elem.document && elem.document.nodeType !== 11 ) {
5323
+							return ret;
5324
+						}
5325
+					} catch(e) {}
5326
+				}
5327
+
5328
+				return Sizzle( expr, null, null, [ elem ] ).length > 0;
5329
+			};
5330
+		}
5331
+	})();
5332
+}
5333
+
5334
+// Deprecated
5335
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
5336
+
5337
+// Back-compat
5338
+function setFilters() {}
5339
+Expr.filters = setFilters.prototype = Expr.pseudos;
5340
+Expr.setFilters = new setFilters();
5341
+
5342
+// Override sizzle attribute retrieval
5343
+Sizzle.attr = jQuery.attr;
5344
+jQuery.find = Sizzle;
5345
+jQuery.expr = Sizzle.selectors;
5346
+jQuery.expr[":"] = jQuery.expr.pseudos;
5347
+jQuery.unique = Sizzle.uniqueSort;
5348
+jQuery.text = Sizzle.getText;
5349
+jQuery.isXMLDoc = Sizzle.isXML;
5350
+jQuery.contains = Sizzle.contains;
5351
+
5352
+
5353
+})( window );
5354
+var runtil = /Until$/,
5355
+	rparentsprev = /^(?:parents|prev(?:Until|All))/,
5356
+	isSimple = /^.[^:#\[\.,]*$/,
5357
+	rneedsContext = jQuery.expr.match.needsContext,
5358
+	// methods guaranteed to produce a unique set when starting from a unique set
5359
+	guaranteedUnique = {
5360
+		children: true,
5361
+		contents: true,
5362
+		next: true,
5363
+		prev: true
5364
+	};
5365
+
5366
+jQuery.fn.extend({
5367
+	find: function( selector ) {
5368
+		var i, l, length, n, r, ret,
5369
+			self = this;
5370
+
5371
+		if ( typeof selector !== "string" ) {
5372
+			return jQuery( selector ).filter(function() {
5373
+				for ( i = 0, l = self.length; i < l; i++ ) {
5374
+					if ( jQuery.contains( self[ i ], this ) ) {
5375
+						return true;
5376
+					}
5377
+				}
5378
+			});
5379
+		}
5380
+
5381
+		ret = this.pushStack( "", "find", selector );
5382
+
5383
+		for ( i = 0, l = this.length; i < l; i++ ) {
5384
+			length = ret.length;
5385
+			jQuery.find( selector, this[i], ret );
5386
+
5387
+			if ( i > 0 ) {
5388
+				// Make sure that the results are unique
5389
+				for ( n = length; n < ret.length; n++ ) {
5390
+					for ( r = 0; r < length; r++ ) {
5391
+						if ( ret[r] === ret[n] ) {
5392
+							ret.splice(n--, 1);
5393
+							break;
5394
+						}
5395
+					}
5396
+				}
5397
+			}
5398
+		}
5399
+
5400
+		return ret;
5401
+	},
5402
+
5403
+	has: function( target ) {
5404
+		var i,
5405
+			targets = jQuery( target, this ),
5406
+			len = targets.length;
5407
+
5408
+		return this.filter(function() {
5409
+			for ( i = 0; i < len; i++ ) {
5410
+				if ( jQuery.contains( this, targets[i] ) ) {
5411
+					return true;
5412
+				}
5413
+			}
5414
+		});
5415
+	},
5416
+
5417
+	not: function( selector ) {
5418
+		return this.pushStack( winnow(this, selector, false), "not", selector);
5419
+	},
5420
+
5421
+	filter: function( selector ) {
5422
+		return this.pushStack( winnow(this, selector, true), "filter", selector );
5423
+	},
5424
+
5425
+	is: function( selector ) {
5426
+		return !!selector && (
5427
+			typeof selector === "string" ?
5428
+				// If this is a positional/relative selector, check membership in the returned set
5429
+				// so $("p:first").is("p:last") won't return true for a doc with two "p".
5430
+				rneedsContext.test( selector ) ?
5431
+					jQuery( selector, this.context ).index( this[0] ) >= 0 :
5432
+					jQuery.filter( selector, this ).length > 0 :
5433
+				this.filter( selector ).length > 0 );
5434
+	},
5435
+
5436
+	closest: function( selectors, context ) {
5437
+		var cur,
5438
+			i = 0,
5439
+			l = this.length,
5440
+			ret = [],
5441
+			pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
5442
+				jQuery( selectors, context || this.context ) :
5443
+				0;
5444
+
5445
+		for ( ; i < l; i++ ) {
5446
+			cur = this[i];
5447
+
5448
+			while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) {
5449
+				if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5450
+					ret.push( cur );
5451
+					break;
5452
+				}
5453
+				cur = cur.parentNode;
5454
+			}
5455
+		}
5456
+
5457
+		ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5458
+
5459
+		return this.pushStack( ret, "closest", selectors );
5460
+	},
5461
+
5462
+	// Determine the position of an element within
5463
+	// the matched set of elements
5464
+	index: function( elem ) {
5465
+
5466
+		// No argument, return index in parent
5467
+		if ( !elem ) {
5468
+			return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;
5469
+		}
5470
+
5471
+		// index in selector
5472
+		if ( typeof elem === "string" ) {
5473
+			return jQuery.inArray( this[0], jQuery( elem ) );
5474
+		}
5475
+
5476
+		// Locate the position of the desired element
5477
+		return jQuery.inArray(
5478
+			// If it receives a jQuery object, the first element is used
5479
+			elem.jquery ? elem[0] : elem, this );
5480
+	},
5481
+
5482
+	add: function( selector, context ) {
5483
+		var set = typeof selector === "string" ?
5484
+				jQuery( selector, context ) :
5485
+				jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5486
+			all = jQuery.merge( this.get(), set );
5487
+
5488
+		return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5489
+			all :
5490
+			jQuery.unique( all ) );
5491
+	},
5492
+
5493
+	addBack: function( selector ) {
5494
+		return this.add( selector == null ?
5495
+			this.prevObject : this.prevObject.filter(selector)
5496
+		);
5497
+	}
5498
+});
5499
+
5500
+jQuery.fn.andSelf = jQuery.fn.addBack;
5501
+
5502
+// A painfully simple check to see if an element is disconnected
5503
+// from a document (should be improved, where feasible).
5504
+function isDisconnected( node ) {
5505
+	return !node || !node.parentNode || node.parentNode.nodeType === 11;
5506
+}
5507
+
5508
+function sibling( cur, dir ) {
5509
+	do {
5510
+		cur = cur[ dir ];
5511
+	} while ( cur && cur.nodeType !== 1 );
5512
+
5513
+	return cur;
5514
+}
5515
+
5516
+jQuery.each({
5517
+	parent: function( elem ) {
5518
+		var parent = elem.parentNode;
5519
+		return parent && parent.nodeType !== 11 ? parent : null;
5520
+	},
5521
+	parents: function( elem ) {
5522
+		return jQuery.dir( elem, "parentNode" );
5523
+	},
5524
+	parentsUntil: function( elem, i, until ) {
5525
+		return jQuery.dir( elem, "parentNode", until );
5526
+	},
5527
+	next: function( elem ) {
5528
+		return sibling( elem, "nextSibling" );
5529
+	},
5530
+	prev: function( elem ) {
5531
+		return sibling( elem, "previousSibling" );
5532
+	},
5533
+	nextAll: function( elem ) {
5534
+		return jQuery.dir( elem, "nextSibling" );
5535
+	},
5536
+	prevAll: function( elem ) {
5537
+		return jQuery.dir( elem, "previousSibling" );
5538
+	},
5539
+	nextUntil: function( elem, i, until ) {
5540
+		return jQuery.dir( elem, "nextSibling", until );
5541
+	},
5542
+	prevUntil: function( elem, i, until ) {
5543
+		return jQuery.dir( elem, "previousSibling", until );
5544
+	},
5545
+	siblings: function( elem ) {
5546
+		return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
5547
+	},
5548
+	children: function( elem ) {
5549
+		return jQuery.sibling( elem.firstChild );
5550
+	},
5551
+	contents: function( elem ) {
5552
+		return jQuery.nodeName( elem, "iframe" ) ?
5553
+			elem.contentDocument || elem.contentWindow.document :
5554
+			jQuery.merge( [], elem.childNodes );
5555
+	}
5556
+}, function( name, fn ) {
5557
+	jQuery.fn[ name ] = function( until, selector ) {
5558
+		var ret = jQuery.map( this, fn, until );
5559
+
5560
+		if ( !runtil.test( name ) ) {
5561
+			selector = until;
5562
+		}
5563
+
5564
+		if ( selector && typeof selector === "string" ) {
5565
+			ret = jQuery.filter( selector, ret );
5566
+		}
5567
+
5568
+		ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
5569
+
5570
+		if ( this.length > 1 && rparentsprev.test( name ) ) {
5571
+			ret = ret.reverse();
5572
+		}
5573
+
5574
+		return this.pushStack( ret, name, core_slice.call( arguments ).join(",") );
5575
+	};
5576
+});
5577
+
5578
+jQuery.extend({
5579
+	filter: function( expr, elems, not ) {
5580
+		if ( not ) {
5581
+			expr = ":not(" + expr + ")";
5582
+		}
5583
+
5584
+		return elems.length === 1 ?
5585
+			jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
5586
+			jQuery.find.matches(expr, elems);
5587
+	},
5588
+
5589
+	dir: function( elem, dir, until ) {
5590
+		var matched = [],
5591
+			cur = elem[ dir ];
5592
+
5593
+		while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
5594
+			if ( cur.nodeType === 1 ) {
5595
+				matched.push( cur );
5596
+			}
5597
+			cur = cur[dir];
5598
+		}
5599
+		return matched;
5600
+	},
5601
+
5602
+	sibling: function( n, elem ) {
5603
+		var r = [];
5604
+
5605
+		for ( ; n; n = n.nextSibling ) {
5606
+			if ( n.nodeType === 1 && n !== elem ) {
5607
+				r.push( n );
5608
+			}
5609
+		}
5610
+
5611
+		return r;
5612
+	}
5613
+});
5614
+
5615
+// Implement the identical functionality for filter and not
5616
+function winnow( elements, qualifier, keep ) {
5617
+
5618
+	// Can't pass null or undefined to indexOf in Firefox 4
5619
+	// Set to 0 to skip string check
5620
+	qualifier = qualifier || 0;
5621
+
5622
+	if ( jQuery.isFunction( qualifier ) ) {
5623
+		return jQuery.grep(elements, function( elem, i ) {
5624
+			var retVal = !!qualifier.call( elem, i, elem );
5625
+			return retVal === keep;
5626
+		});
5627
+
5628
+	} else if ( qualifier.nodeType ) {
5629
+		return jQuery.grep(elements, function( elem, i ) {
5630
+			return ( elem === qualifier ) === keep;
5631
+		});
5632
+
5633
+	} else if ( typeof qualifier === "string" ) {
5634
+		var filtered = jQuery.grep(elements, function( elem ) {
5635
+			return elem.nodeType === 1;
5636
+		});
5637
+
5638
+		if ( isSimple.test( qualifier ) ) {
5639
+			return jQuery.filter(qualifier, filtered, !keep);
5640
+		} else {
5641
+			qualifier = jQuery.filter( qualifier, filtered );
5642
+		}
5643
+	}
5644
+
5645
+	return jQuery.grep(elements, function( elem, i ) {
5646
+		return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;
5647
+	});
5648
+}
5649
+function createSafeFragment( document ) {
5650
+	var list = nodeNames.split( "|" ),
5651
+	safeFrag = document.createDocumentFragment();
5652
+
5653
+	if ( safeFrag.createElement ) {
5654
+		while ( list.length ) {
5655
+			safeFrag.createElement(
5656
+				list.pop()
5657
+			);
5658
+		}
5659
+	}
5660
+	return safeFrag;
5661
+}
5662
+
5663
+var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
5664
+		"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
5665
+	rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
5666
+	rleadingWhitespace = /^\s+/,
5667
+	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
5668
+	rtagName = /<([\w:]+)/,
5669
+	rtbody = /<tbody/i,
5670
+	rhtml = /<|&#?\w+;/,
5671
+	rnoInnerhtml = /<(?:script|style|link)/i,
5672
+	rnocache = /<(?:script|object|embed|option|style)/i,
5673
+	rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
5674
+	rcheckableType = /^(?:checkbox|radio)$/,
5675
+	// checked="checked" or checked
5676
+	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5677
+	rscriptType = /\/(java|ecma)script/i,
5678
+	rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,
5679
+	wrapMap = {
5680
+		option: [ 1, "<select multiple='multiple'>", "</select>" ],
5681
+		legend: [ 1, "<fieldset>", "</fieldset>" ],
5682
+		thead: [ 1, "<table>", "</table>" ],
5683
+		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5684
+		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5685
+		col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5686
+		area: [ 1, "<map>", "</map>" ],
5687
+		_default: [ 0, "", "" ]
5688
+	},
5689
+	safeFragment = createSafeFragment( document ),
5690
+	fragmentDiv = safeFragment.appendChild( document.createElement("div") );
5691
+
5692
+wrapMap.optgroup = wrapMap.option;
5693
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5694
+wrapMap.th = wrapMap.td;
5695
+
5696
+// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
5697
+// unless wrapped in a div with non-breaking characters in front of it.
5698
+if ( !jQuery.support.htmlSerialize ) {
5699
+	wrapMap._default = [ 1, "X<div>", "</div>" ];
5700
+}
5701
+
5702
+jQuery.fn.extend({
5703
+	text: function( value ) {
5704
+		return jQuery.access( this, function( value ) {
5705
+			return value === undefined ?
5706
+				jQuery.text( this ) :
5707
+				this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
5708
+		}, null, value, arguments.length );
5709
+	},
5710
+
5711
+	wrapAll: function( html ) {
5712
+		if ( jQuery.isFunction( html ) ) {
5713
+			return this.each(function(i) {
5714
+				jQuery(this).wrapAll( html.call(this, i) );
5715
+			});
5716
+		}
5717
+
5718
+		if ( this[0] ) {
5719
+			// The elements to wrap the target around
5720
+			var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
5721
+
5722
+			if ( this[0].parentNode ) {
5723
+				wrap.insertBefore( this[0] );
5724
+			}
5725
+
5726
+			wrap.map(function() {
5727
+				var elem = this;
5728
+
5729
+				while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
5730
+					elem = elem.firstChild;
5731
+				}
5732
+
5733
+				return elem;
5734
+			}).append( this );
5735
+		}
5736
+
5737
+		return this;
5738
+	},
5739
+
5740
+	wrapInner: function( html ) {
5741
+		if ( jQuery.isFunction( html ) ) {
5742
+			return this.each(function(i) {
5743
+				jQuery(this).wrapInner( html.call(this, i) );
5744
+			});
5745
+		}
5746
+
5747
+		return this.each(function() {
5748
+			var self = jQuery( this ),
5749
+				contents = self.contents();
5750
+
5751
+			if ( contents.length ) {
5752
+				contents.wrapAll( html );
5753
+
5754
+			} else {
5755
+				self.append( html );
5756
+			}
5757
+		});
5758
+	},
5759
+
5760
+	wrap: function( html ) {
5761
+		var isFunction = jQuery.isFunction( html );
5762
+
5763
+		return this.each(function(i) {
5764
+			jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
5765
+		});
5766
+	},
5767
+
5768
+	unwrap: function() {
5769
+		return this.parent().each(function() {
5770
+			if ( !jQuery.nodeName( this, "body" ) ) {
5771
+				jQuery( this ).replaceWith( this.childNodes );
5772
+			}
5773
+		}).end();
5774
+	},
5775
+
5776
+	append: function() {
5777
+		return this.domManip(arguments, true, function( elem ) {
5778
+			if ( this.nodeType === 1 || this.nodeType === 11 ) {
5779
+				this.appendChild( elem );
5780
+			}
5781
+		});
5782
+	},
5783
+
5784
+	prepend: function() {
5785
+		return this.domManip(arguments, true, function( elem ) {
5786
+			if ( this.nodeType === 1 || this.nodeType === 11 ) {
5787
+				this.insertBefore( elem, this.firstChild );
5788
+			}
5789
+		});
5790
+	},
5791
+
5792
+	before: function() {
5793
+		if ( !isDisconnected( this[0] ) ) {
5794
+			return this.domManip(arguments, false, function( elem ) {
5795
+				this.parentNode.insertBefore( elem, this );
5796
+			});
5797
+		}
5798
+
5799
+		if ( arguments.length ) {
5800
+			var set = jQuery.clean( arguments );
5801
+			return this.pushStack( jQuery.merge( set, this ), "before", this.selector );
5802
+		}
5803
+	},
5804
+
5805
+	after: function() {
5806
+		if ( !isDisconnected( this[0] ) ) {
5807
+			return this.domManip(arguments, false, function( elem ) {
5808
+				this.parentNode.insertBefore( elem, this.nextSibling );
5809
+			});
5810
+		}
5811
+
5812
+		if ( arguments.length ) {
5813
+			var set = jQuery.clean( arguments );
5814
+			return this.pushStack( jQuery.merge( this, set ), "after", this.selector );
5815
+		}
5816
+	},
5817
+
5818
+	// keepData is for internal use only--do not document
5819
+	remove: function( selector, keepData ) {
5820
+		var elem,
5821
+			i = 0;
5822
+
5823
+		for ( ; (elem = this[i]) != null; i++ ) {
5824
+			if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
5825
+				if ( !keepData && elem.nodeType === 1 ) {
5826
+					jQuery.cleanData( elem.getElementsByTagName("*") );
5827
+					jQuery.cleanData( [ elem ] );
5828
+				}
5829
+
5830
+				if ( elem.parentNode ) {
5831
+					elem.parentNode.removeChild( elem );
5832
+				}
5833
+			}
5834
+		}
5835
+
5836
+		return this;
5837
+	},
5838
+
5839
+	empty: function() {
5840
+		var elem,
5841
+			i = 0;
5842
+
5843
+		for ( ; (elem = this[i]) != null; i++ ) {
5844
+			// Remove element nodes and prevent memory leaks
5845
+			if ( elem.nodeType === 1 ) {
5846
+				jQuery.cleanData( elem.getElementsByTagName("*") );
5847
+			}
5848
+
5849
+			// Remove any remaining nodes
5850
+			while ( elem.firstChild ) {
5851
+				elem.removeChild( elem.firstChild );
5852
+			}
5853
+		}
5854
+
5855
+		return this;
5856
+	},
5857
+
5858
+	clone: function( dataAndEvents, deepDataAndEvents ) {
5859
+		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5860
+		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5861
+
5862
+		return this.map( function () {
5863
+			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5864
+		});
5865
+	},
5866
+
5867
+	html: function( value ) {
5868
+		return jQuery.access( this, function( value ) {
5869
+			var elem = this[0] || {},
5870
+				i = 0,
5871
+				l = this.length;
5872
+
5873
+			if ( value === undefined ) {
5874
+				return elem.nodeType === 1 ?
5875
+					elem.innerHTML.replace( rinlinejQuery, "" ) :
5876
+					undefined;
5877
+			}
5878
+
5879
+			// See if we can take a shortcut and just use innerHTML
5880
+			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5881
+				( jQuery.support.htmlSerialize || !rnoshimcache.test( value )  ) &&
5882
+				( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
5883
+				!wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {
5884
+
5885
+				value = value.replace( rxhtmlTag, "<$1></$2>" );
5886
+
5887
+				try {
5888
+					for (; i < l; i++ ) {
5889
+						// Remove element nodes and prevent memory leaks
5890
+						elem = this[i] || {};
5891
+						if ( elem.nodeType === 1 ) {
5892
+							jQuery.cleanData( elem.getElementsByTagName( "*" ) );
5893
+							elem.innerHTML = value;
5894
+						}
5895
+					}
5896
+
5897
+					elem = 0;
5898
+
5899
+				// If using innerHTML throws an exception, use the fallback method
5900
+				} catch(e) {}
5901
+			}
5902
+
5903
+			if ( elem ) {
5904
+				this.empty().append( value );
5905
+			}
5906
+		}, null, value, arguments.length );
5907
+	},
5908
+
5909
+	replaceWith: function( value ) {
5910
+		if ( !isDisconnected( this[0] ) ) {
5911
+			// Make sure that the elements are removed from the DOM before they are inserted
5912
+			// this can help fix replacing a parent with child elements
5913
+			if ( jQuery.isFunction( value ) ) {
5914
+				return this.each(function(i) {
5915
+					var self = jQuery(this), old = self.html();
5916
+					self.replaceWith( value.call( this, i, old ) );
5917
+				});
5918
+			}
5919
+
5920
+			if ( typeof value !== "string" ) {
5921
+				value = jQuery( value ).detach();
5922
+			}
5923
+
5924
+			return this.each(function() {
5925
+				var next = this.nextSibling,
5926
+					parent = this.parentNode;
5927
+
5928
+				jQuery( this ).remove();
5929
+
5930
+				if ( next ) {
5931
+					jQuery(next).before( value );
5932
+				} else {
5933
+					jQuery(parent).append( value );
5934
+				}
5935
+			});
5936
+		}
5937
+
5938
+		return this.length ?
5939
+			this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
5940
+			this;
5941
+	},
5942
+
5943
+	detach: function( selector ) {
5944
+		return this.remove( selector, true );
5945
+	},
5946
+
5947
+	domManip: function( args, table, callback ) {
5948
+
5949
+		// Flatten any nested arrays
5950
+		args = [].concat.apply( [], args );
5951
+
5952
+		var results, first, fragment, iNoClone,
5953
+			i = 0,
5954
+			value = args[0],
5955
+			scripts = [],
5956
+			l = this.length;
5957
+
5958
+		// We can't cloneNode fragments that contain checked, in WebKit
5959
+		if ( !jQuery.support.checkClone && l > 1 && typeof value === "string" && rchecked.test( value ) ) {
5960
+			return this.each(function() {
5961
+				jQuery(this).domManip( args, table, callback );
5962
+			});
5963
+		}
5964
+
5965
+		if ( jQuery.isFunction(value) ) {
5966
+			return this.each(function(i) {
5967
+				var self = jQuery(this);
5968
+				args[0] = value.call( this, i, table ? self.html() : undefined );
5969
+				self.domManip( args, table, callback );
5970
+			});
5971
+		}
5972
+
5973
+		if ( this[0] ) {
5974
+			results = jQuery.buildFragment( args, this, scripts );
5975
+			fragment = results.fragment;
5976
+			first = fragment.firstChild;
5977
+
5978
+			if ( fragment.childNodes.length === 1 ) {
5979
+				fragment = first;
5980
+			}
5981
+
5982
+			if ( first ) {
5983
+				table = table && jQuery.nodeName( first, "tr" );
5984
+
5985
+				// Use the original fragment for the last item instead of the first because it can end up
5986
+				// being emptied incorrectly in certain situations (#8070).
5987
+				// Fragments from the fragment cache must always be cloned and never used in place.
5988
+				for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) {
5989
+					callback.call(
5990
+						table && jQuery.nodeName( this[i], "table" ) ?
5991
+							findOrAppend( this[i], "tbody" ) :
5992
+							this[i],
5993
+						i === iNoClone ?
5994
+							fragment :
5995
+							jQuery.clone( fragment, true, true )
5996
+					);
5997
+				}
5998
+			}
5999
+
6000
+			// Fix #11809: Avoid leaking memory
6001
+			fragment = first = null;
6002
+
6003
+			if ( scripts.length ) {
6004
+				jQuery.each( scripts, function( i, elem ) {
6005
+					if ( elem.src ) {
6006
+						if ( jQuery.ajax ) {
6007
+							jQuery.ajax({
6008
+								url: elem.src,
6009
+								type: "GET",
6010
+								dataType: "script",
6011
+								async: false,
6012
+								global: false,
6013
+								"throws": true
6014
+							});
6015
+						} else {
6016
+							jQuery.error("no ajax");
6017
+						}
6018
+					} else {
6019
+						jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "" ) );
6020
+					}
6021
+
6022
+					if ( elem.parentNode ) {
6023
+						elem.parentNode.removeChild( elem );
6024
+					}
6025
+				});
6026
+			}
6027
+		}
6028
+
6029
+		return this;
6030
+	}
6031
+});
6032
+
6033
+function findOrAppend( elem, tag ) {
6034
+	return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) );
6035
+}
6036
+
6037
+function cloneCopyEvent( src, dest ) {
6038
+
6039
+	if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
6040
+		return;
6041
+	}
6042
+
6043
+	var type, i, l,
6044
+		oldData = jQuery._data( src ),
6045
+		curData = jQuery._data( dest, oldData ),
6046
+		events = oldData.events;
6047
+
6048
+	if ( events ) {
6049
+		delete curData.handle;
6050
+		curData.events = {};
6051
+
6052
+		for ( type in events ) {
6053
+			for ( i = 0, l = events[ type ].length; i < l; i++ ) {
6054
+				jQuery.event.add( dest, type, events[ type ][ i ] );
6055
+			}
6056
+		}
6057
+	}
6058
+
6059
+	// make the cloned public data object a copy from the original
6060
+	if ( curData.data ) {
6061
+		curData.data = jQuery.extend( {}, curData.data );
6062
+	}
6063
+}
6064
+
6065
+function cloneFixAttributes( src, dest ) {
6066
+	var nodeName;
6067
+
6068
+	// We do not need to do anything for non-Elements
6069
+	if ( dest.nodeType !== 1 ) {
6070
+		return;
6071
+	}
6072
+
6073
+	// clearAttributes removes the attributes, which we don't want,
6074
+	// but also removes the attachEvent events, which we *do* want
6075
+	if ( dest.clearAttributes ) {
6076
+		dest.clearAttributes();
6077
+	}
6078
+
6079
+	// mergeAttributes, in contrast, only merges back on the
6080
+	// original attributes, not the events
6081
+	if ( dest.mergeAttributes ) {
6082
+		dest.mergeAttributes( src );
6083
+	}
6084
+
6085
+	nodeName = dest.nodeName.toLowerCase();
6086
+
6087
+	if ( nodeName === "object" ) {
6088
+		// IE6-10 improperly clones children of object elements using classid.
6089
+		// IE10 throws NoModificationAllowedError if parent is null, #12132.
6090
+		if ( dest.parentNode ) {
6091
+			dest.outerHTML = src.outerHTML;
6092
+		}
6093
+
6094
+		// This path appears unavoidable for IE9. When cloning an object
6095
+		// element in IE9, the outerHTML strategy above is not sufficient.
6096
+		// If the src has innerHTML and the destination does not,
6097
+		// copy the src.innerHTML into the dest.innerHTML. #10324
6098
+		if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) {
6099
+			dest.innerHTML = src.innerHTML;
6100
+		}
6101
+
6102
+	} else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
6103
+		// IE6-8 fails to persist the checked state of a cloned checkbox
6104
+		// or radio button. Worse, IE6-7 fail to give the cloned element
6105
+		// a checked appearance if the defaultChecked value isn't also set
6106
+
6107
+		dest.defaultChecked = dest.checked = src.checked;
6108
+
6109
+		// IE6-7 get confused and end up setting the value of a cloned
6110
+		// checkbox/radio button to an empty string instead of "on"
6111
+		if ( dest.value !== src.value ) {
6112
+			dest.value = src.value;
6113
+		}
6114
+
6115
+	// IE6-8 fails to return the selected option to the default selected
6116
+	// state when cloning options
6117
+	} else if ( nodeName === "option" ) {
6118
+		dest.selected = src.defaultSelected;
6119
+
6120
+	// IE6-8 fails to set the defaultValue to the correct value when
6121
+	// cloning other types of input fields
6122
+	} else if ( nodeName === "input" || nodeName === "textarea" ) {
6123
+		dest.defaultValue = src.defaultValue;
6124
+
6125
+	// IE blanks contents when cloning scripts
6126
+	} else if ( nodeName === "script" && dest.text !== src.text ) {
6127
+		dest.text = src.text;
6128
+	}
6129
+
6130
+	// Event data gets referenced instead of copied if the expando
6131
+	// gets copied too
6132
+	dest.removeAttribute( jQuery.expando );
6133
+}
6134
+
6135
+jQuery.buildFragment = function( args, context, scripts ) {
6136
+	var fragment, cacheable, cachehit,
6137
+		first = args[ 0 ];
6138
+
6139
+	// Set context from what may come in as undefined or a jQuery collection or a node
6140
+	// Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 &
6141
+	// also doubles as fix for #8950 where plain objects caused createDocumentFragment exception
6142
+	context = context || document;
6143
+	context = !context.nodeType && context[0] || context;
6144
+	context = context.ownerDocument || context;
6145
+
6146
+	// Only cache "small" (1/2 KB) HTML strings that are associated with the main document
6147
+	// Cloning options loses the selected state, so don't cache them
6148
+	// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
6149
+	// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
6150
+	// Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501
6151
+	if ( args.length === 1 && typeof first === "string" && first.length < 512 && context === document &&
6152
+		first.charAt(0) === "<" && !rnocache.test( first ) &&
6153
+		(jQuery.support.checkClone || !rchecked.test( first )) &&
6154
+		(jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {
6155
+
6156
+		// Mark cacheable and look for a hit
6157
+		cacheable = true;
6158
+		fragment = jQuery.fragments[ first ];
6159
+		cachehit = fragment !== undefined;
6160
+	}
6161
+
6162
+	if ( !fragment ) {
6163
+		fragment = context.createDocumentFragment();
6164
+		jQuery.clean( args, context, fragment, scripts );
6165
+
6166
+		// Update the cache, but only store false
6167
+		// unless this is a second parsing of the same content
6168
+		if ( cacheable ) {
6169
+			jQuery.fragments[ first ] = cachehit && fragment;
6170
+		}
6171
+	}
6172
+
6173
+	return { fragment: fragment, cacheable: cacheable };
6174
+};
6175
+
6176
+jQuery.fragments = {};
6177
+
6178
+jQuery.each({
6179
+	appendTo: "append",
6180
+	prependTo: "prepend",
6181
+	insertBefore: "before",
6182
+	insertAfter: "after",
6183
+	replaceAll: "replaceWith"
6184
+}, function( name, original ) {
6185
+	jQuery.fn[ name ] = function( selector ) {
6186
+		var elems,
6187
+			i = 0,
6188
+			ret = [],
6189
+			insert = jQuery( selector ),
6190
+			l = insert.length,
6191
+			parent = this.length === 1 && this[0].parentNode;
6192
+
6193
+		if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) {
6194
+			insert[ original ]( this[0] );
6195
+			return this;
6196
+		} else {
6197
+			for ( ; i < l; i++ ) {
6198
+				elems = ( i > 0 ? this.clone(true) : this ).get();
6199
+				jQuery( insert[i] )[ original ]( elems );
6200
+				ret = ret.concat( elems );
6201
+			}
6202
+
6203
+			return this.pushStack( ret, name, insert.selector );
6204
+		}
6205
+	};
6206
+});
6207
+
6208
+function getAll( elem ) {
6209
+	if ( typeof elem.getElementsByTagName !== "undefined" ) {
6210
+		return elem.getElementsByTagName( "*" );
6211
+
6212
+	} else if ( typeof elem.querySelectorAll !== "undefined" ) {
6213
+		return elem.querySelectorAll( "*" );
6214
+
6215
+	} else {
6216
+		return [];
6217
+	}
6218
+}
6219
+
6220
+// Used in clean, fixes the defaultChecked property
6221
+function fixDefaultChecked( elem ) {
6222
+	if ( rcheckableType.test( elem.type ) ) {
6223
+		elem.defaultChecked = elem.checked;
6224
+	}
6225
+}
6226
+
6227
+jQuery.extend({
6228
+	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6229
+		var srcElements,
6230
+			destElements,
6231
+			i,
6232
+			clone;
6233
+
6234
+		if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
6235
+			clone = elem.cloneNode( true );
6236
+
6237
+		// IE<=8 does not properly clone detached, unknown element nodes
6238
+		} else {
6239
+			fragmentDiv.innerHTML = elem.outerHTML;
6240
+			fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
6241
+		}
6242
+
6243
+		if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
6244
+				(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
6245
+			// IE copies events bound via attachEvent when using cloneNode.
6246
+			// Calling detachEvent on the clone will also remove the events
6247
+			// from the original. In order to get around this, we use some
6248
+			// proprietary methods to clear the events. Thanks to MooTools
6249
+			// guys for this hotness.
6250
+
6251
+			cloneFixAttributes( elem, clone );
6252
+
6253
+			// Using Sizzle here is crazy slow, so we use getElementsByTagName instead
6254
+			srcElements = getAll( elem );
6255
+			destElements = getAll( clone );
6256
+
6257
+			// Weird iteration because IE will replace the length property
6258
+			// with an element if you are cloning the body and one of the
6259
+			// elements on the page has a name or id of "length"
6260
+			for ( i = 0; srcElements[i]; ++i ) {
6261
+				// Ensure that the destination node is not null; Fixes #9587
6262
+				if ( destElements[i] ) {
6263
+					cloneFixAttributes( srcElements[i], destElements[i] );
6264
+				}
6265
+			}
6266
+		}
6267
+
6268
+		// Copy the events from the original to the clone
6269
+		if ( dataAndEvents ) {
6270
+			cloneCopyEvent( elem, clone );
6271
+
6272
+			if ( deepDataAndEvents ) {
6273
+				srcElements = getAll( elem );
6274
+				destElements = getAll( clone );
6275
+
6276
+				for ( i = 0; srcElements[i]; ++i ) {
6277
+					cloneCopyEvent( srcElements[i], destElements[i] );
6278
+				}
6279
+			}
6280
+		}
6281
+
6282
+		srcElements = destElements = null;
6283
+
6284
+		// Return the cloned set
6285
+		return clone;
6286
+	},
6287
+
6288
+	clean: function( elems, context, fragment, scripts ) {
6289
+		var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags,
6290
+			safe = context === document && safeFragment,
6291
+			ret = [];
6292
+
6293
+		// Ensure that context is a document
6294
+		if ( !context || typeof context.createDocumentFragment === "undefined" ) {
6295
+			context = document;
6296
+		}
6297
+
6298
+		// Use the already-created safe fragment if context permits
6299
+		for ( i = 0; (elem = elems[i]) != null; i++ ) {
6300
+			if ( typeof elem === "number" ) {
6301
+				elem += "";
6302
+			}
6303
+
6304
+			if ( !elem ) {
6305
+				continue;
6306
+			}
6307
+
6308
+			// Convert html string into DOM nodes
6309
+			if ( typeof elem === "string" ) {
6310
+				if ( !rhtml.test( elem ) ) {
6311
+					elem = context.createTextNode( elem );
6312
+				} else {
6313
+					// Ensure a safe container in which to render the html
6314
+					safe = safe || createSafeFragment( context );
6315
+					div = context.createElement("div");
6316
+					safe.appendChild( div );
6317
+
6318
+					// Fix "XHTML"-style tags in all browsers
6319
+					elem = elem.replace(rxhtmlTag, "<$1></$2>");
6320
+
6321
+					// Go to html and back, then peel off extra wrappers
6322
+					tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase();
6323
+					wrap = wrapMap[ tag ] || wrapMap._default;
6324
+					depth = wrap[0];
6325
+					div.innerHTML = wrap[1] + elem + wrap[2];
6326
+
6327
+					// Move to the right depth
6328
+					while ( depth-- ) {
6329
+						div = div.lastChild;
6330
+					}
6331
+
6332
+					// Remove IE's autoinserted <tbody> from table fragments
6333
+					if ( !jQuery.support.tbody ) {
6334
+
6335
+						// String was a <table>, *may* have spurious <tbody>
6336
+						hasBody = rtbody.test(elem);
6337
+							tbody = tag === "table" && !hasBody ?
6338
+								div.firstChild && div.firstChild.childNodes :
6339
+
6340
+								// String was a bare <thead> or <tfoot>
6341
+								wrap[1] === "<table>" && !hasBody ?
6342
+									div.childNodes :
6343
+									[];
6344
+
6345
+						for ( j = tbody.length - 1; j >= 0 ; --j ) {
6346
+							if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6347
+								tbody[ j ].parentNode.removeChild( tbody[ j ] );
6348
+							}
6349
+						}
6350
+					}
6351
+
6352
+					// IE completely kills leading whitespace when innerHTML is used
6353
+					if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6354
+						div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6355
+					}
6356
+
6357
+					elem = div.childNodes;
6358
+
6359
+					// Take out of fragment container (we need a fresh div each time)
6360
+					div.parentNode.removeChild( div );
6361
+				}
6362
+			}
6363
+
6364
+			if ( elem.nodeType ) {
6365
+				ret.push( elem );
6366
+			} else {
6367
+				jQuery.merge( ret, elem );
6368
+			}
6369
+		}
6370
+
6371
+		// Fix #11356: Clear elements from safeFragment
6372
+		if ( div ) {
6373
+			elem = div = safe = null;
6374
+		}
6375
+
6376
+		// Reset defaultChecked for any radios and checkboxes
6377
+		// about to be appended to the DOM in IE 6/7 (#8060)
6378
+		if ( !jQuery.support.appendChecked ) {
6379
+			for ( i = 0; (elem = ret[i]) != null; i++ ) {
6380
+				if ( jQuery.nodeName( elem, "input" ) ) {
6381
+					fixDefaultChecked( elem );
6382
+				} else if ( typeof elem.getElementsByTagName !== "undefined" ) {
6383
+					jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
6384
+				}
6385
+			}
6386
+		}
6387
+
6388
+		// Append elements to a provided document fragment
6389
+		if ( fragment ) {
6390
+			// Special handling of each script element
6391
+			handleScript = function( elem ) {
6392
+				// Check if we consider it executable
6393
+				if ( !elem.type || rscriptType.test( elem.type ) ) {
6394
+					// Detach the script and store it in the scripts array (if provided) or the fragment
6395
+					// Return truthy to indicate that it has been handled
6396
+					return scripts ?
6397
+						scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :
6398
+						fragment.appendChild( elem );
6399
+				}
6400
+			};
6401
+
6402
+			for ( i = 0; (elem = ret[i]) != null; i++ ) {
6403
+				// Check if we're done after handling an executable script
6404
+				if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) {
6405
+					// Append to fragment and handle embedded scripts
6406
+					fragment.appendChild( elem );
6407
+					if ( typeof elem.getElementsByTagName !== "undefined" ) {
6408
+						// handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration
6409
+						jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript );
6410
+
6411
+						// Splice the scripts into ret after their former ancestor and advance our index beyond them
6412
+						ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6413
+						i += jsTags.length;
6414
+					}
6415
+				}
6416
+			}
6417
+		}
6418
+
6419
+		return ret;
6420
+	},
6421
+
6422
+	cleanData: function( elems, /* internal */ acceptData ) {
6423
+		var data, id, elem, type,
6424
+			i = 0,
6425
+			internalKey = jQuery.expando,
6426
+			cache = jQuery.cache,
6427
+			deleteExpando = jQuery.support.deleteExpando,
6428
+			special = jQuery.event.special;
6429
+
6430
+		for ( ; (elem = elems[i]) != null; i++ ) {
6431
+
6432
+			if ( acceptData || jQuery.acceptData( elem ) ) {
6433
+
6434
+				id = elem[ internalKey ];
6435
+				data = id && cache[ id ];
6436
+
6437
+				if ( data ) {
6438
+					if ( data.events ) {
6439
+						for ( type in data.events ) {
6440
+							if ( special[ type ] ) {
6441
+								jQuery.event.remove( elem, type );
6442
+
6443
+							// This is a shortcut to avoid jQuery.event.remove's overhead
6444
+							} else {
6445
+								jQuery.removeEvent( elem, type, data.handle );
6446
+							}
6447
+						}
6448
+					}
6449
+
6450
+					// Remove cache only if it was not already removed by jQuery.event.remove
6451
+					if ( cache[ id ] ) {
6452
+
6453
+						delete cache[ id ];
6454
+
6455
+						// IE does not allow us to delete expando properties from nodes,
6456
+						// nor does it have a removeAttribute function on Document nodes;
6457
+						// we must handle all of these cases
6458
+						if ( deleteExpando ) {
6459
+							delete elem[ internalKey ];
6460
+
6461
+						} else if ( elem.removeAttribute ) {
6462
+							elem.removeAttribute( internalKey );
6463
+
6464
+						} else {
6465
+							elem[ internalKey ] = null;
6466
+						}
6467
+
6468
+						jQuery.deletedIds.push( id );
6469
+					}
6470
+				}
6471
+			}
6472
+		}
6473
+	}
6474
+});
6475
+// Limit scope pollution from any deprecated API
6476
+(function() {
6477
+
6478
+var matched, browser;
6479
+
6480
+// Use of jQuery.browser is frowned upon.
6481
+// More details: http://api.jquery.com/jQuery.browser
6482
+// jQuery.uaMatch maintained for back-compat
6483
+jQuery.uaMatch = function( ua ) {
6484
+	ua = ua.toLowerCase();
6485
+
6486
+	var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
6487
+		/(webkit)[ \/]([\w.]+)/.exec( ua ) ||
6488
+		/(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
6489
+		/(msie) ([\w.]+)/.exec( ua ) ||
6490
+		ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
6491
+		[];
6492
+
6493
+	return {
6494
+		browser: match[ 1 ] || "",
6495
+		version: match[ 2 ] || "0"
6496
+	};
6497
+};
6498
+
6499
+matched = jQuery.uaMatch( navigator.userAgent );
6500
+browser = {};
6501
+
6502
+if ( matched.browser ) {
6503
+	browser[ matched.browser ] = true;
6504
+	browser.version = matched.version;
6505
+}
6506
+
6507
+// Chrome is Webkit, but Webkit is also Safari.
6508
+if ( browser.chrome ) {
6509
+	browser.webkit = true;
6510
+} else if ( browser.webkit ) {
6511
+	browser.safari = true;
6512
+}
6513
+
6514
+jQuery.browser = browser;
6515
+
6516
+jQuery.sub = function() {
6517
+	function jQuerySub( selector, context ) {
6518
+		return new jQuerySub.fn.init( selector, context );
6519
+	}
6520
+	jQuery.extend( true, jQuerySub, this );
6521
+	jQuerySub.superclass = this;
6522
+	jQuerySub.fn = jQuerySub.prototype = this();
6523
+	jQuerySub.fn.constructor = jQuerySub;
6524
+	jQuerySub.sub = this.sub;
6525
+	jQuerySub.fn.init = function init( selector, context ) {
6526
+		if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
6527
+			context = jQuerySub( context );
6528
+		}
6529
+
6530
+		return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
6531
+	};
6532
+	jQuerySub.fn.init.prototype = jQuerySub.fn;
6533
+	var rootjQuerySub = jQuerySub(document);
6534
+	return jQuerySub;
6535
+};
6536
+
6537
+})();
6538
+var curCSS, iframe, iframeDoc,
6539
+	ralpha = /alpha\([^)]*\)/i,
6540
+	ropacity = /opacity=([^)]*)/,
6541
+	rposition = /^(top|right|bottom|left)$/,
6542
+	// swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
6543
+	// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6544
+	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6545
+	rmargin = /^margin/,
6546
+	rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
6547
+	rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
6548
+	rrelNum = new RegExp( "^([-+])=(" + core_pnum + ")", "i" ),
6549
+	elemdisplay = { BODY: "block" },
6550
+
6551
+	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6552
+	cssNormalTransform = {
6553
+		letterSpacing: 0,
6554
+		fontWeight: 400
6555
+	},
6556
+
6557
+	cssExpand = [ "Top", "Right", "Bottom", "Left" ],
6558
+	cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
6559
+
6560
+	eventsToggle = jQuery.fn.toggle;
6561
+
6562
+// return a css property mapped to a potentially vendor prefixed property
6563
+function vendorPropName( style, name ) {
6564
+
6565
+	// shortcut for names that are not vendor prefixed
6566
+	if ( name in style ) {
6567
+		return name;
6568
+	}
6569
+
6570
+	// check for vendor prefixed names
6571
+	var capName = name.charAt(0).toUpperCase() + name.slice(1),
6572
+		origName = name,
6573
+		i = cssPrefixes.length;
6574
+
6575
+	while ( i-- ) {
6576
+		name = cssPrefixes[ i ] + capName;
6577
+		if ( name in style ) {
6578
+			return name;
6579
+		}
6580
+	}
6581
+
6582
+	return origName;
6583
+}
6584
+
6585
+function isHidden( elem, el ) {
6586
+	elem = el || elem;
6587
+	return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
6588
+}
6589
+
6590
+function showHide( elements, show ) {
6591
+	var elem, display,
6592
+		values = [],
6593
+		index = 0,
6594
+		length = elements.length;
6595
+
6596
+	for ( ; index < length; index++ ) {
6597
+		elem = elements[ index ];
6598
+		if ( !elem.style ) {
6599
+			continue;
6600
+		}
6601
+		values[ index ] = jQuery._data( elem, "olddisplay" );
6602
+		if ( show ) {
6603
+			// Reset the inline display of this element to learn if it is
6604
+			// being hidden by cascaded rules or not
6605
+			if ( !values[ index ] && elem.style.display === "none" ) {
6606
+				elem.style.display = "";
6607
+			}
6608
+
6609
+			// Set elements which have been overridden with display: none
6610
+			// in a stylesheet to whatever the default browser style is
6611
+			// for such an element
6612
+			if ( elem.style.display === "" && isHidden( elem ) ) {
6613
+				values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
6614
+			}
6615
+		} else {
6616
+			display = curCSS( elem, "display" );
6617
+
6618
+			if ( !values[ index ] && display !== "none" ) {
6619
+				jQuery._data( elem, "olddisplay", display );
6620
+			}
6621
+		}
6622
+	}
6623
+
6624
+	// Set the display of most of the elements in a second loop
6625
+	// to avoid the constant reflow
6626
+	for ( index = 0; index < length; index++ ) {
6627
+		elem = elements[ index ];
6628
+		if ( !elem.style ) {
6629
+			continue;
6630
+		}
6631
+		if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
6632
+			elem.style.display = show ? values[ index ] || "" : "none";
6633
+		}
6634
+	}
6635
+
6636
+	return elements;
6637
+}
6638
+
6639
+jQuery.fn.extend({
6640
+	css: function( name, value ) {
6641
+		return jQuery.access( this, function( elem, name, value ) {
6642
+			return value !== undefined ?
6643
+				jQuery.style( elem, name, value ) :
6644
+				jQuery.css( elem, name );
6645
+		}, name, value, arguments.length > 1 );
6646
+	},
6647
+	show: function() {
6648
+		return showHide( this, true );
6649
+	},
6650
+	hide: function() {
6651
+		return showHide( this );
6652
+	},
6653
+	toggle: function( state, fn2 ) {
6654
+		var bool = typeof state === "boolean";
6655
+
6656
+		if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) {
6657
+			return eventsToggle.apply( this, arguments );
6658
+		}
6659
+
6660
+		return this.each(function() {
6661
+			if ( bool ? state : isHidden( this ) ) {
6662
+				jQuery( this ).show();
6663
+			} else {
6664
+				jQuery( this ).hide();
6665
+			}
6666
+		});
6667
+	}
6668
+});
6669
+
6670
+jQuery.extend({
6671
+	// Add in style property hooks for overriding the default
6672
+	// behavior of getting and setting a style property
6673
+	cssHooks: {
6674
+		opacity: {
6675
+			get: function( elem, computed ) {
6676
+				if ( computed ) {
6677
+					// We should always get a number back from opacity
6678
+					var ret = curCSS( elem, "opacity" );
6679
+					return ret === "" ? "1" : ret;
6680
+
6681
+				}
6682
+			}
6683
+		}
6684
+	},
6685
+
6686
+	// Exclude the following css properties to add px
6687
+	cssNumber: {
6688
+		"fillOpacity": true,
6689
+		"fontWeight": true,
6690
+		"lineHeight": true,
6691
+		"opacity": true,
6692
+		"orphans": true,
6693
+		"widows": true,
6694
+		"zIndex": true,
6695
+		"zoom": true
6696
+	},
6697
+
6698
+	// Add in properties whose names you wish to fix before
6699
+	// setting or getting the value
6700
+	cssProps: {
6701
+		// normalize float css property
6702
+		"float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6703
+	},
6704
+
6705
+	// Get and set the style property on a DOM Node
6706
+	style: function( elem, name, value, extra ) {
6707
+		// Don't set styles on text and comment nodes
6708
+		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6709
+			return;
6710
+		}
6711
+
6712
+		// Make sure that we're working with the right name
6713
+		var ret, type, hooks,
6714
+			origName = jQuery.camelCase( name ),
6715
+			style = elem.style;
6716
+
6717
+		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
6718
+
6719
+		// gets hook for the prefixed version
6720
+		// followed by the unprefixed version
6721
+		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6722
+
6723
+		// Check if we're setting a value
6724
+		if ( value !== undefined ) {
6725
+			type = typeof value;
6726
+
6727
+			// convert relative number strings (+= or -=) to relative numbers. #7345
6728
+			if ( type === "string" && (ret = rrelNum.exec( value )) ) {
6729
+				value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
6730
+				// Fixes bug #9237
6731
+				type = "number";
6732
+			}
6733
+
6734
+			// Make sure that NaN and null values aren't set. See: #7116
6735
+			if ( value == null || type === "number" && isNaN( value ) ) {
6736
+				return;
6737
+			}
6738
+
6739
+			// If a number was passed in, add 'px' to the (except for certain CSS properties)
6740
+			if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6741
+				value += "px";
6742
+			}
6743
+
6744
+			// If a hook was provided, use that value, otherwise just set the specified value
6745
+			if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
6746
+				// Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6747
+				// Fixes bug #5509
6748
+				try {
6749
+					style[ name ] = value;
6750
+				} catch(e) {}
6751
+			}
6752
+
6753
+		} else {
6754
+			// If a hook was provided get the non-computed value from there
6755
+			if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6756
+				return ret;
6757
+			}
6758
+
6759
+			// Otherwise just get the value from the style object
6760
+			return style[ name ];
6761
+		}
6762
+	},
6763
+
6764
+	css: function( elem, name, numeric, extra ) {
6765
+		var val, num, hooks,
6766
+			origName = jQuery.camelCase( name );
6767
+
6768
+		// Make sure that we're working with the right name
6769
+		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
6770
+
6771
+		// gets hook for the prefixed version
6772
+		// followed by the unprefixed version
6773
+		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6774
+
6775
+		// If a hook was provided get the computed value from there
6776
+		if ( hooks && "get" in hooks ) {
6777
+			val = hooks.get( elem, true, extra );
6778
+		}
6779
+
6780
+		// Otherwise, if a way to get the computed value exists, use that
6781
+		if ( val === undefined ) {
6782
+			val = curCSS( elem, name );
6783
+		}
6784
+
6785
+		//convert "normal" to computed value
6786
+		if ( val === "normal" && name in cssNormalTransform ) {
6787
+			val = cssNormalTransform[ name ];
6788
+		}
6789
+
6790
+		// Return, converting to number if forced or a qualifier was provided and val looks numeric
6791
+		if ( numeric || extra !== undefined ) {
6792
+			num = parseFloat( val );
6793
+			return numeric || jQuery.isNumeric( num ) ? num || 0 : val;
6794
+		}
6795
+		return val;
6796
+	},
6797
+
6798
+	// A method for quickly swapping in/out CSS properties to get correct calculations
6799
+	swap: function( elem, options, callback ) {
6800
+		var ret, name,
6801
+			old = {};
6802
+
6803
+		// Remember the old values, and insert the new ones
6804
+		for ( name in options ) {
6805
+			old[ name ] = elem.style[ name ];
6806
+			elem.style[ name ] = options[ name ];
6807
+		}
6808
+
6809
+		ret = callback.call( elem );
6810
+
6811
+		// Revert the old values
6812
+		for ( name in options ) {
6813
+			elem.style[ name ] = old[ name ];
6814
+		}
6815
+
6816
+		return ret;
6817
+	}
6818
+});
6819
+
6820
+// NOTE: To any future maintainer, we've window.getComputedStyle
6821
+// because jsdom on node.js will break without it.
6822
+if ( window.getComputedStyle ) {
6823
+	curCSS = function( elem, name ) {
6824
+		var ret, width, minWidth, maxWidth,
6825
+			computed = window.getComputedStyle( elem, null ),
6826
+			style = elem.style;
6827
+
6828
+		if ( computed ) {
6829
+
6830
+			// getPropertyValue is only needed for .css('filter') in IE9, see #12537
6831
+			ret = computed.getPropertyValue( name ) || computed[ name ];
6832
+
6833
+			if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
6834
+				ret = jQuery.style( elem, name );
6835
+			}
6836
+
6837
+			// A tribute to the "awesome hack by Dean Edwards"
6838
+			// Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
6839
+			// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
6840
+			// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
6841
+			if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
6842
+				width = style.width;
6843
+				minWidth = style.minWidth;
6844
+				maxWidth = style.maxWidth;
6845
+
6846
+				style.minWidth = style.maxWidth = style.width = ret;
6847
+				ret = computed.width;
6848
+
6849
+				style.width = width;
6850
+				style.minWidth = minWidth;
6851
+				style.maxWidth = maxWidth;
6852
+			}
6853
+		}
6854
+
6855
+		return ret;
6856
+	};
6857
+} else if ( document.documentElement.currentStyle ) {
6858
+	curCSS = function( elem, name ) {
6859
+		var left, rsLeft,
6860
+			ret = elem.currentStyle && elem.currentStyle[ name ],
6861
+			style = elem.style;
6862
+
6863
+		// Avoid setting ret to empty string here
6864
+		// so we don't default to auto
6865
+		if ( ret == null && style && style[ name ] ) {
6866
+			ret = style[ name ];
6867
+		}
6868
+
6869
+		// From the awesome hack by Dean Edwards
6870
+		// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6871
+
6872
+		// If we're not dealing with a regular pixel number
6873
+		// but a number that has a weird ending, we need to convert it to pixels
6874
+		// but not position css attributes, as those are proportional to the parent element instead
6875
+		// and we can't measure the parent instead because it might trigger a "stacking dolls" problem
6876
+		if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
6877
+
6878
+			// Remember the original values
6879
+			left = style.left;
6880
+			rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;
6881
+
6882
+			// Put in the new values to get a computed value out
6883
+			if ( rsLeft ) {
6884
+				elem.runtimeStyle.left = elem.currentStyle.left;
6885
+			}
6886
+			style.left = name === "fontSize" ? "1em" : ret;
6887
+			ret = style.pixelLeft + "px";
6888
+
6889
+			// Revert the changed values
6890
+			style.left = left;
6891
+			if ( rsLeft ) {
6892
+				elem.runtimeStyle.left = rsLeft;
6893
+			}
6894
+		}
6895
+
6896
+		return ret === "" ? "auto" : ret;
6897
+	};
6898
+}
6899
+
6900
+function setPositiveNumber( elem, value, subtract ) {
6901
+	var matches = rnumsplit.exec( value );
6902
+	return matches ?
6903
+			Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
6904
+			value;
6905
+}
6906
+
6907
+function augmentWidthOrHeight( elem, name, extra, isBorderBox ) {
6908
+	var i = extra === ( isBorderBox ? "border" : "content" ) ?
6909
+		// If we already have the right measurement, avoid augmentation
6910
+		4 :
6911
+		// Otherwise initialize for horizontal or vertical properties
6912
+		name === "width" ? 1 : 0,
6913
+
6914
+		val = 0;
6915
+
6916
+	for ( ; i < 4; i += 2 ) {
6917
+		// both box models exclude margin, so add it if we want it
6918
+		if ( extra === "margin" ) {
6919
+			// we use jQuery.css instead of curCSS here
6920
+			// because of the reliableMarginRight CSS hook!
6921
+			val += jQuery.css( elem, extra + cssExpand[ i ], true );
6922
+		}
6923
+
6924
+		// From this point on we use curCSS for maximum performance (relevant in animations)
6925
+		if ( isBorderBox ) {
6926
+			// border-box includes padding, so remove it if we want content
6927
+			if ( extra === "content" ) {
6928
+				val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0;
6929
+			}
6930
+
6931
+			// at this point, extra isn't border nor margin, so remove border
6932
+			if ( extra !== "margin" ) {
6933
+				val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
6934
+			}
6935
+		} else {
6936
+			// at this point, extra isn't content, so add padding
6937
+			val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0;
6938
+
6939
+			// at this point, extra isn't content nor padding, so add border
6940
+			if ( extra !== "padding" ) {
6941
+				val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
6942
+			}
6943
+		}
6944
+	}
6945
+
6946
+	return val;
6947
+}
6948
+
6949
+function getWidthOrHeight( elem, name, extra ) {
6950
+
6951
+	// Start with offset property, which is equivalent to the border-box value
6952
+	var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6953
+		valueIsBorderBox = true,
6954
+		isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box";
6955
+
6956
+	// some non-html elements return undefined for offsetWidth, so check for null/undefined
6957
+	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
6958
+	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
6959
+	if ( val <= 0 || val == null ) {
6960
+		// Fall back to computed then uncomputed css if necessary
6961
+		val = curCSS( elem, name );
6962
+		if ( val < 0 || val == null ) {
6963
+			val = elem.style[ name ];
6964
+		}
6965
+
6966
+		// Computed unit is not pixels. Stop here and return.
6967
+		if ( rnumnonpx.test(val) ) {
6968
+			return val;
6969
+		}
6970
+
6971
+		// we need the check for style in case a browser which returns unreliable values
6972
+		// for getComputedStyle silently falls back to the reliable elem.style
6973
+		valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );
6974
+
6975
+		// Normalize "", auto, and prepare for extra
6976
+		val = parseFloat( val ) || 0;
6977
+	}
6978
+
6979
+	// use the active box-sizing model to add/subtract irrelevant styles
6980
+	return ( val +
6981
+		augmentWidthOrHeight(
6982
+			elem,
6983
+			name,
6984
+			extra || ( isBorderBox ? "border" : "content" ),
6985
+			valueIsBorderBox
6986
+		)
6987
+	) + "px";
6988
+}
6989
+
6990
+
6991
+// Try to determine the default display value of an element
6992
+function css_defaultDisplay( nodeName ) {
6993
+	if ( elemdisplay[ nodeName ] ) {
6994
+		return elemdisplay[ nodeName ];
6995
+	}
6996
+
6997
+	var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ),
6998
+		display = elem.css("display");
6999
+	elem.remove();
7000
+
7001
+	// If the simple way fails,
7002
+	// get element's real default display by attaching it to a temp iframe
7003
+	if ( display === "none" || display === "" ) {
7004
+		// Use the already-created iframe if possible
7005
+		iframe = document.body.appendChild(
7006
+			iframe || jQuery.extend( document.createElement("iframe"), {
7007
+				frameBorder: 0,
7008
+				width: 0,
7009
+				height: 0
7010
+			})
7011
+		);
7012
+
7013
+		// Create a cacheable copy of the iframe document on first call.
7014
+		// IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
7015
+		// document to it; WebKit & Firefox won't allow reusing the iframe document.
7016
+		if ( !iframeDoc || !iframe.createElement ) {
7017
+			iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
7018
+			iframeDoc.write("<!doctype html><html><body>");
7019
+			iframeDoc.close();
7020
+		}
7021
+
7022
+		elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) );
7023
+
7024
+		display = curCSS( elem, "display" );
7025
+		document.body.removeChild( iframe );
7026
+	}
7027
+
7028
+	// Store the correct default display
7029
+	elemdisplay[ nodeName ] = display;
7030
+
7031
+	return display;
7032
+}
7033
+
7034
+jQuery.each([ "height", "width" ], function( i, name ) {
7035
+	jQuery.cssHooks[ name ] = {
7036
+		get: function( elem, computed, extra ) {
7037
+			if ( computed ) {
7038
+				// certain elements can have dimension info if we invisibly show them
7039
+				// however, it must have a current display style that would benefit from this
7040
+				if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) {
7041
+					return jQuery.swap( elem, cssShow, function() {
7042
+						return getWidthOrHeight( elem, name, extra );
7043
+					});
7044
+				} else {
7045
+					return getWidthOrHeight( elem, name, extra );
7046
+				}
7047
+			}
7048
+		},
7049
+
7050
+		set: function( elem, value, extra ) {
7051
+			return setPositiveNumber( elem, value, extra ?
7052
+				augmentWidthOrHeight(
7053
+					elem,
7054
+					name,
7055
+					extra,
7056
+					jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"
7057
+				) : 0
7058
+			);
7059
+		}
7060
+	};
7061
+});
7062
+
7063
+if ( !jQuery.support.opacity ) {
7064
+	jQuery.cssHooks.opacity = {
7065
+		get: function( elem, computed ) {
7066
+			// IE uses filters for opacity
7067
+			return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
7068
+				( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
7069
+				computed ? "1" : "";
7070
+		},
7071
+
7072
+		set: function( elem, value ) {
7073
+			var style = elem.style,
7074
+				currentStyle = elem.currentStyle,
7075
+				opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
7076
+				filter = currentStyle && currentStyle.filter || style.filter || "";
7077
+
7078
+			// IE has trouble with opacity if it does not have layout
7079
+			// Force it by setting the zoom level
7080
+			style.zoom = 1;
7081
+
7082
+			// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
7083
+			if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
7084
+				style.removeAttribute ) {
7085
+
7086
+				// Setting style.filter to null, "" & " " still leave "filter:" in the cssText
7087
+				// if "filter:" is present at all, clearType is disabled, we want to avoid this
7088
+				// style.removeAttribute is IE Only, but so apparently is this code path...
7089
+				style.removeAttribute( "filter" );
7090
+
7091
+				// if there there is no filter style applied in a css rule, we are done
7092
+				if ( currentStyle && !currentStyle.filter ) {
7093
+					return;
7094
+				}
7095
+			}
7096
+
7097
+			// otherwise, set new filter values
7098
+			style.filter = ralpha.test( filter ) ?
7099
+				filter.replace( ralpha, opacity ) :
7100
+				filter + " " + opacity;
7101
+		}
7102
+	};
7103
+}
7104
+
7105
+// These hooks cannot be added until DOM ready because the support test
7106
+// for it is not run until after DOM ready
7107
+jQuery(function() {
7108
+	if ( !jQuery.support.reliableMarginRight ) {
7109
+		jQuery.cssHooks.marginRight = {
7110
+			get: function( elem, computed ) {
7111
+				// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
7112
+				// Work around by temporarily setting element display to inline-block
7113
+				return jQuery.swap( elem, { "display": "inline-block" }, function() {
7114
+					if ( computed ) {
7115
+						return curCSS( elem, "marginRight" );
7116
+					}
7117
+				});
7118
+			}
7119
+		};
7120
+	}
7121
+
7122
+	// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
7123
+	// getComputedStyle returns percent when specified for top/left/bottom/right
7124
+	// rather than make the css module depend on the offset module, we just check for it here
7125
+	if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {
7126
+		jQuery.each( [ "top", "left" ], function( i, prop ) {
7127
+			jQuery.cssHooks[ prop ] = {
7128
+				get: function( elem, computed ) {
7129
+					if ( computed ) {
7130
+						var ret = curCSS( elem, prop );
7131
+						// if curCSS returns percentage, fallback to offset
7132
+						return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + "px" : ret;
7133
+					}
7134
+				}
7135
+			};
7136
+		});
7137
+	}
7138
+
7139
+});
7140
+
7141
+if ( jQuery.expr && jQuery.expr.filters ) {
7142
+	jQuery.expr.filters.hidden = function( elem ) {
7143
+		return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, "display" )) === "none");
7144
+	};
7145
+
7146
+	jQuery.expr.filters.visible = function( elem ) {
7147
+		return !jQuery.expr.filters.hidden( elem );
7148
+	};
7149
+}
7150
+
7151
+// These hooks are used by animate to expand properties
7152
+jQuery.each({
7153
+	margin: "",
7154
+	padding: "",
7155
+	border: "Width"
7156
+}, function( prefix, suffix ) {
7157
+	jQuery.cssHooks[ prefix + suffix ] = {
7158
+		expand: function( value ) {
7159
+			var i,
7160
+
7161
+				// assumes a single number if not a string
7162
+				parts = typeof value === "string" ? value.split(" ") : [ value ],
7163
+				expanded = {};
7164
+
7165
+			for ( i = 0; i < 4; i++ ) {
7166
+				expanded[ prefix + cssExpand[ i ] + suffix ] =
7167
+					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
7168
+			}
7169
+
7170
+			return expanded;
7171
+		}
7172
+	};
7173
+
7174
+	if ( !rmargin.test( prefix ) ) {
7175
+		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
7176
+	}
7177
+});
7178
+var r20 = /%20/g,
7179
+	rbracket = /\[\]$/,
7180
+	rCRLF = /\r?\n/g,
7181
+	rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
7182
+	rselectTextarea = /^(?:select|textarea)/i;
7183
+
7184
+jQuery.fn.extend({
7185
+	serialize: function() {
7186
+		return jQuery.param( this.serializeArray() );
7187
+	},
7188
+	serializeArray: function() {
7189
+		return this.map(function(){
7190
+			return this.elements ? jQuery.makeArray( this.elements ) : this;
7191
+		})
7192
+		.filter(function(){
7193
+			return this.name && !this.disabled &&
7194
+				( this.checked || rselectTextarea.test( this.nodeName ) ||
7195
+					rinput.test( this.type ) );
7196
+		})
7197
+		.map(function( i, elem ){
7198
+			var val = jQuery( this ).val();
7199
+
7200
+			return val == null ?
7201
+				null :
7202
+				jQuery.isArray( val ) ?
7203
+					jQuery.map( val, function( val, i ){
7204
+						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7205
+					}) :
7206
+					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7207
+		}).get();
7208
+	}
7209
+});
7210
+
7211
+//Serialize an array of form elements or a set of
7212
+//key/values into a query string
7213
+jQuery.param = function( a, traditional ) {
7214
+	var prefix,
7215
+		s = [],
7216
+		add = function( key, value ) {
7217
+			// If value is a function, invoke it and return its value
7218
+			value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
7219
+			s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7220
+		};
7221
+
7222
+	// Set traditional to true for jQuery <= 1.3.2 behavior.
7223
+	if ( traditional === undefined ) {
7224
+		traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
7225
+	}
7226
+
7227
+	// If an array was passed in, assume that it is an array of form elements.
7228
+	if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7229
+		// Serialize the form elements
7230
+		jQuery.each( a, function() {
7231
+			add( this.name, this.value );
7232
+		});
7233
+
7234
+	} else {
7235
+		// If traditional, encode the "old" way (the way 1.3.2 or older
7236
+		// did it), otherwise encode params recursively.
7237
+		for ( prefix in a ) {
7238
+			buildParams( prefix, a[ prefix ], traditional, add );
7239
+		}
7240
+	}
7241
+
7242
+	// Return the resulting serialization
7243
+	return s.join( "&" ).replace( r20, "+" );
7244
+};
7245
+
7246
+function buildParams( prefix, obj, traditional, add ) {
7247
+	var name;
7248
+
7249
+	if ( jQuery.isArray( obj ) ) {
7250
+		// Serialize array item.
7251
+		jQuery.each( obj, function( i, v ) {
7252
+			if ( traditional || rbracket.test( prefix ) ) {
7253
+				// Treat each array item as a scalar.
7254
+				add( prefix, v );
7255
+
7256
+			} else {
7257
+				// If array item is non-scalar (array or object), encode its
7258
+				// numeric index to resolve deserialization ambiguity issues.
7259
+				// Note that rack (as of 1.0.0) can't currently deserialize
7260
+				// nested arrays properly, and attempting to do so may cause
7261
+				// a server error. Possible fixes are to modify rack's
7262
+				// deserialization algorithm or to provide an option or flag
7263
+				// to force array serialization to be shallow.
7264
+				buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
7265
+			}
7266
+		});
7267
+
7268
+	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
7269
+		// Serialize object item.
7270
+		for ( name in obj ) {
7271
+			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
7272
+		}
7273
+
7274
+	} else {
7275
+		// Serialize scalar item.
7276
+		add( prefix, obj );
7277
+	}
7278
+}
7279
+var
7280
+	// Document location
7281
+	ajaxLocParts,
7282
+	ajaxLocation,
7283
+
7284
+	rhash = /#.*$/,
7285
+	rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
7286
+	// #7653, #8125, #8152: local protocol detection
7287
+	rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
7288
+	rnoContent = /^(?:GET|HEAD)$/,
7289
+	rprotocol = /^\/\//,
7290
+	rquery = /\?/,
7291
+	rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
7292
+	rts = /([?&])_=[^&]*/,
7293
+	rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
7294
+
7295
+	// Keep a copy of the old load method
7296
+	_load = jQuery.fn.load,
7297
+
7298
+	/* Prefilters
7299
+	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
7300
+	 * 2) These are called:
7301
+	 *    - BEFORE asking for a transport
7302
+	 *    - AFTER param serialization (s.data is a string if s.processData is true)
7303
+	 * 3) key is the dataType
7304
+	 * 4) the catchall symbol "*" can be used
7305
+	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
7306
+	 */
7307
+	prefilters = {},
7308
+
7309
+	/* Transports bindings
7310
+	 * 1) key is the dataType
7311
+	 * 2) the catchall symbol "*" can be used
7312
+	 * 3) selection will start with transport dataType and THEN go to "*" if needed
7313
+	 */
7314
+	transports = {},
7315
+
7316
+	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
7317
+	allTypes = ["*/"] + ["*"];
7318
+
7319
+// #8138, IE may throw an exception when accessing
7320
+// a field from window.location if document.domain has been set
7321
+try {
7322
+	ajaxLocation = location.href;
7323
+} catch( e ) {
7324
+	// Use the href attribute of an A element
7325
+	// since IE will modify it given document.location
7326
+	ajaxLocation = document.createElement( "a" );
7327
+	ajaxLocation.href = "";
7328
+	ajaxLocation = ajaxLocation.href;
7329
+}
7330
+
7331
+// Segment location into parts
7332
+ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
7333
+
7334
+// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
7335
+function addToPrefiltersOrTransports( structure ) {
7336
+
7337
+	// dataTypeExpression is optional and defaults to "*"
7338
+	return function( dataTypeExpression, func ) {
7339
+
7340
+		if ( typeof dataTypeExpression !== "string" ) {
7341
+			func = dataTypeExpression;
7342
+			dataTypeExpression = "*";
7343
+		}
7344
+
7345
+		var dataType, list, placeBefore,
7346
+			dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ),
7347
+			i = 0,
7348
+			length = dataTypes.length;
7349
+
7350
+		if ( jQuery.isFunction( func ) ) {
7351
+			// For each dataType in the dataTypeExpression
7352
+			for ( ; i < length; i++ ) {
7353
+				dataType = dataTypes[ i ];
7354
+				// We control if we're asked to add before
7355
+				// any existing element
7356
+				placeBefore = /^\+/.test( dataType );
7357
+				if ( placeBefore ) {
7358
+					dataType = dataType.substr( 1 ) || "*";
7359
+				}
7360
+				list = structure[ dataType ] = structure[ dataType ] || [];
7361
+				// then we add to the structure accordingly
7362
+				list[ placeBefore ? "unshift" : "push" ]( func );
7363
+			}
7364
+		}
7365
+	};
7366
+}
7367
+
7368
+// Base inspection function for prefilters and transports
7369
+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
7370
+		dataType /* internal */, inspected /* internal */ ) {
7371
+
7372
+	dataType = dataType || options.dataTypes[ 0 ];
7373
+	inspected = inspected || {};
7374
+
7375
+	inspected[ dataType ] = true;
7376
+
7377
+	var selection,
7378
+		list = structure[ dataType ],
7379
+		i = 0,
7380
+		length = list ? list.length : 0,
7381
+		executeOnly = ( structure === prefilters );
7382
+
7383
+	for ( ; i < length && ( executeOnly || !selection ); i++ ) {
7384
+		selection = list[ i ]( options, originalOptions, jqXHR );
7385
+		// If we got redirected to another dataType
7386
+		// we try there if executing only and not done already
7387
+		if ( typeof selection === "string" ) {
7388
+			if ( !executeOnly || inspected[ selection ] ) {
7389
+				selection = undefined;
7390
+			} else {
7391
+				options.dataTypes.unshift( selection );
7392
+				selection = inspectPrefiltersOrTransports(
7393
+						structure, options, originalOptions, jqXHR, selection, inspected );
7394
+			}
7395
+		}
7396
+	}
7397
+	// If we're only executing or nothing was selected
7398
+	// we try the catchall dataType if not done already
7399
+	if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
7400
+		selection = inspectPrefiltersOrTransports(
7401
+				structure, options, originalOptions, jqXHR, "*", inspected );
7402
+	}
7403
+	// unnecessary when only executing (prefilters)
7404
+	// but it'll be ignored by the caller in that case
7405
+	return selection;
7406
+}
7407
+
7408
+// A special extend for ajax options
7409
+// that takes "flat" options (not to be deep extended)
7410
+// Fixes #9887
7411
+function ajaxExtend( target, src ) {
7412
+	var key, deep,
7413
+		flatOptions = jQuery.ajaxSettings.flatOptions || {};
7414
+	for ( key in src ) {
7415
+		if ( src[ key ] !== undefined ) {
7416
+			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
7417
+		}
7418
+	}
7419
+	if ( deep ) {
7420
+		jQuery.extend( true, target, deep );
7421
+	}
7422
+}
7423
+
7424
+jQuery.fn.load = function( url, params, callback ) {
7425
+	if ( typeof url !== "string" && _load ) {
7426
+		return _load.apply( this, arguments );
7427
+	}
7428
+
7429
+	// Don't do a request if no elements are being requested
7430
+	if ( !this.length ) {
7431
+		return this;
7432
+	}
7433
+
7434
+	var selector, type, response,
7435
+		self = this,
7436
+		off = url.indexOf(" ");
7437
+
7438
+	if ( off >= 0 ) {
7439
+		selector = url.slice( off, url.length );
7440
+		url = url.slice( 0, off );
7441
+	}
7442
+
7443
+	// If it's a function
7444
+	if ( jQuery.isFunction( params ) ) {
7445
+
7446
+		// We assume that it's the callback
7447
+		callback = params;
7448
+		params = undefined;
7449
+
7450
+	// Otherwise, build a param string
7451
+	} else if ( params && typeof params === "object" ) {
7452
+		type = "POST";
7453
+	}
7454
+
7455
+	// Request the remote document
7456
+	jQuery.ajax({
7457
+		url: url,
7458
+
7459
+		// if "type" variable is undefined, then "GET" method will be used
7460
+		type: type,
7461
+		dataType: "html",
7462
+		data: params,
7463
+		complete: function( jqXHR, status ) {
7464
+			if ( callback ) {
7465
+				self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
7466
+			}
7467
+		}
7468
+	}).done(function( responseText ) {
7469
+
7470
+		// Save response for use in complete callback
7471
+		response = arguments;
7472
+
7473
+		// See if a selector was specified
7474
+		self.html( selector ?
7475
+
7476
+			// Create a dummy div to hold the results
7477
+			jQuery("<div>")
7478
+
7479
+				// inject the contents of the document in, removing the scripts
7480
+				// to avoid any 'Permission Denied' errors in IE
7481
+				.append( responseText.replace( rscript, "" ) )
7482
+
7483
+				// Locate the specified elements
7484
+				.find( selector ) :
7485
+
7486
+			// If not, just inject the full result
7487
+			responseText );
7488
+
7489
+	});
7490
+
7491
+	return this;
7492
+};
7493
+
7494
+// Attach a bunch of functions for handling common AJAX events
7495
+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
7496
+	jQuery.fn[ o ] = function( f ){
7497
+		return this.on( o, f );
7498
+	};
7499
+});
7500
+
7501
+jQuery.each( [ "get", "post" ], function( i, method ) {
7502
+	jQuery[ method ] = function( url, data, callback, type ) {
7503
+		// shift arguments if data argument was omitted
7504
+		if ( jQuery.isFunction( data ) ) {
7505
+			type = type || callback;
7506
+			callback = data;
7507
+			data = undefined;
7508
+		}
7509
+
7510
+		return jQuery.ajax({
7511
+			type: method,
7512
+			url: url,
7513
+			data: data,
7514
+			success: callback,
7515
+			dataType: type
7516
+		});
7517
+	};
7518
+});
7519
+
7520
+jQuery.extend({
7521
+
7522
+	getScript: function( url, callback ) {
7523
+		return jQuery.get( url, undefined, callback, "script" );
7524
+	},
7525
+
7526
+	getJSON: function( url, data, callback ) {
7527
+		return jQuery.get( url, data, callback, "json" );
7528
+	},
7529
+
7530
+	// Creates a full fledged settings object into target
7531
+	// with both ajaxSettings and settings fields.
7532
+	// If target is omitted, writes into ajaxSettings.
7533
+	ajaxSetup: function( target, settings ) {
7534
+		if ( settings ) {
7535
+			// Building a settings object
7536
+			ajaxExtend( target, jQuery.ajaxSettings );
7537
+		} else {
7538
+			// Extending ajaxSettings
7539
+			settings = target;
7540
+			target = jQuery.ajaxSettings;
7541
+		}
7542
+		ajaxExtend( target, settings );
7543
+		return target;
7544
+	},
7545
+
7546
+	ajaxSettings: {
7547
+		url: ajaxLocation,
7548
+		isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
7549
+		global: true,
7550
+		type: "GET",
7551
+		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
7552
+		processData: true,
7553
+		async: true,
7554
+		/*
7555
+		timeout: 0,
7556
+		data: null,
7557
+		dataType: null,
7558
+		username: null,
7559
+		password: null,
7560
+		cache: null,
7561
+		throws: false,
7562
+		traditional: false,
7563
+		headers: {},
7564
+		*/
7565
+
7566
+		accepts: {
7567
+			xml: "application/xml, text/xml",
7568
+			html: "text/html",
7569
+			text: "text/plain",
7570
+			json: "application/json, text/javascript",
7571
+			"*": allTypes
7572
+		},
7573
+
7574
+		contents: {
7575
+			xml: /xml/,
7576
+			html: /html/,
7577
+			json: /json/
7578
+		},
7579
+
7580
+		responseFields: {
7581
+			xml: "responseXML",
7582
+			text: "responseText"
7583
+		},
7584
+
7585
+		// List of data converters
7586
+		// 1) key format is "source_type destination_type" (a single space in-between)
7587
+		// 2) the catchall symbol "*" can be used for source_type
7588
+		converters: {
7589
+
7590
+			// Convert anything to text
7591
+			"* text": window.String,
7592
+
7593
+			// Text to html (true = no transformation)
7594
+			"text html": true,
7595
+
7596
+			// Evaluate text as a json expression
7597
+			"text json": jQuery.parseJSON,
7598
+
7599
+			// Parse text as xml
7600
+			"text xml": jQuery.parseXML
7601
+		},
7602
+
7603
+		// For options that shouldn't be deep extended:
7604
+		// you can add your own custom options here if
7605
+		// and when you create one that shouldn't be
7606
+		// deep extended (see ajaxExtend)
7607
+		flatOptions: {
7608
+			context: true,
7609
+			url: true
7610
+		}
7611
+	},
7612
+
7613
+	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
7614
+	ajaxTransport: addToPrefiltersOrTransports( transports ),
7615
+
7616
+	// Main method
7617
+	ajax: function( url, options ) {
7618
+
7619
+		// If url is an object, simulate pre-1.5 signature
7620
+		if ( typeof url === "object" ) {
7621
+			options = url;
7622
+			url = undefined;
7623
+		}
7624
+
7625
+		// Force options to be an object
7626
+		options = options || {};
7627
+
7628
+		var // ifModified key
7629
+			ifModifiedKey,
7630
+			// Response headers
7631
+			responseHeadersString,
7632
+			responseHeaders,
7633
+			// transport
7634
+			transport,
7635
+			// timeout handle
7636
+			timeoutTimer,
7637
+			// Cross-domain detection vars
7638
+			parts,
7639
+			// To know if global events are to be dispatched
7640
+			fireGlobals,
7641
+			// Loop variable
7642
+			i,
7643
+			// Create the final options object
7644
+			s = jQuery.ajaxSetup( {}, options ),
7645
+			// Callbacks context
7646
+			callbackContext = s.context || s,
7647
+			// Context for global events
7648
+			// It's the callbackContext if one was provided in the options
7649
+			// and if it's a DOM node or a jQuery collection
7650
+			globalEventContext = callbackContext !== s &&
7651
+				( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
7652
+						jQuery( callbackContext ) : jQuery.event,
7653
+			// Deferreds
7654
+			deferred = jQuery.Deferred(),
7655
+			completeDeferred = jQuery.Callbacks( "once memory" ),
7656
+			// Status-dependent callbacks
7657
+			statusCode = s.statusCode || {},
7658
+			// Headers (they are sent all at once)
7659
+			requestHeaders = {},
7660
+			requestHeadersNames = {},
7661
+			// The jqXHR state
7662
+			state = 0,
7663
+			// Default abort message
7664
+			strAbort = "canceled",
7665
+			// Fake xhr
7666
+			jqXHR = {
7667
+
7668
+				readyState: 0,
7669
+
7670
+				// Caches the header
7671
+				setRequestHeader: function( name, value ) {
7672
+					if ( !state ) {
7673
+						var lname = name.toLowerCase();
7674
+						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7675
+						requestHeaders[ name ] = value;
7676
+					}
7677
+					return this;
7678
+				},
7679
+
7680
+				// Raw string
7681
+				getAllResponseHeaders: function() {
7682
+					return state === 2 ? responseHeadersString : null;
7683
+				},
7684
+
7685
+				// Builds headers hashtable if needed
7686
+				getResponseHeader: function( key ) {
7687
+					var match;
7688
+					if ( state === 2 ) {
7689
+						if ( !responseHeaders ) {
7690
+							responseHeaders = {};
7691
+							while( ( match = rheaders.exec( responseHeadersString ) ) ) {
7692
+								responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7693
+							}
7694
+						}
7695
+						match = responseHeaders[ key.toLowerCase() ];
7696
+					}
7697
+					return match === undefined ? null : match;
7698
+				},
7699
+
7700
+				// Overrides response content-type header
7701
+				overrideMimeType: function( type ) {
7702
+					if ( !state ) {
7703
+						s.mimeType = type;
7704
+					}
7705
+					return this;
7706
+				},
7707
+
7708
+				// Cancel the request
7709
+				abort: function( statusText ) {
7710
+					statusText = statusText || strAbort;
7711
+					if ( transport ) {
7712
+						transport.abort( statusText );
7713
+					}
7714
+					done( 0, statusText );
7715
+					return this;
7716
+				}
7717
+			};
7718
+
7719
+		// Callback for when everything is done
7720
+		// It is defined here because jslint complains if it is declared
7721
+		// at the end of the function (which would be more logical and readable)
7722
+		function done( status, nativeStatusText, responses, headers ) {
7723
+			var isSuccess, success, error, response, modified,
7724
+				statusText = nativeStatusText;
7725
+
7726
+			// Called once
7727
+			if ( state === 2 ) {
7728
+				return;
7729
+			}
7730
+
7731
+			// State is "done" now
7732
+			state = 2;
7733
+
7734
+			// Clear timeout if it exists
7735
+			if ( timeoutTimer ) {
7736
+				clearTimeout( timeoutTimer );
7737
+			}
7738
+
7739
+			// Dereference transport for early garbage collection
7740
+			// (no matter how long the jqXHR object will be used)
7741
+			transport = undefined;
7742
+
7743
+			// Cache response headers
7744
+			responseHeadersString = headers || "";
7745
+
7746
+			// Set readyState
7747
+			jqXHR.readyState = status > 0 ? 4 : 0;
7748
+
7749
+			// Get response data
7750
+			if ( responses ) {
7751
+				response = ajaxHandleResponses( s, jqXHR, responses );
7752
+			}
7753
+
7754
+			// If successful, handle type chaining
7755
+			if ( status >= 200 && status < 300 || status === 304 ) {
7756
+
7757
+				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7758
+				if ( s.ifModified ) {
7759
+
7760
+					modified = jqXHR.getResponseHeader("Last-Modified");
7761
+					if ( modified ) {
7762
+						jQuery.lastModified[ ifModifiedKey ] = modified;
7763
+					}
7764
+					modified = jqXHR.getResponseHeader("Etag");
7765
+					if ( modified ) {
7766
+						jQuery.etag[ ifModifiedKey ] = modified;
7767
+					}
7768
+				}
7769
+
7770
+				// If not modified
7771
+				if ( status === 304 ) {
7772
+
7773
+					statusText = "notmodified";
7774
+					isSuccess = true;
7775
+
7776
+				// If we have data
7777
+				} else {
7778
+
7779
+					isSuccess = ajaxConvert( s, response );
7780
+					statusText = isSuccess.state;
7781
+					success = isSuccess.data;
7782
+					error = isSuccess.error;
7783
+					isSuccess = !error;
7784
+				}
7785
+			} else {
7786
+				// We extract error from statusText
7787
+				// then normalize statusText and status for non-aborts
7788
+				error = statusText;
7789
+				if ( !statusText || status ) {
7790
+					statusText = "error";
7791
+					if ( status < 0 ) {
7792
+						status = 0;
7793
+					}
7794
+				}
7795
+			}
7796
+
7797
+			// Set data for the fake xhr object
7798
+			jqXHR.status = status;
7799
+			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
7800
+
7801
+			// Success/Error
7802
+			if ( isSuccess ) {
7803
+				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7804
+			} else {
7805
+				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7806
+			}
7807
+
7808
+			// Status-dependent callbacks
7809
+			jqXHR.statusCode( statusCode );
7810
+			statusCode = undefined;
7811
+
7812
+			if ( fireGlobals ) {
7813
+				globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7814
+						[ jqXHR, s, isSuccess ? success : error ] );
7815
+			}
7816
+
7817
+			// Complete
7818
+			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
7819
+
7820
+			if ( fireGlobals ) {
7821
+				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
7822
+				// Handle the global AJAX counter
7823
+				if ( !( --jQuery.active ) ) {
7824
+					jQuery.event.trigger( "ajaxStop" );
7825
+				}
7826
+			}
7827
+		}
7828
+
7829
+		// Attach deferreds
7830
+		deferred.promise( jqXHR );
7831
+		jqXHR.success = jqXHR.done;
7832
+		jqXHR.error = jqXHR.fail;
7833
+		jqXHR.complete = completeDeferred.add;
7834
+
7835
+		// Status-dependent callbacks
7836
+		jqXHR.statusCode = function( map ) {
7837
+			if ( map ) {
7838
+				var tmp;
7839
+				if ( state < 2 ) {
7840
+					for ( tmp in map ) {
7841
+						statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7842
+					}
7843
+				} else {
7844
+					tmp = map[ jqXHR.status ];
7845
+					jqXHR.always( tmp );
7846
+				}
7847
+			}
7848
+			return this;
7849
+		};
7850
+
7851
+		// Remove hash character (#7531: and string promotion)
7852
+		// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7853
+		// We also use the url parameter if available
7854
+		s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7855
+
7856
+		// Extract dataTypes list
7857
+		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace );
7858
+
7859
+		// A cross-domain request is in order when we have a protocol:host:port mismatch
7860
+		if ( s.crossDomain == null ) {
7861
+			parts = rurl.exec( s.url.toLowerCase() );
7862
+			s.crossDomain = !!( parts &&
7863
+				( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
7864
+					( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
7865
+						( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
7866
+			);
7867
+		}
7868
+
7869
+		// Convert data if not already a string
7870
+		if ( s.data && s.processData && typeof s.data !== "string" ) {
7871
+			s.data = jQuery.param( s.data, s.traditional );
7872
+		}
7873
+
7874
+		// Apply prefilters
7875
+		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7876
+
7877
+		// If request was aborted inside a prefilter, stop there
7878
+		if ( state === 2 ) {
7879
+			return jqXHR;
7880
+		}
7881
+
7882
+		// We can fire global events as of now if asked to
7883
+		fireGlobals = s.global;
7884
+
7885
+		// Uppercase the type
7886
+		s.type = s.type.toUpperCase();
7887
+
7888
+		// Determine if request has content
7889
+		s.hasContent = !rnoContent.test( s.type );
7890
+
7891
+		// Watch for a new set of requests
7892
+		if ( fireGlobals && jQuery.active++ === 0 ) {
7893
+			jQuery.event.trigger( "ajaxStart" );
7894
+		}
7895
+
7896
+		// More options handling for requests with no content
7897
+		if ( !s.hasContent ) {
7898
+
7899
+			// If data is available, append data to url
7900
+			if ( s.data ) {
7901
+				s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7902
+				// #9682: remove data so that it's not used in an eventual retry
7903
+				delete s.data;
7904
+			}
7905
+
7906
+			// Get ifModifiedKey before adding the anti-cache parameter
7907
+			ifModifiedKey = s.url;
7908
+
7909
+			// Add anti-cache in url if needed
7910
+			if ( s.cache === false ) {
7911
+
7912
+				var ts = jQuery.now(),
7913
+					// try replacing _= if it is there
7914
+					ret = s.url.replace( rts, "$1_=" + ts );
7915
+
7916
+				// if nothing was replaced, add timestamp to the end
7917
+				s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7918
+			}
7919
+		}
7920
+
7921
+		// Set the correct header, if data is being sent
7922
+		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7923
+			jqXHR.setRequestHeader( "Content-Type", s.contentType );
7924
+		}
7925
+
7926
+		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7927
+		if ( s.ifModified ) {
7928
+			ifModifiedKey = ifModifiedKey || s.url;
7929
+			if ( jQuery.lastModified[ ifModifiedKey ] ) {
7930
+				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7931
+			}
7932
+			if ( jQuery.etag[ ifModifiedKey ] ) {
7933
+				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7934
+			}
7935
+		}
7936
+
7937
+		// Set the Accepts header for the server, depending on the dataType
7938
+		jqXHR.setRequestHeader(
7939
+			"Accept",
7940
+			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7941
+				s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
7942
+				s.accepts[ "*" ]
7943
+		);
7944
+
7945
+		// Check for headers option
7946
+		for ( i in s.headers ) {
7947
+			jqXHR.setRequestHeader( i, s.headers[ i ] );
7948
+		}
7949
+
7950
+		// Allow custom headers/mimetypes and early abort
7951
+		if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7952
+				// Abort if not done already and return
7953
+				return jqXHR.abort();
7954
+
7955
+		}
7956
+
7957
+		// aborting is no longer a cancellation
7958
+		strAbort = "abort";
7959
+
7960
+		// Install callbacks on deferreds
7961
+		for ( i in { success: 1, error: 1, complete: 1 } ) {
7962
+			jqXHR[ i ]( s[ i ] );
7963
+		}
7964
+
7965
+		// Get transport
7966
+		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7967
+
7968
+		// If no transport, we auto-abort
7969
+		if ( !transport ) {
7970
+			done( -1, "No Transport" );
7971
+		} else {
7972
+			jqXHR.readyState = 1;
7973
+			// Send global event
7974
+			if ( fireGlobals ) {
7975
+				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7976
+			}
7977
+			// Timeout
7978
+			if ( s.async && s.timeout > 0 ) {
7979
+				timeoutTimer = setTimeout( function(){
7980
+					jqXHR.abort( "timeout" );
7981
+				}, s.timeout );
7982
+			}
7983
+
7984
+			try {
7985
+				state = 1;
7986
+				transport.send( requestHeaders, done );
7987
+			} catch (e) {
7988
+				// Propagate exception as error if not done
7989
+				if ( state < 2 ) {
7990
+					done( -1, e );
7991
+				// Simply rethrow otherwise
7992
+				} else {
7993
+					throw e;
7994
+				}
7995
+			}
7996
+		}
7997
+
7998
+		return jqXHR;
7999
+	},
8000
+
8001
+	// Counter for holding the number of active queries
8002
+	active: 0,
8003
+
8004
+	// Last-Modified header cache for next request
8005
+	lastModified: {},
8006
+	etag: {}
8007
+
8008
+});
8009
+
8010
+/* Handles responses to an ajax request:
8011
+ * - sets all responseXXX fields accordingly
8012
+ * - finds the right dataType (mediates between content-type and expected dataType)
8013
+ * - returns the corresponding response
8014
+ */
8015
+function ajaxHandleResponses( s, jqXHR, responses ) {
8016
+
8017
+	var ct, type, finalDataType, firstDataType,
8018
+		contents = s.contents,
8019
+		dataTypes = s.dataTypes,
8020
+		responseFields = s.responseFields;
8021
+
8022
+	// Fill responseXXX fields
8023
+	for ( type in responseFields ) {
8024
+		if ( type in responses ) {
8025
+			jqXHR[ responseFields[type] ] = responses[ type ];
8026
+		}
8027
+	}
8028
+
8029
+	// Remove auto dataType and get content-type in the process
8030
+	while( dataTypes[ 0 ] === "*" ) {
8031
+		dataTypes.shift();
8032
+		if ( ct === undefined ) {
8033
+			ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
8034
+		}
8035
+	}
8036
+
8037
+	// Check if we're dealing with a known content-type
8038
+	if ( ct ) {
8039
+		for ( type in contents ) {
8040
+			if ( contents[ type ] && contents[ type ].test( ct ) ) {
8041
+				dataTypes.unshift( type );
8042
+				break;
8043
+			}
8044
+		}
8045
+	}
8046
+
8047
+	// Check to see if we have a response for the expected dataType
8048
+	if ( dataTypes[ 0 ] in responses ) {
8049
+		finalDataType = dataTypes[ 0 ];
8050
+	} else {
8051
+		// Try convertible dataTypes
8052
+		for ( type in responses ) {
8053
+			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
8054
+				finalDataType = type;
8055
+				break;
8056
+			}
8057
+			if ( !firstDataType ) {
8058
+				firstDataType = type;
8059
+			}
8060
+		}
8061
+		// Or just use first one
8062
+		finalDataType = finalDataType || firstDataType;
8063
+	}
8064
+
8065
+	// If we found a dataType
8066
+	// We add the dataType to the list if needed
8067
+	// and return the corresponding response
8068
+	if ( finalDataType ) {
8069
+		if ( finalDataType !== dataTypes[ 0 ] ) {
8070
+			dataTypes.unshift( finalDataType );
8071
+		}
8072
+		return responses[ finalDataType ];
8073
+	}
8074
+}
8075
+
8076
+// Chain conversions given the request and the original response
8077
+function ajaxConvert( s, response ) {
8078
+
8079
+	var conv, conv2, current, tmp,
8080
+		// Work with a copy of dataTypes in case we need to modify it for conversion
8081
+		dataTypes = s.dataTypes.slice(),
8082
+		prev = dataTypes[ 0 ],
8083
+		converters = {},
8084
+		i = 0;
8085
+
8086
+	// Apply the dataFilter if provided
8087
+	if ( s.dataFilter ) {
8088
+		response = s.dataFilter( response, s.dataType );
8089
+	}
8090
+
8091
+	// Create converters map with lowercased keys
8092
+	if ( dataTypes[ 1 ] ) {
8093
+		for ( conv in s.converters ) {
8094
+			converters[ conv.toLowerCase() ] = s.converters[ conv ];
8095
+		}
8096
+	}
8097
+
8098
+	// Convert to each sequential dataType, tolerating list modification
8099
+	for ( ; (current = dataTypes[++i]); ) {
8100
+
8101
+		// There's only work to do if current dataType is non-auto
8102
+		if ( current !== "*" ) {
8103
+
8104
+			// Convert response if prev dataType is non-auto and differs from current
8105
+			if ( prev !== "*" && prev !== current ) {
8106
+
8107
+				// Seek a direct converter
8108
+				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
8109
+
8110
+				// If none found, seek a pair
8111
+				if ( !conv ) {
8112
+					for ( conv2 in converters ) {
8113
+
8114
+						// If conv2 outputs current
8115
+						tmp = conv2.split(" ");
8116
+						if ( tmp[ 1 ] === current ) {
8117
+
8118
+							// If prev can be converted to accepted input
8119
+							conv = converters[ prev + " " + tmp[ 0 ] ] ||
8120
+								converters[ "* " + tmp[ 0 ] ];
8121
+							if ( conv ) {
8122
+								// Condense equivalence converters
8123
+								if ( conv === true ) {
8124
+									conv = converters[ conv2 ];
8125
+
8126
+								// Otherwise, insert the intermediate dataType
8127
+								} else if ( converters[ conv2 ] !== true ) {
8128
+									current = tmp[ 0 ];
8129
+									dataTypes.splice( i--, 0, current );
8130
+								}
8131
+
8132
+								break;
8133
+							}
8134
+						}
8135
+					}
8136
+				}
8137
+
8138
+				// Apply converter (if not an equivalence)
8139
+				if ( conv !== true ) {
8140
+
8141
+					// Unless errors are allowed to bubble, catch and return them
8142
+					if ( conv && s["throws"] ) {
8143
+						response = conv( response );
8144
+					} else {
8145
+						try {
8146
+							response = conv( response );
8147
+						} catch ( e ) {
8148
+							return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
8149
+						}
8150
+					}
8151
+				}
8152
+			}
8153
+
8154
+			// Update prev for next iteration
8155
+			prev = current;
8156
+		}
8157
+	}
8158
+
8159
+	return { state: "success", data: response };
8160
+}
8161
+var oldCallbacks = [],
8162
+	rquestion = /\?/,
8163
+	rjsonp = /(=)\?(?=&|$)|\?\?/,
8164
+	nonce = jQuery.now();
8165
+
8166
+// Default jsonp settings
8167
+jQuery.ajaxSetup({
8168
+	jsonp: "callback",
8169
+	jsonpCallback: function() {
8170
+		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
8171
+		this[ callback ] = true;
8172
+		return callback;
8173
+	}
8174
+});
8175
+
8176
+// Detect, normalize options and install callbacks for jsonp requests
8177
+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
8178
+
8179
+	var callbackName, overwritten, responseContainer,
8180
+		data = s.data,
8181
+		url = s.url,
8182
+		hasCallback = s.jsonp !== false,
8183
+		replaceInUrl = hasCallback && rjsonp.test( url ),
8184
+		replaceInData = hasCallback && !replaceInUrl && typeof data === "string" &&
8185
+			!( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") &&
8186
+			rjsonp.test( data );
8187
+
8188
+	// Handle iff the expected data type is "jsonp" or we have a parameter to set
8189
+	if ( s.dataTypes[ 0 ] === "jsonp" || replaceInUrl || replaceInData ) {
8190
+
8191
+		// Get callback name, remembering preexisting value associated with it
8192
+		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
8193
+			s.jsonpCallback() :
8194
+			s.jsonpCallback;
8195
+		overwritten = window[ callbackName ];
8196
+
8197
+		// Insert callback into url or form data
8198
+		if ( replaceInUrl ) {
8199
+			s.url = url.replace( rjsonp, "$1" + callbackName );
8200
+		} else if ( replaceInData ) {
8201
+			s.data = data.replace( rjsonp, "$1" + callbackName );
8202
+		} else if ( hasCallback ) {
8203
+			s.url += ( rquestion.test( url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
8204
+		}
8205
+
8206
+		// Use data converter to retrieve json after script execution
8207
+		s.converters["script json"] = function() {
8208
+			if ( !responseContainer ) {
8209
+				jQuery.error( callbackName + " was not called" );
8210
+			}
8211
+			return responseContainer[ 0 ];
8212
+		};
8213
+
8214
+		// force json dataType
8215
+		s.dataTypes[ 0 ] = "json";
8216
+
8217
+		// Install callback
8218
+		window[ callbackName ] = function() {
8219
+			responseContainer = arguments;
8220
+		};
8221
+
8222
+		// Clean-up function (fires after converters)
8223
+		jqXHR.always(function() {
8224
+			// Restore preexisting value
8225
+			window[ callbackName ] = overwritten;
8226
+
8227
+			// Save back as free
8228
+			if ( s[ callbackName ] ) {
8229
+				// make sure that re-using the options doesn't screw things around
8230
+				s.jsonpCallback = originalSettings.jsonpCallback;
8231
+
8232
+				// save the callback name for future use
8233
+				oldCallbacks.push( callbackName );
8234
+			}
8235
+
8236
+			// Call if it was a function and we have a response
8237
+			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
8238
+				overwritten( responseContainer[ 0 ] );
8239
+			}
8240
+
8241
+			responseContainer = overwritten = undefined;
8242
+		});
8243
+
8244
+		// Delegate to script
8245
+		return "script";
8246
+	}
8247
+});
8248
+// Install script dataType
8249
+jQuery.ajaxSetup({
8250
+	accepts: {
8251
+		script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
8252
+	},
8253
+	contents: {
8254
+		script: /javascript|ecmascript/
8255
+	},
8256
+	converters: {
8257
+		"text script": function( text ) {
8258
+			jQuery.globalEval( text );
8259
+			return text;
8260
+		}
8261
+	}
8262
+});
8263
+
8264
+// Handle cache's special case and global
8265
+jQuery.ajaxPrefilter( "script", function( s ) {
8266
+	if ( s.cache === undefined ) {
8267
+		s.cache = false;
8268
+	}
8269
+	if ( s.crossDomain ) {
8270
+		s.type = "GET";
8271
+		s.global = false;
8272
+	}
8273
+});
8274
+
8275
+// Bind script tag hack transport
8276
+jQuery.ajaxTransport( "script", function(s) {
8277
+
8278
+	// This transport only deals with cross domain requests
8279
+	if ( s.crossDomain ) {
8280
+
8281
+		var script,
8282
+			head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
8283
+
8284
+		return {
8285
+
8286
+			send: function( _, callback ) {
8287
+
8288
+				script = document.createElement( "script" );
8289
+
8290
+				script.async = "async";
8291
+
8292
+				if ( s.scriptCharset ) {
8293
+					script.charset = s.scriptCharset;
8294
+				}
8295
+
8296
+				script.src = s.url;
8297
+
8298
+				// Attach handlers for all browsers
8299
+				script.onload = script.onreadystatechange = function( _, isAbort ) {
8300
+
8301
+					if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
8302
+
8303
+						// Handle memory leak in IE
8304
+						script.onload = script.onreadystatechange = null;
8305
+
8306
+						// Remove the script
8307
+						if ( head && script.parentNode ) {
8308
+							head.removeChild( script );
8309
+						}
8310
+
8311
+						// Dereference the script
8312
+						script = undefined;
8313
+
8314
+						// Callback if not abort
8315
+						if ( !isAbort ) {
8316
+							callback( 200, "success" );
8317
+						}
8318
+					}
8319
+				};
8320
+				// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
8321
+				// This arises when a base node is used (#2709 and #4378).
8322
+				head.insertBefore( script, head.firstChild );
8323
+			},
8324
+
8325
+			abort: function() {
8326
+				if ( script ) {
8327
+					script.onload( 0, 1 );
8328
+				}
8329
+			}
8330
+		};
8331
+	}
8332
+});
8333
+var xhrCallbacks,
8334
+	// #5280: Internet Explorer will keep connections alive if we don't abort on unload
8335
+	xhrOnUnloadAbort = window.ActiveXObject ? function() {
8336
+		// Abort all pending requests
8337
+		for ( var key in xhrCallbacks ) {
8338
+			xhrCallbacks[ key ]( 0, 1 );
8339
+		}
8340
+	} : false,
8341
+	xhrId = 0;
8342
+
8343
+// Functions to create xhrs
8344
+function createStandardXHR() {
8345
+	try {
8346
+		return new window.XMLHttpRequest();
8347
+	} catch( e ) {}
8348
+}
8349
+
8350
+function createActiveXHR() {
8351
+	try {
8352
+		return new window.ActiveXObject( "Microsoft.XMLHTTP" );
8353
+	} catch( e ) {}
8354
+}
8355
+
8356
+// Create the request object
8357
+// (This is still attached to ajaxSettings for backward compatibility)
8358
+jQuery.ajaxSettings.xhr = window.ActiveXObject ?
8359
+	/* Microsoft failed to properly
8360
+	 * implement the XMLHttpRequest in IE7 (can't request local files),
8361
+	 * so we use the ActiveXObject when it is available
8362
+	 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
8363
+	 * we need a fallback.
8364
+	 */
8365
+	function() {
8366
+		return !this.isLocal && createStandardXHR() || createActiveXHR();
8367
+	} :
8368
+	// For all other browsers, use the standard XMLHttpRequest object
8369
+	createStandardXHR;
8370
+
8371
+// Determine support properties
8372
+(function( xhr ) {
8373
+	jQuery.extend( jQuery.support, {
8374
+		ajax: !!xhr,
8375
+		cors: !!xhr && ( "withCredentials" in xhr )
8376
+	});
8377
+})( jQuery.ajaxSettings.xhr() );
8378
+
8379
+// Create transport if the browser can provide an xhr
8380
+if ( jQuery.support.ajax ) {
8381
+
8382
+	jQuery.ajaxTransport(function( s ) {
8383
+		// Cross domain only allowed if supported through XMLHttpRequest
8384
+		if ( !s.crossDomain || jQuery.support.cors ) {
8385
+
8386
+			var callback;
8387
+
8388
+			return {
8389
+				send: function( headers, complete ) {
8390
+
8391
+					// Get a new xhr
8392
+					var handle, i,
8393
+						xhr = s.xhr();
8394
+
8395
+					// Open the socket
8396
+					// Passing null username, generates a login popup on Opera (#2865)
8397
+					if ( s.username ) {
8398
+						xhr.open( s.type, s.url, s.async, s.username, s.password );
8399
+					} else {
8400
+						xhr.open( s.type, s.url, s.async );
8401
+					}
8402
+
8403
+					// Apply custom fields if provided
8404
+					if ( s.xhrFields ) {
8405
+						for ( i in s.xhrFields ) {
8406
+							xhr[ i ] = s.xhrFields[ i ];
8407
+						}
8408
+					}
8409
+
8410
+					// Override mime type if needed
8411
+					if ( s.mimeType && xhr.overrideMimeType ) {
8412
+						xhr.overrideMimeType( s.mimeType );
8413
+					}
8414
+
8415
+					// X-Requested-With header
8416
+					// For cross-domain requests, seeing as conditions for a preflight are
8417
+					// akin to a jigsaw puzzle, we simply never set it to be sure.
8418
+					// (it can always be set on a per-request basis or even using ajaxSetup)
8419
+					// For same-domain requests, won't change header if already provided.
8420
+					if ( !s.crossDomain && !headers["X-Requested-With"] ) {
8421
+						headers[ "X-Requested-With" ] = "XMLHttpRequest";
8422
+					}
8423
+
8424
+					// Need an extra try/catch for cross domain requests in Firefox 3
8425
+					try {
8426
+						for ( i in headers ) {
8427
+							xhr.setRequestHeader( i, headers[ i ] );
8428
+						}
8429
+					} catch( _ ) {}
8430
+
8431
+					// Do send the request
8432
+					// This may raise an exception which is actually
8433
+					// handled in jQuery.ajax (so no try/catch here)
8434
+					xhr.send( ( s.hasContent && s.data ) || null );
8435
+
8436
+					// Listener
8437
+					callback = function( _, isAbort ) {
8438
+
8439
+						var status,
8440
+							statusText,
8441
+							responseHeaders,
8442
+							responses,
8443
+							xml;
8444
+
8445
+						// Firefox throws exceptions when accessing properties
8446
+						// of an xhr when a network error occurred
8447
+						// http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
8448
+						try {
8449
+
8450
+							// Was never called and is aborted or complete
8451
+							if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
8452
+
8453
+								// Only called once
8454
+								callback = undefined;
8455
+
8456
+								// Do not keep as active anymore
8457
+								if ( handle ) {
8458
+									xhr.onreadystatechange = jQuery.noop;
8459
+									if ( xhrOnUnloadAbort ) {
8460
+										delete xhrCallbacks[ handle ];
8461
+									}
8462
+								}
8463
+
8464
+								// If it's an abort
8465
+								if ( isAbort ) {
8466
+									// Abort it manually if needed
8467
+									if ( xhr.readyState !== 4 ) {
8468
+										xhr.abort();
8469
+									}
8470
+								} else {
8471
+									status = xhr.status;
8472
+									responseHeaders = xhr.getAllResponseHeaders();
8473
+									responses = {};
8474
+									xml = xhr.responseXML;
8475
+
8476
+									// Construct response list
8477
+									if ( xml && xml.documentElement /* #4958 */ ) {
8478
+										responses.xml = xml;
8479
+									}
8480
+
8481
+									// When requesting binary data, IE6-9 will throw an exception
8482
+									// on any attempt to access responseText (#11426)
8483
+									try {
8484
+										responses.text = xhr.responseText;
8485
+									} catch( e ) {
8486
+									}
8487
+
8488
+									// Firefox throws an exception when accessing
8489
+									// statusText for faulty cross-domain requests
8490
+									try {
8491
+										statusText = xhr.statusText;
8492
+									} catch( e ) {
8493
+										// We normalize with Webkit giving an empty statusText
8494
+										statusText = "";
8495
+									}
8496
+
8497
+									// Filter status for non standard behaviors
8498
+
8499
+									// If the request is local and we have data: assume a success
8500
+									// (success with no data won't get notified, that's the best we
8501
+									// can do given current implementations)
8502
+									if ( !status && s.isLocal && !s.crossDomain ) {
8503
+										status = responses.text ? 200 : 404;
8504
+									// IE - #1450: sometimes returns 1223 when it should be 204
8505
+									} else if ( status === 1223 ) {
8506
+										status = 204;
8507
+									}
8508
+								}
8509
+							}
8510
+						} catch( firefoxAccessException ) {
8511
+							if ( !isAbort ) {
8512
+								complete( -1, firefoxAccessException );
8513
+							}
8514
+						}
8515
+
8516
+						// Call complete if needed
8517
+						if ( responses ) {
8518
+							complete( status, statusText, responses, responseHeaders );
8519
+						}
8520
+					};
8521
+
8522
+					if ( !s.async ) {
8523
+						// if we're in sync mode we fire the callback
8524
+						callback();
8525
+					} else if ( xhr.readyState === 4 ) {
8526
+						// (IE6 & IE7) if it's in cache and has been
8527
+						// retrieved directly we need to fire the callback
8528
+						setTimeout( callback, 0 );
8529
+					} else {
8530
+						handle = ++xhrId;
8531
+						if ( xhrOnUnloadAbort ) {
8532
+							// Create the active xhrs callbacks list if needed
8533
+							// and attach the unload handler
8534
+							if ( !xhrCallbacks ) {
8535
+								xhrCallbacks = {};
8536
+								jQuery( window ).unload( xhrOnUnloadAbort );
8537
+							}
8538
+							// Add to list of active xhrs callbacks
8539
+							xhrCallbacks[ handle ] = callback;
8540
+						}
8541
+						xhr.onreadystatechange = callback;
8542
+					}
8543
+				},
8544
+
8545
+				abort: function() {
8546
+					if ( callback ) {
8547
+						callback(0,1);
8548
+					}
8549
+				}
8550
+			};
8551
+		}
8552
+	});
8553
+}
8554
+var fxNow, timerId,
8555
+	rfxtypes = /^(?:toggle|show|hide)$/,
8556
+	rfxnum = new RegExp( "^(?:([-+])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),
8557
+	rrun = /queueHooks$/,
8558
+	animationPrefilters = [ defaultPrefilter ],
8559
+	tweeners = {
8560
+		"*": [function( prop, value ) {
8561
+			var end, unit,
8562
+				tween = this.createTween( prop, value ),
8563
+				parts = rfxnum.exec( value ),
8564
+				target = tween.cur(),
8565
+				start = +target || 0,
8566
+				scale = 1,
8567
+				maxIterations = 20;
8568
+
8569
+			if ( parts ) {
8570
+				end = +parts[2];
8571
+				unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" );
8572
+
8573
+				// We need to compute starting value
8574
+				if ( unit !== "px" && start ) {
8575
+					// Iteratively approximate from a nonzero starting point
8576
+					// Prefer the current property, because this process will be trivial if it uses the same units
8577
+					// Fallback to end or a simple constant
8578
+					start = jQuery.css( tween.elem, prop, true ) || end || 1;
8579
+
8580
+					do {
8581
+						// If previous iteration zeroed out, double until we get *something*
8582
+						// Use a string for doubling factor so we don't accidentally see scale as unchanged below
8583
+						scale = scale || ".5";
8584
+
8585
+						// Adjust and apply
8586
+						start = start / scale;
8587
+						jQuery.style( tween.elem, prop, start + unit );
8588
+
8589
+					// Update scale, tolerating zero or NaN from tween.cur()
8590
+					// And breaking the loop if scale is unchanged or perfect, or if we've just had enough
8591
+					} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
8592
+				}
8593
+
8594
+				tween.unit = unit;
8595
+				tween.start = start;
8596
+				// If a +=/-= token was provided, we're doing a relative animation
8597
+				tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end;
8598
+			}
8599
+			return tween;
8600
+		}]
8601
+	};
8602
+
8603
+// Animations created synchronously will run synchronously
8604
+function createFxNow() {
8605
+	setTimeout(function() {
8606
+		fxNow = undefined;
8607
+	}, 0 );
8608
+	return ( fxNow = jQuery.now() );
8609
+}
8610
+
8611
+function createTweens( animation, props ) {
8612
+	jQuery.each( props, function( prop, value ) {
8613
+		var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
8614
+			index = 0,
8615
+			length = collection.length;
8616
+		for ( ; index < length; index++ ) {
8617
+			if ( collection[ index ].call( animation, prop, value ) ) {
8618
+
8619
+				// we're done with this property
8620
+				return;
8621
+			}
8622
+		}
8623
+	});
8624
+}
8625
+
8626
+function Animation( elem, properties, options ) {
8627
+	var result,
8628
+		index = 0,
8629
+		tweenerIndex = 0,
8630
+		length = animationPrefilters.length,
8631
+		deferred = jQuery.Deferred().always( function() {
8632
+			// don't match elem in the :animated selector
8633
+			delete tick.elem;
8634
+		}),
8635
+		tick = function() {
8636
+			var currentTime = fxNow || createFxNow(),
8637
+				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
8638
+				// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
8639
+				temp = remaining / animation.duration || 0,
8640
+				percent = 1 - temp,
8641
+				index = 0,
8642
+				length = animation.tweens.length;
8643
+
8644
+			for ( ; index < length ; index++ ) {
8645
+				animation.tweens[ index ].run( percent );
8646
+			}
8647
+
8648
+			deferred.notifyWith( elem, [ animation, percent, remaining ]);
8649
+
8650
+			if ( percent < 1 && length ) {
8651
+				return remaining;
8652
+			} else {
8653
+				deferred.resolveWith( elem, [ animation ] );
8654
+				return false;
8655
+			}
8656
+		},
8657
+		animation = deferred.promise({
8658
+			elem: elem,
8659
+			props: jQuery.extend( {}, properties ),
8660
+			opts: jQuery.extend( true, { specialEasing: {} }, options ),
8661
+			originalProperties: properties,
8662
+			originalOptions: options,
8663
+			startTime: fxNow || createFxNow(),
8664
+			duration: options.duration,
8665
+			tweens: [],
8666
+			createTween: function( prop, end, easing ) {
8667
+				var tween = jQuery.Tween( elem, animation.opts, prop, end,
8668
+						animation.opts.specialEasing[ prop ] || animation.opts.easing );
8669
+				animation.tweens.push( tween );
8670
+				return tween;
8671
+			},
8672
+			stop: function( gotoEnd ) {
8673
+				var index = 0,
8674
+					// if we are going to the end, we want to run all the tweens
8675
+					// otherwise we skip this part
8676
+					length = gotoEnd ? animation.tweens.length : 0;
8677
+
8678
+				for ( ; index < length ; index++ ) {
8679
+					animation.tweens[ index ].run( 1 );
8680
+				}
8681
+
8682
+				// resolve when we played the last frame
8683
+				// otherwise, reject
8684
+				if ( gotoEnd ) {
8685
+					deferred.resolveWith( elem, [ animation, gotoEnd ] );
8686
+				} else {
8687
+					deferred.rejectWith( elem, [ animation, gotoEnd ] );
8688
+				}
8689
+				return this;
8690
+			}
8691
+		}),
8692
+		props = animation.props;
8693
+
8694
+	propFilter( props, animation.opts.specialEasing );
8695
+
8696
+	for ( ; index < length ; index++ ) {
8697
+		result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
8698
+		if ( result ) {
8699
+			return result;
8700
+		}
8701
+	}
8702
+
8703
+	createTweens( animation, props );
8704
+
8705
+	if ( jQuery.isFunction( animation.opts.start ) ) {
8706
+		animation.opts.start.call( elem, animation );
8707
+	}
8708
+
8709
+	jQuery.fx.timer(
8710
+		jQuery.extend( tick, {
8711
+			anim: animation,
8712
+			queue: animation.opts.queue,
8713
+			elem: elem
8714
+		})
8715
+	);
8716
+
8717
+	// attach callbacks from options
8718
+	return animation.progress( animation.opts.progress )
8719
+		.done( animation.opts.done, animation.opts.complete )
8720
+		.fail( animation.opts.fail )
8721
+		.always( animation.opts.always );
8722
+}
8723
+
8724
+function propFilter( props, specialEasing ) {
8725
+	var index, name, easing, value, hooks;
8726
+
8727
+	// camelCase, specialEasing and expand cssHook pass
8728
+	for ( index in props ) {
8729
+		name = jQuery.camelCase( index );
8730
+		easing = specialEasing[ name ];
8731
+		value = props[ index ];
8732
+		if ( jQuery.isArray( value ) ) {
8733
+			easing = value[ 1 ];
8734
+			value = props[ index ] = value[ 0 ];
8735
+		}
8736
+
8737
+		if ( index !== name ) {
8738
+			props[ name ] = value;
8739
+			delete props[ index ];
8740
+		}
8741
+
8742
+		hooks = jQuery.cssHooks[ name ];
8743
+		if ( hooks && "expand" in hooks ) {
8744
+			value = hooks.expand( value );
8745
+			delete props[ name ];
8746
+
8747
+			// not quite $.extend, this wont overwrite keys already present.
8748
+			// also - reusing 'index' from above because we have the correct "name"
8749
+			for ( index in value ) {
8750
+				if ( !( index in props ) ) {
8751
+					props[ index ] = value[ index ];
8752
+					specialEasing[ index ] = easing;
8753
+				}
8754
+			}
8755
+		} else {
8756
+			specialEasing[ name ] = easing;
8757
+		}
8758
+	}
8759
+}
8760
+
8761
+jQuery.Animation = jQuery.extend( Animation, {
8762
+
8763
+	tweener: function( props, callback ) {
8764
+		if ( jQuery.isFunction( props ) ) {
8765
+			callback = props;
8766
+			props = [ "*" ];
8767
+		} else {
8768
+			props = props.split(" ");
8769
+		}
8770
+
8771
+		var prop,
8772
+			index = 0,
8773
+			length = props.length;
8774
+
8775
+		for ( ; index < length ; index++ ) {
8776
+			prop = props[ index ];
8777
+			tweeners[ prop ] = tweeners[ prop ] || [];
8778
+			tweeners[ prop ].unshift( callback );
8779
+		}
8780
+	},
8781
+
8782
+	prefilter: function( callback, prepend ) {
8783
+		if ( prepend ) {
8784
+			animationPrefilters.unshift( callback );
8785
+		} else {
8786
+			animationPrefilters.push( callback );
8787
+		}
8788
+	}
8789
+});
8790
+
8791
+function defaultPrefilter( elem, props, opts ) {
8792
+	var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire,
8793
+		anim = this,
8794
+		style = elem.style,
8795
+		orig = {},
8796
+		handled = [],
8797
+		hidden = elem.nodeType && isHidden( elem );
8798
+
8799
+	// handle queue: false promises
8800
+	if ( !opts.queue ) {
8801
+		hooks = jQuery._queueHooks( elem, "fx" );
8802
+		if ( hooks.unqueued == null ) {
8803
+			hooks.unqueued = 0;
8804
+			oldfire = hooks.empty.fire;
8805
+			hooks.empty.fire = function() {
8806
+				if ( !hooks.unqueued ) {
8807
+					oldfire();
8808
+				}
8809
+			};
8810
+		}
8811
+		hooks.unqueued++;
8812
+
8813
+		anim.always(function() {
8814
+			// doing this makes sure that the complete handler will be called
8815
+			// before this completes
8816
+			anim.always(function() {
8817
+				hooks.unqueued--;
8818
+				if ( !jQuery.queue( elem, "fx" ).length ) {
8819
+					hooks.empty.fire();
8820
+				}
8821
+			});
8822
+		});
8823
+	}
8824
+
8825
+	// height/width overflow pass
8826
+	if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
8827
+		// Make sure that nothing sneaks out
8828
+		// Record all 3 overflow attributes because IE does not
8829
+		// change the overflow attribute when overflowX and
8830
+		// overflowY are set to the same value
8831
+		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
8832
+
8833
+		// Set display property to inline-block for height/width
8834
+		// animations on inline elements that are having width/height animated
8835
+		if ( jQuery.css( elem, "display" ) === "inline" &&
8836
+				jQuery.css( elem, "float" ) === "none" ) {
8837
+
8838
+			// inline-level elements accept inline-block;
8839
+			// block-level elements need to be inline with layout
8840
+			if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) {
8841
+				style.display = "inline-block";
8842
+
8843
+			} else {
8844
+				style.zoom = 1;
8845
+			}
8846
+		}
8847
+	}
8848
+
8849
+	if ( opts.overflow ) {
8850
+		style.overflow = "hidden";
8851
+		if ( !jQuery.support.shrinkWrapBlocks ) {
8852
+			anim.done(function() {
8853
+				style.overflow = opts.overflow[ 0 ];
8854
+				style.overflowX = opts.overflow[ 1 ];
8855
+				style.overflowY = opts.overflow[ 2 ];
8856
+			});
8857
+		}
8858
+	}
8859
+
8860
+
8861
+	// show/hide pass
8862
+	for ( index in props ) {
8863
+		value = props[ index ];
8864
+		if ( rfxtypes.exec( value ) ) {
8865
+			delete props[ index ];
8866
+			toggle = toggle || value === "toggle";
8867
+			if ( value === ( hidden ? "hide" : "show" ) ) {
8868
+				continue;
8869
+			}
8870
+			handled.push( index );
8871
+		}
8872
+	}
8873
+
8874
+	length = handled.length;
8875
+	if ( length ) {
8876
+		dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} );
8877
+		if ( "hidden" in dataShow ) {
8878
+			hidden = dataShow.hidden;
8879
+		}
8880
+
8881
+		// store state if its toggle - enables .stop().toggle() to "reverse"
8882
+		if ( toggle ) {
8883
+			dataShow.hidden = !hidden;
8884
+		}
8885
+		if ( hidden ) {
8886
+			jQuery( elem ).show();
8887
+		} else {
8888
+			anim.done(function() {
8889
+				jQuery( elem ).hide();
8890
+			});
8891
+		}
8892
+		anim.done(function() {
8893
+			var prop;
8894
+			jQuery.removeData( elem, "fxshow", true );
8895
+			for ( prop in orig ) {
8896
+				jQuery.style( elem, prop, orig[ prop ] );
8897
+			}
8898
+		});
8899
+		for ( index = 0 ; index < length ; index++ ) {
8900
+			prop = handled[ index ];
8901
+			tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 );
8902
+			orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop );
8903
+
8904
+			if ( !( prop in dataShow ) ) {
8905
+				dataShow[ prop ] = tween.start;
8906
+				if ( hidden ) {
8907
+					tween.end = tween.start;
8908
+					tween.start = prop === "width" || prop === "height" ? 1 : 0;
8909
+				}
8910
+			}
8911
+		}
8912
+	}
8913
+}
8914
+
8915
+function Tween( elem, options, prop, end, easing ) {
8916
+	return new Tween.prototype.init( elem, options, prop, end, easing );
8917
+}
8918
+jQuery.Tween = Tween;
8919
+
8920
+Tween.prototype = {
8921
+	constructor: Tween,
8922
+	init: function( elem, options, prop, end, easing, unit ) {
8923
+		this.elem = elem;
8924
+		this.prop = prop;
8925
+		this.easing = easing || "swing";
8926
+		this.options = options;
8927
+		this.start = this.now = this.cur();
8928
+		this.end = end;
8929
+		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
8930
+	},
8931
+	cur: function() {
8932
+		var hooks = Tween.propHooks[ this.prop ];
8933
+
8934
+		return hooks && hooks.get ?
8935
+			hooks.get( this ) :
8936
+			Tween.propHooks._default.get( this );
8937
+	},
8938
+	run: function( percent ) {
8939
+		var eased,
8940
+			hooks = Tween.propHooks[ this.prop ];
8941
+
8942
+		if ( this.options.duration ) {
8943
+			this.pos = eased = jQuery.easing[ this.easing ](
8944
+				percent, this.options.duration * percent, 0, 1, this.options.duration
8945
+			);
8946
+		} else {
8947
+			this.pos = eased = percent;
8948
+		}
8949
+		this.now = ( this.end - this.start ) * eased + this.start;
8950
+
8951
+		if ( this.options.step ) {
8952
+			this.options.step.call( this.elem, this.now, this );
8953
+		}
8954
+
8955
+		if ( hooks && hooks.set ) {
8956
+			hooks.set( this );
8957
+		} else {
8958
+			Tween.propHooks._default.set( this );
8959
+		}
8960
+		return this;
8961
+	}
8962
+};
8963
+
8964
+Tween.prototype.init.prototype = Tween.prototype;
8965
+
8966
+Tween.propHooks = {
8967
+	_default: {
8968
+		get: function( tween ) {
8969
+			var result;
8970
+
8971
+			if ( tween.elem[ tween.prop ] != null &&
8972
+				(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
8973
+				return tween.elem[ tween.prop ];
8974
+			}
8975
+
8976
+			// passing any value as a 4th parameter to .css will automatically
8977
+			// attempt a parseFloat and fallback to a string if the parse fails
8978
+			// so, simple values such as "10px" are parsed to Float.
8979
+			// complex values such as "rotate(1rad)" are returned as is.
8980
+			result = jQuery.css( tween.elem, tween.prop, false, "" );
8981
+			// Empty strings, null, undefined and "auto" are converted to 0.
8982
+			return !result || result === "auto" ? 0 : result;
8983
+		},
8984
+		set: function( tween ) {
8985
+			// use step hook for back compat - use cssHook if its there - use .style if its
8986
+			// available and use plain properties where available
8987
+			if ( jQuery.fx.step[ tween.prop ] ) {
8988
+				jQuery.fx.step[ tween.prop ]( tween );
8989
+			} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
8990
+				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
8991
+			} else {
8992
+				tween.elem[ tween.prop ] = tween.now;
8993
+			}
8994
+		}
8995
+	}
8996
+};
8997
+
8998
+// Remove in 2.0 - this supports IE8's panic based approach
8999
+// to setting things on disconnected nodes
9000
+
9001
+Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
9002
+	set: function( tween ) {
9003
+		if ( tween.elem.nodeType && tween.elem.parentNode ) {
9004
+			tween.elem[ tween.prop ] = tween.now;
9005
+		}
9006
+	}
9007
+};
9008
+
9009
+jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
9010
+	var cssFn = jQuery.fn[ name ];
9011
+	jQuery.fn[ name ] = function( speed, easing, callback ) {
9012
+		return speed == null || typeof speed === "boolean" ||
9013
+			// special check for .toggle( handler, handler, ... )
9014
+			( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ?
9015
+			cssFn.apply( this, arguments ) :
9016
+			this.animate( genFx( name, true ), speed, easing, callback );
9017
+	};
9018
+});
9019
+
9020
+jQuery.fn.extend({
9021
+	fadeTo: function( speed, to, easing, callback ) {
9022
+
9023
+		// show any hidden elements after setting opacity to 0
9024
+		return this.filter( isHidden ).css( "opacity", 0 ).show()
9025
+
9026
+			// animate to the value specified
9027
+			.end().animate({ opacity: to }, speed, easing, callback );
9028
+	},
9029
+	animate: function( prop, speed, easing, callback ) {
9030
+		var empty = jQuery.isEmptyObject( prop ),
9031
+			optall = jQuery.speed( speed, easing, callback ),
9032
+			doAnimation = function() {
9033
+				// Operate on a copy of prop so per-property easing won't be lost
9034
+				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
9035
+
9036
+				// Empty animations resolve immediately
9037
+				if ( empty ) {
9038
+					anim.stop( true );
9039
+				}
9040
+			};
9041
+
9042
+		return empty || optall.queue === false ?
9043
+			this.each( doAnimation ) :
9044
+			this.queue( optall.queue, doAnimation );
9045
+	},
9046
+	stop: function( type, clearQueue, gotoEnd ) {
9047
+		var stopQueue = function( hooks ) {
9048
+			var stop = hooks.stop;
9049
+			delete hooks.stop;
9050
+			stop( gotoEnd );
9051
+		};
9052
+
9053
+		if ( typeof type !== "string" ) {
9054
+			gotoEnd = clearQueue;
9055
+			clearQueue = type;
9056
+			type = undefined;
9057
+		}
9058
+		if ( clearQueue && type !== false ) {
9059
+			this.queue( type || "fx", [] );
9060
+		}
9061
+
9062
+		return this.each(function() {
9063
+			var dequeue = true,
9064
+				index = type != null && type + "queueHooks",
9065
+				timers = jQuery.timers,
9066
+				data = jQuery._data( this );
9067
+
9068
+			if ( index ) {
9069
+				if ( data[ index ] && data[ index ].stop ) {
9070
+					stopQueue( data[ index ] );
9071
+				}
9072
+			} else {
9073
+				for ( index in data ) {
9074
+					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
9075
+						stopQueue( data[ index ] );
9076
+					}
9077
+				}
9078
+			}
9079
+
9080
+			for ( index = timers.length; index--; ) {
9081
+				if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
9082
+					timers[ index ].anim.stop( gotoEnd );
9083
+					dequeue = false;
9084
+					timers.splice( index, 1 );
9085
+				}
9086
+			}
9087
+
9088
+			// start the next in the queue if the last step wasn't forced
9089
+			// timers currently will call their complete callbacks, which will dequeue
9090
+			// but only if they were gotoEnd
9091
+			if ( dequeue || !gotoEnd ) {
9092
+				jQuery.dequeue( this, type );
9093
+			}
9094
+		});
9095
+	}
9096
+});
9097
+
9098
+// Generate parameters to create a standard animation
9099
+function genFx( type, includeWidth ) {
9100
+	var which,
9101
+		attrs = { height: type },
9102
+		i = 0;
9103
+
9104
+	// if we include width, step value is 1 to do all cssExpand values,
9105
+	// if we don't include width, step value is 2 to skip over Left and Right
9106
+	includeWidth = includeWidth? 1 : 0;
9107
+	for( ; i < 4 ; i += 2 - includeWidth ) {
9108
+		which = cssExpand[ i ];
9109
+		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
9110
+	}
9111
+
9112
+	if ( includeWidth ) {
9113
+		attrs.opacity = attrs.width = type;
9114
+	}
9115
+
9116
+	return attrs;
9117
+}
9118
+
9119
+// Generate shortcuts for custom animations
9120
+jQuery.each({
9121
+	slideDown: genFx("show"),
9122
+	slideUp: genFx("hide"),
9123
+	slideToggle: genFx("toggle"),
9124
+	fadeIn: { opacity: "show" },
9125
+	fadeOut: { opacity: "hide" },
9126
+	fadeToggle: { opacity: "toggle" }
9127
+}, function( name, props ) {
9128
+	jQuery.fn[ name ] = function( speed, easing, callback ) {
9129
+		return this.animate( props, speed, easing, callback );
9130
+	};
9131
+});
9132
+
9133
+jQuery.speed = function( speed, easing, fn ) {
9134
+	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
9135
+		complete: fn || !fn && easing ||
9136
+			jQuery.isFunction( speed ) && speed,
9137
+		duration: speed,
9138
+		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
9139
+	};
9140
+
9141
+	opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
9142
+		opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
9143
+
9144
+	// normalize opt.queue - true/undefined/null -> "fx"
9145
+	if ( opt.queue == null || opt.queue === true ) {
9146
+		opt.queue = "fx";
9147
+	}
9148
+
9149
+	// Queueing
9150
+	opt.old = opt.complete;
9151
+
9152
+	opt.complete = function() {
9153
+		if ( jQuery.isFunction( opt.old ) ) {
9154
+			opt.old.call( this );
9155
+		}
9156
+
9157
+		if ( opt.queue ) {
9158
+			jQuery.dequeue( this, opt.queue );
9159
+		}
9160
+	};
9161
+
9162
+	return opt;
9163
+};
9164
+
9165
+jQuery.easing = {
9166
+	linear: function( p ) {
9167
+		return p;
9168
+	},
9169
+	swing: function( p ) {
9170
+		return 0.5 - Math.cos( p*Math.PI ) / 2;
9171
+	}
9172
+};
9173
+
9174
+jQuery.timers = [];
9175
+jQuery.fx = Tween.prototype.init;
9176
+jQuery.fx.tick = function() {
9177
+	var timer,
9178
+		timers = jQuery.timers,
9179
+		i = 0;
9180
+
9181
+	fxNow = jQuery.now();
9182
+
9183
+	for ( ; i < timers.length; i++ ) {
9184
+		timer = timers[ i ];
9185
+		// Checks the timer has not already been removed
9186
+		if ( !timer() && timers[ i ] === timer ) {
9187
+			timers.splice( i--, 1 );
9188
+		}
9189
+	}
9190
+
9191
+	if ( !timers.length ) {
9192
+		jQuery.fx.stop();
9193
+	}
9194
+	fxNow = undefined;
9195
+};
9196
+
9197
+jQuery.fx.timer = function( timer ) {
9198
+	if ( timer() && jQuery.timers.push( timer ) && !timerId ) {
9199
+		timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
9200
+	}
9201
+};
9202
+
9203
+jQuery.fx.interval = 13;
9204
+
9205
+jQuery.fx.stop = function() {
9206
+	clearInterval( timerId );
9207
+	timerId = null;
9208
+};
9209
+
9210
+jQuery.fx.speeds = {
9211
+	slow: 600,
9212
+	fast: 200,
9213
+	// Default speed
9214
+	_default: 400
9215
+};
9216
+
9217
+// Back Compat <1.8 extension point
9218
+jQuery.fx.step = {};
9219
+
9220
+if ( jQuery.expr && jQuery.expr.filters ) {
9221
+	jQuery.expr.filters.animated = function( elem ) {
9222
+		return jQuery.grep(jQuery.timers, function( fn ) {
9223
+			return elem === fn.elem;
9224
+		}).length;
9225
+	};
9226
+}
9227
+var rroot = /^(?:body|html)$/i;
9228
+
9229
+jQuery.fn.offset = function( options ) {
9230
+	if ( arguments.length ) {
9231
+		return options === undefined ?
9232
+			this :
9233
+			this.each(function( i ) {
9234
+				jQuery.offset.setOffset( this, options, i );
9235
+			});
9236
+	}
9237
+
9238
+	var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft,
9239
+		box = { top: 0, left: 0 },
9240
+		elem = this[ 0 ],
9241
+		doc = elem && elem.ownerDocument;
9242
+
9243
+	if ( !doc ) {
9244
+		return;
9245
+	}
9246
+
9247
+	if ( (body = doc.body) === elem ) {
9248
+		return jQuery.offset.bodyOffset( elem );
9249
+	}
9250
+
9251
+	docElem = doc.documentElement;
9252
+
9253
+	// Make sure it's not a disconnected DOM node
9254
+	if ( !jQuery.contains( docElem, elem ) ) {
9255
+		return box;
9256
+	}
9257
+
9258
+	// If we don't have gBCR, just use 0,0 rather than error
9259
+	// BlackBerry 5, iOS 3 (original iPhone)
9260
+	if ( typeof elem.getBoundingClientRect !== "undefined" ) {
9261
+		box = elem.getBoundingClientRect();
9262
+	}
9263
+	win = getWindow( doc );
9264
+	clientTop  = docElem.clientTop  || body.clientTop  || 0;
9265
+	clientLeft = docElem.clientLeft || body.clientLeft || 0;
9266
+	scrollTop  = win.pageYOffset || docElem.scrollTop;
9267
+	scrollLeft = win.pageXOffset || docElem.scrollLeft;
9268
+	return {
9269
+		top: box.top  + scrollTop  - clientTop,
9270
+		left: box.left + scrollLeft - clientLeft
9271
+	};
9272
+};
9273
+
9274
+jQuery.offset = {
9275
+
9276
+	bodyOffset: function( body ) {
9277
+		var top = body.offsetTop,
9278
+			left = body.offsetLeft;
9279
+
9280
+		if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {
9281
+			top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
9282
+			left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
9283
+		}
9284
+
9285
+		return { top: top, left: left };
9286
+	},
9287
+
9288
+	setOffset: function( elem, options, i ) {
9289
+		var position = jQuery.css( elem, "position" );
9290
+
9291
+		// set position first, in-case top/left are set even on static elem
9292
+		if ( position === "static" ) {
9293
+			elem.style.position = "relative";
9294
+		}
9295
+
9296
+		var curElem = jQuery( elem ),
9297
+			curOffset = curElem.offset(),
9298
+			curCSSTop = jQuery.css( elem, "top" ),
9299
+			curCSSLeft = jQuery.css( elem, "left" ),
9300
+			calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
9301
+			props = {}, curPosition = {}, curTop, curLeft;
9302
+
9303
+		// need to be able to calculate position if either top or left is auto and position is either absolute or fixed
9304
+		if ( calculatePosition ) {
9305
+			curPosition = curElem.position();
9306
+			curTop = curPosition.top;
9307
+			curLeft = curPosition.left;
9308
+		} else {
9309
+			curTop = parseFloat( curCSSTop ) || 0;
9310
+			curLeft = parseFloat( curCSSLeft ) || 0;
9311
+		}
9312
+
9313
+		if ( jQuery.isFunction( options ) ) {
9314
+			options = options.call( elem, i, curOffset );
9315
+		}
9316
+
9317
+		if ( options.top != null ) {
9318
+			props.top = ( options.top - curOffset.top ) + curTop;
9319
+		}
9320
+		if ( options.left != null ) {
9321
+			props.left = ( options.left - curOffset.left ) + curLeft;
9322
+		}
9323
+
9324
+		if ( "using" in options ) {
9325
+			options.using.call( elem, props );
9326
+		} else {
9327
+			curElem.css( props );
9328
+		}
9329
+	}
9330
+};
9331
+
9332
+
9333
+jQuery.fn.extend({
9334
+
9335
+	position: function() {
9336
+		if ( !this[0] ) {
9337
+			return;
9338
+		}
9339
+
9340
+		var elem = this[0],
9341
+
9342
+		// Get *real* offsetParent
9343
+		offsetParent = this.offsetParent(),
9344
+
9345
+		// Get correct offsets
9346
+		offset       = this.offset(),
9347
+		parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
9348
+
9349
+		// Subtract element margins
9350
+		// note: when an element has margin: auto the offsetLeft and marginLeft
9351
+		// are the same in Safari causing offset.left to incorrectly be 0
9352
+		offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
9353
+		offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
9354
+
9355
+		// Add offsetParent borders
9356
+		parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
9357
+		parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
9358
+
9359
+		// Subtract the two offsets
9360
+		return {
9361
+			top:  offset.top  - parentOffset.top,
9362
+			left: offset.left - parentOffset.left
9363
+		};
9364
+	},
9365
+
9366
+	offsetParent: function() {
9367
+		return this.map(function() {
9368
+			var offsetParent = this.offsetParent || document.body;
9369
+			while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
9370
+				offsetParent = offsetParent.offsetParent;
9371
+			}
9372
+			return offsetParent || document.body;
9373
+		});
9374
+	}
9375
+});
9376
+
9377
+
9378
+// Create scrollLeft and scrollTop methods
9379
+jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
9380
+	var top = /Y/.test( prop );
9381
+
9382
+	jQuery.fn[ method ] = function( val ) {
9383
+		return jQuery.access( this, function( elem, method, val ) {
9384
+			var win = getWindow( elem );
9385
+
9386
+			if ( val === undefined ) {
9387
+				return win ? (prop in win) ? win[ prop ] :
9388
+					win.document.documentElement[ method ] :
9389
+					elem[ method ];
9390
+			}
9391
+
9392
+			if ( win ) {
9393
+				win.scrollTo(
9394
+					!top ? val : jQuery( win ).scrollLeft(),
9395
+					 top ? val : jQuery( win ).scrollTop()
9396
+				);
9397
+
9398
+			} else {
9399
+				elem[ method ] = val;
9400
+			}
9401
+		}, method, val, arguments.length, null );
9402
+	};
9403
+});
9404
+
9405
+function getWindow( elem ) {
9406
+	return jQuery.isWindow( elem ) ?
9407
+		elem :
9408
+		elem.nodeType === 9 ?
9409
+			elem.defaultView || elem.parentWindow :
9410
+			false;
9411
+}
9412
+// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
9413
+jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
9414
+	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
9415
+		// margin is only for outerHeight, outerWidth
9416
+		jQuery.fn[ funcName ] = function( margin, value ) {
9417
+			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
9418
+				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
9419
+
9420
+			return jQuery.access( this, function( elem, type, value ) {
9421
+				var doc;
9422
+
9423
+				if ( jQuery.isWindow( elem ) ) {
9424
+					// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
9425
+					// isn't a whole lot we can do. See pull request at this URL for discussion:
9426
+					// https://github.com/jquery/jquery/pull/764
9427
+					return elem.document.documentElement[ "client" + name ];
9428
+				}
9429
+
9430
+				// Get document width or height
9431
+				if ( elem.nodeType === 9 ) {
9432
+					doc = elem.documentElement;
9433
+
9434
+					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
9435
+					// unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
9436
+					return Math.max(
9437
+						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
9438
+						elem.body[ "offset" + name ], doc[ "offset" + name ],
9439
+						doc[ "client" + name ]
9440
+					);
9441
+				}
9442
+
9443
+				return value === undefined ?
9444
+					// Get width or height on the element, requesting but not forcing parseFloat
9445
+					jQuery.css( elem, type, value, extra ) :
9446
+
9447
+					// Set width or height on the element
9448
+					jQuery.style( elem, type, value, extra );
9449
+			}, type, chainable ? margin : undefined, chainable, null );
9450
+		};
9451
+	});
9452
+});
9453
+// Expose jQuery to the global object
9454
+window.jQuery = window.$ = jQuery;
9455
+
9456
+// Expose jQuery as an AMD module, but only for AMD loaders that
9457
+// understand the issues with loading multiple versions of jQuery
9458
+// in a page that all might call define(). The loader will indicate
9459
+// they have special allowances for multiple jQuery versions by
9460
+// specifying define.amd.jQuery = true. Register as a named module,
9461
+// since jQuery can be concatenated with other files that may use define,
9462
+// but not use a proper concatenation script that understands anonymous
9463
+// AMD modules. A named AMD is safest and most robust way to register.
9464
+// Lowercase jquery is used because AMD module names are derived from
9465
+// file names, and jQuery is normally delivered in a lowercase file name.
9466
+// Do this after creating the global so that if an AMD module wants to call
9467
+// noConflict to hide this version of jQuery, it will work.
9468
+if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
9469
+	define( "jquery", [], function () { return jQuery; } );
9470
+}
9471
+
9472
+})( window );
... ...
@@ -0,0 +1,5 @@
1
+(function(window,undefined){var rootjQuery,readyList,document=window.document,location=window.location,navigator=window.navigator,_jQuery=window.jQuery,_$=window.$,core_push=Array.prototype.push,core_slice=Array.prototype.slice,core_indexOf=Array.prototype.indexOf,core_toString=Object.prototype.toString,core_hasOwn=Object.prototype.hasOwnProperty,core_trim=String.prototype.trim,jQuery=function(selector,context){return new jQuery.fn.init(selector,context,rootjQuery)},core_pnum=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,core_rnotwhite=/\S/,core_rspace=/\s+/,rtrim=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,rquickExpr=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,rsingleTag=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,rvalidchars=/^[\],:{}\s]*$/,rvalidbraces=/(?:^|:|,)(?:\s*\[)+/g,rvalidescape=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,rvalidtokens=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,rmsPrefix=/^-ms-/,rdashAlpha=/-([\da-z])/gi,fcamelCase=function(all,letter){return(letter+"").toUpperCase()},DOMContentLoaded=function(){if(document.addEventListener){document.removeEventListener("DOMContentLoaded",DOMContentLoaded,false);jQuery.ready()}else if(document.readyState==="complete"){document.detachEvent("onreadystatechange",DOMContentLoaded);jQuery.ready()}},class2type={};jQuery.fn=jQuery.prototype={constructor:jQuery,init:function(selector,context,rootjQuery){var match,elem,ret,doc;if(!selector){return this}if(selector.nodeType){this.context=this[0]=selector;this.length=1;return this}if(typeof selector==="string"){if(selector.charAt(0)==="<"&&selector.charAt(selector.length-1)===">"&&selector.length>=3){match=[null,selector,null]}else{match=rquickExpr.exec(selector)}if(match&&(match[1]||!context)){if(match[1]){context=context instanceof jQuery?context[0]:context;doc=context&&context.nodeType?context.ownerDocument||context:document;selector=jQuery.parseHTML(match[1],doc,true);if(rsingleTag.test(match[1])&&jQuery.isPlainObject(context)){this.attr.call(selector,context,true)}return jQuery.merge(this,selector)}else{elem=document.getElementById(match[2]);if(elem&&elem.parentNode){if(elem.id!==match[2]){return rootjQuery.find(selector)}this.length=1;this[0]=elem}this.context=document;this.selector=selector;return this}}else if(!context||context.jquery){return(context||rootjQuery).find(selector)}else{return this.constructor(context).find(selector)}}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)},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return core_slice.call(this)},get:function(num){return num==null?this.toArray():num<0?this[this.length+num]:this[num]},pushStack:function(elems,name,selector){var ret=jQuery.merge(this.constructor(),elems);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 ret},each:function(callback,args){return jQuery.each(this,callback,args)},ready:function(fn){jQuery.ready.promise().done(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(core_slice.apply(this,arguments),"slice",core_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)},push:core_push,sort:[].sort,splice:[].splice};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;if(typeof target==="boolean"){deep=target;target=arguments[1]||{};i=2}if(typeof target!=="object"&&!jQuery.isFunction(target)){target={}}if(length===i){target=this;--i}for(;i<length;i++){if((options=arguments[i])!=null){for(name in options){src=target[name];copy=options[name];if(target===copy){continue}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:{}}target[name]=jQuery.extend(deep,clone,copy)}else if(copy!==undefined){target[name]=copy}}}}return target};jQuery.extend({noConflict:function(deep){if(window.$===jQuery){window.$=_$}if(deep&&window.jQuery===jQuery){window.jQuery=_jQuery}return jQuery},isReady:false,readyWait:1,holdReady:function(hold){if(hold){jQuery.readyWait++}else{jQuery.ready(true)}},ready:function(wait){if(wait===true?--jQuery.readyWait:jQuery.isReady){return}if(!document.body){return setTimeout(jQuery.ready,1)}jQuery.isReady=true;if(wait!==true&&--jQuery.readyWait>0){return}readyList.resolveWith(document,[jQuery]);if(jQuery.fn.trigger){jQuery(document).trigger("ready").off("ready")}},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[core_toString.call(obj)]||"object"},isPlainObject:function(obj){if(!obj||jQuery.type(obj)!=="object"||obj.nodeType||jQuery.isWindow(obj)){return false}try{if(obj.constructor&&!core_hasOwn.call(obj,"constructor")&&!core_hasOwn.call(obj.constructor.prototype,"isPrototypeOf")){return false}}catch(e){return false}var key;for(key in obj){}return key===undefined||core_hasOwn.call(obj,key)},isEmptyObject:function(obj){var name;for(name in obj){return false}return true},error:function(msg){throw new Error(msg)},parseHTML:function(data,context,scripts){var parsed;if(!data||typeof data!=="string"){return null}if(typeof context==="boolean"){scripts=context;context=0}context=context||document;if(parsed=rsingleTag.exec(data)){return[context.createElement(parsed[1])]}parsed=jQuery.buildFragment([data],context,scripts?null:[]);return jQuery.merge([],(parsed.cacheable?jQuery.clone(parsed.fragment):parsed.fragment).childNodes)},parseJSON:function(data){if(!data||typeof data!=="string"){return null}data=jQuery.trim(data);if(window.JSON&&window.JSON.parse){return window.JSON.parse(data)}if(rvalidchars.test(data.replace(rvalidescape,"@").replace(rvalidtokens,"]").replace(rvalidbraces,""))){return new Function("return "+data)()}jQuery.error("Invalid JSON: "+data)},parseXML:function(data){var xml,tmp;if(!data||typeof data!=="string"){return null}try{if(window.DOMParser){tmp=new DOMParser;xml=tmp.parseFromString(data,"text/xml")}else{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(){},globalEval:function(data){if(data&&core_rnotwhite.test(data)){(window.execScript||function(data){window["eval"].call(window,data)})(data)}},camelCase:function(string){return string.replace(rmsPrefix,"ms-").replace(rdashAlpha,fcamelCase)},nodeName:function(elem,name){return elem.nodeName&&elem.nodeName.toLowerCase()===name.toLowerCase()},each:function(obj,callback,args){var name,i=0,length=obj.length,isObj=length===undefined||jQuery.isFunction(obj);if(args){if(isObj){for(name in obj){if(callback.apply(obj[name],args)===false){break}}}else{for(;i<length;){if(callback.apply(obj[i++],args)===false){break}}}}else{if(isObj){for(name in obj){if(callback.call(obj[name],name,obj[name])===false){break}}}else{for(;i<length;){if(callback.call(obj[i],i,obj[i++])===false){break}}}}return obj},trim:core_trim&&!core_trim.call(" ")?function(text){return text==null?"":core_trim.call(text)}:function(text){return text==null?"":(text+"").replace(rtrim,"")},makeArray:function(arr,results){var type,ret=results||[];if(arr!=null){type=jQuery.type(arr);if(arr.length==null||type==="string"||type==="function"||type==="regexp"||jQuery.isWindow(arr)){core_push.call(ret,arr)}else{jQuery.merge(ret,arr)}}return ret},inArray:function(elem,arr,i){var len;if(arr){if(core_indexOf){return core_indexOf.call(arr,elem,i)}len=arr.length;i=i?i<0?Math.max(0,len+i):i:0;for(;i<len;i++){if(i in arr&&arr[i]===elem){return i}}}return-1},merge:function(first,second){var l=second.length,i=first.length,j=0;if(typeof l==="number"){for(;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 retVal,ret=[],i=0,length=elems.length;inv=!!inv;for(;i<length;i++){retVal=!!callback(elems[i],i);if(inv!==retVal){ret.push(elems[i])}}return ret},map:function(elems,callback,arg){var value,key,ret=[],i=0,length=elems.length,isArray=elems instanceof jQuery||length!==undefined&&typeof length==="number"&&(length>0&&elems[0]&&elems[length-1]||length===0||jQuery.isArray(elems));if(isArray){for(;i<length;i++){value=callback(elems[i],i,arg);if(value!=null){ret[ret.length]=value}}}else{for(key in elems){value=callback(elems[key],key,arg);if(value!=null){ret[ret.length]=value}}}return ret.concat.apply([],ret)},guid:1,proxy:function(fn,context){var tmp,args,proxy;if(typeof context==="string"){tmp=fn[context];context=fn;fn=tmp}if(!jQuery.isFunction(fn)){return undefined}args=core_slice.call(arguments,2);proxy=function(){return fn.apply(context,args.concat(core_slice.call(arguments)))};proxy.guid=fn.guid=fn.guid||jQuery.guid++;return proxy},access:function(elems,fn,key,value,chainable,emptyGet,pass){var exec,bulk=key==null,i=0,length=elems.length;if(key&&typeof key==="object"){for(i in key){jQuery.access(elems,fn,i,key[i],1,emptyGet,value)}chainable=1}else if(value!==undefined){exec=pass===undefined&&jQuery.isFunction(value);if(bulk){if(exec){exec=fn;fn=function(elem,key,value){return exec.call(jQuery(elem),value)}}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:bulk?fn.call(elems):length?fn(elems[0],key):emptyGet},now:function(){return(new Date).getTime()}});jQuery.ready.promise=function(obj){if(!readyList){readyList=jQuery.Deferred();if(document.readyState==="complete"){setTimeout(jQuery.ready,1)}else if(document.addEventListener){document.addEventListener("DOMContentLoaded",DOMContentLoaded,false);window.addEventListener("load",jQuery.ready,false)}else{document.attachEvent("onreadystatechange",DOMContentLoaded);window.attachEvent("onload",jQuery.ready);var top=false;try{top=window.frameElement==null&&document.documentElement}catch(e){}if(top&&top.doScroll){(function doScrollCheck(){if(!jQuery.isReady){try{top.doScroll("left")}catch(e){return setTimeout(doScrollCheck,50)}jQuery.ready()}})()}}}return readyList.promise(obj)};jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(i,name){class2type["[object "+name+"]"]=name.toLowerCase()});rootjQuery=jQuery(document);var optionsCache={};function createOptions(options){var object=optionsCache[options]={};jQuery.each(options.split(core_rspace),function(_,flag){object[flag]=true});return object}jQuery.Callbacks=function(options){options=typeof options==="string"?optionsCache[options]||createOptions(options):jQuery.extend({},options);var memory,fired,firing,firingStart,firingLength,firingIndex,list=[],stack=!options.once&&[],fire=function(data){memory=options.memory&&data;fired=true;firingIndex=firingStart||0;firingStart=0;firingLength=list.length;firing=true;for(;list&&firingIndex<firingLength;firingIndex++){if(list[firingIndex].apply(data[0],data[1])===false&&options.stopOnFalse){memory=false;break}}firing=false;if(list){if(stack){if(stack.length){fire(stack.shift())}}else if(memory){list=[]}else{self.disable()}}},self={add:function(){if(list){var start=list.length;(function add(args){jQuery.each(args,function(_,arg){var type=jQuery.type(arg);if(type==="function"){if(!options.unique||!self.has(arg)){list.push(arg)}}else if(arg&&arg.length&&type!=="string"){add(arg)}})})(arguments);if(firing){firingLength=list.length}else if(memory){firingStart=start;fire(memory)}}return this},remove:function(){if(list){jQuery.each(arguments,function(_,arg){var index;while((index=jQuery.inArray(arg,list,index))>-1){list.splice(index,1);if(firing){if(index<=firingLength){firingLength--}if(index<=firingIndex){firingIndex--}}}})}return this},has:function(fn){return jQuery.inArray(fn,list)>-1},empty:function(){list=[];return this},disable:function(){list=stack=memory=undefined;return this},disabled:function(){return!list},lock:function(){stack=undefined;if(!memory){self.disable()}return this},locked:function(){return!stack},fireWith:function(context,args){args=args||[];args=[context,args.slice?args.slice():args];if(list&&(!fired||stack)){if(firing){stack.push(args)}else{fire(args)}}return this},fire:function(){self.fireWith(this,arguments);return this},fired:function(){return!!fired}};return self};jQuery.extend({Deferred:function(func){var tuples=[["resolve","done",jQuery.Callbacks("once memory"),"resolved"],["reject","fail",jQuery.Callbacks("once memory"),"rejected"],["notify","progress",jQuery.Callbacks("memory")]],state="pending",promise={state:function(){return state},always:function(){deferred.done(arguments).fail(arguments);return this},then:function(){var fns=arguments;return jQuery.Deferred(function(newDefer){jQuery.each(tuples,function(i,tuple){var action=tuple[0],fn=fns[i];deferred[tuple[1]](jQuery.isFunction(fn)?function(){var returned=fn.apply(this,arguments);if(returned&&jQuery.isFunction(returned.promise)){returned.promise().done(newDefer.resolve).fail(newDefer.reject).progress(newDefer.notify)}else{newDefer[action+"With"](this===deferred?newDefer:this,[returned])}}:newDefer[action])});fns=null}).promise()},promise:function(obj){return obj!=null?jQuery.extend(obj,promise):promise}},deferred={};promise.pipe=promise.then;jQuery.each(tuples,function(i,tuple){var list=tuple[2],stateString=tuple[3];promise[tuple[1]]=list.add;if(stateString){list.add(function(){state=stateString},tuples[i^1][2].disable,tuples[2][2].lock)}deferred[tuple[0]]=list.fire;deferred[tuple[0]+"With"]=list.fireWith});promise.promise(deferred);if(func){func.call(deferred,deferred)}return deferred},when:function(subordinate){var i=0,resolveValues=core_slice.call(arguments),length=resolveValues.length,remaining=length!==1||subordinate&&jQuery.isFunction(subordinate.promise)?length:0,deferred=remaining===1?subordinate:jQuery.Deferred(),updateFunc=function(i,contexts,values){return function(value){contexts[i]=this;values[i]=arguments.length>1?core_slice.call(arguments):value;if(values===progressValues){deferred.notifyWith(contexts,values)}else if(!--remaining){deferred.resolveWith(contexts,values)}}},progressValues,progressContexts,resolveContexts;if(length>1){progressValues=new Array(length);progressContexts=new Array(length);resolveContexts=new Array(length);for(;i<length;i++){if(resolveValues[i]&&jQuery.isFunction(resolveValues[i].promise)){resolveValues[i].promise().done(updateFunc(i,resolveContexts,resolveValues)).fail(deferred.reject).progress(updateFunc(i,progressContexts,progressValues))}else{--remaining}}}if(!remaining){deferred.resolveWith(resolveContexts,resolveValues)}return deferred.promise()}});jQuery.support=function(){var support,all,a,select,opt,input,fragment,eventName,i,isSupported,clickFn,div=document.createElement("div");div.setAttribute("className","t");div.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";all=div.getElementsByTagName("*");a=div.getElementsByTagName("a")[0];if(!all||!a||!all.length){return{}}select=document.createElement("select");opt=select.appendChild(document.createElement("option"));input=div.getElementsByTagName("input")[0];a.style.cssText="top:1px;float:left;opacity:.5";support={leadingWhitespace:div.firstChild.nodeType===3,tbody:!div.getElementsByTagName("tbody").length,htmlSerialize:!!div.getElementsByTagName("link").length,style:/top/.test(a.getAttribute("style")),hrefNormalized:a.getAttribute("href")==="/a",opacity:/^0.5/.test(a.style.opacity),cssFloat:!!a.style.cssFloat,checkOn:input.value==="on",optSelected:opt.selected,getSetAttribute:div.className!=="t",enctype:!!document.createElement("form").enctype,html5Clone:document.createElement("nav").cloneNode(true).outerHTML!=="<:nav></:nav>",boxModel:document.compatMode==="CSS1Compat",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true,boxSizingReliable:true,pixelPosition:false};input.checked=true;support.noCloneChecked=input.cloneNode(true).checked;select.disabled=true;support.optDisabled=!opt.disabled;try{delete div.test}catch(e){support.deleteExpando=false}if(!div.addEventListener&&div.attachEvent&&div.fireEvent){div.attachEvent("onclick",clickFn=function(){support.noCloneEvent=false});div.cloneNode(true).fireEvent("onclick");div.detachEvent("onclick",clickFn)}input=document.createElement("input");input.value="t";input.setAttribute("type","radio");support.radioValue=input.value==="t";input.setAttribute("checked","checked");input.setAttribute("name","t");div.appendChild(input);fragment=document.createDocumentFragment();fragment.appendChild(div.lastChild);support.checkClone=fragment.cloneNode(true).cloneNode(true).lastChild.checked;support.appendChecked=input.checked;fragment.removeChild(input);fragment.appendChild(div);if(div.attachEvent){for(i in{submit:true,change:true,focusin:true}){eventName="on"+i;isSupported=eventName in div;if(!isSupported){div.setAttribute(eventName,"return;");isSupported=typeof div[eventName]==="function"}support[i+"Bubbles"]=isSupported}}jQuery(function(){var container,div,tds,marginDiv,divReset="padding:0;margin:0;border:0;display:block;overflow:hidden;",body=document.getElementsByTagName("body")[0];if(!body){return}container=document.createElement("div");container.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px";body.insertBefore(container,body.firstChild);div=document.createElement("div");container.appendChild(div);div.innerHTML="<table><tr><td></td><td>t</td></tr></table>";tds=div.getElementsByTagName("td");tds[0].style.cssText="padding:0;margin:0;border:0;display:none";isSupported=tds[0].offsetHeight===0;tds[0].style.display="";tds[1].style.display="none";support.reliableHiddenOffsets=isSupported&&tds[0].offsetHeight===0;div.innerHTML="";div.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";support.boxSizing=div.offsetWidth===4;support.doesNotIncludeMarginInBodyOffset=body.offsetTop!==1;if(window.getComputedStyle){support.pixelPosition=(window.getComputedStyle(div,null)||{}).top!=="1%";support.boxSizingReliable=(window.getComputedStyle(div,null)||{width:"4px"}).width==="4px";marginDiv=document.createElement("div");marginDiv.style.cssText=div.style.cssText=divReset;marginDiv.style.marginRight=marginDiv.style.width="0";div.style.width="1px";div.appendChild(marginDiv);support.reliableMarginRight=!parseFloat((window.getComputedStyle(marginDiv,null)||{}).marginRight)}if(typeof div.style.zoom!=="undefined"){div.innerHTML="";div.style.cssText=divReset+"width:1px;padding:1px;display:inline;zoom:1";support.inlineBlockNeedsLayout=div.offsetWidth===3;div.style.display="block";div.style.overflow="visible";div.innerHTML="<div></div>";div.firstChild.style.width="5px";support.shrinkWrapBlocks=div.offsetWidth!==3;container.style.zoom=1}body.removeChild(container);container=div=tds=marginDiv=null});fragment.removeChild(div);all=a=select=opt=input=fragment=div=null;return support}();var rbrace=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,rmultiDash=/([A-Z])/g;jQuery.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(jQuery.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,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){if(!jQuery.acceptData(elem)){return}var thisCache,ret,internalKey=jQuery.expando,getByName=typeof name==="string",isNode=elem.nodeType,cache=isNode?jQuery.cache:elem,id=isNode?elem[internalKey]:elem[internalKey]&&internalKey;if((!id||!cache[id]||!pvt&&!cache[id].data)&&getByName&&data===undefined){return}if(!id){if(isNode){elem[internalKey]=id=jQuery.deletedIds.pop()||jQuery.guid++}else{id=internalKey}}if(!cache[id]){cache[id]={};if(!isNode){cache[id].toJSON=jQuery.noop}}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)}}thisCache=cache[id];if(!pvt){if(!thisCache.data){thisCache.data={}}thisCache=thisCache.data}if(data!==undefined){thisCache[jQuery.camelCase(name)]=data}if(getByName){ret=thisCache[name];if(ret==null){ret=thisCache[jQuery.camelCase(name)]}}else{ret=thisCache}return ret},removeData:function(elem,name,pvt){if(!jQuery.acceptData(elem)){return}var thisCache,i,l,isNode=elem.nodeType,cache=isNode?jQuery.cache:elem,id=isNode?elem[jQuery.expando]:jQuery.expando;if(!cache[id]){return}if(name){thisCache=pvt?cache[id]:cache[id].data;if(thisCache){if(!jQuery.isArray(name)){if(name in thisCache){name=[name]}else{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(!(pvt?isEmptyDataObject:jQuery.isEmptyObject)(thisCache)){return}}}if(!pvt){delete cache[id].data;if(!isEmptyDataObject(cache[id])){return}}if(isNode){jQuery.cleanData([elem],true)}else if(jQuery.support.deleteExpando||cache!=cache.window){delete cache[id]}else{cache[id]=null}},_data:function(elem,name,data){return jQuery.data(elem,name,data,true)},acceptData:function(elem){var noData=elem.nodeName&&jQuery.noData[elem.nodeName.toLowerCase()];return!noData||noData!==true&&elem.getAttribute("classid")===noData}});jQuery.fn.extend({data:function(key,value){var parts,part,attr,name,l,elem=this[0],i=0,data=null;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-")){name=jQuery.camelCase(name.substring(5));dataAttr(elem,name,data[name])}}jQuery._data(elem,"parsedAttrs",true)}}return data}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]]);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(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:+data+""===data?+data:rbrace.test(data)?jQuery.parseJSON(data):data}catch(e){}jQuery.data(elem,key,data)}else{data=undefined}}return data}function isEmptyDataObject(obj){var name;for(name in obj){if(name==="data"&&jQuery.isEmptyObject(obj[name])){continue}if(name!=="toJSON"){return false}}return true}jQuery.extend({queue:function(elem,type,data){var queue;if(elem){type=(type||"fx")+"queue";queue=jQuery._data(elem,type);if(data){if(!queue||jQuery.isArray(data)){queue=jQuery._data(elem,type,jQuery.makeArray(data))}else{queue.push(data)}}return queue||[]}},dequeue:function(elem,type){type=type||"fx";var queue=jQuery.queue(elem,type),startLength=queue.length,fn=queue.shift(),hooks=jQuery._queueHooks(elem,type),next=function(){jQuery.dequeue(elem,type)};if(fn==="inprogress"){fn=queue.shift();startLength--}if(fn){if(type==="fx"){queue.unshift("inprogress")}delete hooks.stop;fn.call(elem,next,hooks)}if(!startLength&&hooks){hooks.empty.fire()}},_queueHooks:function(elem,type){var key=type+"queueHooks";return jQuery._data(elem,key)||jQuery._data(elem,key,{empty:jQuery.Callbacks("once memory").add(function(){jQuery.removeData(elem,type+"queue",true);jQuery.removeData(elem,key,true)})})}});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);jQuery._queueHooks(this,type);if(type==="fx"&&queue[0]!=="inprogress"){jQuery.dequeue(this,type)}})},dequeue:function(type){return this.each(function(){jQuery.dequeue(this,type)})},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",[])},promise:function(type,obj){var tmp,count=1,defer=jQuery.Deferred(),elements=this,i=this.length,resolve=function(){if(!--count){defer.resolveWith(elements,[elements])}};if(typeof type!=="string"){obj=type;type=undefined}type=type||"fx";while(i--){tmp=jQuery._data(elements[i],type+"queueHooks");if(tmp&&tmp.empty){count++;tmp.empty.add(resolve)}}resolve();return defer.promise(obj)}});var nodeHook,boolHook,fixSpecified,rclass=/[\t\r\n]/g,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;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{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(core_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]+" ")<0){setClass+=classNames[c]+" "}}elem.className=jQuery.trim(setClass)}}}}return this},removeClass:function(value){var removes,className,elem,c,cl,i,l;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){removes=(value||"").split(core_rspace);for(i=0,l=this.length;i<l;i++){elem=this[i];if(elem.nodeType===1&&elem.className){className=(" "+elem.className+" ").replace(rclass," ");for(c=0,cl=removes.length;c<cl;c++){while(className.indexOf(" "+removes[c]+" ")>=0){className=className.replace(" "+removes[c]+" "," ")}}elem.className=value?jQuery.trim(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"){var className,i=0,self=jQuery(this),state=stateVal,classNames=value.split(core_rspace);while(className=classNames[i++]){state=isBool?state:!self.hasClass(className);self[state?"addClass":"removeClass"](className)}}else if(type==="undefined"||type==="boolean"){if(this.className){jQuery._data(this,"__className__",this.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)>=0){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"?ret.replace(rreturn,""):ret==null?"":ret}return}isFunction=jQuery.isFunction(value);return this.each(function(i){var val,self=jQuery(this);if(this.nodeType!==1){return}if(isFunction){val=value.call(this,i,self.val())}else{val=value}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(!hooks||!("set"in hooks)||hooks.set(this,val,"value")===undefined){this.value=val}})}});jQuery.extend({valHooks:{option:{get:function(elem){var val=elem.attributes.value;return!val||val.specified?elem.value:elem.text}},select:{get:function(elem){var value,option,options=elem.options,index=elem.selectedIndex,one=elem.type==="select-one"||index<0,values=one?null:[],max=one?index+1:options.length,i=index<0?max:one?index:0;for(;i<max;i++){option=options[i];if((option.selected||i===index)&&(jQuery.support.optDisabled?!option.disabled:option.getAttribute("disabled")===null)&&(!option.parentNode.disabled||!jQuery.nodeName(option.parentNode,"optgroup"))){value=jQuery(option).val();if(one){return value}values.push(value)}}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:{},attr:function(elem,name,value,pass){var ret,hooks,notxml,nType=elem.nodeType;if(!elem||nType===3||nType===8||nType===2){return}if(pass&&jQuery.isFunction(jQuery.fn[name])){return jQuery(elem)[name](value)}if(typeof elem.getAttribute==="undefined"){return jQuery.prop(elem,name,value)}notxml=nType!==1||!jQuery.isXMLDoc(elem);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);return ret===null?undefined:ret}},removeAttr:function(elem,value){var propName,attrNames,name,isBool,i=0;if(value&&elem.nodeType===1){attrNames=value.split(core_rspace);for(;i<attrNames.length;i++){name=attrNames[i];if(name){propName=jQuery.propFix[name]||name;isBool=rboolean.test(name);if(!isBool){jQuery.attr(elem,name,"")}elem.removeAttribute(getSetAttribute?name:propName);if(isBool&&propName in elem){elem[propName]=false}}}}},attrHooks:{type:{set:function(elem,value){if(rtype.test(elem.nodeName)&&elem.parentNode){jQuery.error("type property can't be changed")
2
+}else if(!jQuery.support.radioValue&&value==="radio"&&jQuery.nodeName(elem,"input")){var val=elem.value;elem.setAttribute("type",value);if(val){elem.value=val}return value}}},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)}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;if(!elem||nType===3||nType===8||nType===2){return}notxml=nType!==1||!jQuery.isXMLDoc(elem);if(notxml){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){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}}}});boolHook={get:function(elem,name){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){jQuery.removeAttr(elem,name)}else{propName=jQuery.propFix[name]||name;if(propName in elem){elem[propName]=true}elem.setAttribute(name,name.toLowerCase())}return name}};if(!getSetAttribute){fixSpecified={name:true,id:true,coords:true};nodeHook=jQuery.valHooks.button={get:function(elem,name){var ret;ret=elem.getAttributeNode(name);return ret&&(fixSpecified[name]?ret.value!=="":ret.specified)?ret.value:undefined},set:function(elem,value,name){var ret=elem.getAttributeNode(name);if(!ret){ret=document.createAttribute(name);elem.setAttributeNode(ret)}return ret.value=value+""}};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}}})});jQuery.attrHooks.contenteditable={get:nodeHook.get,set:function(elem,value,name){if(value===""){value="false"}nodeHook.set(elem,value,name)}}}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 elem.style.cssText.toLowerCase()||undefined},set:function(elem,value){return elem.style.cssText=value+""}}}if(!jQuery.support.optSelected){jQuery.propHooks.selected=jQuery.extend(jQuery.propHooks.selected,{get:function(elem){var parent=elem.parentNode;if(parent){parent.selectedIndex;if(parent.parentNode){parent.parentNode.selectedIndex}}return null}})}if(!jQuery.support.enctype){jQuery.propFix.enctype="encoding"}if(!jQuery.support.checkOn){jQuery.each(["radio","checkbox"],function(){jQuery.valHooks[this]={get:function(elem){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)$/,hoverHack=function(events){return jQuery.event.special.hover?events:events.replace(rhoverHack,"mouseenter$1 mouseleave$1")};jQuery.event={add:function(elem,types,handler,data,selector){var elemData,eventHandle,events,t,tns,type,namespaces,handleObj,handleObjIn,handlers,special;if(elem.nodeType===3||elem.nodeType===8||!types||!handler||!(elemData=jQuery._data(elem))){return}if(handler.handler){handleObjIn=handler;handler=handleObjIn.handler;selector=handleObjIn.selector}if(!handler.guid){handler.guid=jQuery.guid++}events=elemData.events;if(!events){elemData.events=events={}}eventHandle=elemData.handle;if(!eventHandle){elemData.handle=eventHandle=function(e){return typeof jQuery!=="undefined"&&(!e||jQuery.event.triggered!==e.type)?jQuery.event.dispatch.apply(eventHandle.elem,arguments):undefined};eventHandle.elem=elem}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();special=jQuery.event.special[type]||{};type=(selector?special.delegateType:special.bindType)||type;special=jQuery.event.special[type]||{};handleObj=jQuery.extend({type:type,origType:tns[1],data:data,handler:handler,guid:handler.guid,selector:selector,needsContext:selector&&jQuery.expr.match.needsContext.test(selector),namespace:namespaces.join(".")},handleObjIn);handlers=events[type];if(!handlers){handlers=events[type]=[];handlers.delegateCount=0;if(!special.setup||special.setup.call(elem,data,namespaces,eventHandle)===false){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}}if(selector){handlers.splice(handlers.delegateCount++,0,handleObj)}else{handlers.push(handleObj)}jQuery.event.global[type]=true}elem=null},global:{},remove:function(elem,types,handler,selector,mappedTypes){var t,tns,type,origType,namespaces,origCount,j,events,special,eventType,handleObj,elemData=jQuery.hasData(elem)&&jQuery._data(elem);if(!elemData||!(events=elemData.events)){return}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];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;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)}}}if(eventType.length===0&&origCount!==eventType.length){if(!special.teardown||special.teardown.call(elem,namespaces,elemData.handle)===false){jQuery.removeEvent(elem,type,elemData.handle)}delete events[type]}}if(jQuery.isEmptyObject(events)){delete elemData.handle;jQuery.removeData(elem,"events",true)}},customEvent:{getData:true,setData:true,changeData:true},trigger:function(event,data,elem,onlyHandlers){if(elem&&(elem.nodeType===3||elem.nodeType===8)){return}var cache,exclusive,i,cur,old,ontype,special,handle,eventPath,bubbleType,type=event.type||event,namespaces=[];if(rfocusMorph.test(type+jQuery.event.triggered)){return}if(type.indexOf("!")>=0){type=type.slice(0,-1);exclusive=true}if(type.indexOf(".")>=0){namespaces=type.split(".");type=namespaces.shift();namespaces.sort()}if((!elem||jQuery.event.customEvent[type])&&!jQuery.event.global[type]){return}event=typeof event==="object"?event[jQuery.expando]?event:new jQuery.Event(type,event):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:"";if(!elem){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}event.result=undefined;if(!event.target){event.target=elem}data=data!=null?jQuery.makeArray(data):[];data.unshift(event);special=jQuery.event.special[type]||{};if(special.trigger&&special.trigger.apply(elem,data)===false){return}eventPath=[[elem,special.bindType||type]];if(!onlyHandlers&&!special.noBubble&&!jQuery.isWindow(elem)){bubbleType=special.delegateType||type;cur=rfocusMorph.test(bubbleType+type)?elem:elem.parentNode;for(old=elem;cur;cur=cur.parentNode){eventPath.push([cur,bubbleType]);old=cur}if(old===(elem.ownerDocument||document)){eventPath.push([old.defaultView||old.parentWindow||window,bubbleType])}}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)}handle=ontype&&cur[ontype];if(handle&&jQuery.acceptData(cur)&&handle.apply&&handle.apply(cur,data)===false){event.preventDefault()}}event.type=type;if(!onlyHandlers&&!event.isDefaultPrevented()){if((!special._default||special._default.apply(elem.ownerDocument,data)===false)&&!(type==="click"&&jQuery.nodeName(elem,"a"))&&jQuery.acceptData(elem)){if(ontype&&elem[type]&&(type!=="focus"&&type!=="blur"||event.target.offsetWidth!==0)&&!jQuery.isWindow(elem)){old=elem[ontype];if(old){elem[ontype]=null}jQuery.event.triggered=type;elem[type]();jQuery.event.triggered=undefined;if(old){elem[ontype]=old}}}}return event.result},dispatch:function(event){event=jQuery.event.fix(event||window.event);var i,j,cur,ret,selMatch,matched,matches,handleObj,sel,related,handlers=(jQuery._data(this,"events")||{})[event.type]||[],delegateCount=handlers.delegateCount,args=core_slice.call(arguments),run_all=!event.exclusive&&!event.namespace,special=jQuery.event.special[event.type]||{},handlerQueue=[];args[0]=event;event.delegateTarget=this;if(special.preDispatch&&special.preDispatch.call(this,event)===false){return}if(delegateCount&&!(event.button&&event.type==="click")){for(cur=event.target;cur!=this;cur=cur.parentNode||this){if(cur.disabled!==true||event.type!=="click"){selMatch={};matches=[];for(i=0;i<delegateCount;i++){handleObj=handlers[i];sel=handleObj.selector;if(selMatch[sel]===undefined){selMatch[sel]=handleObj.needsContext?jQuery(sel,this).index(cur)>=0:jQuery.find(sel,this,null,[cur]).length}if(selMatch[sel]){matches.push(handleObj)}}if(matches.length){handlerQueue.push({elem:cur,matches:matches})}}}}if(handlers.length>delegateCount){handlerQueue.push({elem:this,matches:handlers.slice(delegateCount)})}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];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()}}}}}if(special.postDispatch){special.postDispatch.call(this,event)}return event.result},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){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;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)}if(!event.relatedTarget&&fromElement){event.relatedTarget=fromElement===event.target?original.toElement:fromElement}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}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]}if(!event.target){event.target=originalEvent.srcElement||document}if(event.target.nodeType===3){event.target=event.target.parentNode}event.metaKey=!!event.metaKey;return fixHook.filter?fixHook.filter(event,originalEvent):event},special:{load:{noBubble:true},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(data,namespaces,eventHandle){if(jQuery.isWindow(this)){this.onbeforeunload=eventHandle}},teardown:function(namespaces,eventHandle){if(this.onbeforeunload===eventHandle){this.onbeforeunload=null}}}},simulate:function(type,elem,event,bubble){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()}}};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){var name="on"+type;if(elem.detachEvent){if(typeof elem[name]==="undefined"){elem[name]=null}elem.detachEvent(name,handle)}};jQuery.Event=function(src,props){if(!(this instanceof jQuery.Event)){return new jQuery.Event(src,props)}if(src&&src.type){this.originalEvent=src;this.type=src.type;this.isDefaultPrevented=src.defaultPrevented||src.returnValue===false||src.getPreventDefault&&src.getPreventDefault()?returnTrue:returnFalse}else{this.type=src}if(props){jQuery.extend(this,props)}this.timeStamp=src&&src.timeStamp||jQuery.now();this[jQuery.expando]=true};function returnFalse(){return false}function returnTrue(){return true}jQuery.Event.prototype={preventDefault:function(){this.isDefaultPrevented=returnTrue;var e=this.originalEvent;if(!e){return}if(e.preventDefault){e.preventDefault()}else{e.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=returnTrue;var e=this.originalEvent;if(!e){return}if(e.stopPropagation){e.stopPropagation()}e.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=returnTrue;this.stopPropagation()},isDefaultPrevented:returnFalse,isPropagationStopped:returnFalse,isImmediatePropagationStopped:returnFalse};jQuery.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(orig,fix){jQuery.event.special[orig]={delegateType:fix,bindType:fix,handle:function(event){var ret,target=this,related=event.relatedTarget,handleObj=event.handleObj,selector=handleObj.selector;if(!related||related!==target&&!jQuery.contains(target,related)){event.type=handleObj.origType;ret=handleObj.handler.apply(this,arguments);event.type=fix}return ret}}});if(!jQuery.support.submitBubbles){jQuery.event.special.submit={setup:function(){if(jQuery.nodeName(this,"form")){return false}jQuery.event.add(this,"click._submit keypress._submit",function(e){var elem=e.target,form=jQuery.nodeName(elem,"input")||jQuery.nodeName(elem,"button")?elem.form:undefined;if(form&&!jQuery._data(form,"_submit_attached")){jQuery.event.add(form,"submit._submit",function(event){event._submit_bubble=true});jQuery._data(form,"_submit_attached",true)}})},postDispatch:function(event){if(event._submit_bubble){delete event._submit_bubble;if(this.parentNode&&!event.isTrigger){jQuery.event.simulate("submit",this.parentNode,event,true)}}},teardown:function(){if(jQuery.nodeName(this,"form")){return false}jQuery.event.remove(this,"._submit")}}}if(!jQuery.support.changeBubbles){jQuery.event.special.change={setup:function(){if(rformElems.test(this.nodeName)){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}jQuery.event.add(this,"beforeactivate._change",function(e){var elem=e.target;if(rformElems.test(elem.nodeName)&&!jQuery._data(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)}});jQuery._data(elem,"_change_attached",true)}})},handle:function(event){var elem=event.target;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)}}}if(!jQuery.support.focusinBubbles){jQuery.each({focus:"focusin",blur:"focusout"},function(orig,fix){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,one){var origFn,type;if(typeof types==="object"){if(typeof selector!=="string"){data=data||selector;selector=undefined}for(type in types){this.on(type,selector,data,types[type],one)}return this}if(data==null&&fn==null){fn=selector;data=selector=undefined}else if(fn==null){if(typeof selector==="string"){fn=data;data=undefined}else{fn=data;data=selector;selector=undefined}}if(fn===false){fn=returnFalse}else if(!fn){return this}if(one===1){origFn=fn;fn=function(event){jQuery().off(event);return origFn.apply(this,arguments)};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){var handleObj,type;if(types&&types.preventDefault&&types.handleObj){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"){for(type in types){this.off(type,selector,types[type])}return this}if(selector===false||typeof selector==="function"){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){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){var args=arguments,guid=fn.guid||jQuery.guid++,i=0,toggler=function(event){var lastToggle=(jQuery._data(this,"lastToggle"+fn.guid)||0)%i;jQuery._data(this,"lastToggle"+fn.guid,lastToggle+1);event.preventDefault();return args[lastToggle].apply(this,arguments)||false};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){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(rkeyEvent.test(name)){jQuery.event.fixHooks[name]=jQuery.event.keyHooks}if(rmouseEvent.test(name)){jQuery.event.fixHooks[name]=jQuery.event.mouseHooks}});(function(window,undefined){var cachedruns,assertGetIdNotName,Expr,getText,isXML,contains,compile,sortOrder,hasDuplicate,outermostContext,baseHasDuplicate=true,strundefined="undefined",expando=("sizcache"+Math.random()).replace(".",""),Token=String,document=window.document,docElem=document.documentElement,dirruns=0,done=0,pop=[].pop,push=[].push,slice=[].slice,indexOf=[].indexOf||function(elem){var i=0,len=this.length;for(;i<len;i++){if(this[i]===elem){return i}}return-1},markFunction=function(fn,value){fn[expando]=value==null||value;return fn},createCache=function(){var cache={},keys=[];return markFunction(function(key,value){if(keys.push(key)>Expr.cacheLength){delete cache[keys.shift()]}return cache[key+" "]=value},cache)},classCache=createCache(),tokenCache=createCache(),compilerCache=createCache(),whitespace="[\\x20\\t\\r\\n\\f]",characterEncoding="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",identifier=characterEncoding.replace("w","w#"),operators="([*^$|!~]?=)",attributes="\\["+whitespace+"*("+characterEncoding+")"+whitespace+"*(?:"+operators+whitespace+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+identifier+")|)|)"+whitespace+"*\\]",pseudos=":("+characterEncoding+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+attributes+")|[^:]|\\\\.)*|.*))\\)|)",pos=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+whitespace+"*((?:-\\d)?\\d*)"+whitespace+"*\\)|)(?=[^-]|$)",rtrim=new RegExp("^"+whitespace+"+|((?:^|[^\\\\])(?:\\\\.)*)"+whitespace+"+$","g"),rcomma=new RegExp("^"+whitespace+"*,"+whitespace+"*"),rcombinators=new RegExp("^"+whitespace+"*([\\x20\\t\\r\\n\\f>+~])"+whitespace+"*"),rpseudo=new RegExp(pseudos),rquickExpr=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,rnot=/^:not/,rsibling=/[\x20\t\r\n\f]*[+~]/,rendsWithNot=/:not\($/,rheader=/h\d/i,rinputs=/input|select|textarea|button/i,rbackslash=/\\(?!\\)/g,matchExpr={ID:new RegExp("^#("+characterEncoding+")"),CLASS:new RegExp("^\\.("+characterEncoding+")"),NAME:new RegExp("^\\[name=['\"]?("+characterEncoding+")['\"]?\\]"),TAG:new RegExp("^("+characterEncoding.replace("w","w*")+")"),ATTR:new RegExp("^"+attributes),PSEUDO:new RegExp("^"+pseudos),POS:new RegExp(pos,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+whitespace+"*(even|odd|(([+-]|)(\\d*)n|)"+whitespace+"*(?:([+-]|)"+whitespace+"*(\\d+)|))"+whitespace+"*\\)|)","i"),needsContext:new RegExp("^"+whitespace+"*[>+~]|"+pos,"i")},assert=function(fn){var div=document.createElement("div");try{return fn(div)}catch(e){return false}finally{div=null}},assertTagNameNoComments=assert(function(div){div.appendChild(document.createComment(""));return!div.getElementsByTagName("*").length}),assertHrefNotNormalized=assert(function(div){div.innerHTML="<a href='#'></a>";return div.firstChild&&typeof div.firstChild.getAttribute!==strundefined&&div.firstChild.getAttribute("href")==="#"}),assertAttributes=assert(function(div){div.innerHTML="<select></select>";var type=typeof div.lastChild.getAttribute("multiple");return type!=="boolean"&&type!=="string"}),assertUsableClassName=assert(function(div){div.innerHTML="<div class='hidden e'></div><div class='hidden'></div>";if(!div.getElementsByClassName||!div.getElementsByClassName("e").length){return false}div.lastChild.className="e";return div.getElementsByClassName("e").length===2}),assertUsableName=assert(function(div){div.id=expando+0;div.innerHTML="<a name='"+expando+"'></a><div name='"+expando+"'></div>";docElem.insertBefore(div,docElem.firstChild);var pass=document.getElementsByName&&document.getElementsByName(expando).length===2+document.getElementsByName(expando+0).length;assertGetIdNotName=!document.getElementById(expando);docElem.removeChild(div);return pass});try{slice.call(docElem.childNodes,0)[0].nodeType}catch(e){slice=function(i){var elem,results=[];for(;elem=this[i];i++){results.push(elem)}return results}}function Sizzle(selector,context,results,seed){results=results||[];context=context||document;var match,elem,xml,m,nodeType=context.nodeType;if(!selector||typeof selector!=="string"){return results}if(nodeType!==1&&nodeType!==9){return[]}xml=isXML(context);if(!xml&&!seed){if(match=rquickExpr.exec(selector)){if(m=match[1]){if(nodeType===9){elem=context.getElementById(m);if(elem&&elem.parentNode){if(elem.id===m){results.push(elem);return results}}else{return results}}else{if(context.ownerDocument&&(elem=context.ownerDocument.getElementById(m))&&contains(context,elem)&&elem.id===m){results.push(elem);return results}}}else if(match[2]){push.apply(results,slice.call(context.getElementsByTagName(selector),0));return results}else if((m=match[3])&&assertUsableClassName&&context.getElementsByClassName){push.apply(results,slice.call(context.getElementsByClassName(m),0));return results}}}return select(selector.replace(rtrim,"$1"),context,results,seed,xml)}Sizzle.matches=function(expr,elements){return Sizzle(expr,null,null,elements)};Sizzle.matchesSelector=function(elem,expr){return Sizzle(expr,null,null,[elem]).length>0};function createInputPseudo(type){return function(elem){var name=elem.nodeName.toLowerCase();return name==="input"&&elem.type===type}}function createButtonPseudo(type){return function(elem){var name=elem.nodeName.toLowerCase();return(name==="input"||name==="button")&&elem.type===type}}function createPositionalPseudo(fn){return markFunction(function(argument){argument=+argument;return markFunction(function(seed,matches){var j,matchIndexes=fn([],seed.length,argument),i=matchIndexes.length;while(i--){if(seed[j=matchIndexes[i]]){seed[j]=!(matches[j]=seed[j])}}})})}getText=Sizzle.getText=function(elem){var node,ret="",i=0,nodeType=elem.nodeType;if(nodeType){if(nodeType===1||nodeType===9||nodeType===11){if(typeof elem.textContent==="string"){return elem.textContent}else{for(elem=elem.firstChild;elem;elem=elem.nextSibling){ret+=getText(elem)}}}else if(nodeType===3||nodeType===4){return elem.nodeValue}}else{for(;node=elem[i];i++){ret+=getText(node)}}return ret};isXML=Sizzle.isXML=function(elem){var documentElement=elem&&(elem.ownerDocument||elem).documentElement;return documentElement?documentElement.nodeName!=="HTML":false};contains=Sizzle.contains=docElem.contains?function(a,b){var adown=a.nodeType===9?a.documentElement:a,bup=b&&b.parentNode;return a===bup||!!(bup&&bup.nodeType===1&&adown.contains&&adown.contains(bup))}:docElem.compareDocumentPosition?function(a,b){return b&&!!(a.compareDocumentPosition(b)&16)}:function(a,b){while(b=b.parentNode){if(b===a){return true}}return false};Sizzle.attr=function(elem,name){var val,xml=isXML(elem);if(!xml){name=name.toLowerCase()}if(val=Expr.attrHandle[name]){return val(elem)}if(xml||assertAttributes){return elem.getAttribute(name)}val=elem.getAttributeNode(name);return val?typeof elem[name]==="boolean"?elem[name]?name:null:val.specified?val.value:null:null};Expr=Sizzle.selectors={cacheLength:50,createPseudo:markFunction,match:matchExpr,attrHandle:assertHrefNotNormalized?{}:{href:function(elem){return elem.getAttribute("href",2)},type:function(elem){return elem.getAttribute("type")}},find:{ID:assertGetIdNotName?function(id,context,xml){if(typeof context.getElementById!==strundefined&&!xml){var m=context.getElementById(id);return m&&m.parentNode?[m]:[]}}:function(id,context,xml){if(typeof context.getElementById!==strundefined&&!xml){var m=context.getElementById(id);return m?m.id===id||typeof m.getAttributeNode!==strundefined&&m.getAttributeNode("id").value===id?[m]:undefined:[]}},TAG:assertTagNameNoComments?function(tag,context){if(typeof context.getElementsByTagName!==strundefined){return context.getElementsByTagName(tag)}}:function(tag,context){var results=context.getElementsByTagName(tag);if(tag==="*"){var elem,tmp=[],i=0;for(;elem=results[i];i++){if(elem.nodeType===1){tmp.push(elem)}}return tmp}return results},NAME:assertUsableName&&function(tag,context){if(typeof context.getElementsByName!==strundefined){return context.getElementsByName(name)}},CLASS:assertUsableClassName&&function(className,context,xml){if(typeof context.getElementsByClassName!==strundefined&&!xml){return context.getElementsByClassName(className)}}},relative:{">":{dir:"parentNode",first:true}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:true},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(match){match[1]=match[1].replace(rbackslash,"");match[3]=(match[4]||match[5]||"").replace(rbackslash,"");if(match[2]==="~="){match[3]=" "+match[3]+" "}return match.slice(0,4)},CHILD:function(match){match[1]=match[1].toLowerCase();if(match[1]==="nth"){if(!match[2]){Sizzle.error(match[0])}match[3]=+(match[3]?match[4]+(match[5]||1):2*(match[2]==="even"||match[2]==="odd"));match[4]=+(match[6]+match[7]||match[2]==="odd")}else if(match[2]){Sizzle.error(match[0])}return match},PSEUDO:function(match){var unquoted,excess;if(matchExpr["CHILD"].test(match[0])){return null}if(match[3]){match[2]=match[3]}else if(unquoted=match[4]){if(rpseudo.test(unquoted)&&(excess=tokenize(unquoted,true))&&(excess=unquoted.indexOf(")",unquoted.length-excess)-unquoted.length)){unquoted=unquoted.slice(0,excess);match[0]=match[0].slice(0,excess)}match[2]=unquoted}return match.slice(0,3)}},filter:{ID:assertGetIdNotName?function(id){id=id.replace(rbackslash,"");return function(elem){return elem.getAttribute("id")===id}}:function(id){id=id.replace(rbackslash,"");return function(elem){var node=typeof elem.getAttributeNode!==strundefined&&elem.getAttributeNode("id");return node&&node.value===id}},TAG:function(nodeName){if(nodeName==="*"){return function(){return true}}nodeName=nodeName.replace(rbackslash,"").toLowerCase();return function(elem){return elem.nodeName&&elem.nodeName.toLowerCase()===nodeName}},CLASS:function(className){var pattern=classCache[expando][className+" "];return pattern||(pattern=new RegExp("(^|"+whitespace+")"+className+"("+whitespace+"|$)"))&&classCache(className,function(elem){return pattern.test(elem.className||typeof elem.getAttribute!==strundefined&&elem.getAttribute("class")||"")})},ATTR:function(name,operator,check){return function(elem,context){var result=Sizzle.attr(elem,name);if(result==null){return operator==="!="}if(!operator){return true}result+="";return operator==="="?result===check:operator==="!="?result!==check:operator==="^="?check&&result.indexOf(check)===0:operator==="*="?check&&result.indexOf(check)>-1:operator==="$="?check&&result.substr(result.length-check.length)===check:operator==="~="?(" "+result+" ").indexOf(check)>-1:operator==="|="?result===check||result.substr(0,check.length+1)===check+"-":false}},CHILD:function(type,argument,first,last){if(type==="nth"){return function(elem){var node,diff,parent=elem.parentNode;if(first===1&&last===0){return true}if(parent){diff=0;for(node=parent.firstChild;node;node=node.nextSibling){if(node.nodeType===1){diff++;
3
+if(elem===node){break}}}}diff-=last;return diff===first||diff%first===0&&diff/first>=0}}return function(elem){var 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;case"last":while(node=node.nextSibling){if(node.nodeType===1){return false}}return true}}},PSEUDO:function(pseudo,argument){var args,fn=Expr.pseudos[pseudo]||Expr.setFilters[pseudo.toLowerCase()]||Sizzle.error("unsupported pseudo: "+pseudo);if(fn[expando]){return fn(argument)}if(fn.length>1){args=[pseudo,pseudo,"",argument];return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase())?markFunction(function(seed,matches){var idx,matched=fn(seed,argument),i=matched.length;while(i--){idx=indexOf.call(seed,matched[i]);seed[idx]=!(matches[idx]=matched[i])}}):function(elem){return fn(elem,0,args)}}return fn}},pseudos:{not:markFunction(function(selector){var input=[],results=[],matcher=compile(selector.replace(rtrim,"$1"));return matcher[expando]?markFunction(function(seed,matches,context,xml){var elem,unmatched=matcher(seed,null,xml,[]),i=seed.length;while(i--){if(elem=unmatched[i]){seed[i]=!(matches[i]=elem)}}}):function(elem,context,xml){input[0]=elem;matcher(input,null,xml,results);return!results.pop()}}),has:markFunction(function(selector){return function(elem){return Sizzle(selector,elem).length>0}}),contains:markFunction(function(text){return function(elem){return(elem.textContent||elem.innerText||getText(elem)).indexOf(text)>-1}}),enabled:function(elem){return elem.disabled===false},disabled:function(elem){return elem.disabled===true},checked:function(elem){var nodeName=elem.nodeName.toLowerCase();return nodeName==="input"&&!!elem.checked||nodeName==="option"&&!!elem.selected},selected:function(elem){if(elem.parentNode){elem.parentNode.selectedIndex}return elem.selected===true},parent:function(elem){return!Expr.pseudos["empty"](elem)},empty:function(elem){var nodeType;elem=elem.firstChild;while(elem){if(elem.nodeName>"@"||(nodeType=elem.nodeType)===3||nodeType===4){return false}elem=elem.nextSibling}return true},header:function(elem){return rheader.test(elem.nodeName)},text:function(elem){var type,attr;return elem.nodeName.toLowerCase()==="input"&&(type=elem.type)==="text"&&((attr=elem.getAttribute("type"))==null||attr.toLowerCase()===type)},radio:createInputPseudo("radio"),checkbox:createInputPseudo("checkbox"),file:createInputPseudo("file"),password:createInputPseudo("password"),image:createInputPseudo("image"),submit:createButtonPseudo("submit"),reset:createButtonPseudo("reset"),button:function(elem){var name=elem.nodeName.toLowerCase();return name==="input"&&elem.type==="button"||name==="button"},input:function(elem){return rinputs.test(elem.nodeName)},focus:function(elem){var doc=elem.ownerDocument;return elem===doc.activeElement&&(!doc.hasFocus||doc.hasFocus())&&!!(elem.type||elem.href||~elem.tabIndex)},active:function(elem){return elem===elem.ownerDocument.activeElement},first:createPositionalPseudo(function(){return[0]}),last:createPositionalPseudo(function(matchIndexes,length){return[length-1]}),eq:createPositionalPseudo(function(matchIndexes,length,argument){return[argument<0?argument+length:argument]}),even:createPositionalPseudo(function(matchIndexes,length){for(var i=0;i<length;i+=2){matchIndexes.push(i)}return matchIndexes}),odd:createPositionalPseudo(function(matchIndexes,length){for(var i=1;i<length;i+=2){matchIndexes.push(i)}return matchIndexes}),lt:createPositionalPseudo(function(matchIndexes,length,argument){for(var i=argument<0?argument+length:argument;--i>=0;){matchIndexes.push(i)}return matchIndexes}),gt:createPositionalPseudo(function(matchIndexes,length,argument){for(var i=argument<0?argument+length:argument;++i<length;){matchIndexes.push(i)}return matchIndexes})}};function siblingCheck(a,b,ret){if(a===b){return ret}var cur=a.nextSibling;while(cur){if(cur===b){return-1}cur=cur.nextSibling}return 1}sortOrder=docElem.compareDocumentPosition?function(a,b){if(a===b){hasDuplicate=true;return 0}return(!a.compareDocumentPosition||!b.compareDocumentPosition?a.compareDocumentPosition:a.compareDocumentPosition(b)&4)?-1:1}:function(a,b){if(a===b){hasDuplicate=true;return 0}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(aup===bup){return siblingCheck(a,b)}else if(!aup){return-1}else if(!bup){return 1}while(cur){ap.unshift(cur);cur=cur.parentNode}cur=bup;while(cur){bp.unshift(cur);cur=cur.parentNode}al=ap.length;bl=bp.length;for(var i=0;i<al&&i<bl;i++){if(ap[i]!==bp[i]){return siblingCheck(ap[i],bp[i])}}return i===al?siblingCheck(a,bp[i],-1):siblingCheck(ap[i],b,1)};[0,0].sort(sortOrder);baseHasDuplicate=!hasDuplicate;Sizzle.uniqueSort=function(results){var elem,duplicates=[],i=1,j=0;hasDuplicate=baseHasDuplicate;results.sort(sortOrder);if(hasDuplicate){for(;elem=results[i];i++){if(elem===results[i-1]){j=duplicates.push(i)}}while(j--){results.splice(duplicates[j],1)}}return results};Sizzle.error=function(msg){throw new Error("Syntax error, unrecognized expression: "+msg)};function tokenize(selector,parseOnly){var matched,match,tokens,type,soFar,groups,preFilters,cached=tokenCache[expando][selector+" "];if(cached){return parseOnly?0:cached.slice(0)}soFar=selector;groups=[];preFilters=Expr.preFilter;while(soFar){if(!matched||(match=rcomma.exec(soFar))){if(match){soFar=soFar.slice(match[0].length)||soFar}groups.push(tokens=[])}matched=false;if(match=rcombinators.exec(soFar)){tokens.push(matched=new Token(match.shift()));soFar=soFar.slice(matched.length);matched.type=match[0].replace(rtrim," ")}for(type in Expr.filter){if((match=matchExpr[type].exec(soFar))&&(!preFilters[type]||(match=preFilters[type](match)))){tokens.push(matched=new Token(match.shift()));soFar=soFar.slice(matched.length);matched.type=type;matched.matches=match}}if(!matched){break}}return parseOnly?soFar.length:soFar?Sizzle.error(selector):tokenCache(selector,groups).slice(0)}function addCombinator(matcher,combinator,base){var dir=combinator.dir,checkNonElements=base&&combinator.dir==="parentNode",doneName=done++;return combinator.first?function(elem,context,xml){while(elem=elem[dir]){if(checkNonElements||elem.nodeType===1){return matcher(elem,context,xml)}}}:function(elem,context,xml){if(!xml){var cache,dirkey=dirruns+" "+doneName+" ",cachedkey=dirkey+cachedruns;while(elem=elem[dir]){if(checkNonElements||elem.nodeType===1){if((cache=elem[expando])===cachedkey){return elem.sizset}else if(typeof cache==="string"&&cache.indexOf(dirkey)===0){if(elem.sizset){return elem}}else{elem[expando]=cachedkey;if(matcher(elem,context,xml)){elem.sizset=true;return elem}elem.sizset=false}}}}else{while(elem=elem[dir]){if(checkNonElements||elem.nodeType===1){if(matcher(elem,context,xml)){return elem}}}}}}function elementMatcher(matchers){return matchers.length>1?function(elem,context,xml){var i=matchers.length;while(i--){if(!matchers[i](elem,context,xml)){return false}}return true}:matchers[0]}function condense(unmatched,map,filter,context,xml){var elem,newUnmatched=[],i=0,len=unmatched.length,mapped=map!=null;for(;i<len;i++){if(elem=unmatched[i]){if(!filter||filter(elem,context,xml)){newUnmatched.push(elem);if(mapped){map.push(i)}}}}return newUnmatched}function setMatcher(preFilter,selector,matcher,postFilter,postFinder,postSelector){if(postFilter&&!postFilter[expando]){postFilter=setMatcher(postFilter)}if(postFinder&&!postFinder[expando]){postFinder=setMatcher(postFinder,postSelector)}return markFunction(function(seed,results,context,xml){var temp,i,elem,preMap=[],postMap=[],preexisting=results.length,elems=seed||multipleContexts(selector||"*",context.nodeType?[context]:context,[]),matcherIn=preFilter&&(seed||!selector)?condense(elems,preMap,preFilter,context,xml):elems,matcherOut=matcher?postFinder||(seed?preFilter:preexisting||postFilter)?[]:results:matcherIn;if(matcher){matcher(matcherIn,matcherOut,context,xml)}if(postFilter){temp=condense(matcherOut,postMap);postFilter(temp,[],context,xml);i=temp.length;while(i--){if(elem=temp[i]){matcherOut[postMap[i]]=!(matcherIn[postMap[i]]=elem)}}}if(seed){if(postFinder||preFilter){if(postFinder){temp=[];i=matcherOut.length;while(i--){if(elem=matcherOut[i]){temp.push(matcherIn[i]=elem)}}postFinder(null,matcherOut=[],temp,xml)}i=matcherOut.length;while(i--){if((elem=matcherOut[i])&&(temp=postFinder?indexOf.call(seed,elem):preMap[i])>-1){seed[temp]=!(results[temp]=elem)}}}}else{matcherOut=condense(matcherOut===results?matcherOut.splice(preexisting,matcherOut.length):matcherOut);if(postFinder){postFinder(null,results,matcherOut,xml)}else{push.apply(results,matcherOut)}}})}function matcherFromTokens(tokens){var checkContext,matcher,j,len=tokens.length,leadingRelative=Expr.relative[tokens[0].type],implicitRelative=leadingRelative||Expr.relative[" "],i=leadingRelative?1:0,matchContext=addCombinator(function(elem){return elem===checkContext},implicitRelative,true),matchAnyContext=addCombinator(function(elem){return indexOf.call(checkContext,elem)>-1},implicitRelative,true),matchers=[function(elem,context,xml){return!leadingRelative&&(xml||context!==outermostContext)||((checkContext=context).nodeType?matchContext(elem,context,xml):matchAnyContext(elem,context,xml))}];for(;i<len;i++){if(matcher=Expr.relative[tokens[i].type]){matchers=[addCombinator(elementMatcher(matchers),matcher)]}else{matcher=Expr.filter[tokens[i].type].apply(null,tokens[i].matches);if(matcher[expando]){j=++i;for(;j<len;j++){if(Expr.relative[tokens[j].type]){break}}return setMatcher(i>1&&elementMatcher(matchers),i>1&&tokens.slice(0,i-1).join("").replace(rtrim,"$1"),matcher,i<j&&matcherFromTokens(tokens.slice(i,j)),j<len&&matcherFromTokens(tokens=tokens.slice(j)),j<len&&tokens.join(""))}matchers.push(matcher)}}return elementMatcher(matchers)}function matcherFromGroupMatchers(elementMatchers,setMatchers){var bySet=setMatchers.length>0,byElement=elementMatchers.length>0,superMatcher=function(seed,context,xml,results,expandContext){var elem,j,matcher,setMatched=[],matchedCount=0,i="0",unmatched=seed&&[],outermost=expandContext!=null,contextBackup=outermostContext,elems=seed||byElement&&Expr.find["TAG"]("*",expandContext&&context.parentNode||context),dirrunsUnique=dirruns+=contextBackup==null?1:Math.E;if(outermost){outermostContext=context!==document&&context;cachedruns=superMatcher.el}for(;(elem=elems[i])!=null;i++){if(byElement&&elem){for(j=0;matcher=elementMatchers[j];j++){if(matcher(elem,context,xml)){results.push(elem);break}}if(outermost){dirruns=dirrunsUnique;cachedruns=++superMatcher.el}}if(bySet){if(elem=!matcher&&elem){matchedCount--}if(seed){unmatched.push(elem)}}}matchedCount+=i;if(bySet&&i!==matchedCount){for(j=0;matcher=setMatchers[j];j++){matcher(unmatched,setMatched,context,xml)}if(seed){if(matchedCount>0){while(i--){if(!(unmatched[i]||setMatched[i])){setMatched[i]=pop.call(results)}}}setMatched=condense(setMatched)}push.apply(results,setMatched);if(outermost&&!seed&&setMatched.length>0&&matchedCount+setMatchers.length>1){Sizzle.uniqueSort(results)}}if(outermost){dirruns=dirrunsUnique;outermostContext=contextBackup}return unmatched};superMatcher.el=0;return bySet?markFunction(superMatcher):superMatcher}compile=Sizzle.compile=function(selector,group){var i,setMatchers=[],elementMatchers=[],cached=compilerCache[expando][selector+" "];if(!cached){if(!group){group=tokenize(selector)}i=group.length;while(i--){cached=matcherFromTokens(group[i]);if(cached[expando]){setMatchers.push(cached)}else{elementMatchers.push(cached)}}cached=compilerCache(selector,matcherFromGroupMatchers(elementMatchers,setMatchers))}return cached};function multipleContexts(selector,contexts,results){var i=0,len=contexts.length;for(;i<len;i++){Sizzle(selector,contexts[i],results)}return results}function select(selector,context,results,seed,xml){var i,tokens,token,type,find,match=tokenize(selector),j=match.length;if(!seed){if(match.length===1){tokens=match[0]=match[0].slice(0);if(tokens.length>2&&(token=tokens[0]).type==="ID"&&context.nodeType===9&&!xml&&Expr.relative[tokens[1].type]){context=Expr.find["ID"](token.matches[0].replace(rbackslash,""),context,xml)[0];if(!context){return results}selector=selector.slice(tokens.shift().length)}for(i=matchExpr["POS"].test(selector)?-1:tokens.length-1;i>=0;i--){token=tokens[i];if(Expr.relative[type=token.type]){break}if(find=Expr.find[type]){if(seed=find(token.matches[0].replace(rbackslash,""),rsibling.test(tokens[0].type)&&context.parentNode||context,xml)){tokens.splice(i,1);selector=seed.length&&tokens.join("");if(!selector){push.apply(results,slice.call(seed,0));return results}break}}}}}compile(selector,match)(seed,context,xml,results,rsibling.test(selector));return results}if(document.querySelectorAll){(function(){var disconnectedMatch,oldSelect=select,rescape=/'|\\/g,rattributeQuotes=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,rbuggyQSA=[":focus"],rbuggyMatches=[":active"],matches=docElem.matchesSelector||docElem.mozMatchesSelector||docElem.webkitMatchesSelector||docElem.oMatchesSelector||docElem.msMatchesSelector;assert(function(div){div.innerHTML="<select><option selected=''></option></select>";if(!div.querySelectorAll("[selected]").length){rbuggyQSA.push("\\["+whitespace+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)")}if(!div.querySelectorAll(":checked").length){rbuggyQSA.push(":checked")}});assert(function(div){div.innerHTML="<p test=''></p>";if(div.querySelectorAll("[test^='']").length){rbuggyQSA.push("[*^$]="+whitespace+"*(?:\"\"|'')")}div.innerHTML="<input type='hidden'/>";if(!div.querySelectorAll(":enabled").length){rbuggyQSA.push(":enabled",":disabled")}});rbuggyQSA=new RegExp(rbuggyQSA.join("|"));select=function(selector,context,results,seed,xml){if(!seed&&!xml&&!rbuggyQSA.test(selector)){var groups,i,old=true,nid=expando,newContext=context,newSelector=context.nodeType===9&&selector;if(context.nodeType===1&&context.nodeName.toLowerCase()!=="object"){groups=tokenize(selector);if(old=context.getAttribute("id")){nid=old.replace(rescape,"\\$&")}else{context.setAttribute("id",nid)}nid="[id='"+nid+"'] ";i=groups.length;while(i--){groups[i]=nid+groups[i].join("")}newContext=rsibling.test(selector)&&context.parentNode||context;newSelector=groups.join(",")}if(newSelector){try{push.apply(results,slice.call(newContext.querySelectorAll(newSelector),0));return results}catch(qsaError){}finally{if(!old){context.removeAttribute("id")}}}}return oldSelect(selector,context,results,seed,xml)};if(matches){assert(function(div){disconnectedMatch=matches.call(div,"div");try{matches.call(div,"[test!='']:sizzle");rbuggyMatches.push("!=",pseudos)}catch(e){}});rbuggyMatches=new RegExp(rbuggyMatches.join("|"));Sizzle.matchesSelector=function(elem,expr){expr=expr.replace(rattributeQuotes,"='$1']");if(!isXML(elem)&&!rbuggyMatches.test(expr)&&!rbuggyQSA.test(expr)){try{var ret=matches.call(elem,expr);if(ret||disconnectedMatch||elem.document&&elem.document.nodeType!==11){return ret}}catch(e){}}return Sizzle(expr,null,null,[elem]).length>0}}})()}Expr.pseudos["nth"]=Expr.pseudos["eq"];function setFilters(){}Expr.filters=setFilters.prototype=Expr.pseudos;Expr.setFilters=new setFilters;Sizzle.attr=jQuery.attr;jQuery.find=Sizzle;jQuery.expr=Sizzle.selectors;jQuery.expr[":"]=jQuery.expr.pseudos;jQuery.unique=Sizzle.uniqueSort;jQuery.text=Sizzle.getText;jQuery.isXMLDoc=Sizzle.isXML;jQuery.contains=Sizzle.contains})(window);var runtil=/Until$/,rparentsprev=/^(?:parents|prev(?:Until|All))/,isSimple=/^.[^:#\[\.,]*$/,rneedsContext=jQuery.expr.match.needsContext,guaranteedUnique={children:true,contents:true,next:true,prev:true};jQuery.fn.extend({find:function(selector){var i,l,length,n,r,ret,self=this;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}}})}ret=this.pushStack("","find",selector);for(i=0,l=this.length;i<l;i++){length=ret.length;jQuery.find(selector,this[i],ret);if(i>0){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 i,targets=jQuery(target,this),len=targets.length;return this.filter(function(){for(i=0;i<len;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"?rneedsContext.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 cur,i=0,l=this.length,ret=[],pos=rneedsContext.test(selectors)||typeof selectors!=="string"?jQuery(selectors,context||this.context):0;for(;i<l;i++){cur=this[i];while(cur&&cur.ownerDocument&&cur!==context&&cur.nodeType!==11){if(pos?pos.index(cur)>-1:jQuery.find.matchesSelector(cur,selectors)){ret.push(cur);break}cur=cur.parentNode}}ret=ret.length>1?jQuery.unique(ret):ret;return this.pushStack(ret,"closest",selectors)},index:function(elem){if(!elem){return this[0]&&this[0].parentNode?this.prevAll().length:-1}if(typeof elem==="string"){return jQuery.inArray(this[0],jQuery(elem))}return jQuery.inArray(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))},addBack:function(selector){return this.add(selector==null?this.prevObject:this.prevObject.filter(selector))}});jQuery.fn.andSelf=jQuery.fn.addBack;function isDisconnected(node){return!node||!node.parentNode||node.parentNode.nodeType===11}function sibling(cur,dir){do{cur=cur[dir]}while(cur&&cur.nodeType!==1);return cur}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 sibling(elem,"nextSibling")},prev:function(elem){return sibling(elem,"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.merge([],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&&rparentsprev.test(name)){ret=ret.reverse()}return this.pushStack(ret,name,core_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},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType===1&&n!==elem){r.push(n)}}return r}});function winnow(elements,qualifier,keep){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+="(?:null|\d+)"/g,rleadingWhitespace=/^\s+/,rxhtmlTag=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,rtagName=/<([\w:]+)/,rtbody=/<tbody/i,rhtml=/<|&#?\w+;/,rnoInnerhtml=/<(?:script|style|link)/i,rnocache=/<(?:script|object|embed|option|style)/i,rnoshimcache=new RegExp("<(?:"+nodeNames+")[\\s/>]","i"),rcheckableType=/^(?:checkbox|radio)$/,rchecked=/checked\s*(?:[^=]|=\s*.checked.)/i,rscriptType=/\/(java|ecma)script/i,rcleanScript=/^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,wrapMap={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},safeFragment=createSafeFragment(document),fragmentDiv=safeFragment.appendChild(document.createElement("div"));wrapMap.optgroup=wrapMap.option;wrapMap.tbody=wrapMap.tfoot=wrapMap.colgroup=wrapMap.caption=wrapMap.thead;wrapMap.th=wrapMap.td;if(!jQuery.support.htmlSerialize){wrapMap._default=[1,"X<div>","</div>"]}jQuery.fn.extend({text:function(value){return jQuery.access(this,function(value){return value===undefined?jQuery.text(this):this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(value))},null,value,arguments.length)},wrapAll:function(html){if(jQuery.isFunction(html)){return this.each(function(i){jQuery(this).wrapAll(html.call(this,i))})}if(this[0]){var wrap=jQuery(html,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){wrap.insertBefore(this[0])}wrap.map(function(){var elem=this;while(elem.firstChild&&elem.firstChild.nodeType===1){elem=elem.firstChild}return elem}).append(this)}return this},wrapInner:function(html){if(jQuery.isFunction(html)){return this.each(function(i){jQuery(this).wrapInner(html.call(this,i))})}return this.each(function(){var self=jQuery(this),contents=self.contents();if(contents.length){contents.wrapAll(html)}else{self.append(html)}})},wrap:function(html){var isFunction=jQuery.isFunction(html);return this.each(function(i){jQuery(this).wrapAll(isFunction?html.call(this,i):html)})},unwrap:function(){return this.parent().each(function(){if(!jQuery.nodeName(this,"body")){jQuery(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(elem){if(this.nodeType===1||this.nodeType===11){this.appendChild(elem)}})},prepend:function(){return this.domManip(arguments,true,function(elem){if(this.nodeType===1||this.nodeType===11){this.insertBefore(elem,this.firstChild)}})},before:function(){if(!isDisconnected(this[0])){return this.domManip(arguments,false,function(elem){this.parentNode.insertBefore(elem,this)})}if(arguments.length){var set=jQuery.clean(arguments);return this.pushStack(jQuery.merge(set,this),"before",this.selector)}},after:function(){if(!isDisconnected(this[0])){return this.domManip(arguments,false,function(elem){this.parentNode.insertBefore(elem,this.nextSibling)})}if(arguments.length){var set=jQuery.clean(arguments);return this.pushStack(jQuery.merge(this,set),"after",this.selector)}},remove:function(selector,keepData){var elem,i=0;for(;(elem=this[i])!=null;i++){if(!selector||jQuery.filter(selector,[elem]).length){if(!keepData&&elem.nodeType===1){jQuery.cleanData(elem.getElementsByTagName("*"));jQuery.cleanData([elem])}if(elem.parentNode){elem.parentNode.removeChild(elem)}}}return this},empty:function(){var elem,i=0;for(;(elem=this[i])!=null;i++){if(elem.nodeType===1){jQuery.cleanData(elem.getElementsByTagName("*"))}while(elem.firstChild){elem.removeChild(elem.firstChild)}}return this},clone:function(dataAndEvents,deepDataAndEvents){dataAndEvents=dataAndEvents==null?false:dataAndEvents;deepDataAndEvents=deepDataAndEvents==null?dataAndEvents:deepDataAndEvents;return this.map(function(){return jQuery.clone(this,dataAndEvents,deepDataAndEvents)})},html:function(value){return jQuery.access(this,function(value){var elem=this[0]||{},i=0,l=this.length;if(value===undefined){return elem.nodeType===1?elem.innerHTML.replace(rinlinejQuery,""):undefined}if(typeof value==="string"&&!rnoInnerhtml.test(value)&&(jQuery.support.htmlSerialize||!rnoshimcache.test(value))&&(jQuery.support.leadingWhitespace||!rleadingWhitespace.test(value))&&!wrapMap[(rtagName.exec(value)||["",""])[1].toLowerCase()]){value=value.replace(rxhtmlTag,"<$1></$2>");try{for(;i<l;i++){elem=this[i]||{};if(elem.nodeType===1){jQuery.cleanData(elem.getElementsByTagName("*"));elem.innerHTML=value}}elem=0}catch(e){}}if(elem){this.empty().append(value)}},null,value,arguments.length)},replaceWith:function(value){if(!isDisconnected(this[0])){if(jQuery.isFunction(value)){return this.each(function(i){var self=jQuery(this),old=self.html();self.replaceWith(value.call(this,i,old))})}if(typeof value!=="string"){value=jQuery(value).detach()}return this.each(function(){var next=this.nextSibling,parent=this.parentNode;jQuery(this).remove();if(next){jQuery(next).before(value)}else{jQuery(parent).append(value)}})}return this.length?this.pushStack(jQuery(jQuery.isFunction(value)?value():value),"replaceWith",value):this},detach:function(selector){return this.remove(selector,true)},domManip:function(args,table,callback){args=[].concat.apply([],args);var results,first,fragment,iNoClone,i=0,value=args[0],scripts=[],l=this.length;if(!jQuery.support.checkClone&&l>1&&typeof value==="string"&&rchecked.test(value)){return this.each(function(){jQuery(this).domManip(args,table,callback)})}if(jQuery.isFunction(value)){return this.each(function(i){var self=jQuery(this);args[0]=value.call(this,i,table?self.html():undefined);self.domManip(args,table,callback)})}if(this[0]){results=jQuery.buildFragment(args,this,scripts);fragment=results.fragment;first=fragment.firstChild;if(fragment.childNodes.length===1){fragment=first}if(first){table=table&&jQuery.nodeName(first,"tr");for(iNoClone=results.cacheable||l-1;i<l;i++){callback.call(table&&jQuery.nodeName(this[i],"table")?findOrAppend(this[i],"tbody"):this[i],i===iNoClone?fragment:jQuery.clone(fragment,true,true))}}fragment=first=null;if(scripts.length){jQuery.each(scripts,function(i,elem){if(elem.src){if(jQuery.ajax){jQuery.ajax({url:elem.src,type:"GET",dataType:"script",async:false,global:false,"throws":true})}else{jQuery.error("no ajax")}}else{jQuery.globalEval((elem.text||elem.textContent||elem.innerHTML||"").replace(rcleanScript,""))}if(elem.parentNode){elem.parentNode.removeChild(elem)}})}}return this}});function findOrAppend(elem,tag){return elem.getElementsByTagName(tag)[0]||elem.appendChild(elem.ownerDocument.createElement(tag))}function cloneCopyEvent(src,dest){if(dest.nodeType!==1||!jQuery.hasData(src)){return}var type,i,l,oldData=jQuery._data(src),curData=jQuery._data(dest,oldData),events=oldData.events;if(events){delete curData.handle;curData.events={};for(type in events){for(i=0,l=events[type].length;i<l;i++){jQuery.event.add(dest,type,events[type][i])}}}if(curData.data){curData.data=jQuery.extend({},curData.data)}}function cloneFixAttributes(src,dest){var nodeName;if(dest.nodeType!==1){return}if(dest.clearAttributes){dest.clearAttributes()}if(dest.mergeAttributes){dest.mergeAttributes(src)}nodeName=dest.nodeName.toLowerCase();if(nodeName==="object"){if(dest.parentNode){dest.outerHTML=src.outerHTML}if(jQuery.support.html5Clone&&(src.innerHTML&&!jQuery.trim(dest.innerHTML))){dest.innerHTML=src.innerHTML}}else if(nodeName==="input"&&rcheckableType.test(src.type)){dest.defaultChecked=dest.checked=src.checked;if(dest.value!==src.value){dest.value=src.value}}else if(nodeName==="option"){dest.selected=src.defaultSelected}else if(nodeName==="input"||nodeName==="textarea"){dest.defaultValue=src.defaultValue}else if(nodeName==="script"&&dest.text!==src.text){dest.text=src.text}dest.removeAttribute(jQuery.expando)}jQuery.buildFragment=function(args,context,scripts){var fragment,cacheable,cachehit,first=args[0];context=context||document;context=!context.nodeType&&context[0]||context;context=context.ownerDocument||context;if(args.length===1&&typeof first==="string"&&first.length<512&&context===document&&first.charAt(0)==="<"&&!rnocache.test(first)&&(jQuery.support.checkClone||!rchecked.test(first))&&(jQuery.support.html5Clone||!rnoshimcache.test(first))){cacheable=true;fragment=jQuery.fragments[first];cachehit=fragment!==undefined}if(!fragment){fragment=context.createDocumentFragment();jQuery.clean(args,context,fragment,scripts);if(cacheable){jQuery.fragments[first]=cachehit&&fragment}}return{fragment:fragment,cacheable:cacheable}};jQuery.fragments={};jQuery.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(name,original){jQuery.fn[name]=function(selector){var elems,i=0,ret=[],insert=jQuery(selector),l=insert.length,parent=this.length===1&&this[0].parentNode;if((parent==null||parent&&parent.nodeType===11&&parent.childNodes.length===1)&&l===1){insert[original](this[0]);return this}else{for(;i<l;i++){elems=(i>0?this.clone(true):this).get();jQuery(insert[i])[original](elems);ret=ret.concat(elems)}return this.pushStack(ret,name,insert.selector)}}});function getAll(elem){if(typeof elem.getElementsByTagName!=="undefined"){return elem.getElementsByTagName("*")}else if(typeof elem.querySelectorAll!=="undefined"){return elem.querySelectorAll("*")}else{return[]}}function fixDefaultChecked(elem){if(rcheckableType.test(elem.type)){elem.defaultChecked=elem.checked}}jQuery.extend({clone:function(elem,dataAndEvents,deepDataAndEvents){var srcElements,destElements,i,clone;if(jQuery.support.html5Clone||jQuery.isXMLDoc(elem)||!rnoshimcache.test("<"+elem.nodeName+">")){clone=elem.cloneNode(true)}else{fragmentDiv.innerHTML=elem.outerHTML;fragmentDiv.removeChild(clone=fragmentDiv.firstChild)}if((!jQuery.support.noCloneEvent||!jQuery.support.noCloneChecked)&&(elem.nodeType===1||elem.nodeType===11)&&!jQuery.isXMLDoc(elem)){cloneFixAttributes(elem,clone);srcElements=getAll(elem);destElements=getAll(clone);for(i=0;srcElements[i];++i){if(destElements[i]){cloneFixAttributes(srcElements[i],destElements[i])}}}if(dataAndEvents){cloneCopyEvent(elem,clone);if(deepDataAndEvents){srcElements=getAll(elem);destElements=getAll(clone);for(i=0;srcElements[i];++i){cloneCopyEvent(srcElements[i],destElements[i])}}}srcElements=destElements=null;return clone},clean:function(elems,context,fragment,scripts){var i,j,elem,tag,wrap,depth,div,hasBody,tbody,len,handleScript,jsTags,safe=context===document&&safeFragment,ret=[];if(!context||typeof context.createDocumentFragment==="undefined"){context=document}for(i=0;(elem=elems[i])!=null;i++){if(typeof elem==="number"){elem+=""}if(!elem){continue}if(typeof elem==="string"){if(!rhtml.test(elem)){elem=context.createTextNode(elem)}else{safe=safe||createSafeFragment(context);div=context.createElement("div");safe.appendChild(div);elem=elem.replace(rxhtmlTag,"<$1></$2>");tag=(rtagName.exec(elem)||["",""])[1].toLowerCase();wrap=wrapMap[tag]||wrapMap._default;depth=wrap[0];div.innerHTML=wrap[1]+elem+wrap[2];while(depth--){div=div.lastChild
4
+}if(!jQuery.support.tbody){hasBody=rtbody.test(elem);tbody=tag==="table"&&!hasBody?div.firstChild&&div.firstChild.childNodes:wrap[1]==="<table>"&&!hasBody?div.childNodes:[];for(j=tbody.length-1;j>=0;--j){if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length){tbody[j].parentNode.removeChild(tbody[j])}}}if(!jQuery.support.leadingWhitespace&&rleadingWhitespace.test(elem)){div.insertBefore(context.createTextNode(rleadingWhitespace.exec(elem)[0]),div.firstChild)}elem=div.childNodes;div.parentNode.removeChild(div)}}if(elem.nodeType){ret.push(elem)}else{jQuery.merge(ret,elem)}}if(div){elem=div=safe=null}if(!jQuery.support.appendChecked){for(i=0;(elem=ret[i])!=null;i++){if(jQuery.nodeName(elem,"input")){fixDefaultChecked(elem)}else if(typeof elem.getElementsByTagName!=="undefined"){jQuery.grep(elem.getElementsByTagName("input"),fixDefaultChecked)}}}if(fragment){handleScript=function(elem){if(!elem.type||rscriptType.test(elem.type)){return scripts?scripts.push(elem.parentNode?elem.parentNode.removeChild(elem):elem):fragment.appendChild(elem)}};for(i=0;(elem=ret[i])!=null;i++){if(!(jQuery.nodeName(elem,"script")&&handleScript(elem))){fragment.appendChild(elem);if(typeof elem.getElementsByTagName!=="undefined"){jsTags=jQuery.grep(jQuery.merge([],elem.getElementsByTagName("script")),handleScript);ret.splice.apply(ret,[i+1,0].concat(jsTags));i+=jsTags.length}}}}return ret},cleanData:function(elems,acceptData){var data,id,elem,type,i=0,internalKey=jQuery.expando,cache=jQuery.cache,deleteExpando=jQuery.support.deleteExpando,special=jQuery.event.special;for(;(elem=elems[i])!=null;i++){if(acceptData||jQuery.acceptData(elem)){id=elem[internalKey];data=id&&cache[id];if(data){if(data.events){for(type in data.events){if(special[type]){jQuery.event.remove(elem,type)}else{jQuery.removeEvent(elem,type,data.handle)}}}if(cache[id]){delete cache[id];if(deleteExpando){delete elem[internalKey]}else if(elem.removeAttribute){elem.removeAttribute(internalKey)}else{elem[internalKey]=null}jQuery.deletedIds.push(id)}}}}}});(function(){var matched,browser;jQuery.uaMatch=function(ua){ua=ua.toLowerCase();var match=/(chrome)[ \/]([\w.]+)/.exec(ua)||/(webkit)[ \/]([\w.]+)/.exec(ua)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua)||/(msie) ([\w.]+)/.exec(ua)||ua.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua)||[];return{browser:match[1]||"",version:match[2]||"0"}};matched=jQuery.uaMatch(navigator.userAgent);browser={};if(matched.browser){browser[matched.browser]=true;browser.version=matched.version}if(browser.chrome){browser.webkit=true}else if(browser.webkit){browser.safari=true}jQuery.browser=browser;jQuery.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}})();var curCSS,iframe,iframeDoc,ralpha=/alpha\([^)]*\)/i,ropacity=/opacity=([^)]*)/,rposition=/^(top|right|bottom|left)$/,rdisplayswap=/^(none|table(?!-c[ea]).+)/,rmargin=/^margin/,rnumsplit=new RegExp("^("+core_pnum+")(.*)$","i"),rnumnonpx=new RegExp("^("+core_pnum+")(?!px)[a-z%]+$","i"),rrelNum=new RegExp("^([-+])=("+core_pnum+")","i"),elemdisplay={BODY:"block"},cssShow={position:"absolute",visibility:"hidden",display:"block"},cssNormalTransform={letterSpacing:0,fontWeight:400},cssExpand=["Top","Right","Bottom","Left"],cssPrefixes=["Webkit","O","Moz","ms"],eventsToggle=jQuery.fn.toggle;function vendorPropName(style,name){if(name in style){return name}var capName=name.charAt(0).toUpperCase()+name.slice(1),origName=name,i=cssPrefixes.length;while(i--){name=cssPrefixes[i]+capName;if(name in style){return name}}return origName}function isHidden(elem,el){elem=el||elem;return jQuery.css(elem,"display")==="none"||!jQuery.contains(elem.ownerDocument,elem)}function showHide(elements,show){var elem,display,values=[],index=0,length=elements.length;for(;index<length;index++){elem=elements[index];if(!elem.style){continue}values[index]=jQuery._data(elem,"olddisplay");if(show){if(!values[index]&&elem.style.display==="none"){elem.style.display=""}if(elem.style.display===""&&isHidden(elem)){values[index]=jQuery._data(elem,"olddisplay",css_defaultDisplay(elem.nodeName))}}else{display=curCSS(elem,"display");if(!values[index]&&display!=="none"){jQuery._data(elem,"olddisplay",display)}}}for(index=0;index<length;index++){elem=elements[index];if(!elem.style){continue}if(!show||elem.style.display==="none"||elem.style.display===""){elem.style.display=show?values[index]||"":"none"}}return elements}jQuery.fn.extend({css:function(name,value){return jQuery.access(this,function(elem,name,value){return value!==undefined?jQuery.style(elem,name,value):jQuery.css(elem,name)},name,value,arguments.length>1)},show:function(){return showHide(this,true)},hide:function(){return showHide(this)},toggle:function(state,fn2){var bool=typeof state==="boolean";if(jQuery.isFunction(state)&&jQuery.isFunction(fn2)){return eventsToggle.apply(this,arguments)}return this.each(function(){if(bool?state:isHidden(this)){jQuery(this).show()}else{jQuery(this).hide()}})}});jQuery.extend({cssHooks:{opacity:{get:function(elem,computed){if(computed){var ret=curCSS(elem,"opacity");return ret===""?"1":ret}}}},cssNumber:{fillOpacity:true,fontWeight:true,lineHeight:true,opacity:true,orphans:true,widows:true,zIndex:true,zoom:true},cssProps:{"float":jQuery.support.cssFloat?"cssFloat":"styleFloat"},style:function(elem,name,value,extra){if(!elem||elem.nodeType===3||elem.nodeType===8||!elem.style){return}var ret,type,hooks,origName=jQuery.camelCase(name),style=elem.style;name=jQuery.cssProps[origName]||(jQuery.cssProps[origName]=vendorPropName(style,origName));hooks=jQuery.cssHooks[name]||jQuery.cssHooks[origName];if(value!==undefined){type=typeof value;if(type==="string"&&(ret=rrelNum.exec(value))){value=(ret[1]+1)*ret[2]+parseFloat(jQuery.css(elem,name));type="number"}if(value==null||type==="number"&&isNaN(value)){return}if(type==="number"&&!jQuery.cssNumber[origName]){value+="px"}if(!hooks||!("set"in hooks)||(value=hooks.set(elem,value,extra))!==undefined){try{style[name]=value}catch(e){}}}else{if(hooks&&"get"in hooks&&(ret=hooks.get(elem,false,extra))!==undefined){return ret}return style[name]}},css:function(elem,name,numeric,extra){var val,num,hooks,origName=jQuery.camelCase(name);name=jQuery.cssProps[origName]||(jQuery.cssProps[origName]=vendorPropName(elem.style,origName));hooks=jQuery.cssHooks[name]||jQuery.cssHooks[origName];if(hooks&&"get"in hooks){val=hooks.get(elem,true,extra)}if(val===undefined){val=curCSS(elem,name)}if(val==="normal"&&name in cssNormalTransform){val=cssNormalTransform[name]}if(numeric||extra!==undefined){num=parseFloat(val);return numeric||jQuery.isNumeric(num)?num||0:val}return val},swap:function(elem,options,callback){var ret,name,old={};for(name in options){old[name]=elem.style[name];elem.style[name]=options[name]}ret=callback.call(elem);for(name in options){elem.style[name]=old[name]}return ret}});if(window.getComputedStyle){curCSS=function(elem,name){var ret,width,minWidth,maxWidth,computed=window.getComputedStyle(elem,null),style=elem.style;if(computed){ret=computed.getPropertyValue(name)||computed[name];if(ret===""&&!jQuery.contains(elem.ownerDocument,elem)){ret=jQuery.style(elem,name)}if(rnumnonpx.test(ret)&&rmargin.test(name)){width=style.width;minWidth=style.minWidth;maxWidth=style.maxWidth;style.minWidth=style.maxWidth=style.width=ret;ret=computed.width;style.width=width;style.minWidth=minWidth;style.maxWidth=maxWidth}}return ret}}else if(document.documentElement.currentStyle){curCSS=function(elem,name){var left,rsLeft,ret=elem.currentStyle&&elem.currentStyle[name],style=elem.style;if(ret==null&&style&&style[name]){ret=style[name]}if(rnumnonpx.test(ret)&&!rposition.test(name)){left=style.left;rsLeft=elem.runtimeStyle&&elem.runtimeStyle.left;if(rsLeft){elem.runtimeStyle.left=elem.currentStyle.left}style.left=name==="fontSize"?"1em":ret;ret=style.pixelLeft+"px";style.left=left;if(rsLeft){elem.runtimeStyle.left=rsLeft}}return ret===""?"auto":ret}}function setPositiveNumber(elem,value,subtract){var matches=rnumsplit.exec(value);return matches?Math.max(0,matches[1]-(subtract||0))+(matches[2]||"px"):value}function augmentWidthOrHeight(elem,name,extra,isBorderBox){var i=extra===(isBorderBox?"border":"content")?4:name==="width"?1:0,val=0;for(;i<4;i+=2){if(extra==="margin"){val+=jQuery.css(elem,extra+cssExpand[i],true)}if(isBorderBox){if(extra==="content"){val-=parseFloat(curCSS(elem,"padding"+cssExpand[i]))||0}if(extra!=="margin"){val-=parseFloat(curCSS(elem,"border"+cssExpand[i]+"Width"))||0}}else{val+=parseFloat(curCSS(elem,"padding"+cssExpand[i]))||0;if(extra!=="padding"){val+=parseFloat(curCSS(elem,"border"+cssExpand[i]+"Width"))||0}}}return val}function getWidthOrHeight(elem,name,extra){var val=name==="width"?elem.offsetWidth:elem.offsetHeight,valueIsBorderBox=true,isBorderBox=jQuery.support.boxSizing&&jQuery.css(elem,"boxSizing")==="border-box";if(val<=0||val==null){val=curCSS(elem,name);if(val<0||val==null){val=elem.style[name]}if(rnumnonpx.test(val)){return val}valueIsBorderBox=isBorderBox&&(jQuery.support.boxSizingReliable||val===elem.style[name]);val=parseFloat(val)||0}return val+augmentWidthOrHeight(elem,name,extra||(isBorderBox?"border":"content"),valueIsBorderBox)+"px"}function css_defaultDisplay(nodeName){if(elemdisplay[nodeName]){return elemdisplay[nodeName]}var elem=jQuery("<"+nodeName+">").appendTo(document.body),display=elem.css("display");elem.remove();if(display==="none"||display===""){iframe=document.body.appendChild(iframe||jQuery.extend(document.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!iframeDoc||!iframe.createElement){iframeDoc=(iframe.contentWindow||iframe.contentDocument).document;iframeDoc.write("<!doctype html><html><body>");iframeDoc.close()}elem=iframeDoc.body.appendChild(iframeDoc.createElement(nodeName));display=curCSS(elem,"display");document.body.removeChild(iframe)}elemdisplay[nodeName]=display;return display}jQuery.each(["height","width"],function(i,name){jQuery.cssHooks[name]={get:function(elem,computed,extra){if(computed){if(elem.offsetWidth===0&&rdisplayswap.test(curCSS(elem,"display"))){return jQuery.swap(elem,cssShow,function(){return getWidthOrHeight(elem,name,extra)})}else{return getWidthOrHeight(elem,name,extra)}}},set:function(elem,value,extra){return setPositiveNumber(elem,value,extra?augmentWidthOrHeight(elem,name,extra,jQuery.support.boxSizing&&jQuery.css(elem,"boxSizing")==="border-box"):0)}}});if(!jQuery.support.opacity){jQuery.cssHooks.opacity={get:function(elem,computed){return ropacity.test((computed&&elem.currentStyle?elem.currentStyle.filter:elem.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":computed?"1":""},set:function(elem,value){var style=elem.style,currentStyle=elem.currentStyle,opacity=jQuery.isNumeric(value)?"alpha(opacity="+value*100+")":"",filter=currentStyle&&currentStyle.filter||style.filter||"";style.zoom=1;if(value>=1&&jQuery.trim(filter.replace(ralpha,""))===""&&style.removeAttribute){style.removeAttribute("filter");if(currentStyle&&!currentStyle.filter){return}}style.filter=ralpha.test(filter)?filter.replace(ralpha,opacity):filter+" "+opacity}}}jQuery(function(){if(!jQuery.support.reliableMarginRight){jQuery.cssHooks.marginRight={get:function(elem,computed){return jQuery.swap(elem,{display:"inline-block"},function(){if(computed){return curCSS(elem,"marginRight")}})}}}if(!jQuery.support.pixelPosition&&jQuery.fn.position){jQuery.each(["top","left"],function(i,prop){jQuery.cssHooks[prop]={get:function(elem,computed){if(computed){var ret=curCSS(elem,prop);return rnumnonpx.test(ret)?jQuery(elem).position()[prop]+"px":ret}}}})}});if(jQuery.expr&&jQuery.expr.filters){jQuery.expr.filters.hidden=function(elem){return elem.offsetWidth===0&&elem.offsetHeight===0||!jQuery.support.reliableHiddenOffsets&&(elem.style&&elem.style.display||curCSS(elem,"display"))==="none"};jQuery.expr.filters.visible=function(elem){return!jQuery.expr.filters.hidden(elem)}}jQuery.each({margin:"",padding:"",border:"Width"},function(prefix,suffix){jQuery.cssHooks[prefix+suffix]={expand:function(value){var i,parts=typeof value==="string"?value.split(" "):[value],expanded={};for(i=0;i<4;i++){expanded[prefix+cssExpand[i]+suffix]=parts[i]||parts[i-2]||parts[0]}return expanded}};if(!rmargin.test(prefix)){jQuery.cssHooks[prefix+suffix].set=setPositiveNumber}});var r20=/%20/g,rbracket=/\[\]$/,rCRLF=/\r?\n/g,rinput=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,rselectTextarea=/^(?:select|textarea)/i;jQuery.fn.extend({serialize:function(){return jQuery.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?jQuery.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||rselectTextarea.test(this.nodeName)||rinput.test(this.type))}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:jQuery.isArray(val)?jQuery.map(val,function(val,i){return{name:elem.name,value:val.replace(rCRLF,"\r\n")}}):{name:elem.name,value:val.replace(rCRLF,"\r\n")}}).get()}});jQuery.param=function(a,traditional){var prefix,s=[],add=function(key,value){value=jQuery.isFunction(value)?value():value==null?"":value;s[s.length]=encodeURIComponent(key)+"="+encodeURIComponent(value)};if(traditional===undefined){traditional=jQuery.ajaxSettings&&jQuery.ajaxSettings.traditional}if(jQuery.isArray(a)||a.jquery&&!jQuery.isPlainObject(a)){jQuery.each(a,function(){add(this.name,this.value)})}else{for(prefix in a){buildParams(prefix,a[prefix],traditional,add)}}return s.join("&").replace(r20,"+")};function buildParams(prefix,obj,traditional,add){var name;if(jQuery.isArray(obj)){jQuery.each(obj,function(i,v){if(traditional||rbracket.test(prefix)){add(prefix,v)}else{buildParams(prefix+"["+(typeof v==="object"?i:"")+"]",v,traditional,add)}})}else if(!traditional&&jQuery.type(obj)==="object"){for(name in obj){buildParams(prefix+"["+name+"]",obj[name],traditional,add)}}else{add(prefix,obj)}}var ajaxLocParts,ajaxLocation,rhash=/#.*$/,rheaders=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,rlocalProtocol=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,rnoContent=/^(?:GET|HEAD)$/,rprotocol=/^\/\//,rquery=/\?/,rscript=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,rts=/([?&])_=[^&]*/,rurl=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,_load=jQuery.fn.load,prefilters={},transports={},allTypes=["*/"]+["*"];try{ajaxLocation=location.href}catch(e){ajaxLocation=document.createElement("a");ajaxLocation.href="";ajaxLocation=ajaxLocation.href}ajaxLocParts=rurl.exec(ajaxLocation.toLowerCase())||[];function addToPrefiltersOrTransports(structure){return function(dataTypeExpression,func){if(typeof dataTypeExpression!=="string"){func=dataTypeExpression;dataTypeExpression="*"}var dataType,list,placeBefore,dataTypes=dataTypeExpression.toLowerCase().split(core_rspace),i=0,length=dataTypes.length;if(jQuery.isFunction(func)){for(;i<length;i++){dataType=dataTypes[i];placeBefore=/^\+/.test(dataType);if(placeBefore){dataType=dataType.substr(1)||"*"}list=structure[dataType]=structure[dataType]||[];list[placeBefore?"unshift":"push"](func)}}}}function inspectPrefiltersOrTransports(structure,options,originalOptions,jqXHR,dataType,inspected){dataType=dataType||options.dataTypes[0];inspected=inspected||{};inspected[dataType]=true;var selection,list=structure[dataType],i=0,length=list?list.length:0,executeOnly=structure===prefilters;for(;i<length&&(executeOnly||!selection);i++){selection=list[i](options,originalOptions,jqXHR);if(typeof selection==="string"){if(!executeOnly||inspected[selection]){selection=undefined}else{options.dataTypes.unshift(selection);selection=inspectPrefiltersOrTransports(structure,options,originalOptions,jqXHR,selection,inspected)}}}if((executeOnly||!selection)&&!inspected["*"]){selection=inspectPrefiltersOrTransports(structure,options,originalOptions,jqXHR,"*",inspected)}return selection}function ajaxExtend(target,src){var key,deep,flatOptions=jQuery.ajaxSettings.flatOptions||{};for(key in src){if(src[key]!==undefined){(flatOptions[key]?target:deep||(deep={}))[key]=src[key]}}if(deep){jQuery.extend(true,target,deep)}}jQuery.fn.load=function(url,params,callback){if(typeof url!=="string"&&_load){return _load.apply(this,arguments)}if(!this.length){return this}var selector,type,response,self=this,off=url.indexOf(" ");if(off>=0){selector=url.slice(off,url.length);url=url.slice(0,off)}if(jQuery.isFunction(params)){callback=params;params=undefined}else if(params&&typeof params==="object"){type="POST"}jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(jqXHR,status){if(callback){self.each(callback,response||[jqXHR.responseText,status,jqXHR])}}}).done(function(responseText){response=arguments;self.html(selector?jQuery("<div>").append(responseText.replace(rscript,"")).find(selector):responseText)});return this};jQuery.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(i,o){jQuery.fn[o]=function(f){return this.on(o,f)}});jQuery.each(["get","post"],function(i,method){jQuery[method]=function(url,data,callback,type){if(jQuery.isFunction(data)){type=type||callback;callback=data;data=undefined}return jQuery.ajax({type:method,url:url,data:data,success:callback,dataType:type})}});jQuery.extend({getScript:function(url,callback){return jQuery.get(url,undefined,callback,"script")},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json")},ajaxSetup:function(target,settings){if(settings){ajaxExtend(target,jQuery.ajaxSettings)}else{settings=target;target=jQuery.ajaxSettings}ajaxExtend(target,settings);return target},ajaxSettings:{url:ajaxLocation,isLocal:rlocalProtocol.test(ajaxLocParts[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":allTypes},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":window.String,"text html":true,"text json":jQuery.parseJSON,"text xml":jQuery.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:addToPrefiltersOrTransports(prefilters),ajaxTransport:addToPrefiltersOrTransports(transports),ajax:function(url,options){if(typeof url==="object"){options=url;url=undefined}options=options||{};var ifModifiedKey,responseHeadersString,responseHeaders,transport,timeoutTimer,parts,fireGlobals,i,s=jQuery.ajaxSetup({},options),callbackContext=s.context||s,globalEventContext=callbackContext!==s&&(callbackContext.nodeType||callbackContext instanceof jQuery)?jQuery(callbackContext):jQuery.event,deferred=jQuery.Deferred(),completeDeferred=jQuery.Callbacks("once memory"),statusCode=s.statusCode||{},requestHeaders={},requestHeadersNames={},state=0,strAbort="canceled",jqXHR={readyState:0,setRequestHeader:function(name,value){if(!state){var lname=name.toLowerCase();name=requestHeadersNames[lname]=requestHeadersNames[lname]||name;requestHeaders[name]=value}return this},getAllResponseHeaders:function(){return state===2?responseHeadersString:null},getResponseHeader:function(key){var match;if(state===2){if(!responseHeaders){responseHeaders={};while(match=rheaders.exec(responseHeadersString)){responseHeaders[match[1].toLowerCase()]=match[2]}}match=responseHeaders[key.toLowerCase()]}return match===undefined?null:match},overrideMimeType:function(type){if(!state){s.mimeType=type}return this},abort:function(statusText){statusText=statusText||strAbort;if(transport){transport.abort(statusText)}done(0,statusText);return this}};function done(status,nativeStatusText,responses,headers){var isSuccess,success,error,response,modified,statusText=nativeStatusText;if(state===2){return}state=2;if(timeoutTimer){clearTimeout(timeoutTimer)}transport=undefined;responseHeadersString=headers||"";jqXHR.readyState=status>0?4:0;if(responses){response=ajaxHandleResponses(s,jqXHR,responses)}if(status>=200&&status<300||status===304){if(s.ifModified){modified=jqXHR.getResponseHeader("Last-Modified");if(modified){jQuery.lastModified[ifModifiedKey]=modified}modified=jqXHR.getResponseHeader("Etag");if(modified){jQuery.etag[ifModifiedKey]=modified}}if(status===304){statusText="notmodified";isSuccess=true}else{isSuccess=ajaxConvert(s,response);statusText=isSuccess.state;success=isSuccess.data;error=isSuccess.error;isSuccess=!error}}else{error=statusText;if(!statusText||status){statusText="error";if(status<0){status=0}}}jqXHR.status=status;jqXHR.statusText=(nativeStatusText||statusText)+"";if(isSuccess){deferred.resolveWith(callbackContext,[success,statusText,jqXHR])}else{deferred.rejectWith(callbackContext,[jqXHR,statusText,error])}jqXHR.statusCode(statusCode);statusCode=undefined;if(fireGlobals){globalEventContext.trigger("ajax"+(isSuccess?"Success":"Error"),[jqXHR,s,isSuccess?success:error])}completeDeferred.fireWith(callbackContext,[jqXHR,statusText]);if(fireGlobals){globalEventContext.trigger("ajaxComplete",[jqXHR,s]);if(!--jQuery.active){jQuery.event.trigger("ajaxStop")}}}deferred.promise(jqXHR);jqXHR.success=jqXHR.done;jqXHR.error=jqXHR.fail;jqXHR.complete=completeDeferred.add;jqXHR.statusCode=function(map){if(map){var tmp;if(state<2){for(tmp in map){statusCode[tmp]=[statusCode[tmp],map[tmp]]}}else{tmp=map[jqXHR.status];jqXHR.always(tmp)}}return this};s.url=((url||s.url)+"").replace(rhash,"").replace(rprotocol,ajaxLocParts[1]+"//");s.dataTypes=jQuery.trim(s.dataType||"*").toLowerCase().split(core_rspace);if(s.crossDomain==null){parts=rurl.exec(s.url.toLowerCase());s.crossDomain=!!(parts&&(parts[1]!==ajaxLocParts[1]||parts[2]!==ajaxLocParts[2]||(parts[3]||(parts[1]==="http:"?80:443))!=(ajaxLocParts[3]||(ajaxLocParts[1]==="http:"?80:443))))}if(s.data&&s.processData&&typeof s.data!=="string"){s.data=jQuery.param(s.data,s.traditional)}inspectPrefiltersOrTransports(prefilters,s,options,jqXHR);if(state===2){return jqXHR}fireGlobals=s.global;s.type=s.type.toUpperCase();s.hasContent=!rnoContent.test(s.type);if(fireGlobals&&jQuery.active++===0){jQuery.event.trigger("ajaxStart")}if(!s.hasContent){if(s.data){s.url+=(rquery.test(s.url)?"&":"?")+s.data;delete s.data}ifModifiedKey=s.url;if(s.cache===false){var ts=jQuery.now(),ret=s.url.replace(rts,"$1_="+ts);s.url=ret+(ret===s.url?(rquery.test(s.url)?"&":"?")+"_="+ts:"")}}if(s.data&&s.hasContent&&s.contentType!==false||options.contentType){jqXHR.setRequestHeader("Content-Type",s.contentType)}if(s.ifModified){ifModifiedKey=ifModifiedKey||s.url;if(jQuery.lastModified[ifModifiedKey]){jqXHR.setRequestHeader("If-Modified-Since",jQuery.lastModified[ifModifiedKey])}if(jQuery.etag[ifModifiedKey]){jqXHR.setRequestHeader("If-None-Match",jQuery.etag[ifModifiedKey])}}jqXHR.setRequestHeader("Accept",s.dataTypes[0]&&s.accepts[s.dataTypes[0]]?s.accepts[s.dataTypes[0]]+(s.dataTypes[0]!=="*"?", "+allTypes+"; q=0.01":""):s.accepts["*"]);for(i in s.headers){jqXHR.setRequestHeader(i,s.headers[i])}if(s.beforeSend&&(s.beforeSend.call(callbackContext,jqXHR,s)===false||state===2)){return jqXHR.abort()}strAbort="abort";for(i in{success:1,error:1,complete:1}){jqXHR[i](s[i])}transport=inspectPrefiltersOrTransports(transports,s,options,jqXHR);if(!transport){done(-1,"No Transport")}else{jqXHR.readyState=1;if(fireGlobals){globalEventContext.trigger("ajaxSend",[jqXHR,s])}if(s.async&&s.timeout>0){timeoutTimer=setTimeout(function(){jqXHR.abort("timeout")},s.timeout)}try{state=1;transport.send(requestHeaders,done)}catch(e){if(state<2){done(-1,e)}else{throw e}}}return jqXHR},active:0,lastModified:{},etag:{}});function ajaxHandleResponses(s,jqXHR,responses){var ct,type,finalDataType,firstDataType,contents=s.contents,dataTypes=s.dataTypes,responseFields=s.responseFields;for(type in responseFields){if(type in responses){jqXHR[responseFields[type]]=responses[type]}}while(dataTypes[0]==="*"){dataTypes.shift();if(ct===undefined){ct=s.mimeType||jqXHR.getResponseHeader("content-type")}}if(ct){for(type in contents){if(contents[type]&&contents[type].test(ct)){dataTypes.unshift(type);break}}}if(dataTypes[0]in responses){finalDataType=dataTypes[0]}else{for(type in responses){if(!dataTypes[0]||s.converters[type+" "+dataTypes[0]]){finalDataType=type;break}if(!firstDataType){firstDataType=type}}finalDataType=finalDataType||firstDataType}if(finalDataType){if(finalDataType!==dataTypes[0]){dataTypes.unshift(finalDataType)}return responses[finalDataType]}}function ajaxConvert(s,response){var conv,conv2,current,tmp,dataTypes=s.dataTypes.slice(),prev=dataTypes[0],converters={},i=0;if(s.dataFilter){response=s.dataFilter(response,s.dataType)}if(dataTypes[1]){for(conv in s.converters){converters[conv.toLowerCase()]=s.converters[conv]}}for(;current=dataTypes[++i];){if(current!=="*"){if(prev!=="*"&&prev!==current){conv=converters[prev+" "+current]||converters["* "+current];if(!conv){for(conv2 in converters){tmp=conv2.split(" ");if(tmp[1]===current){conv=converters[prev+" "+tmp[0]]||converters["* "+tmp[0]];if(conv){if(conv===true){conv=converters[conv2]}else if(converters[conv2]!==true){current=tmp[0];dataTypes.splice(i--,0,current)}break}}}}if(conv!==true){if(conv&&s["throws"]){response=conv(response)}else{try{response=conv(response)}catch(e){return{state:"parsererror",error:conv?e:"No conversion from "+prev+" to "+current}}}}}prev=current}}return{state:"success",data:response}}var oldCallbacks=[],rquestion=/\?/,rjsonp=/(=)\?(?=&|$)|\?\?/,nonce=jQuery.now();jQuery.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var callback=oldCallbacks.pop()||jQuery.expando+"_"+nonce++;this[callback]=true;return callback}});jQuery.ajaxPrefilter("json jsonp",function(s,originalSettings,jqXHR){var callbackName,overwritten,responseContainer,data=s.data,url=s.url,hasCallback=s.jsonp!==false,replaceInUrl=hasCallback&&rjsonp.test(url),replaceInData=hasCallback&&!replaceInUrl&&typeof data==="string"&&!(s.contentType||"").indexOf("application/x-www-form-urlencoded")&&rjsonp.test(data);if(s.dataTypes[0]==="jsonp"||replaceInUrl||replaceInData){callbackName=s.jsonpCallback=jQuery.isFunction(s.jsonpCallback)?s.jsonpCallback():s.jsonpCallback;overwritten=window[callbackName];if(replaceInUrl){s.url=url.replace(rjsonp,"$1"+callbackName)}else if(replaceInData){s.data=data.replace(rjsonp,"$1"+callbackName)}else if(hasCallback){s.url+=(rquestion.test(url)?"&":"?")+s.jsonp+"="+callbackName}s.converters["script json"]=function(){if(!responseContainer){jQuery.error(callbackName+" was not called")}return responseContainer[0]};s.dataTypes[0]="json";window[callbackName]=function(){responseContainer=arguments};jqXHR.always(function(){window[callbackName]=overwritten;if(s[callbackName]){s.jsonpCallback=originalSettings.jsonpCallback;oldCallbacks.push(callbackName)}if(responseContainer&&jQuery.isFunction(overwritten)){overwritten(responseContainer[0])}responseContainer=overwritten=undefined});return"script"}});jQuery.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(text){jQuery.globalEval(text);return text}}});jQuery.ajaxPrefilter("script",function(s){if(s.cache===undefined){s.cache=false}if(s.crossDomain){s.type="GET";s.global=false}});jQuery.ajaxTransport("script",function(s){if(s.crossDomain){var script,head=document.head||document.getElementsByTagName("head")[0]||document.documentElement;return{send:function(_,callback){script=document.createElement("script");script.async="async";if(s.scriptCharset){script.charset=s.scriptCharset}script.src=s.url;script.onload=script.onreadystatechange=function(_,isAbort){if(isAbort||!script.readyState||/loaded|complete/.test(script.readyState)){script.onload=script.onreadystatechange=null;if(head&&script.parentNode){head.removeChild(script)}script=undefined;if(!isAbort){callback(200,"success")}}};head.insertBefore(script,head.firstChild)},abort:function(){if(script){script.onload(0,1)}}}}});var xhrCallbacks,xhrOnUnloadAbort=window.ActiveXObject?function(){for(var key in xhrCallbacks){xhrCallbacks[key](0,1)}}:false,xhrId=0;function createStandardXHR(){try{return new window.XMLHttpRequest}catch(e){}}function createActiveXHR(){try{return new window.ActiveXObject("Microsoft.XMLHTTP")}catch(e){}}jQuery.ajaxSettings.xhr=window.ActiveXObject?function(){return!this.isLocal&&createStandardXHR()||createActiveXHR()}:createStandardXHR;(function(xhr){jQuery.extend(jQuery.support,{ajax:!!xhr,cors:!!xhr&&"withCredentials"in xhr})})(jQuery.ajaxSettings.xhr());if(jQuery.support.ajax){jQuery.ajaxTransport(function(s){if(!s.crossDomain||jQuery.support.cors){var callback;return{send:function(headers,complete){var handle,i,xhr=s.xhr();if(s.username){xhr.open(s.type,s.url,s.async,s.username,s.password)}else{xhr.open(s.type,s.url,s.async)}if(s.xhrFields){for(i in s.xhrFields){xhr[i]=s.xhrFields[i]}}if(s.mimeType&&xhr.overrideMimeType){xhr.overrideMimeType(s.mimeType)}if(!s.crossDomain&&!headers["X-Requested-With"]){headers["X-Requested-With"]="XMLHttpRequest"}try{for(i in headers){xhr.setRequestHeader(i,headers[i])}}catch(_){}xhr.send(s.hasContent&&s.data||null);callback=function(_,isAbort){var status,statusText,responseHeaders,responses,xml;try{if(callback&&(isAbort||xhr.readyState===4)){callback=undefined;if(handle){xhr.onreadystatechange=jQuery.noop;if(xhrOnUnloadAbort){delete xhrCallbacks[handle]}}if(isAbort){if(xhr.readyState!==4){xhr.abort()}}else{status=xhr.status;responseHeaders=xhr.getAllResponseHeaders();responses={};xml=xhr.responseXML;if(xml&&xml.documentElement){responses.xml=xml}try{responses.text=xhr.responseText}catch(e){}try{statusText=xhr.statusText}catch(e){statusText=""}if(!status&&s.isLocal&&!s.crossDomain){status=responses.text?200:404}else if(status===1223){status=204}}}}catch(firefoxAccessException){if(!isAbort){complete(-1,firefoxAccessException)}}if(responses){complete(status,statusText,responses,responseHeaders)}};if(!s.async){callback()}else if(xhr.readyState===4){setTimeout(callback,0)}else{handle=++xhrId;if(xhrOnUnloadAbort){if(!xhrCallbacks){xhrCallbacks={};jQuery(window).unload(xhrOnUnloadAbort)}xhrCallbacks[handle]=callback}xhr.onreadystatechange=callback}},abort:function(){if(callback){callback(0,1)}}}}})}var fxNow,timerId,rfxtypes=/^(?:toggle|show|hide)$/,rfxnum=new RegExp("^(?:([-+])=|)("+core_pnum+")([a-z%]*)$","i"),rrun=/queueHooks$/,animationPrefilters=[defaultPrefilter],tweeners={"*":[function(prop,value){var end,unit,tween=this.createTween(prop,value),parts=rfxnum.exec(value),target=tween.cur(),start=+target||0,scale=1,maxIterations=20;if(parts){end=+parts[2];unit=parts[3]||(jQuery.cssNumber[prop]?"":"px");if(unit!=="px"&&start){start=jQuery.css(tween.elem,prop,true)||end||1;do{scale=scale||".5";start=start/scale;jQuery.style(tween.elem,prop,start+unit)}while(scale!==(scale=tween.cur()/target)&&scale!==1&&--maxIterations)}tween.unit=unit;tween.start=start;tween.end=parts[1]?start+(parts[1]+1)*end:end}return tween}]};function createFxNow(){setTimeout(function(){fxNow=undefined},0);return fxNow=jQuery.now()}function createTweens(animation,props){jQuery.each(props,function(prop,value){var collection=(tweeners[prop]||[]).concat(tweeners["*"]),index=0,length=collection.length;for(;index<length;index++){if(collection[index].call(animation,prop,value)){return}}})}function Animation(elem,properties,options){var result,index=0,tweenerIndex=0,length=animationPrefilters.length,deferred=jQuery.Deferred().always(function(){delete tick.elem}),tick=function(){var currentTime=fxNow||createFxNow(),remaining=Math.max(0,animation.startTime+animation.duration-currentTime),temp=remaining/animation.duration||0,percent=1-temp,index=0,length=animation.tweens.length;
5
+for(;index<length;index++){animation.tweens[index].run(percent)}deferred.notifyWith(elem,[animation,percent,remaining]);if(percent<1&&length){return remaining}else{deferred.resolveWith(elem,[animation]);return false}},animation=deferred.promise({elem:elem,props:jQuery.extend({},properties),opts:jQuery.extend(true,{specialEasing:{}},options),originalProperties:properties,originalOptions:options,startTime:fxNow||createFxNow(),duration:options.duration,tweens:[],createTween:function(prop,end,easing){var tween=jQuery.Tween(elem,animation.opts,prop,end,animation.opts.specialEasing[prop]||animation.opts.easing);animation.tweens.push(tween);return tween},stop:function(gotoEnd){var index=0,length=gotoEnd?animation.tweens.length:0;for(;index<length;index++){animation.tweens[index].run(1)}if(gotoEnd){deferred.resolveWith(elem,[animation,gotoEnd])}else{deferred.rejectWith(elem,[animation,gotoEnd])}return this}}),props=animation.props;propFilter(props,animation.opts.specialEasing);for(;index<length;index++){result=animationPrefilters[index].call(animation,elem,props,animation.opts);if(result){return result}}createTweens(animation,props);if(jQuery.isFunction(animation.opts.start)){animation.opts.start.call(elem,animation)}jQuery.fx.timer(jQuery.extend(tick,{anim:animation,queue:animation.opts.queue,elem:elem}));return animation.progress(animation.opts.progress).done(animation.opts.done,animation.opts.complete).fail(animation.opts.fail).always(animation.opts.always)}function propFilter(props,specialEasing){var index,name,easing,value,hooks;for(index in props){name=jQuery.camelCase(index);easing=specialEasing[name];value=props[index];if(jQuery.isArray(value)){easing=value[1];value=props[index]=value[0]}if(index!==name){props[name]=value;delete props[index]}hooks=jQuery.cssHooks[name];if(hooks&&"expand"in hooks){value=hooks.expand(value);delete props[name];for(index in value){if(!(index in props)){props[index]=value[index];specialEasing[index]=easing}}}else{specialEasing[name]=easing}}}jQuery.Animation=jQuery.extend(Animation,{tweener:function(props,callback){if(jQuery.isFunction(props)){callback=props;props=["*"]}else{props=props.split(" ")}var prop,index=0,length=props.length;for(;index<length;index++){prop=props[index];tweeners[prop]=tweeners[prop]||[];tweeners[prop].unshift(callback)}},prefilter:function(callback,prepend){if(prepend){animationPrefilters.unshift(callback)}else{animationPrefilters.push(callback)}}});function defaultPrefilter(elem,props,opts){var index,prop,value,length,dataShow,toggle,tween,hooks,oldfire,anim=this,style=elem.style,orig={},handled=[],hidden=elem.nodeType&&isHidden(elem);if(!opts.queue){hooks=jQuery._queueHooks(elem,"fx");if(hooks.unqueued==null){hooks.unqueued=0;oldfire=hooks.empty.fire;hooks.empty.fire=function(){if(!hooks.unqueued){oldfire()}}}hooks.unqueued++;anim.always(function(){anim.always(function(){hooks.unqueued--;if(!jQuery.queue(elem,"fx").length){hooks.empty.fire()}})})}if(elem.nodeType===1&&("height"in props||"width"in props)){opts.overflow=[style.overflow,style.overflowX,style.overflowY];if(jQuery.css(elem,"display")==="inline"&&jQuery.css(elem,"float")==="none"){if(!jQuery.support.inlineBlockNeedsLayout||css_defaultDisplay(elem.nodeName)==="inline"){style.display="inline-block"}else{style.zoom=1}}}if(opts.overflow){style.overflow="hidden";if(!jQuery.support.shrinkWrapBlocks){anim.done(function(){style.overflow=opts.overflow[0];style.overflowX=opts.overflow[1];style.overflowY=opts.overflow[2]})}}for(index in props){value=props[index];if(rfxtypes.exec(value)){delete props[index];toggle=toggle||value==="toggle";if(value===(hidden?"hide":"show")){continue}handled.push(index)}}length=handled.length;if(length){dataShow=jQuery._data(elem,"fxshow")||jQuery._data(elem,"fxshow",{});if("hidden"in dataShow){hidden=dataShow.hidden}if(toggle){dataShow.hidden=!hidden}if(hidden){jQuery(elem).show()}else{anim.done(function(){jQuery(elem).hide()})}anim.done(function(){var prop;jQuery.removeData(elem,"fxshow",true);for(prop in orig){jQuery.style(elem,prop,orig[prop])}});for(index=0;index<length;index++){prop=handled[index];tween=anim.createTween(prop,hidden?dataShow[prop]:0);orig[prop]=dataShow[prop]||jQuery.style(elem,prop);if(!(prop in dataShow)){dataShow[prop]=tween.start;if(hidden){tween.end=tween.start;tween.start=prop==="width"||prop==="height"?1:0}}}}}function Tween(elem,options,prop,end,easing){return new Tween.prototype.init(elem,options,prop,end,easing)}jQuery.Tween=Tween;Tween.prototype={constructor:Tween,init:function(elem,options,prop,end,easing,unit){this.elem=elem;this.prop=prop;this.easing=easing||"swing";this.options=options;this.start=this.now=this.cur();this.end=end;this.unit=unit||(jQuery.cssNumber[prop]?"":"px")},cur:function(){var hooks=Tween.propHooks[this.prop];return hooks&&hooks.get?hooks.get(this):Tween.propHooks._default.get(this)},run:function(percent){var eased,hooks=Tween.propHooks[this.prop];if(this.options.duration){this.pos=eased=jQuery.easing[this.easing](percent,this.options.duration*percent,0,1,this.options.duration)}else{this.pos=eased=percent}this.now=(this.end-this.start)*eased+this.start;if(this.options.step){this.options.step.call(this.elem,this.now,this)}if(hooks&&hooks.set){hooks.set(this)}else{Tween.propHooks._default.set(this)}return this}};Tween.prototype.init.prototype=Tween.prototype;Tween.propHooks={_default:{get:function(tween){var result;if(tween.elem[tween.prop]!=null&&(!tween.elem.style||tween.elem.style[tween.prop]==null)){return tween.elem[tween.prop]}result=jQuery.css(tween.elem,tween.prop,false,"");return!result||result==="auto"?0:result},set:function(tween){if(jQuery.fx.step[tween.prop]){jQuery.fx.step[tween.prop](tween)}else if(tween.elem.style&&(tween.elem.style[jQuery.cssProps[tween.prop]]!=null||jQuery.cssHooks[tween.prop])){jQuery.style(tween.elem,tween.prop,tween.now+tween.unit)}else{tween.elem[tween.prop]=tween.now}}}};Tween.propHooks.scrollTop=Tween.propHooks.scrollLeft={set:function(tween){if(tween.elem.nodeType&&tween.elem.parentNode){tween.elem[tween.prop]=tween.now}}};jQuery.each(["toggle","show","hide"],function(i,name){var cssFn=jQuery.fn[name];jQuery.fn[name]=function(speed,easing,callback){return speed==null||typeof speed==="boolean"||!i&&jQuery.isFunction(speed)&&jQuery.isFunction(easing)?cssFn.apply(this,arguments):this.animate(genFx(name,true),speed,easing,callback)}});jQuery.fn.extend({fadeTo:function(speed,to,easing,callback){return this.filter(isHidden).css("opacity",0).show().end().animate({opacity:to},speed,easing,callback)},animate:function(prop,speed,easing,callback){var empty=jQuery.isEmptyObject(prop),optall=jQuery.speed(speed,easing,callback),doAnimation=function(){var anim=Animation(this,jQuery.extend({},prop),optall);if(empty){anim.stop(true)}};return empty||optall.queue===false?this.each(doAnimation):this.queue(optall.queue,doAnimation)},stop:function(type,clearQueue,gotoEnd){var stopQueue=function(hooks){var stop=hooks.stop;delete hooks.stop;stop(gotoEnd)};if(typeof type!=="string"){gotoEnd=clearQueue;clearQueue=type;type=undefined}if(clearQueue&&type!==false){this.queue(type||"fx",[])}return this.each(function(){var dequeue=true,index=type!=null&&type+"queueHooks",timers=jQuery.timers,data=jQuery._data(this);if(index){if(data[index]&&data[index].stop){stopQueue(data[index])}}else{for(index in data){if(data[index]&&data[index].stop&&rrun.test(index)){stopQueue(data[index])}}}for(index=timers.length;index--;){if(timers[index].elem===this&&(type==null||timers[index].queue===type)){timers[index].anim.stop(gotoEnd);dequeue=false;timers.splice(index,1)}}if(dequeue||!gotoEnd){jQuery.dequeue(this,type)}})}});function genFx(type,includeWidth){var which,attrs={height:type},i=0;includeWidth=includeWidth?1:0;for(;i<4;i+=2-includeWidth){which=cssExpand[i];attrs["margin"+which]=attrs["padding"+which]=type}if(includeWidth){attrs.opacity=attrs.width=type}return attrs}jQuery.each({slideDown:genFx("show"),slideUp:genFx("hide"),slideToggle:genFx("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(name,props){jQuery.fn[name]=function(speed,easing,callback){return this.animate(props,speed,easing,callback)}});jQuery.speed=function(speed,easing,fn){var opt=speed&&typeof speed==="object"?jQuery.extend({},speed):{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&!jQuery.isFunction(easing)&&easing};opt.duration=jQuery.fx.off?0:typeof opt.duration==="number"?opt.duration:opt.duration in jQuery.fx.speeds?jQuery.fx.speeds[opt.duration]:jQuery.fx.speeds._default;if(opt.queue==null||opt.queue===true){opt.queue="fx"}opt.old=opt.complete;opt.complete=function(){if(jQuery.isFunction(opt.old)){opt.old.call(this)}if(opt.queue){jQuery.dequeue(this,opt.queue)}};return opt};jQuery.easing={linear:function(p){return p},swing:function(p){return.5-Math.cos(p*Math.PI)/2}};jQuery.timers=[];jQuery.fx=Tween.prototype.init;jQuery.fx.tick=function(){var timer,timers=jQuery.timers,i=0;fxNow=jQuery.now();for(;i<timers.length;i++){timer=timers[i];if(!timer()&&timers[i]===timer){timers.splice(i--,1)}}if(!timers.length){jQuery.fx.stop()}fxNow=undefined};jQuery.fx.timer=function(timer){if(timer()&&jQuery.timers.push(timer)&&!timerId){timerId=setInterval(jQuery.fx.tick,jQuery.fx.interval)}};jQuery.fx.interval=13;jQuery.fx.stop=function(){clearInterval(timerId);timerId=null};jQuery.fx.speeds={slow:600,fast:200,_default:400};jQuery.fx.step={};if(jQuery.expr&&jQuery.expr.filters){jQuery.expr.filters.animated=function(elem){return jQuery.grep(jQuery.timers,function(fn){return elem===fn.elem}).length}}var rroot=/^(?:body|html)$/i;jQuery.fn.offset=function(options){if(arguments.length){return options===undefined?this:this.each(function(i){jQuery.offset.setOffset(this,options,i)})}var docElem,body,win,clientTop,clientLeft,scrollTop,scrollLeft,box={top:0,left:0},elem=this[0],doc=elem&&elem.ownerDocument;if(!doc){return}if((body=doc.body)===elem){return jQuery.offset.bodyOffset(elem)}docElem=doc.documentElement;if(!jQuery.contains(docElem,elem)){return box}if(typeof elem.getBoundingClientRect!=="undefined"){box=elem.getBoundingClientRect()}win=getWindow(doc);clientTop=docElem.clientTop||body.clientTop||0;clientLeft=docElem.clientLeft||body.clientLeft||0;scrollTop=win.pageYOffset||docElem.scrollTop;scrollLeft=win.pageXOffset||docElem.scrollLeft;return{top:box.top+scrollTop-clientTop,left:box.left+scrollLeft-clientLeft}};jQuery.offset={bodyOffset:function(body){var top=body.offsetTop,left=body.offsetLeft;if(jQuery.support.doesNotIncludeMarginInBodyOffset){top+=parseFloat(jQuery.css(body,"marginTop"))||0;left+=parseFloat(jQuery.css(body,"marginLeft"))||0}return{top:top,left:left}},setOffset:function(elem,options,i){var position=jQuery.css(elem,"position");if(position==="static"){elem.style.position="relative"}var curElem=jQuery(elem),curOffset=curElem.offset(),curCSSTop=jQuery.css(elem,"top"),curCSSLeft=jQuery.css(elem,"left"),calculatePosition=(position==="absolute"||position==="fixed")&&jQuery.inArray("auto",[curCSSTop,curCSSLeft])>-1,props={},curPosition={},curTop,curLeft;if(calculatePosition){curPosition=curElem.position();curTop=curPosition.top;curLeft=curPosition.left}else{curTop=parseFloat(curCSSTop)||0;curLeft=parseFloat(curCSSLeft)||0}if(jQuery.isFunction(options)){options=options.call(elem,i,curOffset)}if(options.top!=null){props.top=options.top-curOffset.top+curTop}if(options.left!=null){props.left=options.left-curOffset.left+curLeft}if("using"in options){options.using.call(elem,props)}else{curElem.css(props)}}};jQuery.fn.extend({position:function(){if(!this[0]){return}var elem=this[0],offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=rroot.test(offsetParent[0].nodeName)?{top:0,left:0}:offsetParent.offset();offset.top-=parseFloat(jQuery.css(elem,"marginTop"))||0;offset.left-=parseFloat(jQuery.css(elem,"marginLeft"))||0;parentOffset.top+=parseFloat(jQuery.css(offsetParent[0],"borderTopWidth"))||0;parentOffset.left+=parseFloat(jQuery.css(offsetParent[0],"borderLeftWidth"))||0;return{top:offset.top-parentOffset.top,left:offset.left-parentOffset.left}},offsetParent:function(){return this.map(function(){var offsetParent=this.offsetParent||document.body;while(offsetParent&&(!rroot.test(offsetParent.nodeName)&&jQuery.css(offsetParent,"position")==="static")){offsetParent=offsetParent.offsetParent}return offsetParent||document.body})}});jQuery.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(method,prop){var top=/Y/.test(prop);jQuery.fn[method]=function(val){return jQuery.access(this,function(elem,method,val){var win=getWindow(elem);if(val===undefined){return win?prop in win?win[prop]:win.document.documentElement[method]:elem[method]}if(win){win.scrollTo(!top?val:jQuery(win).scrollLeft(),top?val:jQuery(win).scrollTop())}else{elem[method]=val}},method,val,arguments.length,null)}});function getWindow(elem){return jQuery.isWindow(elem)?elem:elem.nodeType===9?elem.defaultView||elem.parentWindow:false}jQuery.each({Height:"height",Width:"width"},function(name,type){jQuery.each({padding:"inner"+name,content:type,"":"outer"+name},function(defaultExtra,funcName){jQuery.fn[funcName]=function(margin,value){var chainable=arguments.length&&(defaultExtra||typeof margin!=="boolean"),extra=defaultExtra||(margin===true||value===true?"margin":"border");return jQuery.access(this,function(elem,type,value){var doc;if(jQuery.isWindow(elem)){return elem.document.documentElement["client"+name]}if(elem.nodeType===9){doc=elem.documentElement;return Math.max(elem.body["scroll"+name],doc["scroll"+name],elem.body["offset"+name],doc["offset"+name],doc["client"+name])}return value===undefined?jQuery.css(elem,type,value,extra):jQuery.style(elem,type,value,extra)},type,chainable?margin:undefined,chainable,null)}})});window.jQuery=window.$=jQuery;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return jQuery})}})(window);
0 6
\ No newline at end of file
... ...
@@ -209,6 +209,36 @@ refresh_group_categories=function(group) {
209 209
   }
210 210
   ul.html(html);
211 211
   $('#view-group-categories ul li').bind('click',on_categories_group_cat_click);
212
+  
213
+  $('#cats-chart').css('width',$(window).width()*0.9+'px');
214
+  
215
+  $.plot($('#cats-chart'),group.getCategoriesStats(),{
216
+    'grid': {
217
+        'hoverable': true
218
+    }, 
219
+    'legend': {
220
+        'show': true,
221
+    },
222
+    'series': { 
223
+        'pie': {
224
+            'show': true,
225
+            'innerRadius': 0.5,
226
+            'radius': 1,
227
+            'label': {
228
+                'show': true,
229
+                'radius': 3/4,
230
+                'background': {
231
+                    'opacity': 0.5,
232
+                    'color': '#000000',
233
+                },
234
+                'formatter': function (label, series) {
235
+return '<div class="cats-chart-label">' + label + '<br/>' +   
236
+                            Math.round(series.percent) + '%</div>';
237
+                }
238
+            }
239
+        }
240
+    }
241
+});
212 242
 }
213 243
 
214 244
 on_categories_group_cat_click=function(e) {
... ...
@@ -404,6 +404,26 @@ function Group(uuid,name,data) {
404 404
 	return ret;
405 405
   }
406 406
   
407
+  this.getCategoriesStats=function() {
408
+    var cats={};
409
+    for (uuid in this.contributions) {
410
+      if (jQuery.type(cats[this.contributions[uuid].category])=='undefined') {
411
+        cats[this.contributions[uuid].category]=0;
412
+      }
413
+      cats[this.contributions[uuid].category]+=this.contributions[uuid].cost;
414
+    }
415
+    var data=[];
416
+    for (cid in cats) {
417
+      if (jQuery.type(this.categories[cid])!='undefined') {
418
+        data.push({
419
+          'label': this.categories[cid].name,
420
+          'data': cats[cid]
421
+        });
422
+      }
423
+    }
424
+    return data;
425
+  }
426
+
407 427
   /*
408 428
    * Balance
409 429
    */
... ...
@@ -136,6 +136,21 @@ span.cat-color {
136 136
 .nav a, #mybalances a, #add_category span {
137 137
   cursor: pointer;
138 138
 }
139
+
140
+#cats-chart {
141
+  width: 350px;
142
+  height: 350px;
143
+  margin-top: 1em;
144
+}
145
+
146
+.cats-chart-label {
147
+  color: #fff;
148
+  background-color: #000;
149
+  padding: 2px;
150
+  border-radius: 3px;
151
+  opacity: 0.6;
152
+  text-align: center;
153
+}
139 154
 </style>
140 155
   <body>
141 156
     <div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
... ...
@@ -312,8 +327,9 @@ span.cat-color {
312 327
   </table>
313 328
 </div>
314 329
 
315
-<div id='view-group-categories' class='part row'>
330
+<div id='view-group-categories' class='part'>
316 331
   <h1>Catégories <button type="button" class="btn btn-default go-back-group"><span class="glyphicon glyphicon-arrow-left"> Retour</span></button></h1>
332
+  <div class='row'>
317 333
     <div class='col-xs-6'>
318 334
       <ul>
319 335
       </ul>
... ...
@@ -323,6 +339,8 @@ span.cat-color {
323 339
       </div>
324 340
     </div>
325 341
   </div>
342
+  <div id='cats-chart'></div>
343
+</div>
326 344
 
327 345
 <div class="modal fade" id="add_group_modal" tabindex="-1" role="dialog" aria-labelledby="addGroupModal" aria-hidden="true">
328 346
   <div class="modal-dialog">
... ...
@@ -641,6 +659,10 @@ span.cat-color {
641 659
   <script src="inc/lib/pickadate/picker.date.js"></script>
642 660
   <script src="inc/lib/pickadate/legacy.js"></script>
643 661
   <script src="inc/lib/typeahead.bundle.js"></script>
662
+  <!-- Flot -->
663
+  <script src="inc/lib/flot-0.8.3/jquery.flot.js"></script>
664
+  <script src="inc/lib/flot-0.8.3/jquery.flot.pie.js"></script>
665
+  
644 666
   <script src="inc/lib/uuid.js"></script>
645 667
   <script src="inc/myco_objects.js"></script>
646 668
   <script src="inc/myco_confirm.js"></script>
647 669