pushnote 0.0.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rspec +3 -0
  4. data/README.md +11 -30
  5. data/Rakefile +20 -0
  6. data/bin/pushnote +20 -2
  7. data/config.codekit +1005 -0
  8. data/config.ru +2 -0
  9. data/config/database.yml +17 -0
  10. data/db/migrate/20150131202537_create_notes_table.rb +9 -0
  11. data/db/schema.rb +23 -0
  12. data/lib/pushnote.rb +0 -3
  13. data/lib/pushnote/adapters.rb +1 -0
  14. data/lib/pushnote/adapters/base.rb +7 -0
  15. data/lib/pushnote/adapters/local.rb +17 -0
  16. data/lib/pushnote/app.rb +50 -0
  17. data/lib/pushnote/models/note.rb +4 -0
  18. data/lib/pushnote/public/css/foundation.css +6139 -0
  19. data/lib/pushnote/public/css/foundation.min.css +1 -0
  20. data/lib/pushnote/public/css/normalize.css +427 -0
  21. data/lib/pushnote/public/humans.txt +8 -0
  22. data/lib/pushnote/public/img/.gitkeep +1 -0
  23. data/lib/pushnote/public/index.html +166 -0
  24. data/lib/pushnote/public/js/foundation.min.js +5960 -0
  25. data/lib/pushnote/public/js/foundation/foundation.abide.js +318 -0
  26. data/lib/pushnote/public/js/foundation/foundation.accordion.js +67 -0
  27. data/lib/pushnote/public/js/foundation/foundation.alert.js +43 -0
  28. data/lib/pushnote/public/js/foundation/foundation.clearing.js +558 -0
  29. data/lib/pushnote/public/js/foundation/foundation.dropdown.js +439 -0
  30. data/lib/pushnote/public/js/foundation/foundation.equalizer.js +73 -0
  31. data/lib/pushnote/public/js/foundation/foundation.interchange.js +348 -0
  32. data/lib/pushnote/public/js/foundation/foundation.joyride.js +924 -0
  33. data/lib/pushnote/public/js/foundation/foundation.js +690 -0
  34. data/lib/pushnote/public/js/foundation/foundation.magellan.js +198 -0
  35. data/lib/pushnote/public/js/foundation/foundation.offcanvas.js +152 -0
  36. data/lib/pushnote/public/js/foundation/foundation.orbit.js +472 -0
  37. data/lib/pushnote/public/js/foundation/foundation.reveal.js +449 -0
  38. data/lib/pushnote/public/js/foundation/foundation.slider.js +267 -0
  39. data/lib/pushnote/public/js/foundation/foundation.tab.js +217 -0
  40. data/lib/pushnote/public/js/foundation/foundation.tooltip.js +300 -0
  41. data/lib/pushnote/public/js/foundation/foundation.topbar.js +445 -0
  42. data/lib/pushnote/public/js/vendor/fastclick.js +9 -0
  43. data/lib/pushnote/public/js/vendor/jquery.cookie.js +8 -0
  44. data/lib/pushnote/public/js/vendor/jquery.js +26 -0
  45. data/lib/pushnote/public/js/vendor/modernizr.js +8 -0
  46. data/lib/pushnote/public/js/vendor/placeholder.js +2 -0
  47. data/lib/pushnote/public/robots.txt +4 -0
  48. data/lib/pushnote/version.rb +1 -1
  49. data/lib/pushnote/views/index.erb +15 -0
  50. data/lib/pushnote/views/layout.erb +48 -0
  51. data/lib/pushnote/views/show.erb +8 -0
  52. data/pushnote.gemspec +15 -5
  53. data/spec/lib/controllers/notes_spec.rb +21 -0
  54. data/spec/spec_helper.rb +16 -0
  55. metadata +193 -9
  56. data/.pushnote.yml +0 -1
  57. data/lib/pushnote/cli.rb +0 -40
  58. data/lib/pushnote/configuration.rb +0 -12
  59. data/lib/pushnote/note.rb +0 -36
