riemann-dash 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,50 @@
1
1
  class Riemann::Dash
2
+ require 'multi_json'
3
+ require 'fileutils'
4
+ require 'set'
5
+
6
+ WS_CONFIG_FILE = "config/config.json"
7
+
2
8
  get '/' do
3
- erb :index
9
+ erb :index, :layout => false
10
+ end
11
+
12
+ get '/config', :provides => 'json' do
13
+ if File.exists? WS_CONFIG_FILE
14
+ send_file WS_CONFIG_FILE, :type => :json
15
+ else
16
+ MultiJson.encode({})
17
+ end
18
+ end
19
+
20
+ post '/config' do
21
+ # Read update
22
+ request.body.rewind
23
+ update = MultiJson.decode(request.body.read)
24
+
25
+ # Read old config
26
+ if File.exists? WS_CONFIG_FILE
27
+ old = MultiJson.decode File.read WS_CONFIG_FILE
28
+ else
29
+ old = {}
30
+ end
31
+
32
+ new = {}
33
+
34
+ # Server
35
+ new['server'] = update['server'] or old['server']
36
+
37
+ p update['workspaces']
38
+ new['workspaces'] = update['workspaces'] or old['workspaces']
39
+
40
+ # Save new config
41
+ FileUtils.mkdir_p 'config'
42
+ File.open(WS_CONFIG_FILE, 'w') do |f|
43
+ f.write(MultiJson.encode(new))
44
+ end
45
+
46
+ # Return current config
47
+ content_type "application/json"
48
+ MultiJson.encode(new)
4
49
  end
5
50
  end
