mini-sharp-hub 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/mini-sharp-hub.gemspec +12 -0
  3. data/rack-mini-profiler-4.0.1/CHANGELOG.md +424 -0
  4. data/rack-mini-profiler-4.0.1/README.md +542 -0
  5. data/rack-mini-profiler-4.0.1/lib/enable_rails_patches.rb +5 -0
  6. data/rack-mini-profiler-4.0.1/lib/generators/rack_mini_profiler/USAGE +9 -0
  7. data/rack-mini-profiler-4.0.1/lib/generators/rack_mini_profiler/install_generator.rb +13 -0
  8. data/rack-mini-profiler-4.0.1/lib/generators/rack_mini_profiler/templates/rack_mini_profiler.rb +8 -0
  9. data/rack-mini-profiler-4.0.1/lib/generators/rack_profiler/USAGE +2 -0
  10. data/rack-mini-profiler-4.0.1/lib/generators/rack_profiler/install_generator.rb +16 -0
  11. data/rack-mini-profiler-4.0.1/lib/html/dot.1.1.2.min.js +2 -0
  12. data/rack-mini-profiler-4.0.1/lib/html/includes.css +474 -0
  13. data/rack-mini-profiler-4.0.1/lib/html/includes.js +1520 -0
  14. data/rack-mini-profiler-4.0.1/lib/html/includes.scss +698 -0
  15. data/rack-mini-profiler-4.0.1/lib/html/includes.tmpl +333 -0
  16. data/rack-mini-profiler-4.0.1/lib/html/pretty-print.js +810 -0
  17. data/rack-mini-profiler-4.0.1/lib/html/profile_handler.js +1 -0
  18. data/rack-mini-profiler-4.0.1/lib/html/rack-mini-profiler.css +3 -0
  19. data/rack-mini-profiler-4.0.1/lib/html/rack-mini-profiler.js +2 -0
  20. data/rack-mini-profiler-4.0.1/lib/html/share.html +10 -0
  21. data/rack-mini-profiler-4.0.1/lib/html/speedscope/LICENSE +21 -0
  22. data/rack-mini-profiler-4.0.1/lib/html/speedscope/README.md +3 -0
  23. data/rack-mini-profiler-4.0.1/lib/html/speedscope/demangle-cpp.1768f4cc.js +4 -0
  24. data/rack-mini-profiler-4.0.1/lib/html/speedscope/favicon-16x16.f74b3187.png +0 -0
  25. data/rack-mini-profiler-4.0.1/lib/html/speedscope/favicon-32x32.bc503437.png +0 -0
  26. data/rack-mini-profiler-4.0.1/lib/html/speedscope/file-format-schema.json +324 -0
  27. data/rack-mini-profiler-4.0.1/lib/html/speedscope/fonts/source-code-pro-regular.css +8 -0
  28. data/rack-mini-profiler-4.0.1/lib/html/speedscope/fonts/source-code-pro-v13-regular.woff +0 -0
  29. data/rack-mini-profiler-4.0.1/lib/html/speedscope/fonts/source-code-pro-v13-regular.woff2 +0 -0
  30. data/rack-mini-profiler-4.0.1/lib/html/speedscope/import.8ae8aa3d.js +123 -0
  31. data/rack-mini-profiler-4.0.1/lib/html/speedscope/index.html +2 -0
  32. data/rack-mini-profiler-4.0.1/lib/html/speedscope/release.txt +3 -0
  33. data/rack-mini-profiler-4.0.1/lib/html/speedscope/reset.8c46b7a1.css +2 -0
  34. data/rack-mini-profiler-4.0.1/lib/html/speedscope/source-map.438fa06b.js +24 -0
  35. data/rack-mini-profiler-4.0.1/lib/html/speedscope/speedscope.f27db165.js +193 -0
  36. data/rack-mini-profiler-4.0.1/lib/html/vendor.js +848 -0
  37. data/rack-mini-profiler-4.0.1/lib/mini_profiler/actions.rb +157 -0
  38. data/rack-mini-profiler-4.0.1/lib/mini_profiler/asset_version.rb +6 -0
  39. data/rack-mini-profiler-4.0.1/lib/mini_profiler/client_settings.rb +127 -0
  40. data/rack-mini-profiler-4.0.1/lib/mini_profiler/config.rb +146 -0
  41. data/rack-mini-profiler-4.0.1/lib/mini_profiler/context.rb +14 -0
  42. data/rack-mini-profiler-4.0.1/lib/mini_profiler/gc_profiler.rb +158 -0
  43. data/rack-mini-profiler-4.0.1/lib/mini_profiler/profiling_methods.rb +167 -0
  44. data/rack-mini-profiler-4.0.1/lib/mini_profiler/snapshots_transporter.rb +111 -0
  45. data/rack-mini-profiler-4.0.1/lib/mini_profiler/storage/abstract_store.rb +97 -0
  46. data/rack-mini-profiler-4.0.1/lib/mini_profiler/storage/file_store.rb +179 -0
  47. data/rack-mini-profiler-4.0.1/lib/mini_profiler/storage/memcache_store.rb +105 -0
  48. data/rack-mini-profiler-4.0.1/lib/mini_profiler/storage/memory_store.rb +233 -0
  49. data/rack-mini-profiler-4.0.1/lib/mini_profiler/storage/redis_store.rb +353 -0
  50. data/rack-mini-profiler-4.0.1/lib/mini_profiler/storage.rb +7 -0
  51. data/rack-mini-profiler-4.0.1/lib/mini_profiler/timer_struct/base.rb +39 -0
  52. data/rack-mini-profiler-4.0.1/lib/mini_profiler/timer_struct/client.rb +90 -0
  53. data/rack-mini-profiler-4.0.1/lib/mini_profiler/timer_struct/custom.rb +25 -0
  54. data/rack-mini-profiler-4.0.1/lib/mini_profiler/timer_struct/page.rb +146 -0
  55. data/rack-mini-profiler-4.0.1/lib/mini_profiler/timer_struct/request.rb +186 -0
  56. data/rack-mini-profiler-4.0.1/lib/mini_profiler/timer_struct/sql.rb +89 -0
  57. data/rack-mini-profiler-4.0.1/lib/mini_profiler/timer_struct.rb +8 -0
  58. data/rack-mini-profiler-4.0.1/lib/mini_profiler/version.rb +8 -0
  59. data/rack-mini-profiler-4.0.1/lib/mini_profiler/views.rb +198 -0
  60. data/rack-mini-profiler-4.0.1/lib/mini_profiler.rb +670 -0
  61. data/rack-mini-profiler-4.0.1/lib/mini_profiler_rails/railtie.rb +234 -0
  62. data/rack-mini-profiler-4.0.1/lib/mini_profiler_rails/railtie_methods.rb +61 -0
  63. data/rack-mini-profiler-4.0.1/lib/patches/db/activerecord.rb +44 -0
  64. data/rack-mini-profiler-4.0.1/lib/patches/db/mongo.rb +18 -0
  65. data/rack-mini-profiler-4.0.1/lib/patches/db/moped.rb +14 -0
  66. data/rack-mini-profiler-4.0.1/lib/patches/db/mysql2/alias_method.rb +30 -0
  67. data/rack-mini-profiler-4.0.1/lib/patches/db/mysql2/prepend.rb +34 -0
  68. data/rack-mini-profiler-4.0.1/lib/patches/db/mysql2.rb +7 -0
  69. data/rack-mini-profiler-4.0.1/lib/patches/db/neo4j.rb +16 -0
  70. data/rack-mini-profiler-4.0.1/lib/patches/db/nobrainer.rb +31 -0
  71. data/rack-mini-profiler-4.0.1/lib/patches/db/oracle_enhanced.rb +70 -0
  72. data/rack-mini-profiler-4.0.1/lib/patches/db/pg/alias_method.rb +121 -0
  73. data/rack-mini-profiler-4.0.1/lib/patches/db/pg/prepend.rb +115 -0
  74. data/rack-mini-profiler-4.0.1/lib/patches/db/pg.rb +7 -0
  75. data/rack-mini-profiler-4.0.1/lib/patches/db/plucky.rb +49 -0
  76. data/rack-mini-profiler-4.0.1/lib/patches/db/riak.rb +105 -0
  77. data/rack-mini-profiler-4.0.1/lib/patches/db/rsolr.rb +26 -0
  78. data/rack-mini-profiler-4.0.1/lib/patches/db/sequel.rb +12 -0
  79. data/rack-mini-profiler-4.0.1/lib/patches/net_patches.rb +27 -0
  80. data/rack-mini-profiler-4.0.1/lib/patches/sql_patches.rb +74 -0
  81. data/rack-mini-profiler-4.0.1/lib/prepend_mysql2_patch.rb +5 -0
  82. data/rack-mini-profiler-4.0.1/lib/prepend_net_http_patch.rb +5 -0
  83. data/rack-mini-profiler-4.0.1/lib/prepend_pg_patch.rb +5 -0
  84. data/rack-mini-profiler-4.0.1/lib/rack-mini-profiler.rb +13 -0
  85. data/rack-mini-profiler-4.0.1/rack-mini-profiler.gemspec +49 -0
  86. metadata +125 -0