@@ -0,0 +1,217 @@
1
+ ;(function ($, window, document, undefined) {
2
+ 'use strict';
3
+
4
+ Foundation.libs.tab = {
5
+ name : 'tab',
6
+
7
+ version : '5.5.0',
8
+
9
+ settings : {
10
+ active_class: 'active',
11
+ callback : function () {},
12
+ deep_linking: false,
13
+ scroll_to_content: true,
14
+ is_hover: false
15
+ },
16
+
17
+ default_tab_hashes: [],
18
+
19
+ init : function (scope, method, options) {
20
+ var self = this,
21
+ S = this.S;
22
+
23
+ this.bindings(method, options);
24
+ this.handle_location_hash_change();
25
+
26
+ // Store the default active tabs which will be referenced when the
27
+ // location hash is absent, as in the case of navigating the tabs and
28
+ // returning to the first viewing via the browser Back button.
29
+ S('[' + this.attr_name() + '] > .active > a', this.scope).each(function () {
30
+ self.default_tab_hashes.push(this.hash);
31
+ });
32
+ },
33
+
34
+ events : function () {
35
+ var self = this,
36
+ S = this.S;
37
+
38
+ var usual_tab_behavior = function (e) {
39
+ var settings = S(this).closest('[' + self.attr_name() +']').data(self.attr_name(true) + '-init');
40
+ if (!settings.is_hover || Modernizr.touch) {
41
+ e.preventDefault();
42
+ e.stopPropagation();
43
+ self.toggle_active_tab(S(this).parent());
44
+ }
45
+ };
46
+
47
+ S(this.scope)
48
+ .off('.tab')
49
+ // Click event: tab title
50
+ .on('focus.fndtn.tab', '[' + this.attr_name() + '] > * > a', usual_tab_behavior )
51
+ .on('click.fndtn.tab', '[' + this.attr_name() + '] > * > a', usual_tab_behavior )
52
+ // Hover event: tab title
53
+ .on('mouseenter.fndtn.tab', '[' + this.attr_name() + '] > * > a', function (e) {
54
+ var settings = S(this).closest('[' + self.attr_name() +']').data(self.attr_name(true) + '-init');
55
+ if (settings.is_hover) self.toggle_active_tab(S(this).parent());
56
+ });
57
+
58
+ // Location hash change event
59
+ S(window).on('hashchange.fndtn.tab', function (e) {
60
+ e.preventDefault();
61
+ self.handle_location_hash_change();
62
+ });
63
+ },
64
+
65
+ handle_location_hash_change : function () {
66
+
67
+ var self = this,
68
+ S = this.S;
69
+
70
+ S('[' + this.attr_name() + ']', this.scope).each(function () {
71
+ var settings = S(this).data(self.attr_name(true) + '-init');
72
+ if (settings.deep_linking) {
73
+ // Match the location hash to a label
74
+ var hash;
75
+ if (settings.scroll_to_content) {
76
+ hash = self.scope.location.hash;
77
+ } else {
78
+ // prefix the hash to prevent anchor scrolling
79
+ hash = self.scope.location.hash.replace('fndtn-', '');
80
+ }
81
+ if (hash != '') {
82
+ // Check whether the location hash references a tab content div or
83
+ // another element on the page (inside or outside the tab content div)
84
+ var hash_element = S(hash);
85
+ if (hash_element.hasClass('content') && hash_element.parent().hasClass('tabs-content')) {
86
+ // Tab content div
87
+ self.toggle_active_tab($('[' + self.attr_name() + '] > * > a[href=' + hash + ']').parent());
88
+ } else {
89
+ // Not the tab content div. If inside the tab content, find the
90
+ // containing tab and toggle it as active.
91
+ var hash_tab_container_id = hash_element.closest('.content').attr('id');
92
+ if (hash_tab_container_id != undefined) {
93
+ self.toggle_active_tab($('[' + self.attr_name() + '] > * > a[href=#' + hash_tab_container_id + ']').parent(), hash);
94
+ }
95
+ }
96
+ } else {
97
+ // Reference the default tab hashes which were initialized in the init function
98
+ for (var ind = 0; ind < self.default_tab_hashes.length; ind++) {
99
+ self.toggle_active_tab($('[' + self.attr_name() + '] > * > a[href=' + self.default_tab_hashes[ind] + ']').parent());
100
+ }
101
+ }
102
+ }
103
+ });
104
+ },
105
+
106
+ toggle_active_tab: function (tab, location_hash) {
107
+ var S = this.S,
108
+ tabs = tab.closest('[' + this.attr_name() + ']'),
109
+ tab_link = tab.find('a'),
110
+ anchor = tab.children('a').first(),
111
+ target_hash = '#' + anchor.attr('href').split('#')[1],
112
+ target = S(target_hash),
113
+ siblings = tab.siblings(),
114
+ settings = tabs.data(this.attr_name(true) + '-init'),
115
+ interpret_keyup_action = function(e) {
116
+ // Light modification of Heydon Pickering's Practical ARIA Examples: http://heydonworks.com/practical_aria_examples/js/a11y.js
117
+
118
+ // define current, previous and next (possible) tabs
119
+
120
+ var $original = $(this);
121
+ var $prev = $(this).parents('li').prev().children('[role="tab"]');
122
+ var $next = $(this).parents('li').next().children('[role="tab"]');
123
+ var $target;
124
+
125
+ // find the direction (prev or next)
126
+
127
+ switch (e.keyCode) {
128
+ case 37:
129
+ $target = $prev;
130
+ break;
131
+ case 39:
132
+ $target = $next;
133
+ break;
134
+ default:
135
+ $target = false
136
+ break;
137
+ }
138
+
139
+ if ($target.length) {
140
+ $original.attr({
141
+ 'tabindex' : '-1',
142
+ 'aria-selected' : null
143
+ });
144
+ $target.attr({
145
+ 'tabindex' : '0',
146
+ 'aria-selected' : true
147
+ }).focus();
148
+ }
149
+
150
+ // Hide panels
151
+
152
+ $('[role="tabpanel"]')
153
+ .attr('aria-hidden', 'true');
154
+
155
+ // Show panel which corresponds to target
156
+
157
+ $('#' + $(document.activeElement).attr('href').substring(1))
158
+ .attr('aria-hidden', null);
159
+
160
+ };
161
+
162
+ // allow usage of data-tab-content attribute instead of href
163
+ if (S(this).data(this.data_attr('tab-content'))) {
164
+ target_hash = '#' + S(this).data(this.data_attr('tab-content')).split('#')[1];
165
+ target = S(target_hash);
166
+ }
167
+
168
+ if (settings.deep_linking) {
169
+
170
+ if (settings.scroll_to_content) {
171
+ // retain current hash to scroll to content
172
+ window.location.hash = location_hash || target_hash;
173
+ if (location_hash == undefined || location_hash == target_hash) {
174
+ tab.parent()[0].scrollIntoView();
175
+ } else {
176
+ S(target_hash)[0].scrollIntoView();
177
+ }
178
+ } else {
179
+ // prefix the hashes so that the browser doesn't scroll down
180
+ if (location_hash != undefined) {
181
+ window.location.hash = 'fndtn-' + location_hash.replace('#', '');
182
+ } else {
183
+ window.location.hash = 'fndtn-' + target_hash.replace('#', '');
184
+ }
185
+ }
186
+ }
187
+
188
+ // WARNING: The activation and deactivation of the tab content must
189
+ // occur after the deep linking in order to properly refresh the browser
190
+ // window (notably in Chrome).
191
+ // Clean up multiple attr instances to done once
192
+ tab.addClass(settings.active_class).triggerHandler('opened');
193
+ tab_link.attr({'aria-selected': 'true', tabindex: 0});
194
+ siblings.removeClass(settings.active_class)
195
+ siblings.find('a').attr({'aria-selected': 'false', tabindex: -1});
196
+ target.siblings().removeClass(settings.active_class).attr({'aria-hidden': 'true', tabindex: -1});
197
+ target.addClass(settings.active_class).attr('aria-hidden', 'false').removeAttr('tabindex');
198
+ settings.callback(tab);
199
+ target.triggerHandler('toggled', [tab]);
200
+ tabs.triggerHandler('toggled', [target]);
201
+
202
+ tab_link.off('keydown').on('keydown', interpret_keyup_action );
203
+ },
204
+
205
+ data_attr: function (str) {
206
+ if (this.namespace.length > 0) {
207
+ return this.namespace + '-' + str;
208
+ }
209
+
210
+ return str;
211
+ },
212
+
213
+ off : function () {},
214
+
215
+ reflow : function () {}
216
+ };
217
+ }(jQuery, window, window.document));
@@ -0,0 +1,300 @@
1
+ ;(function ($, window, document, undefined) {
2
+ 'use strict';
3
+
4
+ Foundation.libs.tooltip = {
5
+ name : 'tooltip',
6
+
7
+ version : '5.5.0',
8
+
9
+ settings : {
10
+ additional_inheritable_classes : [],
11
+ tooltip_class : '.tooltip',
12
+ append_to: 'body',
13
+ touch_close_text: 'Tap To Close',
14
+ disable_for_touch: false,
15
+ hover_delay: 200,
16
+ show_on : 'all',
17
+ tip_template : function (selector, content) {
18
+ return '<span data-selector="' + selector + '" id="' + selector + '" class="'
19
+ + Foundation.libs.tooltip.settings.tooltip_class.substring(1)
20
+ + '" role="tooltip">' + content + '<span class="nub"></span></span>';
21
+ }
22
+ },
23
+
24
+ cache : {},
25
+
26
+ init : function (scope, method, options) {
27
+ Foundation.inherit(this, 'random_str');
28
+ this.bindings(method, options);
29
+ },
30
+
31
+ should_show: function (target, tip) {
32
+ var settings = $.extend({}, this.settings, this.data_options(target));
33
+
34
+ if (settings.show_on === 'all') {
35
+ return true;
36
+ } else if (this.small() && settings.show_on === 'small') {
37
+ return true;
38
+ } else if (this.medium() && settings.show_on === 'medium') {
39
+ return true;
40
+ } else if (this.large() && settings.show_on === 'large') {
41
+ return true;
42
+ }
43
+ return false;
44
+ },
45
+
46
+ medium : function () {
47
+ return matchMedia(Foundation.media_queries['medium']).matches;
48
+ },
49
+
50
+ large : function () {
51
+ return matchMedia(Foundation.media_queries['large']).matches;
52
+ },
53
+
54
+ events : function (instance) {
55
+ var self = this,
56
+ S = self.S;
57
+
58
+ self.create(this.S(instance));
59
+
60
+ $(this.scope)
61
+ .off('.tooltip')
62
+ .on('mouseenter.fndtn.tooltip mouseleave.fndtn.tooltip touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip',
63
+ '[' + this.attr_name() + ']', function (e) {
64
+ var $this = S(this),
65
+ settings = $.extend({}, self.settings, self.data_options($this)),
66
+ is_touch = false;
67
+
68
+ if (Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type) && S(e.target).is('a')) {
69
+ return false;
70
+ }
71
+
72
+ if (/mouse/i.test(e.type) && self.ie_touch(e)) return false;
73
+
74
+ if ($this.hasClass('open')) {
75
+ if (Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) e.preventDefault();
76
+ self.hide($this);
77
+ } else {
78
+ if (settings.disable_for_touch && Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) {
79
+ return;
80
+ } else if(!settings.disable_for_touch && Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) {
81
+ e.preventDefault();
82
+ S(settings.tooltip_class + '.open').hide();
83
+ is_touch = true;
84
+ }
85
+
86
+ if (/enter|over/i.test(e.type)) {
87
+ this.timer = setTimeout(function () {
88
+ var tip = self.showTip($this);
89
+ }.bind(this), self.settings.hover_delay);
90
+ } else if (e.type === 'mouseout' || e.type === 'mouseleave') {
91
+ clearTimeout(this.timer);
92
+ self.hide($this);
93
+ } else {
94
+ self.showTip($this);
95
+ }
96
+ }
97
+ })
98
+ .on('mouseleave.fndtn.tooltip touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip', '[' + this.attr_name() + '].open', function (e) {
99
+ if (/mouse/i.test(e.type) && self.ie_touch(e)) return false;
100
+
101
+ if($(this).data('tooltip-open-event-type') == 'touch' && e.type == 'mouseleave') {
102
+ return;
103
+ }
104
+ else if($(this).data('tooltip-open-event-type') == 'mouse' && /MSPointerDown|touchstart/i.test(e.type)) {
105
+ self.convert_to_touch($(this));
106
+ } else {
107
+ self.hide($(this));
108
+ }
109
+ })
110
+ .on('DOMNodeRemoved DOMAttrModified', '[' + this.attr_name() + ']:not(a)', function (e) {
111
+ self.hide(S(this));
112
+ });
113
+ },
114
+
115
+ ie_touch : function (e) {
116
+ // How do I distinguish between IE11 and Windows Phone 8?????
117
+ return false;
118
+ },
119
+
120
+ showTip : function ($target) {
121
+ var $tip = this.getTip($target);
122
+ if (this.should_show($target, $tip)){
123
+ return this.show($target);
124
+ }
125
+ return;
126
+ },
127
+
128
+ getTip : function ($target) {
129
+ var selector = this.selector($target),
130
+ settings = $.extend({}, this.settings, this.data_options($target)),
131
+ tip = null;
132
+
133
+ if (selector) {
134
+ tip = this.S('span[data-selector="' + selector + '"]' + settings.tooltip_class);
135
+ }
136
+
137
+ return (typeof tip === 'object') ? tip : false;
138
+ },
139
+
140
+ selector : function ($target) {
141
+ var id = $target.attr('id'),
142
+ dataSelector = $target.attr(this.attr_name()) || $target.attr('data-selector');
143
+
144
+ if ((id && id.length < 1 || !id) && typeof dataSelector != 'string') {
145
+ dataSelector = this.random_str(6);
146
+ $target
147
+ .attr('data-selector', dataSelector)
148
+ .attr('aria-describedby', dataSelector);
149
+ }
150
+
151
+ return (id && id.length > 0) ? id : dataSelector;
152
+ },
153
+
154
+ create : function ($target) {
155
+ var self = this,
156
+ settings = $.extend({}, this.settings, this.data_options($target)),
157
+ tip_template = this.settings.tip_template;
158
+
159
+ if (typeof settings.tip_template === 'string' && window.hasOwnProperty(settings.tip_template)) {
160
+ tip_template = window[settings.tip_template];
161
+ }
162
+
163
+ var $tip = $(tip_template(this.selector($target), $('<div></div>').html($target.attr('title')).html())),
164
+ classes = this.inheritable_classes($target);
165
+
166
+ $tip.addClass(classes).appendTo(settings.append_to);
167
+
168
+ if (Modernizr.touch) {
169
+ $tip.append('<span class="tap-to-close">'+settings.touch_close_text+'</span>');
170
+ $tip.on('touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip', function(e) {
171
+ self.hide($target);
172
+ });
173
+ }
174
+
175
+ $target.removeAttr('title').attr('title','');
176
+ },
177
+
178
+ reposition : function (target, tip, classes) {
179
+ var width, nub, nubHeight, nubWidth, column, objPos;
180
+
181
+ tip.css('visibility', 'hidden').show();
182
+
183
+ width = target.data('width');
184
+ nub = tip.children('.nub');
185
+ nubHeight = nub.outerHeight();
186
+ nubWidth = nub.outerHeight();
187
+
188
+ if (this.small()) {
189
+ tip.css({'width' : '100%' });
190
+ } else {
191
+ tip.css({'width' : (width) ? width : 'auto'});
192
+ }
193
+
194
+ objPos = function (obj, top, right, bottom, left, width) {
195
+ return obj.css({
196
+ 'top' : (top) ? top : 'auto',
197
+ 'bottom' : (bottom) ? bottom : 'auto',
198
+ 'left' : (left) ? left : 'auto',
199
+ 'right' : (right) ? right : 'auto'
200
+ }).end();
201
+ };
202
+
203
+ objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', target.offset().left);
204
+
205
+ if (this.small()) {
206
+ objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', 12.5, $(this.scope).width());
207
+ tip.addClass('tip-override');
208
+ objPos(nub, -nubHeight, 'auto', 'auto', target.offset().left);
209
+ } else {
210
+ var left = target.offset().left;
211
+ if (Foundation.rtl) {
212
+ nub.addClass('rtl');
213
+ left = target.offset().left + target.outerWidth() - tip.outerWidth();
214
+ }
215
+ objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', left);
216
+ tip.removeClass('tip-override');
217
+ if (classes && classes.indexOf('tip-top') > -1) {
218
+ if (Foundation.rtl) nub.addClass('rtl');
219
+ objPos(tip, (target.offset().top - tip.outerHeight()), 'auto', 'auto', left)
220
+ .removeClass('tip-override');
221
+ } else if (classes && classes.indexOf('tip-left') > -1) {
222
+ objPos(tip, (target.offset().top + (target.outerHeight() / 2) - (tip.outerHeight() / 2)), 'auto', 'auto', (target.offset().left - tip.outerWidth() - nubHeight))
223
+ .removeClass('tip-override');
224
+ nub.removeClass('rtl');
225
+ } else if (classes && classes.indexOf('tip-right') > -1) {
226
+ objPos(tip, (target.offset().top + (target.outerHeight() / 2) - (tip.outerHeight() / 2)), 'auto', 'auto', (target.offset().left + target.outerWidth() + nubHeight))
227
+ .removeClass('tip-override');
228
+ nub.removeClass('rtl');
229
+ }
230
+ }
231
+
232
+ tip.css('visibility', 'visible').hide();
233
+ },
234
+
235
+ small : function () {
236
+ return matchMedia(Foundation.media_queries.small).matches &&
237
+ !matchMedia(Foundation.media_queries.medium).matches;
238
+ },
239
+
240
+ inheritable_classes : function ($target) {
241
+ var settings = $.extend({}, this.settings, this.data_options($target)),
242
+ inheritables = ['tip-top', 'tip-left', 'tip-bottom', 'tip-right', 'radius', 'round'].concat(settings.additional_inheritable_classes),
243
+ classes = $target.attr('class'),
244
+ filtered = classes ? $.map(classes.split(' '), function (el, i) {
245
+ if ($.inArray(el, inheritables) !== -1) {
246
+ return el;
247
+ }
248
+ }).join(' ') : '';
249
+
250
+ return $.trim(filtered);
251
+ },
252
+
253
+ convert_to_touch : function($target) {
254
+ var self = this,
255
+ $tip = self.getTip($target),
256
+ settings = $.extend({}, self.settings, self.data_options($target));
257
+
258
+ if ($tip.find('.tap-to-close').length === 0) {
259
+ $tip.append('<span class="tap-to-close">'+settings.touch_close_text+'</span>');
260
+ $tip.on('click.fndtn.tooltip.tapclose touchstart.fndtn.tooltip.tapclose MSPointerDown.fndtn.tooltip.tapclose', function(e) {
261
+ self.hide($target);
262
+ });
263
+ }
264
+
265
+ $target.data('tooltip-open-event-type', 'touch');
266
+ },
267
+
268
+ show : function ($target) {
269
+ var $tip = this.getTip($target);
270
+
271
+ if ($target.data('tooltip-open-event-type') == 'touch') {
272
+ this.convert_to_touch($target);
273
+ }
274
+
275
+ this.reposition($target, $tip, $target.attr('class'));
276
+ $target.addClass('open');
277
+ $tip.fadeIn(150);
278
+ },
279
+
280
+ hide : function ($target) {
281
+ var $tip = this.getTip($target);
282
+
283
+ $tip.fadeOut(150, function() {
284
+ $tip.find('.tap-to-close').remove();
285
+ $tip.off('click.fndtn.tooltip.tapclose MSPointerDown.fndtn.tapclose');
286
+ $target.removeClass('open');
287
+ });
288
+ },
289
+
290
+ off : function () {
291
+ var self = this;
292
+ this.S(this.scope).off('.fndtn.tooltip');
293
+ this.S(this.settings.tooltip_class).each(function (i) {
294
+ $('[' + self.attr_name() + ']').eq(i).attr('title', $(this).text());
295
+ }).remove();
296
+ },
297
+
298
+ reflow : function () {}
299
+ };
300
+ }(jQuery, window, window.document));