@@ -59,7 +59,7 @@ dash = (function() {
59
59
  var stash = function() {
60
60
  var currentIndex = currentWorkspaceIndex();
61
61
  if (currentIndex != null) {
62
- console.log(util.merge(currentWorkspace(), {view: currentView.json()}));
62
+ //console.log(util.merge(currentWorkspace(), {view: currentView.json()}));
63
63
  workspaces[currentIndex] =
64
64
  util.merge(currentWorkspace(), {view: currentView.json()});
65
65
  }
@@ -149,8 +149,11 @@ dash = (function() {
149
149
  server: toolbar.server(),
150
150
  workspaces: workspaces
151
151
  },
152
- function() { console.log("Saved config."); },
153
- function(xhr, x, msg) { console.log("Error saving config", msg); }
152
+ function() { toastr.info("Configuration saved.") },
153
+ function(xhr, msg) {
154
+ console.log("Error saving config", msg);
155
+ toastr.error("Error saving config: " + msg);
156
+ }
154
157
  );
155
158
  }
156
159
 
@@ -3,7 +3,7 @@ var persistence = (function() {
3
3
  // Saves configuration to persistent store. Calls success() or error() when
4
4
  // complete.
5
5
  var save = function(config, success, error) {
6
- jQuery.ajax('/ws/config', {
6
+ jQuery.ajax('/config', {
7
7
  type: 'POST',
8
8
  success: success,
9
9
  error: error,
@@ -15,7 +15,7 @@ var persistence = (function() {
15
15
 
16
16
  // Returns configuration from persistent store.
17
17
  var load = function(success, error) {
18
- jQuery.ajax('/ws/config', {
18
+ jQuery.ajax('/config', {
19
19
  type: 'GET',
20
20
  success: success,
21
21
  error: error,
@@ -1,23 +1,74 @@
1
1
  var subs = (function() {
2
- var server = "127.0.0.1:5556";
2
+ // What server shall we connect to by default?
3
+ var server;
4
+
5
+ // Subscription ID counter.
6
+ var id_counter = -1;
7
+
8
+ // Subscriptions
9
+ var subs = {};
10
+
11
+ // Switch to turn on/off event processing
3
12
  var active = true;
13
+
14
+ // Error queue for notification
15
+ var errorQueue = [];
4
16
 
17
+ // Instrumentation
5
18
  var load1 = profile.load(1000);
6
19
  var load5 = profile.load(5000);
7
20
 
8
- // Loads index with query, calling f with each received event.
9
- var subscribe = function(query, f) {
10
- var queryString = "query=" + encodeURI(query);
11
- var uri = "ws://" + server + "/index?subscribe=true&" + queryString;
12
- var ws = new WebSocket(uri);
13
- var $ws = $(ws);
21
+ // Get a new subscription ID.
22
+ var newId = function() {
23
+ return id_counter += 1;
24
+ }
14
25
 
26
+ // Close a subscription's websocket channel.
27
+ var close = function(sub) {
28
+ if (sub.ws == null) {
29
+ return sub;
30
+ }
31
+ sub.ws.close();
32
+ sub.ws == null;
33
+ return sub;
34
+ }
35
+
36
+ // Closes a subscription and deletes it from the subscription manager.
37
+ var unsubscribe = function(sub) {
38
+ delete subs[sub.id];
39
+ close(sub);
40
+ }
41
+
42
+ // Unsubscribe from all subscriptions.
43
+ var unsubscribeAll = function() {
44
+ _.each(subs, unsubscribe);
45
+ }
46
+
47
+ // Open a subscription's websocket channel.
48
+ var open = function(sub) {
49
+ if (sub.ws != null && sub.ws.readyState != WebSocket.CLOSED) {
50
+ return sub;
51
+ }
52
+
53
+ var f = sub.f;
54
+ var queryString = "query=" + encodeURI(sub.query);
55
+ var uri = "ws://" + server + "/index?subscribe=true&" + queryString;
56
+ sub.ws = new WebSocket(uri);
57
+ var $ws = $(sub.ws);
58
+
15
59
  $ws.bind('open', function() {
16
- console.log("connected", query);
60
+ console.log("Socket opened", sub.query);
61
+ });
62
+
63
+ $ws.bind('close', function(e) {
64
+ console.log("Socket closed", sub.query);
65
+ sub.ws = null;
17
66
  });
18
67
 
19
- $ws.bind('close', function() {
20
- console.log("closed", query);
68
+ $ws.bind('error', function(e) {
69
+ console.log("Socket error", sub.query);
70
+ errorQueue.push(e);
71
+ ws.close();
21
72
  });
22
73
 
23
74
  $ws.bind('message', function(e) {
@@ -29,14 +80,68 @@ var subs = (function() {
29
80
  load5(t1, Date.now());
30
81
  });
31
82
 
32
- $(window).unload(function() { ws.close; ws = null });
33
- return ws;
83
+ return sub;
34
84
  }
35
85
 
86
+ // Add a subscription. Returns a subscription object. Subscriptions are
87
+ // opened immediately.
88
+ var subscribe = function(query, f) {
89
+ var sub = {
90
+ id: newId(),
91
+ query: query,
92
+ f: f,
93
+ ws: null
94
+ }
95
+ subs[sub.id] = sub;
96
+ open(sub);
97
+ return sub;
98
+ }
99
+
100
+ // Reconnect all inactive subs.
101
+ var converge = function() {
102
+ var closed = _.filter(subs, function(sub) {
103
+ return (sub.ws == null || sub.ws.readyState == WebSocket.CLOSED);
104
+ });
105
+ if (_.isEmpty(closed)) {
106
+ // Done here.
107
+ return;
108
+ }
109
+
110
+ // Display reconnection notice
111
+ toastr.warning(_.size(closed) + " lost connections");
112
+
113
+ // Reopen
114
+ _.each(closed, function(sub) {
115
+ open(sub);
116
+ });
117
+ }
118
+
119
+ var notifyErrors = function() {
120
+ if (errorQueue.length == 0) {
121
+ return;
122
+ }
123
+ _.warning(errorQueue.length + " socket errors");
124
+ errorQueue.length = 0;
125
+ converge();
126
+ }
127
+
128
+ // Periodically notify of errors.
129
+ window.setInterval(notifyErrors, 100);
130
+
131
+ // Periodically converge.
132
+ setInterval(converge, 6000);
133
+
134
+ // When terminating, close all connections.
135
+ $(window).unload(unsubscribeAll);
136
+
36
137
  return {
37
138
  subscribe: subscribe,
139
+ unsubscribe: unsubscribe,
140
+ unsubscribeAll: unsubscribeAll,
141
+ converge: converge,
38
142
  load1: load1,
39
143
  load5: load5,
144
+ subs: function() { return subs; },
40
145
  enable: function() { active = true; console.log("Subs enabled."); },
41
146
  disable: function() { active = false; console.log("Subs disabled."); },
42
147
  toggle: function() {
@@ -0,0 +1,174 @@
1
+ .toast-title
2
+ {
3
+ font-weight: bold;
4
+ }
5
+
6
+ .toast-message
7
+ {
8
+ -ms-word-wrap: break-word;
9
+ word-wrap: break-word;
10
+ }
11
+
12
+ .toast-message a,
13
+ .toast-message label
14
+ {
15
+ color: #FFF;
16
+ }
17
+
18
+ .toast-message a:hover
19
+ {
20
+ color: #CCC;
21
+ text-decoration: none;
22
+ }
23
+
24
+ .toast-top-left
25
+ {
26
+ left: 12px;
27
+ top: 12px;
28
+ }
29
+
30
+ .toast-bottom-right
31
+ {
32
+ bottom: 12px;
33
+ right: 12px;
34
+ }
35
+
36
+ .toast-bottom-left
37
+ {
38
+ bottom: 12px;
39
+ left: 12px;
40
+ }
41
+
42
+ #toast-container
43
+ {
44
+ position: fixed;
45
+ z-index: 9999;
46
+ }
47
+
48
+ #toast-container > div
49
+ {
50
+ background-position: 15px center;
51
+ background-repeat: no-repeat;
52
+ -moz-border-radius: 3px 3px 3px 3px;
53
+ -webkit-border-radius: 3px 3px 3px 3px;
54
+ border-radius: 3px 3px 3px 3px;
55
+ -moz-box-shadow: 0 0 12px #999999;
56
+ -webkit-box-shadow: 0 0 12px #999999;
57
+ box-shadow: 0 0 12px #999999;
58
+ color: #FFFFFF;
59
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
60
+ filter: alpha(opacity=80);
61
+ margin: 0 0 6px;
62
+ opacity: 0.8;
63
+ padding: 15px 15px 15px 50px;
64
+ width: 300px;
65
+ }
66
+
67
+ .toast
68
+ {
69
+ background-color: #030303;
70
+ }
71
+
72
+ .toast-success
73
+ {
74
+ background-color: #51A351;
75
+ }
76
+
77
+ .toast-error
78
+ {
79
+ background-color: #BD362F;
80
+ }
81
+
82
+ .toast-info
83
+ {
84
+ background-color: #2F96B4;
85
+ }
86
+
87
+ .toast-warning
88
+ {
89
+ background-color: #F89406;
90
+ }
91
+
92
+ .toast-top-right
93
+ {
94
+ right: 12px;
95
+ top: 12px;
96
+ }
97
+
98
+ #toast-container > :hover
99
+ {
100
+ -moz-box-shadow: 0 0 12px #000000;
101
+ -webkit-box-shadow: 0 0 12px #000000;
102
+ box-shadow: 0 0 12px #000000;
103
+ cursor: pointer;
104
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
105
+ filter: alpha(opacity=100);
106
+ opacity: 1;
107
+ }
108
+
109
+ #toast-container > .toast-info
110
+ {
111
+ background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=") !important;
112
+ }
113
+
114
+ #toast-container > .toast-error
115
+ {
116
+ background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=") !important;
117
+ }
118
+
119
+ #toast-container > .toast-success
120
+ {
121
+ background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==") !important;
122
+ }
123
+
124
+ #toast-container > .toast-warning
125
+ {
126
+ background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=") !important;
127
+ }
128
+
129
+ /*Responsive Design*/
130
+
131
+ @media all and (max-width: 240px)
132
+ {
133
+ #toast-container > div
134
+ {
135
+ padding: 8px 8px 8px 50px;
136
+ width: 108px;
137
+ }
138
+ }
139
+
140
+ @media all and (min-width: 241px) and (max-width: 320px)
141
+ {
142
+ #toast-container > div
143
+ {
144
+ padding: 8px 8px 8px 50px;
145
+ width: 128px;
146
+ }
147
+ }
148
+
149
+ @media all and (min-width: 321px) and (max-width: 480px)
150
+ {
151
+ #toast-container > div
152
+ {
153
+ padding: 8px 8px 8px 50px;
154
+ width: 192px;
155
+ }
156
+ }
157
+
158
+ @media all and (min-width: 481px) and (max-width: 768px)
159
+ {
160
+ #toast-container > div
161
+ {
162
+ padding: 15px 15px 15px 50px;
163
+ width: 300px;
164
+ }
165
+ }
166
+
167
+ @media all and (min-width: 769px)
168
+ {
169
+ #toast-container > div
170
+ {
171
+ padding: 15px 15px 15px 50px;
172
+ width: 300px;
173
+ }
174
+ }
@@ -0,0 +1,207 @@
1
+ // By: Hans Fjällemark and John Papa
2
+ // https://github.com/CodeSeven/toastr
3
+ //
4
+ // Modified to support css styling instead of inline styling
5
+ // Inspired by https://github.com/Srirangan/notifer.js/
6
+
7
+ ; (function (define) {
8
+ define(['jquery'], function ($) {
9
+ var toastr = (function () {
10
+ var
11
+ defaults = {
12
+ tapToDismiss: true,
13
+ toastClass: 'toast',
14
+ containerId: 'toast-container',
15
+ debug: false,
16
+ fadeIn: 300,
17
+ fadeOut: 1000,
18
+ extendedTimeOut: 1000,
19
+ iconClasses: {
20
+ error: 'toast-error',
21
+ info: 'toast-info',
22
+ success: 'toast-success',
23
+ warning: 'toast-warning'
24
+ },
25
+ iconClass: 'toast-info',
26
+ positionClass: 'toast-top-right',
27
+ timeOut: 5000, // Set timeOut to 0 to make it sticky
28
+ titleClass: 'toast-title',
29
+ messageClass: 'toast-message'
30
+ },
31
+
32
+ error = function (message, title, optionsOverride) {
33
+ return notify({
34
+ iconClass: getOptions().iconClasses.error,
35
+ message: message,
36
+ optionsOverride: optionsOverride,
37
+ title: title
38
+ });
39
+ },
40
+
41
+ getContainer = function (options) {
42
+ var $container = $('#' + options.containerId);
43
+ if ($container.length) {
44
+ return $container;
45
+ }
46
+ $container = $('<div/>')
47
+ .attr('id', options.containerId)
48
+ .addClass(options.positionClass);
49
+ $container.appendTo($('body'));
50
+ return $container;
51
+ },
52
+
53
+ getOptions = function () {
54
+ return $.extend({}, defaults, toastr.options);
55
+ },
56
+
57
+ info = function (message, title, optionsOverride) {
58
+ return notify({
59
+ iconClass: getOptions().iconClasses.info,
60
+ message: message,
61
+ optionsOverride: optionsOverride,
62
+ title: title
63
+ });
64
+ },
65
+
66
+ notify = function (map) {
67
+ var
68
+ options = getOptions(),
69
+ iconClass = map.iconClass || options.iconClass;
70
+
71
+ if (typeof (map.optionsOverride) !== 'undefined') {
72
+ options = $.extend(options, map.optionsOverride);
73
+ iconClass = map.optionsOverride.iconClass || iconClass;
74
+ }
75
+
76
+ var
77
+ intervalId = null,
78
+ $container = getContainer(options),
79
+ $toastElement = $('<div/>'),
80
+ $titleElement = $('<div/>'),
81
+ $messageElement = $('<div/>'),
82
+ response = { options: options, map: map };
83
+
84
+ if (map.iconClass) {
85
+ $toastElement.addClass(options.toastClass).addClass(iconClass);
86
+ }
87
+
88
+ if (map.title) {
89
+ $titleElement.append(map.title).addClass(options.titleClass);
90
+ $toastElement.append($titleElement);
91
+ }
92
+
93
+ if (map.message) {
94
+ $messageElement.append(map.message).addClass(options.messageClass);
95
+ $toastElement.append($messageElement);
96
+ }
97
+
98
+ var fadeAway = function () {
99
+ if ($(':focus', $toastElement).length > 0) {
100
+ return;
101
+ }
102
+ var fade = function (callback) {
103
+ return $toastElement.fadeOut(options.fadeOut, callback);
104
+ };
105
+ var removeToast = function () {
106
+ if ($toastElement.is(':visible')) {
107
+ return;
108
+ }
109
+ $toastElement.remove();
110
+ if ($container.children().length === 0) {
111
+ $container.remove();
112
+ }
113
+ };
114
+ fade(removeToast);
115
+ };
116
+ var delayedFadeAway = function () {
117
+ if (options.timeOut > 0 || options.extendedTimeOut > 0) {
118
+ intervalId = setTimeout(fadeAway, options.extendedTimeOut);
119
+ }
120
+ };
121
+ var stickAround = function () {
122
+ clearTimeout(intervalId);
123
+ $toastElement.stop(true, true).fadeIn(options.fadeIn);
124
+ };
125
+ $toastElement.hide();
126
+ $container.prepend($toastElement);
127
+ $toastElement.fadeIn(options.fadeIn);
128
+ if (options.timeOut > 0) {
129
+ intervalId = setTimeout(fadeAway, options.timeOut);
130
+ }
131
+
132
+ $toastElement.hover(stickAround, delayedFadeAway);
133
+ if (!options.onclick && options.tapToDismiss) {
134
+ $toastElement.click(fadeAway);
135
+ }
136
+
137
+ if (options.onclick) {
138
+ $toastElement.click(function () {
139
+ options.onclick() && fadeAway();
140
+ });
141
+ }
142
+
143
+ if (options.debug && console) {
144
+ console.log(response);
145
+ }
146
+ return $toastElement;
147
+ },
148
+
149
+ success = function (message, title, optionsOverride) {
150
+ return notify({
151
+ iconClass: getOptions().iconClasses.success,
152
+ message: message,
153
+ optionsOverride: optionsOverride,
154
+ title: title
155
+ });
156
+ },
157
+
158
+ warning = function (message, title, optionsOverride) {
159
+ return notify({
160
+ iconClass: getOptions().iconClasses.warning,
161
+ message: message,
162
+ optionsOverride: optionsOverride,
163
+ title: title
164
+ });
165
+ },
166
+
167
+ clear = function ($toastElement) {
168
+ var options = getOptions();
169
+ var $container = $('#' + options.containerId);
170
+ if ($toastElement && $(':focus', $toastElement).length === 0) {
171
+ var removeToast = function () {
172
+ if ($toastElement.is(':visible')) {
173
+ return;
174
+ }
175
+ $toastElement.remove();
176
+ if ($container.children().length === 0) {
177
+ $container.remove();
178
+ }
179
+ };
180
+ $toastElement.fadeOut(options.fadeOut, removeToast);
181
+ return;
182
+ }
183
+ if ($container.length) {
184
+ $container.fadeOut(options.fadeOut, function () {
185
+ $container.remove();
186
+ });
187
+ }
188
+ };
189
+ return {
190
+ clear: clear,
191
+ error: error,
192
+ info: info,
193
+ options: {},
194
+ success: success,
195
+ version: '1.1.2',
196
+ warning: warning
197
+ };
198
+ })();
199
+ return toastr;
200
+ });
201
+ }(typeof define === 'function' && define.amd ? define : function (deps, factory) {
202
+ if (typeof module !== 'undefined' && module.exports) { //Node
203
+ module.exports = factory(require(deps[0]));
204
+ } else {
205
+ window['toastr'] = factory(window['jQuery']);
206
+ }
207
+ }));