@@ -0,0 +1,1520 @@
1
+ "use strict";
2
+
3
+ var _MiniProfiler = (function() {
4
+ var _arguments = arguments;
5
+ var options,
6
+ container,
7
+ controls,
8
+ fetchedIds = (window.MiniProfiler && window.MiniProfiler.fetchedIds) || [],
9
+ fetchingIds =
10
+ (window.MiniProfiler && window.MiniProfiler.fetchingIds) || [],
11
+ // so we never pull down a profiler twice
12
+ ajaxStartTime,
13
+ totalsControl,
14
+ reqs = 0,
15
+ expandedResults = false,
16
+ totalTime = 0,
17
+ totalSqlCount = 0;
18
+
19
+ var hasLocalStorage = function hasLocalStorage(keyPrefix) {
20
+ try {
21
+ // attempt to save to localStorage as Safari private windows will throw an error
22
+ localStorage[keyPrefix + "-test"] = "1";
23
+ localStorage.removeItem(keyPrefix + "-test");
24
+ return "localStorage" in window && window["localStorage"] !== null;
25
+ } catch (e) {
26
+ return false;
27
+ }
28
+ };
29
+
30
+ var getVersionedKey = function getVersionedKey(keyPrefix) {
31
+ return keyPrefix + "-" + options.version;
32
+ };
33
+
34
+ // polyfills as helper functions to avoid conflicts
35
+ // needed for IE11
36
+ // remove and replace with Element.closest when we drop IE11 support
37
+ // https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
38
+
39
+ var elementMatches =
40
+ Element.prototype.msMatchesSelector ||
41
+ Element.prototype.webkitMatchesSelector;
42
+
43
+ var elementClosest = function elementClosest(el, s) {
44
+ if (typeof el.closest === "function") {
45
+ return el.closest(s);
46
+ }
47
+
48
+ do {
49
+ if (typeof el.matches === "function") {
50
+ if (el.matches(s)) return el;
51
+ } else {
52
+ if (elementMatches.call(el, s)) return el;
53
+ }
54
+
55
+ el = el.parentElement || el.parentNode;
56
+ } while (el !== null && el.nodeType === 1);
57
+
58
+ return null;
59
+ };
60
+
61
+ var save = function save(keyPrefix, value) {
62
+ if (!hasLocalStorage(keyPrefix)) {
63
+ return;
64
+ } // clear old keys with this prefix, if any
65
+
66
+ for (var i = 0; i < localStorage.length; i++) {
67
+ if ((localStorage.key(i) || "").indexOf(keyPrefix) > -1) {
68
+ localStorage.removeItem(localStorage.key(i));
69
+ }
70
+ } // save under this version
71
+
72
+ localStorage[getVersionedKey(keyPrefix)] = value;
73
+ };
74
+
75
+ var load = function load(keyPrefix) {
76
+ if (!hasLocalStorage(keyPrefix)) {
77
+ return null;
78
+ }
79
+
80
+ return localStorage[getVersionedKey(keyPrefix)];
81
+ };
82
+
83
+ var getClientPerformance = function getClientPerformance() {
84
+ return window.performance === null ? null : window.performance;
85
+ };
86
+
87
+ var fetchResults = function fetchResults(ids) {
88
+ var clientPerformance, clientProbes, i, j, p, id, idx;
89
+
90
+ for (i = 0; i < ids.length; i++) {
91
+ id = ids[i];
92
+ clientPerformance = null;
93
+ clientProbes = null;
94
+
95
+ if (window.mPt) {
96
+ clientProbes = mPt.results();
97
+
98
+ for (j = 0; j < clientProbes.length; j++) {
99
+ clientProbes[j].d = clientProbes[j].d.getTime();
100
+ }
101
+
102
+ mPt.flush();
103
+ }
104
+
105
+ if (id == options.currentId) {
106
+ clientPerformance = getClientPerformance();
107
+
108
+ if (clientPerformance !== null) {
109
+ // ie is buggy strip out functions
110
+ var copy = {
111
+ navigation: {},
112
+ timing: clientPerformance.timing.toJSON()
113
+ };
114
+
115
+ if (clientPerformance.navigation) {
116
+ copy.navigation.redirectCount =
117
+ clientPerformance.navigation.redirectCount;
118
+ }
119
+
120
+ clientPerformance = copy;
121
+ }
122
+ } else if (
123
+ ajaxStartTime !== null &&
124
+ clientProbes &&
125
+ clientProbes.length > 0
126
+ ) {
127
+ clientPerformance = {
128
+ timing: {
129
+ navigationStart: ajaxStartTime.getTime()
130
+ }
131
+ };
132
+ ajaxStartTime = null;
133
+ }
134
+
135
+ if (fetchedIds.indexOf(id) < 0 && fetchingIds.indexOf(id) < 0) {
136
+ idx = fetchingIds.push(id) - 1;
137
+
138
+ (function() {
139
+ var request = new XMLHttpRequest();
140
+ var url = options.path + "results";
141
+ var params = {
142
+ id: id,
143
+ clientPerformance: clientPerformance,
144
+ clientProbes: clientProbes,
145
+ popup: 1
146
+ };
147
+ var queryParam = toQueryString(params);
148
+ request.open("POST", url, true);
149
+
150
+ request.onload = function() {
151
+ if (request.status >= 200 && request.status < 400) {
152
+ var json = JSON.parse(request.responseText);
153
+ fetchedIds.push(id);
154
+
155
+ if (json != "hidden" && MiniProfiler.templates) {
156
+ buttonShow(json);
157
+ }
158
+ }
159
+
160
+ fetchingIds.splice(idx, 1);
161
+ };
162
+
163
+ request.setRequestHeader("Accept", "application/json");
164
+ request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
165
+ request.setRequestHeader(
166
+ "Content-Type",
167
+ "application/x-www-form-urlencoded"
168
+ );
169
+ request.send(queryParam);
170
+ })();
171
+ }
172
+ }
173
+ };
174
+
175
+ var toQueryString = function toQueryString(data, parentKey) {
176
+ var result = [];
177
+ for (var key in data) {
178
+ var val = data[key];
179
+ var newKey = !parentKey ? key : parentKey + "[" + key + "]";
180
+ if (
181
+ typeof val === "object" &&
182
+ !Array.isArray(val) &&
183
+ val !== null &&
184
+ val !== undefined
185
+ ) {
186
+ result[result.length] = toQueryString(val, newKey);
187
+ } else {
188
+ if (Array.isArray(val)) {
189
+ val.forEach(function(v) {
190
+ result[result.length] =
191
+ encodeURIComponent(newKey + "[]") + "=" + encodeURIComponent(v);
192
+ });
193
+ } else if (val === null || val === undefined) {
194
+ result[result.length] = encodeURIComponent(newKey) + "=";
195
+ } else {
196
+ result[result.length] =
197
+ encodeURIComponent(newKey) +
198
+ "=" +
199
+ encodeURIComponent(val.toString());
200
+ }
201
+ }
202
+ }
203
+ return result
204
+ .filter(function(element) {
205
+ return element && element.length > 0;
206
+ })
207
+ .join("&");
208
+ };
209
+
210
+ var renderTemplate = function renderTemplate(json) {
211
+ var textDom = MiniProfiler.templates.profilerTemplate(json);
212
+ var tempElement = document.createElement("DIV");
213
+ tempElement.innerHTML = textDom;
214
+ return tempElement.children[0];
215
+ };
216
+
217
+ var buttonShow = function buttonShow(json) {
218
+ var result = renderTemplate(json);
219
+ totalTime += parseFloat(json.duration_milliseconds, 10);
220
+ totalSqlCount += parseInt(json.sql_count);
221
+ reqs++;
222
+
223
+ if (!controls && options.collapseResults && !expandedResults) {
224
+ if (!totalsControl) {
225
+ toArray(container.querySelectorAll(".profiler-result")).forEach(
226
+ function(el) {
227
+ return (el.style.display = "none");
228
+ }
229
+ );
230
+ totalsControl = document.createElement("div");
231
+ totalsControl.setAttribute("class", "profiler-result");
232
+ totalsControl.innerHTML =
233
+ "<div class='profiler-button profiler-totals'></div>";
234
+ container.appendChild(totalsControl);
235
+ totalsControl.addEventListener("click", function() {
236
+ toArray(
237
+ totalsControl.parentNode.querySelectorAll(".profiler-result")
238
+ ).forEach(function(el) {
239
+ return (el.style.display = "block");
240
+ });
241
+ totalsControl.style.display = "none";
242
+ expandedResults = true;
243
+ });
244
+ toArray(totalsControl.querySelectorAll(".profiler-button")).forEach(
245
+ function(el) {
246
+ return (el.style.display = "block");
247
+ }
248
+ );
249
+ }
250
+
251
+ var reqsHtml =
252
+ reqs > 1 ? "<span class='profiler-reqs'>" + reqs + "</span>" : "";
253
+ var sqlHtml =
254
+ options.showTotalSqlCount && totalSqlCount > 0
255
+ ? " / <span class='profiler-number'>" +
256
+ totalSqlCount +
257
+ "</span> <span class='profiler-unit'>sql</span>"
258
+ : "";
259
+ totalsControl.querySelector(".profiler-button").innerHTML =
260
+ "<span class='profiler-number'>" +
261
+ totalTime.toFixed(1) +
262
+ "</span> <span class='profiler-unit'>ms</span>" +
263
+ sqlHtml +
264
+ reqsHtml;
265
+ result.style.display = "none";
266
+ }
267
+
268
+ if (controls) result.insertBefore(controls);
269
+ else container.appendChild(result);
270
+ var button = result.querySelector(".profiler-button"),
271
+ popup = result.querySelector(".profiler-popup"); // button will appear in corner with the total profiling duration - click to show details
272
+
273
+ button.addEventListener("click", function() {
274
+ buttonClick(button, popup);
275
+ }); // small duration steps and the column with aggregate durations are hidden by default; allow toggling
276
+
277
+ toggleHidden(popup); // lightbox in the queries
278
+
279
+ toArray(popup.querySelectorAll(".profiler-queries-show")).forEach(function(
280
+ el
281
+ ) {
282
+ el.addEventListener("click", function() {
283
+ queriesShow(this, result);
284
+ });
285
+ }); // limit count
286
+
287
+ if (
288
+ container.querySelectorAll(".profiler-result:not(:has(.profiler-totals))").length >
289
+ options.maxTracesToShow
290
+ ) {
291
+ var elem = container.querySelector('.profiler-result:not(:has(.profiler-totals))');
292
+
293
+ if (elem) {
294
+ elem.parentElement.removeChild(elem);
295
+ }
296
+ }
297
+
298
+ button.style.display = "block";
299
+ };
300
+
301
+ var toggleHidden = function toggleHidden(popup) {
302
+ var trivial = popup.querySelector(".profiler-toggle-trivial");
303
+ var childrenTime = popup.querySelector(
304
+ ".profiler-toggle-duration-with-children"
305
+ );
306
+ var trivialGaps = popup.parentNode.querySelector(
307
+ ".profiler-toggle-trivial-gaps"
308
+ );
309
+
310
+ var toggleIt = function toggleIt(node) {
311
+ var link = node,
312
+ klass =
313
+ "profiler-" +
314
+ link.getAttribute("class").substr("profiler-toggle-".length),
315
+ isHidden = link.textContent.indexOf("show") > -1;
316
+ var elements = toArray(popup.parentNode.querySelectorAll("." + klass));
317
+
318
+ if (isHidden) {
319
+ elements.forEach(function(el) {
320
+ return (el.style.display = "table-row");
321
+ });
322
+ } else {
323
+ elements.forEach(function(el) {
324
+ return (el.style.display = "none");
325
+ });
326
+ }
327
+
328
+ var text = link.textContent;
329
+ link.textContent = text.replace(
330
+ isHidden ? "show" : "hide",
331
+ isHidden ? "hide" : "show"
332
+ );
333
+ popupPreventHorizontalScroll(popup);
334
+ };
335
+
336
+ [childrenTime, trivial, trivialGaps].forEach(function(el) {
337
+ if (el) {
338
+ el.addEventListener("click", function() {
339
+ toggleIt(this);
340
+ });
341
+ }
342
+ }); // if option is set or all our timings are trivial, go ahead and show them
343
+
344
+ if (
345
+ trivial &&
346
+ (options.showTrivial || trivial.getAttribute("show-on-load"))
347
+ ) {
348
+ toggleIt(trivial);
349
+ } // if option is set, go ahead and show time with children
350
+
351
+ if (childrenTime && options.showChildrenTime) {
352
+ toggleIt(childrenTime);
353
+ }
354
+ };
355
+
356
+ var toArray = function toArray(list) {
357
+ var arr = [];
358
+
359
+ if (!list) {
360
+ return arr;
361
+ }
362
+
363
+ for (var i = 0; i < list.length; i++) {
364
+ arr.push(list[i]);
365
+ }
366
+
367
+ return arr;
368
+ };
369
+
370
+ var buttonClick = function buttonClick(button, popup) {
371
+ // we're toggling this button/popup
372
+ if (popup.offsetWidth > 0 || popup.offsetHeight > 0) {
373
+ // if visible
374
+ popupHide(button, popup);
375
+ } else {
376
+ var visiblePopups = toArray(
377
+ container.querySelectorAll(".profiler-popup")
378
+ ).filter(function(el) {
379
+ return el.offsetWidth > 0 || el.offsetHeight > 0;
380
+ }); // theirButtons = visiblePopups.siblings(".profiler-button");
381
+
382
+ var theirButtons = [];
383
+ visiblePopups.forEach(function(el) {
384
+ theirButtons.push(el.parentNode.querySelector(".profiler-button"));
385
+ }); // hide any other popups
386
+
387
+ popupHide(theirButtons, visiblePopups); // before showing the one we clicked
388
+
389
+ popupShow(button, popup);
390
+ }
391
+ };
392
+
393
+ var popupShow = function popupShow(button, popup) {
394
+ button.classList.add("profiler-button-active");
395
+ popupSetDimensions(button, popup);
396
+ popup.style.display = "block";
397
+ popupPreventHorizontalScroll(popup);
398
+ };
399
+
400
+ var popupSetDimensions = function popupSetDimensions(button, popup) {
401
+ var px = button.offsetTop - 1,
402
+ // position next to the button we clicked
403
+ windowHeight = window.innerHeight,
404
+ maxHeight = windowHeight - px - 40, // make sure the popup doesn't extend below the fold
405
+ pxVertical = options.renderVerticalPosition === 'bottom' ? button.offsetParent.clientHeight - 21 - px : px;
406
+
407
+ popup.style[options.renderVerticalPosition] = "".concat(pxVertical, "px");
408
+ popup.style.maxHeight = "".concat(maxHeight, "px");
409
+ popup.style[options.renderHorizontalPosition] = "".concat(
410
+ button.offsetWidth - 3,
411
+ "px"
412
+ ); // move left or right, based on config
413
+ };
414
+
415
+ var popupPreventHorizontalScroll = function popupPreventHorizontalScroll(
416
+ popup
417
+ ) {
418
+ var childrenHeight = 0;
419
+ toArray(popup.children).forEach(function(el) {
420
+ childrenHeight += el.offsetHeight;
421
+ });
422
+ popup.style.paddingRight = "".concat(
423
+ childrenHeight > popup.offsetHeight ? 40 : 10,
424
+ "px"
425
+ );
426
+ };
427
+
428
+ var popupHide = function popupHide(button, popup) {
429
+ if (button) {
430
+ if (Array.isArray(button)) {
431
+ button.forEach(function(el) {
432
+ return el.classList.remove("profiler-button-active");
433
+ });
434
+ } else {
435
+ button.classList.remove("profiler-button-active");
436
+ }
437
+ }
438
+
439
+ if (popup) {
440
+ if (Array.isArray(popup)) {
441
+ popup.forEach(function(el) {
442
+ return (el.style.display = "none");
443
+ });
444
+ } else {
445
+ popup.style.display = "none";
446
+ }
447
+ }
448
+ };
449
+
450
+ var queriesShow = function queriesShow(link, result) {
451
+ result = result;
452
+ var px = 30,
453
+ win = window,
454
+ width = win.innerWidth - 2 * px,
455
+ height = win.innerHeight - 2 * px,
456
+ queries = result.querySelector(".profiler-queries"); // opaque background
457
+
458
+ var background = document.createElement("div");
459
+ background.classList.add("profiler-queries-bg");
460
+ document.body.appendChild(background);
461
+ background.style.height = "".concat(window.innerHeight, "px");
462
+ background.style.display = "block"; // center the queries and ensure long content is scrolled
463
+
464
+ queries.style[options.renderVerticalPosition] = "".concat(px, "px");
465
+ queries.style.maxHeight = "".concat(height, "px");
466
+ queries.style.width = "".concat(width, "px");
467
+ queries.style[options.renderHorizontalPosition] = "".concat(px, "px");
468
+ queries.querySelector("table").style.width = "".concat(width, "px"); // have to show everything before we can get a position for the first query
469
+
470
+ queries.style.display = "block";
471
+ queriesScrollIntoView(link, queries, queries); // syntax highlighting
472
+
473
+ prettyPrint();
474
+ };
475
+
476
+ var queriesScrollIntoView = function queriesScrollIntoView(
477
+ link,
478
+ queries,
479
+ whatToScroll
480
+ ) {
481
+ var id = elementClosest(link, "tr").getAttribute("data-timing-id"),
482
+ cells = toArray(
483
+ queries.querySelectorAll('tr[data-timing-id="' + id + '"]')
484
+ ); // ensure they're in view
485
+
486
+ whatToScroll.scrollTop =
487
+ (whatToScroll.scrollTop || 0) + cells[0].offsetTop - 100; // highlight and then fade back to original bg color; do it ourselves to prevent any conflicts w/ jquery.UI or other implementations of Resig's color plugin
488
+
489
+ cells.forEach(function(el) {
490
+ el.classList.add("higlight-animate");
491
+ });
492
+ setTimeout(function() {
493
+ cells.forEach(function(el) {
494
+ return el.classList.remove("higlight-animate");
495
+ });
496
+ }, 3000);
497
+ };
498
+
499
+ var onTurboBeforeVisit = function onTurboBeforeVisit(e) {
500
+ if(!e.defaultPrevented) {
501
+ window.MiniProfilerContainer = document.querySelector('body > .profiler-results')
502
+ window.MiniProfiler.pageTransition()
503
+ }
504
+ }
505
+
506
+ var onTurboLoad = function onTurboLoad(e) {
507
+ if(window.MiniProfilerContainer) {
508
+ document.body.appendChild(window.MiniProfilerContainer)
509
+ }
510
+ }
511
+
512
+ var onClickEvents = function onClickEvents(e) {
513
+ // this happens on every keystroke, and :visible is crazy expensive in IE <9
514
+ // and in this case, the display:none check is sufficient.
515
+ var popup = toArray(document.querySelectorAll(".profiler-popup")).filter(
516
+ function(el) {
517
+ return el.style.display === "block";
518
+ }
519
+ );
520
+
521
+ if (!popup.length) {
522
+ return;
523
+ }
524
+
525
+ popup = popup[0];
526
+ var button = popup.parentNode.querySelector(".profiler-button"),
527
+ queries = elementClosest(popup, ".profiler-result").querySelector(
528
+ ".profiler-queries"
529
+ ),
530
+ bg = document.querySelector(".profiler-queries-bg"),
531
+ isEscPress = e.type == "keyup" && e.which == 27,
532
+ hidePopup = false,
533
+ hideQueries = false;
534
+
535
+ if (bg && bg.style.display === "block") {
536
+ hideQueries =
537
+ isEscPress ||
538
+ (e.type == "click" &&
539
+ !(queries !== e.target && queries.contains(e.target)) &&
540
+ !(popup !== e.target && popup.contains(e.target)));
541
+ } else if (popup.style.display === "block") {
542
+ hidePopup =
543
+ isEscPress ||
544
+ (e.type == "click" &&
545
+ !(popup !== e.target && popup.contains(e.target)) &&
546
+ !(button !== e.target && button.contains(e.target)) &&
547
+ button != e.target);
548
+ }
549
+
550
+ if (hideQueries) {
551
+ bg.parentElement.removeChild(bg);
552
+ queries.style.display = "none";
553
+ }
554
+
555
+ if (hidePopup) {
556
+ popupHide(button, popup);
557
+ }
558
+ };
559
+
560
+ var keydownEvent = function keydownEvent() {
561
+ var results = document.querySelector(".profiler-results");
562
+
563
+ if (results.style.display === "none") {
564
+ results.style.display = "block";
565
+ } else {
566
+ results.style.display = "none";
567
+ }
568
+
569
+ sessionStorage["rack-mini-profiler-start-hidden"] =
570
+ results.style.display === "none";
571
+ };
572
+
573
+ var toggleShortcutEvent = function toggleShortcutEvent(e) {
574
+ // simplified version of https://github.com/jeresig/jquery.hotkeys/blob/master/jquery.hotkeys.js
575
+ var shortcut = options.toggleShortcut.toLowerCase();
576
+ var modifier = "";
577
+ ["alt", "ctrl", "shift"].forEach(function(k) {
578
+ if (e[k + "Key"]) {
579
+ modifier += "".concat(k, "+");
580
+ }
581
+ });
582
+ var specialKeys = {
583
+ 8: "backspace",
584
+ 9: "tab",
585
+ 10: "return",
586
+ 13: "return",
587
+ 16: "shift",
588
+ 17: "ctrl",
589
+ 18: "alt",
590
+ 27: "esc",
591
+ 32: "space",
592
+ 59: ";",
593
+ 61: "=",
594
+ 96: "0",
595
+ 97: "1",
596
+ 98: "2",
597
+ 99: "3",
598
+ 100: "4",
599
+ 101: "5",
600
+ 102: "6",
601
+ 103: "7",
602
+ 104: "8",
603
+ 105: "9",
604
+ 106: "*",
605
+ 107: "+",
606
+ 109: "-",
607
+ 110: ".",
608
+ 173: "-",
609
+ 186: ";",
610
+ 187: "="
611
+ };
612
+ var shiftNums = {
613
+ "`": "~",
614
+ "1": "!",
615
+ "2": "@",
616
+ "3": "#",
617
+ "4": "$",
618
+ "5": "%",
619
+ "6": "^",
620
+ "7": "&",
621
+ "8": "*",
622
+ "9": "(",
623
+ "0": ")",
624
+ "-": "_",
625
+ "=": "+",
626
+ ";": ": ",
627
+ "'": '"',
628
+ ",": "<",
629
+ ".": ">",
630
+ "/": "?",
631
+ "\\": "|"
632
+ };
633
+ var character = String.fromCharCode(e.which).toLowerCase();
634
+ var special = specialKeys[e.which];
635
+ var keys = [];
636
+
637
+ if (special) {
638
+ keys.push(special);
639
+ } else {
640
+ keys.push(character);
641
+ keys.push(shiftNums[character]);
642
+ }
643
+
644
+ for (var i = 0; i < keys.length; i++) {
645
+ if (modifier + keys[i] === shortcut) {
646
+ keydownEvent();
647
+ break;
648
+ }
649
+ }
650
+ };
651
+
652
+ var turbolinksSkipResultsFetch = function turbolinksSkipResultsFetch(event) {
653
+ event.data.xhr.__miniProfilerSkipResultsFetch = true;
654
+ };
655
+
656
+ var bindDocumentEvents = function bindDocumentEvents() {
657
+ document.addEventListener("click", onClickEvents);
658
+ document.addEventListener("keyup", onClickEvents);
659
+ document.addEventListener("keyup", toggleShortcutEvent);
660
+
661
+ if (typeof Turbolinks !== "undefined" && Turbolinks.supported) {
662
+ document.addEventListener("page:change", unbindDocumentEvents);
663
+ document.addEventListener("turbolinks:load", unbindDocumentEvents);
664
+ document.addEventListener(
665
+ "turbolinks:request-start",
666
+ turbolinksSkipResultsFetch
667
+ );
668
+ }
669
+
670
+ if (options.hotwireTurboDriveSupport) {
671
+ document.addEventListener("turbo:before-visit", onTurboBeforeVisit)
672
+ document.addEventListener("turbo:load", onTurboLoad)
673
+ }
674
+ };
675
+
676
+ var unbindDocumentEvents = function unbindDocumentEvents() {
677
+ document.removeEventListener("click", onClickEvents);
678
+ document.removeEventListener("keyup", onClickEvents);
679
+ document.removeEventListener("keyup", toggleShortcutEvent);
680
+ document.removeEventListener("page:change", unbindDocumentEvents);
681
+ document.removeEventListener("turbolinks:load", unbindDocumentEvents);
682
+ document.removeEventListener(
683
+ "turbolinks:request-start",
684
+ turbolinksSkipResultsFetch
685
+ );
686
+ document.removeEventListener("turbo:before-visit", onTurboBeforeVisit);
687
+ document.removeEventListener("turbo:load", onTurboLoad);
688
+ };
689
+
690
+ var initFullView = function initFullView() {
691
+ // profiler will be defined in the full page's head
692
+ container[0].appendChild(renderTemplate(profiler));
693
+ var popup = document.querySelector(".profiler-popup");
694
+ toggleHidden(popup);
695
+ prettyPrint(); // since queries are already shown, just highlight and scroll when clicking a "1 sql" link
696
+
697
+ toArray(popup.querySelectorAll(".profiler-queries-show")).forEach(function(
698
+ el
699
+ ) {
700
+ el.addEventListener("click", function() {
701
+ queriesScrollIntoView(
702
+ this,
703
+ document.querySelector(".profiler-queries"),
704
+ document.body
705
+ );
706
+ });
707
+ });
708
+ };
709
+
710
+ var initSnapshots = function initSnapshots(dataElement) {
711
+ var data = JSON.parse(dataElement.textContent);
712
+ var temp = document.createElement("DIV");
713
+ if (data.page === "overview") {
714
+ temp.innerHTML = MiniProfiler.templates.snapshotsGroupsList(data);
715
+ } else if (data.group_name) {
716
+ var allCustomFieldsNames = [];
717
+ data.list.forEach(function(snapshot) {
718
+ Object.keys(snapshot.custom_fields).forEach(function(k) {
719
+ if (
720
+ allCustomFieldsNames.indexOf(k) === -1 &&
721
+ options.hiddenCustomFields.indexOf(k.toLowerCase()) === -1
722
+ ) {
723
+ allCustomFieldsNames.push(k);
724
+ }
725
+ });
726
+ });
727
+ allCustomFieldsNames.sort();
728
+ temp.innerHTML = MiniProfiler.templates.snapshotsList({
729
+ data: data,
730
+ allCustomFieldsNames: allCustomFieldsNames
731
+ });
732
+ }
733
+ Array.from(temp.children).forEach(function(child) {
734
+ document.body.appendChild(child);
735
+ });
736
+ };
737
+
738
+ var initControls = function initControls(container) {
739
+ if (options.showControls) {
740
+ var _controls = document.createElement("div");
741
+
742
+ _controls.classList.add("profiler-controls");
743
+
744
+ _controls.innerHTML =
745
+ '<span class="profiler-min-max">m</span><span class="profiler-clear">c</span>';
746
+ container.appendChild(_controls);
747
+ document
748
+ .querySelector(".profiler-controls .profiler-min-max")
749
+ .addEventListener("click", function() {
750
+ return toggleClass(container, "profiler-min");
751
+ });
752
+ container.addEventListener("mouseenter", function() {
753
+ if (this.classList.contains("profiler-min")) {
754
+ this.querySelector(".profiler-min-max").style.display = "block";
755
+ }
756
+ });
757
+ container.addEventListener("mouseleave", function() {
758
+ if (this.classList.contains("profiler-min")) {
759
+ this.querySelector(".profiler-min-max").style.display = "none";
760
+ }
761
+ });
762
+ document
763
+ .querySelector(".profiler-controls .profiler-clear")
764
+ .addEventListener("click", function() {
765
+ toArray(container.querySelectorAll(".profiler-result")).forEach(
766
+ function(el) {
767
+ return el.parentElement.removeChild(el);
768
+ }
769
+ );
770
+ });
771
+ } else {
772
+ container.classList.add("profiler-no-controls");
773
+ }
774
+ };
775
+
776
+ var toggleClass = function toggleClass(el, className) {
777
+ if (el.classList) {
778
+ el.classList.toggle(className);
779
+ } else {
780
+ var classes = el.className.split(" ");
781
+ var existingIndex = classes.indexOf(className);
782
+ if (existingIndex >= 0) classes.splice(existingIndex, 1);
783
+ else classes.push(className);
784
+ el.className = classes.join(" ");
785
+ }
786
+ };
787
+
788
+ var initPopupView = function initPopupView() {
789
+ if (options.authorized) {
790
+ // all fetched profilings will go in here
791
+ container = document.createElement("div");
792
+ container.className = "profiler-results";
793
+ document.querySelector(options.htmlContainer).appendChild(container); // MiniProfiler.RenderIncludes() sets which corner to render in - default is upper left
794
+
795
+ container.classList.add("profiler-" + options.renderHorizontalPosition);
796
+ container.classList.add("profiler-" + options.renderVerticalPosition); //initialize the controls
797
+
798
+ initControls(container);
799
+ fetchResults(options.ids);
800
+
801
+ if (options.startHidden) container.style.display = "none";
802
+ } else {
803
+ fetchResults(options.ids);
804
+ }
805
+
806
+ if (!window.MiniProfiler || !window.MiniProfiler.patchesApplied) {
807
+ var send = XMLHttpRequest.prototype.send;
808
+
809
+ XMLHttpRequest.prototype.send = function(data) {
810
+ ajaxStartTime = new Date();
811
+ this.addEventListener("load", function() {
812
+ // responseURL isn't available in IE11
813
+ if (
814
+ this.responseURL &&
815
+ this.responseURL.indexOf(window.location.origin) !== 0
816
+ ) {
817
+ return;
818
+ }
819
+ if (this.__miniProfilerSkipResultsFetch) {
820
+ return;
821
+ }
822
+ // getAllResponseHeaders isn't available in Edge.
823
+ var allHeaders = this.getAllResponseHeaders
824
+ ? this.getAllResponseHeaders()
825
+ : null;
826
+ if (
827
+ allHeaders &&
828
+ allHeaders.toLowerCase().indexOf("x-miniprofiler-ids") === -1
829
+ ) {
830
+ return;
831
+ }
832
+ // should be a string of comma-separated ids
833
+ var stringIds = this.getResponseHeader("X-MiniProfiler-Ids");
834
+
835
+ if (stringIds) {
836
+ var ids = stringIds.split(",");
837
+ fetchResults(ids);
838
+ }
839
+ });
840
+ send.call(this, data);
841
+ }; // fetch results after ASP Ajax calls
842
+
843
+ if (
844
+ typeof Sys != "undefined" &&
845
+ typeof Sys.WebForms != "undefined" &&
846
+ typeof Sys.WebForms.PageRequestManager != "undefined"
847
+ ) {
848
+ // Get the instance of PageRequestManager.
849
+ var PageRequestManager = Sys.WebForms.PageRequestManager.getInstance();
850
+ PageRequestManager.add_endRequest(function(sender, args) {
851
+ if (args) {
852
+ var response = args.get_response();
853
+
854
+ if (
855
+ response.get_responseAvailable() &&
856
+ response._xmlHttpRequest !== null
857
+ ) {
858
+ var stringIds = args
859
+ .get_response()
860
+ .getResponseHeader("X-MiniProfiler-Ids");
861
+
862
+ if (stringIds) {
863
+ var ids = stringIds.split(",");
864
+ fetchResults(ids);
865
+ }
866
+ }
867
+ }
868
+ });
869
+ } // more Asp.Net callbacks
870
+
871
+ if (typeof WebForm_ExecuteCallback == "function") {
872
+ WebForm_ExecuteCallback = (function(callbackObject) {
873
+ // Store original function
874
+ var original = WebForm_ExecuteCallback;
875
+ return function(callbackObject) {
876
+ original(callbackObject);
877
+ var stringIds = callbackObject.xmlRequest.getResponseHeader(
878
+ "X-MiniProfiler-Ids"
879
+ );
880
+
881
+ if (stringIds) {
882
+ var ids = stringIds.split(",");
883
+ fetchResults(ids);
884
+ }
885
+ };
886
+ })();
887
+ } // also fetch results after ExtJS requests, in case it is being used
888
+
889
+ if (
890
+ typeof Ext != "undefined" &&
891
+ typeof Ext.Ajax != "undefined" &&
892
+ typeof Ext.Ajax.on != "undefined"
893
+ ) {
894
+ // Ext.Ajax is a singleton, so we just have to attach to its 'requestcomplete' event
895
+ Ext.Ajax.on("requestcomplete", function(e, xhr, settings) {
896
+ //iframed file uploads don't have headers
897
+ if (!xhr || !xhr.getResponseHeader) {
898
+ return;
899
+ }
900
+
901
+ var stringIds = xhr.getResponseHeader("X-MiniProfiler-Ids");
902
+
903
+ if (stringIds) {
904
+ var ids = stringIds.split(",");
905
+ fetchResults(ids);
906
+ }
907
+ });
908
+ }
909
+
910
+ if (typeof MooTools != "undefined" && typeof Request != "undefined") {
911
+ Request.prototype.addEvents({
912
+ onComplete: function onComplete() {
913
+ var stringIds = this.xhr.getResponseHeader("X-MiniProfiler-Ids");
914
+
915
+ if (stringIds) {
916
+ var ids = stringIds.split(",");
917
+ fetchResults(ids);
918
+ }
919
+ }
920
+ });
921
+ } // add support for AngularJS, which use the basic XMLHttpRequest object.
922
+
923
+ if (window.angular && typeof XMLHttpRequest != "undefined") {
924
+ var _send = XMLHttpRequest.prototype.send;
925
+
926
+ XMLHttpRequest.prototype.send = function sendReplacement(data) {
927
+ if (this.onreadystatechange) {
928
+ if (
929
+ typeof this.miniprofiler == "undefined" ||
930
+ typeof this.miniprofiler.prev_onreadystatechange == "undefined"
931
+ ) {
932
+ this.miniprofiler = {
933
+ prev_onreadystatechange: this.onreadystatechange
934
+ };
935
+
936
+ this.onreadystatechange = function onReadyStateChangeReplacement() {
937
+ if (this.readyState == 4) {
938
+ var stringIds = this.getResponseHeader("X-MiniProfiler-Ids");
939
+
940
+ if (stringIds) {
941
+ var ids = stringIds.split(",");
942
+ fetchResults(ids);
943
+ }
944
+ }
945
+
946
+ if (this.miniprofiler.prev_onreadystatechange !== null)
947
+ return this.miniprofiler.prev_onreadystatechange.apply(
948
+ this,
949
+ arguments
950
+ );
951
+ };
952
+ }
953
+ }
954
+
955
+ return _send.apply(this, arguments);
956
+ };
957
+ } // https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
958
+
959
+ if (typeof window.fetch === "function") {
960
+ var __originalFetch = window.fetch;
961
+
962
+ window.fetch = function(input, init) {
963
+ var originalFetchRun = __originalFetch(input, init);
964
+
965
+ originalFetchRun.then(function(response) {
966
+ try {
967
+ // look for x-mini-profile-ids
968
+ var entries = response.headers.entries();
969
+ var _iteratorNormalCompletion = true;
970
+ var _didIteratorError = false;
971
+ var _iteratorError = undefined;
972
+
973
+ try {
974
+ for (
975
+ var _iterator = entries[Symbol.iterator](), _step;
976
+ !(_iteratorNormalCompletion = (_step = _iterator.next())
977
+ .done);
978
+ _iteratorNormalCompletion = true
979
+ ) {
980
+ var pair = _step.value;
981
+
982
+ if (
983
+ pair[0] &&
984
+ pair[0].toLowerCase() == "x-miniprofiler-ids"
985
+ ) {
986
+ var ids = pair[1].split(",");
987
+ fetchResults(ids);
988
+ }
989
+ }
990
+ } catch (err) {
991
+ _didIteratorError = true;
992
+ _iteratorError = err;
993
+ } finally {
994
+ try {
995
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
996
+ _iterator.return();
997
+ }
998
+ } finally {
999
+ if (_didIteratorError) {
1000
+ throw _iteratorError;
1001
+ }
1002
+ }
1003
+ }
1004
+ } catch (e) {
1005
+ console.error(e);
1006
+ }
1007
+ });
1008
+ return originalFetchRun;
1009
+ };
1010
+ }
1011
+ window.MiniProfiler.patchesApplied = true;
1012
+ }
1013
+
1014
+ bindDocumentEvents();
1015
+ };
1016
+
1017
+ return {
1018
+ fetchedIds: fetchedIds,
1019
+ fetchingIds: fetchingIds,
1020
+ init: function init() {
1021
+ var script = document.getElementById("mini-profiler");
1022
+ if (!script || !script.getAttribute) return;
1023
+
1024
+ this.options = options = (function() {
1025
+ var version = script.getAttribute("data-version");
1026
+ var path = script.getAttribute("data-path");
1027
+ var currentId = script.getAttribute("data-current-id");
1028
+ var ids = script.getAttribute("data-ids");
1029
+ if (ids) ids = ids.split(",");
1030
+ var horizontal_position = script.getAttribute(
1031
+ "data-horizontal-position"
1032
+ );
1033
+ var vertical_position = script.getAttribute("data-vertical-position");
1034
+ var toggleShortcut = script.getAttribute("data-toggle-shortcut");
1035
+
1036
+ if (script.getAttribute("data-max-traces")) {
1037
+ var maxTraces = parseInt(script.getAttribute("data-max-traces"), 10);
1038
+ }
1039
+
1040
+ var collapseResults =
1041
+ script.getAttribute("data-collapse-results") === "true";
1042
+ var trivial = script.getAttribute("data-trivial") === "true";
1043
+ var children = script.getAttribute("data-children") === "true";
1044
+ var controls = script.getAttribute("data-controls") === "true";
1045
+ var totalSqlCount =
1046
+ script.getAttribute("data-total-sql-count") === "true";
1047
+ var authorized = script.getAttribute("data-authorized") === "true";
1048
+ var startHidden =
1049
+ script.getAttribute("data-start-hidden") === "true" ||
1050
+ sessionStorage["rack-mini-profiler-start-hidden"] === "true";
1051
+ var htmlContainer = script.getAttribute("data-html-container");
1052
+ var cssUrl = script.getAttribute("data-css-url");
1053
+ var hiddenCustomFields = script
1054
+ .getAttribute("data-hidden-custom-fields")
1055
+ .toLowerCase()
1056
+ .split(",");
1057
+ var hotwireTurboDriveSupport = script
1058
+ .getAttribute('data-turbo-permanent') === "true";
1059
+ return {
1060
+ ids: ids,
1061
+ path: path,
1062
+ version: version,
1063
+ renderHorizontalPosition: horizontal_position,
1064
+ renderVerticalPosition: vertical_position,
1065
+ showTrivial: trivial,
1066
+ showChildrenTime: children,
1067
+ maxTracesToShow: maxTraces,
1068
+ showControls: controls,
1069
+ showTotalSqlCount: totalSqlCount,
1070
+ currentId: currentId,
1071
+ authorized: authorized,
1072
+ toggleShortcut: toggleShortcut,
1073
+ startHidden: startHidden,
1074
+ collapseResults: collapseResults,
1075
+ htmlContainer: htmlContainer,
1076
+ cssUrl: cssUrl,
1077
+ hiddenCustomFields: hiddenCustomFields,
1078
+ hotwireTurboDriveSupport: hotwireTurboDriveSupport
1079
+ };
1080
+ })();
1081
+
1082
+ var doInit = function doInit() {
1083
+ var snapshotsElement = document.getElementById("snapshots-data");
1084
+ if (snapshotsElement != null) {
1085
+ initSnapshots(snapshotsElement);
1086
+ return;
1087
+ }
1088
+
1089
+ // when rendering a shared, full page, this div will exist
1090
+ container = document.querySelectorAll(".profiler-result-full");
1091
+
1092
+ if (container.length) {
1093
+ if (window.location.href.indexOf("&trivial=1") > 0) {
1094
+ options.showTrivial = true;
1095
+ }
1096
+
1097
+ initFullView();
1098
+ } else {
1099
+ initPopupView();
1100
+ }
1101
+ }; // this preserves debugging
1102
+
1103
+ var load = function load(s, f) {
1104
+ var sc = document.createElement("script");
1105
+ sc.async = "async";
1106
+ sc.type = "text/javascript";
1107
+ sc.src = s;
1108
+ var done = false;
1109
+
1110
+ sc.onload = sc.onreadystatechange = function(_, abort) {
1111
+ if (!sc.readyState || /loaded|complete/.test(sc.readyState)) {
1112
+ if (!abort && !done) {
1113
+ done = true;
1114
+ f();
1115
+ }
1116
+ }
1117
+ };
1118
+
1119
+ document.getElementsByTagName("head")[0].appendChild(sc);
1120
+ };
1121
+
1122
+ var wait = 0;
1123
+ var finish = false;
1124
+
1125
+ var deferInit = function deferInit() {
1126
+ if (finish) return;
1127
+
1128
+ if (
1129
+ window.performance &&
1130
+ window.performance.timing &&
1131
+ window.performance.timing.loadEventEnd === 0 &&
1132
+ wait < 10000
1133
+ ) {
1134
+ setTimeout(deferInit, 100);
1135
+ wait += 100;
1136
+ } else {
1137
+ finish = true;
1138
+ init();
1139
+ }
1140
+ };
1141
+
1142
+ var init = function init() {
1143
+ if (options.authorized) {
1144
+ var url = options.cssUrl;
1145
+
1146
+ if (document.createStyleSheet) {
1147
+ document.createStyleSheet(url);
1148
+ } else {
1149
+ var head = document.querySelector("head");
1150
+ var link = document.createElement("link");
1151
+ link.rel = "stylesheet";
1152
+ link.type = "text/css";
1153
+ link.href = url;
1154
+ head.appendChild(link);
1155
+ }
1156
+
1157
+ if (!MiniProfiler.loadedVendor) {
1158
+ load(options.path + "vendor.js?v=" + options.version, doInit);
1159
+ } else {
1160
+ doInit();
1161
+ }
1162
+ } else {
1163
+ doInit();
1164
+ }
1165
+ };
1166
+
1167
+ deferInit();
1168
+ },
1169
+ cleanUp: function cleanUp() {
1170
+ unbindDocumentEvents();
1171
+ },
1172
+ pageTransition: function pageTransition() {
1173
+ if (totalsControl) {
1174
+ if (totalsControl.parentElement) {
1175
+ totalsControl.parentElement.removeChild(totalsControl);
1176
+ }
1177
+ totalsControl = null;
1178
+ }
1179
+
1180
+ reqs = 0;
1181
+ totalTime = 0;
1182
+ totalSqlCount = 0;
1183
+ expandedResults = false;
1184
+ toArray(
1185
+ document.querySelectorAll(".profiler-results .profiler-result")
1186
+ ).forEach(function(el) {
1187
+ return el.parentElement.removeChild(el);
1188
+ });
1189
+ },
1190
+ getClientTimingByName: function getClientTimingByName(clientTiming, name) {
1191
+ for (var i = 0; i < clientTiming.timings.length; i++) {
1192
+ if (clientTiming.timings[i].name == name) {
1193
+ return clientTiming.timings[i];
1194
+ }
1195
+ }
1196
+
1197
+ return {
1198
+ Name: name,
1199
+ Duration: "",
1200
+ Start: ""
1201
+ };
1202
+ },
1203
+ renderDate: function renderDate(jsonDate) {
1204
+ // JavaScriptSerializer sends dates as /Date(1308024322065)/
1205
+ if (jsonDate) {
1206
+ return typeof jsonDate === "string"
1207
+ ? new Date(
1208
+ parseInt(jsonDate.replace("/Date(", "").replace(")/", ""), 10)
1209
+ ).toUTCString()
1210
+ : jsonDate;
1211
+ }
1212
+ },
1213
+ renderIndent: function renderIndent(depth) {
1214
+ var result = "";
1215
+
1216
+ for (var i = 0; i < depth; i++) {
1217
+ result += "&nbsp;";
1218
+ }
1219
+
1220
+ return result;
1221
+ },
1222
+ renderExecuteType: function renderExecuteType(typeId) {
1223
+ // see StackExchange.Profiling.ExecuteType enum
1224
+ switch (typeId) {
1225
+ case 0:
1226
+ return "None";
1227
+
1228
+ case 1:
1229
+ return "NonQuery";
1230
+
1231
+ case 2:
1232
+ return "Scalar";
1233
+
1234
+ case 3:
1235
+ return "Reader";
1236
+ }
1237
+ },
1238
+ shareUrl: function shareUrl(id) {
1239
+ return options.path + "results?id=" + id;
1240
+ },
1241
+ flamegraphUrl: function flamegrapgUrl(id) {
1242
+ return options.path + "flamegraph?id=" + id;
1243
+ },
1244
+ moreUrl: function moreUrl(requestName) {
1245
+ var linkSuffix = requestName.indexOf("?") > 0 ? "&pp=help" : "?pp=help";
1246
+ return requestName + linkSuffix;
1247
+ },
1248
+ getClientTimings: function getClientTimings(clientTimings) {
1249
+ var list = [];
1250
+ var t;
1251
+ if (!clientTimings.timings) return [];
1252
+
1253
+ for (var i = 0; i < clientTimings.timings.length; i++) {
1254
+ t = clientTimings.timings[i];
1255
+ var trivial = t.Name != "Dom Complete" && t.Name != "Response";
1256
+ trivial = t.Duration < 2 ? trivial : false;
1257
+ list.push({
1258
+ isTrivial: trivial,
1259
+ name: t.Name,
1260
+ duration: t.Duration,
1261
+ start: t.Start
1262
+ });
1263
+ } // Use the Paint Timing API for render performance.
1264
+
1265
+ if (window.performance && window.performance.getEntriesByName) {
1266
+ var firstPaint = window.performance.getEntriesByName("first-paint");
1267
+
1268
+ if (firstPaint !== undefined && firstPaint.length >= 1) {
1269
+ list.push({
1270
+ isTrivial: false,
1271
+ name: "First Paint Time",
1272
+ duration: firstPaint[0].duration,
1273
+ start: firstPaint[0].startTime
1274
+ });
1275
+ }
1276
+ }
1277
+
1278
+ list.sort(function(a, b) {
1279
+ return a.start - b.start;
1280
+ });
1281
+ return list;
1282
+ },
1283
+ getSqlTimings: function getSqlTimings(root) {
1284
+ var result = [],
1285
+ addToResults = function addToResults(timing) {
1286
+ if (timing.sql_timings) {
1287
+ for (var i = 0, sqlTiming; i < timing.sql_timings.length; i++) {
1288
+ sqlTiming = timing.sql_timings[i]; // HACK: add info about the parent Timing to each SqlTiming so UI can render
1289
+
1290
+ sqlTiming.parent_timing_name = timing.name;
1291
+
1292
+ if (sqlTiming.cached) {
1293
+ sqlTiming.row_class = "cached";
1294
+ }
1295
+
1296
+ if (sqlTiming.duration_milliseconds > 50) {
1297
+ sqlTiming.row_class = "slow";
1298
+ }
1299
+
1300
+ if (sqlTiming.duration_milliseconds > 200) {
1301
+ sqlTiming.row_class = "very-slow";
1302
+ }
1303
+
1304
+ if (sqlTiming.duration_milliseconds > 400) {
1305
+ sqlTiming.row_class = "very-very-slow";
1306
+ }
1307
+
1308
+ result.push(sqlTiming);
1309
+ }
1310
+ }
1311
+
1312
+ if (timing.children) {
1313
+ for (var i = 0; i < timing.children.length; i++) {
1314
+ addToResults(timing.children[i]);
1315
+ }
1316
+ }
1317
+ }; // start adding at the root and recurse down
1318
+
1319
+ addToResults(root);
1320
+
1321
+ var removeDuration = function removeDuration(list, duration) {
1322
+ var newList = [];
1323
+
1324
+ for (var i = 0; i < list.length; i++) {
1325
+ var item = list[i];
1326
+
1327
+ if (duration.start > item.start) {
1328
+ if (duration.start > item.finish) {
1329
+ newList.push(item);
1330
+ continue;
1331
+ }
1332
+
1333
+ newList.push({
1334
+ start: item.start,
1335
+ finish: duration.start
1336
+ });
1337
+ }
1338
+
1339
+ if (duration.finish < item.finish) {
1340
+ if (duration.finish < item.start) {
1341
+ newList.push(item);
1342
+ continue;
1343
+ }
1344
+
1345
+ newList.push({
1346
+ start: duration.finish,
1347
+ finish: item.finish
1348
+ });
1349
+ }
1350
+ }
1351
+
1352
+ return newList;
1353
+ };
1354
+
1355
+ var processTimes = function processTimes(elem, parent) {
1356
+ var duration = {
1357
+ start: elem.start_milliseconds,
1358
+ finish: elem.start_milliseconds + elem.duration_milliseconds
1359
+ };
1360
+ elem.richTiming = [duration];
1361
+
1362
+ if (parent !== null) {
1363
+ elem.parent = parent;
1364
+ elem.parent.richTiming = removeDuration(
1365
+ elem.parent.richTiming,
1366
+ duration
1367
+ );
1368
+ }
1369
+
1370
+ if (elem.children) {
1371
+ for (var i = 0; i < elem.children.length; i++) {
1372
+ processTimes(elem.children[i], elem);
1373
+ }
1374
+ }
1375
+ };
1376
+
1377
+ processTimes(root, null); // sort results by time
1378
+
1379
+ result.sort(function(a, b) {
1380
+ return a.start_milliseconds - b.start_milliseconds;
1381
+ });
1382
+
1383
+ var determineOverlap = function determineOverlap(gap, node) {
1384
+ var overlap = 0;
1385
+
1386
+ for (var i = 0; i < node.richTiming.length; i++) {
1387
+ var current = node.richTiming[i];
1388
+
1389
+ if (current.start > gap.finish) {
1390
+ break;
1391
+ }
1392
+
1393
+ if (current.finish < gap.start) {
1394
+ continue;
1395
+ }
1396
+
1397
+ overlap +=
1398
+ Math.min(gap.finish, current.finish) -
1399
+ Math.max(gap.start, current.start);
1400
+ }
1401
+
1402
+ return overlap;
1403
+ };
1404
+
1405
+ var determineGap = function determineGap(gap, node, match) {
1406
+ var overlap = determineOverlap(gap, node);
1407
+
1408
+ if (match === null || overlap > match.duration) {
1409
+ match = {
1410
+ name: node.name,
1411
+ duration: overlap
1412
+ };
1413
+ } else if (match.name == node.name) {
1414
+ match.duration += overlap;
1415
+ }
1416
+
1417
+ if (node.children) {
1418
+ for (var i = 0; i < node.children.length; i++) {
1419
+ match = determineGap(gap, node.children[i], match);
1420
+ }
1421
+ }
1422
+
1423
+ return match;
1424
+ };
1425
+
1426
+ var time = 0;
1427
+ var prev = null;
1428
+ result.forEach(function(r) {
1429
+ r.prevGap = {
1430
+ duration: (r.start_milliseconds - time).toFixed(2),
1431
+ start: time,
1432
+ finish: r.start_milliseconds
1433
+ };
1434
+ r.prevGap.topReason = determineGap(r.prevGap, root, null);
1435
+ time = r.start_milliseconds + r.duration_milliseconds;
1436
+ prev = r;
1437
+ });
1438
+
1439
+ if (result.length > 0) {
1440
+ var me = result[result.length - 1];
1441
+ me.nextGap = {
1442
+ duration: (root.duration_milliseconds - time).toFixed(2),
1443
+ start: time,
1444
+ finish: root.duration_milliseconds
1445
+ };
1446
+ me.nextGap.topReason = determineGap(me.nextGap, root, null);
1447
+ }
1448
+
1449
+ return result;
1450
+ },
1451
+ getSqlTimingsCount: function getSqlTimingsCount(root) {
1452
+ var result = 0,
1453
+ countSql = function countSql(timing) {
1454
+ if (timing.sql_timings) {
1455
+ result += timing.sql_timings.length;
1456
+ }
1457
+
1458
+ if (timing.children) {
1459
+ for (var i = 0; i < timing.children.length; i++) {
1460
+ countSql(timing.children[i]);
1461
+ }
1462
+ }
1463
+ };
1464
+
1465
+ countSql(root);
1466
+ return result;
1467
+ },
1468
+ fetchResultsExposed: function fetchResultsExposed(ids) {
1469
+ return fetchResults(ids);
1470
+ },
1471
+ formatParameters: function formatParameters(parameters) {
1472
+ if (parameters != null) {
1473
+ return parameters
1474
+ .map(function(item, index) {
1475
+ return "[" + item[0] + ", " + item[1] + "]";
1476
+ })
1477
+ .join(", ");
1478
+ } else {
1479
+ return "";
1480
+ }
1481
+ },
1482
+ formatDuration: function formatDuration(duration) {
1483
+ return (duration || 0).toFixed(1);
1484
+ },
1485
+ showTotalSqlCount: function showTotalSqlCount() {
1486
+ return options.showTotalSqlCount;
1487
+ },
1488
+ timestampToRelative: function timestampToRelative(timestamp) {
1489
+ var now = Math.round(new Date().getTime() / 1000);
1490
+ timestamp = Math.round(timestamp / 1000);
1491
+ var diff = now - timestamp;
1492
+ if (diff < 60) {
1493
+ return "< 1 minute";
1494
+ }
1495
+ var buildDisplayTime = function buildDisplayTime(num, unit) {
1496
+ var res = num + " " + unit;
1497
+ if (num !== 1) {
1498
+ res += "s";
1499
+ }
1500
+ return res;
1501
+ };
1502
+ diff = Math.round(diff / 60);
1503
+ if (diff <= 60) {
1504
+ return buildDisplayTime(diff, "minute");
1505
+ }
1506
+ diff = Math.round(diff / 60);
1507
+ if (diff <= 24) {
1508
+ return buildDisplayTime(diff, "hour");
1509
+ }
1510
+ diff = Math.round(diff / 24);
1511
+ return buildDisplayTime(diff, "day");
1512
+ }
1513
+ };
1514
+ })();
1515
+
1516
+ if (window.MiniProfiler) {
1517
+ _MiniProfiler.patchesApplied = window.MiniProfiler.patchesApplied;
1518
+ }
1519
+ window.MiniProfiler = _MiniProfiler;
1520
+ _MiniProfiler.init();