solid_loop 0.0.4

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 (137) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +156 -0
  3. data/CODE_OF_CONDUCT.md +67 -0
  4. data/CONTRIBUTING.md +82 -0
  5. data/MIT-LICENSE +21 -0
  6. data/README.md +483 -0
  7. data/Rakefile +11 -0
  8. data/app/assets/javascripts/solid_loop/chart.umd.min.js +14 -0
  9. data/app/assets/javascripts/solid_loop/chartjs-adapter-date-fns.bundle.min.js +7 -0
  10. data/app/assets/javascripts/solid_loop/chartkick.min.js +2 -0
  11. data/app/assets/stylesheets/solid_loop/application.css +15 -0
  12. data/app/controllers/solid_loop/application_controller.rb +29 -0
  13. data/app/controllers/solid_loop/dashboard_controller.rb +104 -0
  14. data/app/controllers/solid_loop/events_controller.rb +12 -0
  15. data/app/controllers/solid_loop/loops_controller.rb +77 -0
  16. data/app/controllers/solid_loop/mcp_inbound_sessions_controller.rb +13 -0
  17. data/app/controllers/solid_loop/mcp_sessions_controller.rb +68 -0
  18. data/app/controllers/solid_loop/mcp_tools_controller.rb +16 -0
  19. data/app/controllers/solid_loop/messages_controller.rb +12 -0
  20. data/app/controllers/solid_loop/tool_calls_controller.rb +12 -0
  21. data/app/helpers/solid_loop/application_helper.rb +125 -0
  22. data/app/jobs/solid_loop/application_job.rb +13 -0
  23. data/app/jobs/solid_loop/llm_completion_job.rb +139 -0
  24. data/app/jobs/solid_loop/observe_broadcast_job.rb +15 -0
  25. data/app/jobs/solid_loop/reaper_job.rb +20 -0
  26. data/app/jobs/solid_loop/tool_execution_job.rb +200 -0
  27. data/app/models/solid_loop/application_record.rb +5 -0
  28. data/app/models/solid_loop/base.rb +190 -0
  29. data/app/models/solid_loop/event.rb +7 -0
  30. data/app/models/solid_loop/loop.rb +225 -0
  31. data/app/models/solid_loop/mcp_inbound_session.rb +25 -0
  32. data/app/models/solid_loop/mcp_session.rb +12 -0
  33. data/app/models/solid_loop/mcp_tool.rb +26 -0
  34. data/app/models/solid_loop/message.rb +69 -0
  35. data/app/models/solid_loop/tool_call.rb +42 -0
  36. data/app/queries/solid_loop/admin/base_query.rb +23 -0
  37. data/app/queries/solid_loop/admin/events_query.rb +31 -0
  38. data/app/queries/solid_loop/admin/loops_query.rb +38 -0
  39. data/app/queries/solid_loop/admin/mcp_inbound_sessions_query.rb +31 -0
  40. data/app/queries/solid_loop/admin/mcp_sessions_query.rb +26 -0
  41. data/app/queries/solid_loop/admin/mcp_tools_query.rb +26 -0
  42. data/app/queries/solid_loop/admin/messages_query.rb +37 -0
  43. data/app/queries/solid_loop/admin/tool_calls_query.rb +34 -0
  44. data/app/services/solid_loop/adapters/native.rb +170 -0
  45. data/app/services/solid_loop/dialects/anthropic.rb +160 -0
  46. data/app/services/solid_loop/dialects/gemini.rb +122 -0
  47. data/app/services/solid_loop/dialects/open_ai.rb +62 -0
  48. data/app/services/solid_loop/dialects/reasoning_packer.rb +37 -0
  49. data/app/services/solid_loop/llm_usage_parser/anthropic.rb +22 -0
  50. data/app/services/solid_loop/llm_usage_parser/gemini.rb +18 -0
  51. data/app/services/solid_loop/llm_usage_parser/llama.rb +15 -0
  52. data/app/services/solid_loop/llm_usage_parser/openai.rb +18 -0
  53. data/app/services/solid_loop/llm_usage_parser.rb +19 -0
  54. data/app/services/solid_loop/mcp_session_initializer.rb +205 -0
  55. data/app/services/solid_loop/mcp_tool_execution_service.rb +153 -0
  56. data/app/services/solid_loop/middlewares/agent_initialization.rb +37 -0
  57. data/app/services/solid_loop/middlewares/error_handling.rb +107 -0
  58. data/app/services/solid_loop/middlewares/event_logging.rb +100 -0
  59. data/app/services/solid_loop/middlewares/message_building.rb +92 -0
  60. data/app/services/solid_loop/middlewares/network_calling.rb +84 -0
  61. data/app/services/solid_loop/middlewares/response_parsing.rb +348 -0
  62. data/app/services/solid_loop/middlewares/tool_call_xml_parser.rb +117 -0
  63. data/app/services/solid_loop/sse_stream_aggregator.rb +105 -0
  64. data/app/services/solid_loop/tool_failure_reconciler.rb +122 -0
  65. data/app/services/solid_loop/tool_middlewares/agent_initialization.rb +17 -0
  66. data/app/services/solid_loop/tool_middlewares/error_handling.rb +66 -0
  67. data/app/services/solid_loop/tool_middlewares/event_logging.rb +27 -0
  68. data/app/services/solid_loop/tool_middlewares/response_creation.rb +110 -0
  69. data/app/services/solid_loop/tool_middlewares/tool_execution.rb +206 -0
  70. data/app/views/layouts/solid_loop/admin.html.erb +416 -0
  71. data/app/views/layouts/solid_loop/application.html.erb +17 -0
  72. data/app/views/solid_loop/dashboard/index.html.erb +184 -0
  73. data/app/views/solid_loop/events/index.html.erb +47 -0
  74. data/app/views/solid_loop/events/show.html.erb +76 -0
  75. data/app/views/solid_loop/loops/index.html.erb +83 -0
  76. data/app/views/solid_loop/loops/show.html.erb +148 -0
  77. data/app/views/solid_loop/mcp_inbound_sessions/index.html.erb +53 -0
  78. data/app/views/solid_loop/mcp_inbound_sessions/show.html.erb +78 -0
  79. data/app/views/solid_loop/mcp_sessions/_tool_output.html.erb +11 -0
  80. data/app/views/solid_loop/mcp_sessions/index.html.erb +46 -0
  81. data/app/views/solid_loop/mcp_sessions/inspector.html.erb +94 -0
  82. data/app/views/solid_loop/mcp_sessions/show.html.erb +142 -0
  83. data/app/views/solid_loop/mcp_tools/index.html.erb +44 -0
  84. data/app/views/solid_loop/mcp_tools/show.html.erb +69 -0
  85. data/app/views/solid_loop/messages/_message.html.erb +75 -0
  86. data/app/views/solid_loop/messages/index.html.erb +80 -0
  87. data/app/views/solid_loop/messages/show.html.erb +121 -0
  88. data/app/views/solid_loop/shared/_pagination.html.erb +21 -0
  89. data/app/views/solid_loop/tool_calls/index.html.erb +53 -0
  90. data/app/views/solid_loop/tool_calls/show.html.erb +59 -0
  91. data/config/routes.rb +27 -0
  92. data/db/migrate/20260408000100_solid_loop_init.rb +136 -0
  93. data/db/migrate/20260709000100_solid_loop_create_mcp_inbound_sessions.rb +16 -0
  94. data/db/migrate/20260713000100_solid_loop_add_execution_guards.rb +6 -0
  95. data/db/migrate/20260714000100_solid_loop_add_message_steering.rb +17 -0
  96. data/db/migrate/20260714000200_solid_loop_add_message_conversation_order.rb +14 -0
  97. data/db/migrate/20260715000100_solid_loop_add_mcp_inbound_session_principal_key.rb +43 -0
  98. data/db/migrate/20260715000200_solid_loop_add_llm_lease.rb +40 -0
  99. data/db/migrate/20260715000300_solid_loop_add_tool_lease.rb +33 -0
  100. data/db/migrate/20260715000400_solid_loop_add_lease_running_check.rb +32 -0
  101. data/db/migrate/20260715000500_solid_loop_add_tool_lease_pair_check.rb +35 -0
  102. data/docs/contributing/coverage.md +64 -0
  103. data/docs/decisions/durable_attempt_lease.md +364 -0
  104. data/docs/decisions/mcp-only-tooling.md +135 -0
  105. data/docs/decisions/mcp-server.md +223 -0
  106. data/docs/decisions/reasoning_persistence.md +51 -0
  107. data/docs/decisions/ruby_llm_rejected.md +35 -0
  108. data/docs/guides/dialects.md +55 -0
  109. data/docs/guides/llm_middlewares.md +294 -0
  110. data/docs/guides/mcp_transports.md +374 -0
  111. data/docs/guides/tool_middlewares.md +148 -0
  112. data/lib/solid_loop/configuration.rb +175 -0
  113. data/lib/solid_loop/engine.rb +14 -0
  114. data/lib/solid_loop/lease_heartbeat.rb +94 -0
  115. data/lib/solid_loop/lease_renewer.rb +347 -0
  116. data/lib/solid_loop/llm_metrics.rb +16 -0
  117. data/lib/solid_loop/mcp/call_context.rb +19 -0
  118. data/lib/solid_loop/mcp/client_factory.rb +61 -0
  119. data/lib/solid_loop/mcp/http_transport.rb +52 -0
  120. data/lib/solid_loop/mcp/principal.rb +82 -0
  121. data/lib/solid_loop/mcp/result.rb +13 -0
  122. data/lib/solid_loop/mcp/server.rb +246 -0
  123. data/lib/solid_loop/mcp/stdio_transport.rb +224 -0
  124. data/lib/solid_loop/mcp/toolset.rb +347 -0
  125. data/lib/solid_loop/mcp/transport.rb +20 -0
  126. data/lib/solid_loop/mcp.rb +25 -0
  127. data/lib/solid_loop/mcp_client.rb +176 -0
  128. data/lib/solid_loop/pipeline/builder.rb +38 -0
  129. data/lib/solid_loop/pipeline/context.rb +61 -0
  130. data/lib/solid_loop/pipeline/tool_context.rb +53 -0
  131. data/lib/solid_loop/pipeline.rb +40 -0
  132. data/lib/solid_loop/reaper.rb +313 -0
  133. data/lib/solid_loop/version.rb +3 -0
  134. data/lib/solid_loop.rb +94 -0
  135. data/lib/tasks/coverage.rake +206 -0
  136. data/lib/tasks/solid_loop_tasks.rake +4 -0
  137. metadata +228 -0
@@ -0,0 +1,7 @@
1
+ /*!
2
+ * chartjs-adapter-date-fns v3.0.0
3
+ * https://www.chartjs.org
4
+ * (c) 2022 chartjs-adapter-date-fns Contributors
5
+ * Released under the MIT license
6
+ */
7
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(require("chart.js")):"function"==typeof define&&define.amd?define(["chart.js"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).Chart)}(this,(function(t){"use strict";function e(t){if(null===t||!0===t||!1===t)return NaN;var e=Number(t);return isNaN(e)?e:e<0?Math.ceil(e):Math.floor(e)}function r(t,e){if(e.length<t)throw new TypeError(t+" argument"+(t>1?"s":"")+" required, but only "+e.length+" present")}function n(t){r(1,arguments);var e=Object.prototype.toString.call(t);return t instanceof Date||"object"==typeof t&&"[object Date]"===e?new Date(t.getTime()):"number"==typeof t||"[object Number]"===e?new Date(t):("string"!=typeof t&&"[object String]"!==e||"undefined"==typeof console||(console.warn("Starting with v2.0.0-beta.1 date-fns doesn't accept strings as date arguments. Please use `parseISO` to parse strings. See: https://git.io/fjule"),console.warn((new Error).stack)),new Date(NaN))}function a(t,a){r(2,arguments);var i=n(t),o=e(a);return isNaN(o)?new Date(NaN):o?(i.setDate(i.getDate()+o),i):i}function i(t,a){r(2,arguments);var i=n(t),o=e(a);if(isNaN(o))return new Date(NaN);if(!o)return i;var u=i.getDate(),s=new Date(i.getTime());s.setMonth(i.getMonth()+o+1,0);var c=s.getDate();return u>=c?s:(i.setFullYear(s.getFullYear(),s.getMonth(),u),i)}function o(t,a){r(2,arguments);var i=n(t).getTime(),o=e(a);return new Date(i+o)}var u=36e5;function s(t,a){r(1,arguments);var i=a||{},o=i.locale,u=o&&o.options&&o.options.weekStartsOn,s=null==u?0:e(u),c=null==i.weekStartsOn?s:e(i.weekStartsOn);if(!(c>=0&&c<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");var d=n(t),l=d.getDay(),f=(l<c?7:0)+l-c;return d.setDate(d.getDate()-f),d.setHours(0,0,0,0),d}function c(t){var e=new Date(Date.UTC(t.getFullYear(),t.getMonth(),t.getDate(),t.getHours(),t.getMinutes(),t.getSeconds(),t.getMilliseconds()));return e.setUTCFullYear(t.getFullYear()),t.getTime()-e.getTime()}function d(t){r(1,arguments);var e=n(t);return e.setHours(0,0,0,0),e}var l=864e5;function f(t,e){r(2,arguments);var n=d(t),a=d(e),i=n.getTime()-c(n),o=a.getTime()-c(a);return Math.round((i-o)/l)}function h(t,e){r(2,arguments);var a=n(t),i=n(e),o=a.getTime()-i.getTime();return o<0?-1:o>0?1:o}function m(t){r(1,arguments);var e=n(t);return!isNaN(e)}function w(t,e){r(2,arguments);var a=n(t),i=n(e),o=a.getFullYear()-i.getFullYear(),u=a.getMonth()-i.getMonth();return 12*o+u}function g(t,e){r(2,arguments);var a=n(t),i=n(e);return a.getFullYear()-i.getFullYear()}function v(t,e){var r=t.getFullYear()-e.getFullYear()||t.getMonth()-e.getMonth()||t.getDate()-e.getDate()||t.getHours()-e.getHours()||t.getMinutes()-e.getMinutes()||t.getSeconds()-e.getSeconds()||t.getMilliseconds()-e.getMilliseconds();return r<0?-1:r>0?1:r}function y(t,e){r(2,arguments);var a=n(t),i=n(e),o=v(a,i),u=Math.abs(f(a,i));a.setDate(a.getDate()-o*u);var s=v(a,i)===-o,c=o*(u-s);return 0===c?0:c}function b(t,e){r(2,arguments);var a=n(t),i=n(e);return a.getTime()-i.getTime()}var T=36e5;function p(t){r(1,arguments);var e=n(t);return e.setHours(23,59,59,999),e}function C(t){r(1,arguments);var e=n(t),a=e.getMonth();return e.setFullYear(e.getFullYear(),a+1,0),e.setHours(23,59,59,999),e}function M(t){r(1,arguments);var e=n(t);return p(e).getTime()===C(e).getTime()}function D(t,e){r(2,arguments);var a,i=n(t),o=n(e),u=h(i,o),s=Math.abs(w(i,o));if(s<1)a=0;else{1===i.getMonth()&&i.getDate()>27&&i.setDate(30),i.setMonth(i.getMonth()-u*s);var c=h(i,o)===-u;M(n(t))&&1===s&&1===h(t,o)&&(c=!1),a=u*(s-c)}return 0===a?0:a}var x={lessThanXSeconds:{one:"less than a second",other:"less than {{count}} seconds"},xSeconds:{one:"1 second",other:"{{count}} seconds"},halfAMinute:"half a minute",lessThanXMinutes:{one:"less than a minute",other:"less than {{count}} minutes"},xMinutes:{one:"1 minute",other:"{{count}} minutes"},aboutXHours:{one:"about 1 hour",other:"about {{count}} hours"},xHours:{one:"1 hour",other:"{{count}} hours"},xDays:{one:"1 day",other:"{{count}} days"},aboutXWeeks:{one:"about 1 week",other:"about {{count}} weeks"},xWeeks:{one:"1 week",other:"{{count}} weeks"},aboutXMonths:{one:"about 1 month",other:"about {{count}} months"},xMonths:{one:"1 month",other:"{{count}} months"},aboutXYears:{one:"about 1 year",other:"about {{count}} years"},xYears:{one:"1 year",other:"{{count}} years"},overXYears:{one:"over 1 year",other:"over {{count}} years"},almostXYears:{one:"almost 1 year",other:"almost {{count}} years"}};function k(t){return function(e){var r=e||{},n=r.width?String(r.width):t.defaultWidth;return t.formats[n]||t.formats[t.defaultWidth]}}var U={date:k({formats:{full:"EEEE, MMMM do, y",long:"MMMM do, y",medium:"MMM d, y",short:"MM/dd/yyyy"},defaultWidth:"full"}),time:k({formats:{full:"h:mm:ss a zzzz",long:"h:mm:ss a z",medium:"h:mm:ss a",short:"h:mm a"},defaultWidth:"full"}),dateTime:k({formats:{full:"{{date}} 'at' {{time}}",long:"{{date}} 'at' {{time}}",medium:"{{date}}, {{time}}",short:"{{date}}, {{time}}"},defaultWidth:"full"})},Y={lastWeek:"'last' eeee 'at' p",yesterday:"'yesterday at' p",today:"'today at' p",tomorrow:"'tomorrow at' p",nextWeek:"eeee 'at' p",other:"P"};function N(t){return function(e,r){var n,a=r||{};if("formatting"===(a.context?String(a.context):"standalone")&&t.formattingValues){var i=t.defaultFormattingWidth||t.defaultWidth,o=a.width?String(a.width):i;n=t.formattingValues[o]||t.formattingValues[i]}else{var u=t.defaultWidth,s=a.width?String(a.width):t.defaultWidth;n=t.values[s]||t.values[u]}return n[t.argumentCallback?t.argumentCallback(e):e]}}function S(t){return function(e,r){var n=String(e),a=r||{},i=a.width,o=i&&t.matchPatterns[i]||t.matchPatterns[t.defaultMatchWidth],u=n.match(o);if(!u)return null;var s,c=u[0],d=i&&t.parsePatterns[i]||t.parsePatterns[t.defaultParseWidth];return s="[object Array]"===Object.prototype.toString.call(d)?function(t,e){for(var r=0;r<t.length;r++)if(e(t[r]))return r}(d,(function(t){return t.test(c)})):function(t,e){for(var r in t)if(t.hasOwnProperty(r)&&e(t[r]))return r}(d,(function(t){return t.test(c)})),s=t.valueCallback?t.valueCallback(s):s,{value:s=a.valueCallback?a.valueCallback(s):s,rest:n.slice(c.length)}}}var P,q={code:"en-US",formatDistance:function(t,e,r){var n;return r=r||{},n="string"==typeof x[t]?x[t]:1===e?x[t].one:x[t].other.replace("{{count}}",e),r.addSuffix?r.comparison>0?"in "+n:n+" ago":n},formatLong:U,formatRelative:function(t,e,r,n){return Y[t]},localize:{ordinalNumber:function(t,e){var r=Number(t),n=r%100;if(n>20||n<10)switch(n%10){case 1:return r+"st";case 2:return r+"nd";case 3:return r+"rd"}return r+"th"},era:N({values:{narrow:["B","A"],abbreviated:["BC","AD"],wide:["Before Christ","Anno Domini"]},defaultWidth:"wide"}),quarter:N({values:{narrow:["1","2","3","4"],abbreviated:["Q1","Q2","Q3","Q4"],wide:["1st quarter","2nd quarter","3rd quarter","4th quarter"]},defaultWidth:"wide",argumentCallback:function(t){return Number(t)-1}}),month:N({values:{narrow:["J","F","M","A","M","J","J","A","S","O","N","D"],abbreviated:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],wide:["January","February","March","April","May","June","July","August","September","October","November","December"]},defaultWidth:"wide"}),day:N({values:{narrow:["S","M","T","W","T","F","S"],short:["Su","Mo","Tu","We","Th","Fr","Sa"],abbreviated:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],wide:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]},defaultWidth:"wide"}),dayPeriod:N({values:{narrow:{am:"a",pm:"p",midnight:"mi",noon:"n",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"},abbreviated:{am:"AM",pm:"PM",midnight:"midnight",noon:"noon",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"},wide:{am:"a.m.",pm:"p.m.",midnight:"midnight",noon:"noon",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"}},defaultWidth:"wide",formattingValues:{narrow:{am:"a",pm:"p",midnight:"mi",noon:"n",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"},abbreviated:{am:"AM",pm:"PM",midnight:"midnight",noon:"noon",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"},wide:{am:"a.m.",pm:"p.m.",midnight:"midnight",noon:"noon",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"}},defaultFormattingWidth:"wide"})},match:{ordinalNumber:(P={matchPattern:/^(\d+)(th|st|nd|rd)?/i,parsePattern:/\d+/i,valueCallback:function(t){return parseInt(t,10)}},function(t,e){var r=String(t),n=e||{},a=r.match(P.matchPattern);if(!a)return null;var i=a[0],o=r.match(P.parsePattern);if(!o)return null;var u=P.valueCallback?P.valueCallback(o[0]):o[0];return{value:u=n.valueCallback?n.valueCallback(u):u,rest:r.slice(i.length)}}),era:S({matchPatterns:{narrow:/^(b|a)/i,abbreviated:/^(b\.?\s?c\.?|b\.?\s?c\.?\s?e\.?|a\.?\s?d\.?|c\.?\s?e\.?)/i,wide:/^(before christ|before common era|anno domini|common era)/i},defaultMatchWidth:"wide",parsePatterns:{any:[/^b/i,/^(a|c)/i]},defaultParseWidth:"any"}),quarter:S({matchPatterns:{narrow:/^[1234]/i,abbreviated:/^q[1234]/i,wide:/^[1234](th|st|nd|rd)? quarter/i},defaultMatchWidth:"wide",parsePatterns:{any:[/1/i,/2/i,/3/i,/4/i]},defaultParseWidth:"any",valueCallback:function(t){return t+1}}),month:S({matchPatterns:{narrow:/^[jfmasond]/i,abbreviated:/^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,wide:/^(january|february|march|april|may|june|july|august|september|october|november|december)/i},defaultMatchWidth:"wide",parsePatterns:{narrow:[/^j/i,/^f/i,/^m/i,/^a/i,/^m/i,/^j/i,/^j/i,/^a/i,/^s/i,/^o/i,/^n/i,/^d/i],any:[/^ja/i,/^f/i,/^mar/i,/^ap/i,/^may/i,/^jun/i,/^jul/i,/^au/i,/^s/i,/^o/i,/^n/i,/^d/i]},defaultParseWidth:"any"}),day:S({matchPatterns:{narrow:/^[smtwf]/i,short:/^(su|mo|tu|we|th|fr|sa)/i,abbreviated:/^(sun|mon|tue|wed|thu|fri|sat)/i,wide:/^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i},defaultMatchWidth:"wide",parsePatterns:{narrow:[/^s/i,/^m/i,/^t/i,/^w/i,/^t/i,/^f/i,/^s/i],any:[/^su/i,/^m/i,/^tu/i,/^w/i,/^th/i,/^f/i,/^sa/i]},defaultParseWidth:"any"}),dayPeriod:S({matchPatterns:{narrow:/^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,any:/^([ap]\.?\s?m\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i},defaultMatchWidth:"any",parsePatterns:{any:{am:/^a/i,pm:/^p/i,midnight:/^mi/i,noon:/^no/i,morning:/morning/i,afternoon:/afternoon/i,evening:/evening/i,night:/night/i}},defaultParseWidth:"any"})},options:{weekStartsOn:0,firstWeekContainsDate:1}};function H(t,n){r(2,arguments);var a=e(n);return o(t,-a)}function E(t,e){for(var r=t<0?"-":"",n=Math.abs(t).toString();n.length<e;)n="0"+n;return r+n}var O={y:function(t,e){var r=t.getUTCFullYear(),n=r>0?r:1-r;return E("yy"===e?n%100:n,e.length)},M:function(t,e){var r=t.getUTCMonth();return"M"===e?String(r+1):E(r+1,2)},d:function(t,e){return E(t.getUTCDate(),e.length)},a:function(t,e){var r=t.getUTCHours()/12>=1?"pm":"am";switch(e){case"a":case"aa":return r.toUpperCase();case"aaa":return r;case"aaaaa":return r[0];default:return"am"===r?"a.m.":"p.m."}},h:function(t,e){return E(t.getUTCHours()%12||12,e.length)},H:function(t,e){return E(t.getUTCHours(),e.length)},m:function(t,e){return E(t.getUTCMinutes(),e.length)},s:function(t,e){return E(t.getUTCSeconds(),e.length)},S:function(t,e){var r=e.length,n=t.getUTCMilliseconds();return E(Math.floor(n*Math.pow(10,r-3)),e.length)}},F=864e5;function W(t){r(1,arguments);var e=1,a=n(t),i=a.getUTCDay(),o=(i<e?7:0)+i-e;return a.setUTCDate(a.getUTCDate()-o),a.setUTCHours(0,0,0,0),a}function L(t){r(1,arguments);var e=n(t),a=e.getUTCFullYear(),i=new Date(0);i.setUTCFullYear(a+1,0,4),i.setUTCHours(0,0,0,0);var o=W(i),u=new Date(0);u.setUTCFullYear(a,0,4),u.setUTCHours(0,0,0,0);var s=W(u);return e.getTime()>=o.getTime()?a+1:e.getTime()>=s.getTime()?a:a-1}function Q(t){r(1,arguments);var e=L(t),n=new Date(0);n.setUTCFullYear(e,0,4),n.setUTCHours(0,0,0,0);var a=W(n);return a}var R=6048e5;function I(t){r(1,arguments);var e=n(t),a=W(e).getTime()-Q(e).getTime();return Math.round(a/R)+1}function G(t,a){r(1,arguments);var i=a||{},o=i.locale,u=o&&o.options&&o.options.weekStartsOn,s=null==u?0:e(u),c=null==i.weekStartsOn?s:e(i.weekStartsOn);if(!(c>=0&&c<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");var d=n(t),l=d.getUTCDay(),f=(l<c?7:0)+l-c;return d.setUTCDate(d.getUTCDate()-f),d.setUTCHours(0,0,0,0),d}function X(t,a){r(1,arguments);var i=n(t,a),o=i.getUTCFullYear(),u=a||{},s=u.locale,c=s&&s.options&&s.options.firstWeekContainsDate,d=null==c?1:e(c),l=null==u.firstWeekContainsDate?d:e(u.firstWeekContainsDate);if(!(l>=1&&l<=7))throw new RangeError("firstWeekContainsDate must be between 1 and 7 inclusively");var f=new Date(0);f.setUTCFullYear(o+1,0,l),f.setUTCHours(0,0,0,0);var h=G(f,a),m=new Date(0);m.setUTCFullYear(o,0,l),m.setUTCHours(0,0,0,0);var w=G(m,a);return i.getTime()>=h.getTime()?o+1:i.getTime()>=w.getTime()?o:o-1}function j(t,n){r(1,arguments);var a=n||{},i=a.locale,o=i&&i.options&&i.options.firstWeekContainsDate,u=null==o?1:e(o),s=null==a.firstWeekContainsDate?u:e(a.firstWeekContainsDate),c=X(t,n),d=new Date(0);d.setUTCFullYear(c,0,s),d.setUTCHours(0,0,0,0);var l=G(d,n);return l}var B=6048e5;function z(t,e){r(1,arguments);var a=n(t),i=G(a,e).getTime()-j(a,e).getTime();return Math.round(i/B)+1}var A="midnight",Z="noon",K="morning",$="afternoon",_="evening",J="night",V={G:function(t,e,r){var n=t.getUTCFullYear()>0?1:0;switch(e){case"G":case"GG":case"GGG":return r.era(n,{width:"abbreviated"});case"GGGGG":return r.era(n,{width:"narrow"});default:return r.era(n,{width:"wide"})}},y:function(t,e,r){if("yo"===e){var n=t.getUTCFullYear(),a=n>0?n:1-n;return r.ordinalNumber(a,{unit:"year"})}return O.y(t,e)},Y:function(t,e,r,n){var a=X(t,n),i=a>0?a:1-a;return"YY"===e?E(i%100,2):"Yo"===e?r.ordinalNumber(i,{unit:"year"}):E(i,e.length)},R:function(t,e){return E(L(t),e.length)},u:function(t,e){return E(t.getUTCFullYear(),e.length)},Q:function(t,e,r){var n=Math.ceil((t.getUTCMonth()+1)/3);switch(e){case"Q":return String(n);case"QQ":return E(n,2);case"Qo":return r.ordinalNumber(n,{unit:"quarter"});case"QQQ":return r.quarter(n,{width:"abbreviated",context:"formatting"});case"QQQQQ":return r.quarter(n,{width:"narrow",context:"formatting"});default:return r.quarter(n,{width:"wide",context:"formatting"})}},q:function(t,e,r){var n=Math.ceil((t.getUTCMonth()+1)/3);switch(e){case"q":return String(n);case"qq":return E(n,2);case"qo":return r.ordinalNumber(n,{unit:"quarter"});case"qqq":return r.quarter(n,{width:"abbreviated",context:"standalone"});case"qqqqq":return r.quarter(n,{width:"narrow",context:"standalone"});default:return r.quarter(n,{width:"wide",context:"standalone"})}},M:function(t,e,r){var n=t.getUTCMonth();switch(e){case"M":case"MM":return O.M(t,e);case"Mo":return r.ordinalNumber(n+1,{unit:"month"});case"MMM":return r.month(n,{width:"abbreviated",context:"formatting"});case"MMMMM":return r.month(n,{width:"narrow",context:"formatting"});default:return r.month(n,{width:"wide",context:"formatting"})}},L:function(t,e,r){var n=t.getUTCMonth();switch(e){case"L":return String(n+1);case"LL":return E(n+1,2);case"Lo":return r.ordinalNumber(n+1,{unit:"month"});case"LLL":return r.month(n,{width:"abbreviated",context:"standalone"});case"LLLLL":return r.month(n,{width:"narrow",context:"standalone"});default:return r.month(n,{width:"wide",context:"standalone"})}},w:function(t,e,r,n){var a=z(t,n);return"wo"===e?r.ordinalNumber(a,{unit:"week"}):E(a,e.length)},I:function(t,e,r){var n=I(t);return"Io"===e?r.ordinalNumber(n,{unit:"week"}):E(n,e.length)},d:function(t,e,r){return"do"===e?r.ordinalNumber(t.getUTCDate(),{unit:"date"}):O.d(t,e)},D:function(t,e,a){var i=function(t){r(1,arguments);var e=n(t),a=e.getTime();e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0);var i=e.getTime(),o=a-i;return Math.floor(o/F)+1}(t);return"Do"===e?a.ordinalNumber(i,{unit:"dayOfYear"}):E(i,e.length)},E:function(t,e,r){var n=t.getUTCDay();switch(e){case"E":case"EE":case"EEE":return r.day(n,{width:"abbreviated",context:"formatting"});case"EEEEE":return r.day(n,{width:"narrow",context:"formatting"});case"EEEEEE":return r.day(n,{width:"short",context:"formatting"});default:return r.day(n,{width:"wide",context:"formatting"})}},e:function(t,e,r,n){var a=t.getUTCDay(),i=(a-n.weekStartsOn+8)%7||7;switch(e){case"e":return String(i);case"ee":return E(i,2);case"eo":return r.ordinalNumber(i,{unit:"day"});case"eee":return r.day(a,{width:"abbreviated",context:"formatting"});case"eeeee":return r.day(a,{width:"narrow",context:"formatting"});case"eeeeee":return r.day(a,{width:"short",context:"formatting"});default:return r.day(a,{width:"wide",context:"formatting"})}},c:function(t,e,r,n){var a=t.getUTCDay(),i=(a-n.weekStartsOn+8)%7||7;switch(e){case"c":return String(i);case"cc":return E(i,e.length);case"co":return r.ordinalNumber(i,{unit:"day"});case"ccc":return r.day(a,{width:"abbreviated",context:"standalone"});case"ccccc":return r.day(a,{width:"narrow",context:"standalone"});case"cccccc":return r.day(a,{width:"short",context:"standalone"});default:return r.day(a,{width:"wide",context:"standalone"})}},i:function(t,e,r){var n=t.getUTCDay(),a=0===n?7:n;switch(e){case"i":return String(a);case"ii":return E(a,e.length);case"io":return r.ordinalNumber(a,{unit:"day"});case"iii":return r.day(n,{width:"abbreviated",context:"formatting"});case"iiiii":return r.day(n,{width:"narrow",context:"formatting"});case"iiiiii":return r.day(n,{width:"short",context:"formatting"});default:return r.day(n,{width:"wide",context:"formatting"})}},a:function(t,e,r){var n=t.getUTCHours()/12>=1?"pm":"am";switch(e){case"a":case"aa":return r.dayPeriod(n,{width:"abbreviated",context:"formatting"});case"aaa":return r.dayPeriod(n,{width:"abbreviated",context:"formatting"}).toLowerCase();case"aaaaa":return r.dayPeriod(n,{width:"narrow",context:"formatting"});default:return r.dayPeriod(n,{width:"wide",context:"formatting"})}},b:function(t,e,r){var n,a=t.getUTCHours();switch(n=12===a?Z:0===a?A:a/12>=1?"pm":"am",e){case"b":case"bb":return r.dayPeriod(n,{width:"abbreviated",context:"formatting"});case"bbb":return r.dayPeriod(n,{width:"abbreviated",context:"formatting"}).toLowerCase();case"bbbbb":return r.dayPeriod(n,{width:"narrow",context:"formatting"});default:return r.dayPeriod(n,{width:"wide",context:"formatting"})}},B:function(t,e,r){var n,a=t.getUTCHours();switch(n=a>=17?_:a>=12?$:a>=4?K:J,e){case"B":case"BB":case"BBB":return r.dayPeriod(n,{width:"abbreviated",context:"formatting"});case"BBBBB":return r.dayPeriod(n,{width:"narrow",context:"formatting"});default:return r.dayPeriod(n,{width:"wide",context:"formatting"})}},h:function(t,e,r){if("ho"===e){var n=t.getUTCHours()%12;return 0===n&&(n=12),r.ordinalNumber(n,{unit:"hour"})}return O.h(t,e)},H:function(t,e,r){return"Ho"===e?r.ordinalNumber(t.getUTCHours(),{unit:"hour"}):O.H(t,e)},K:function(t,e,r){var n=t.getUTCHours()%12;return"Ko"===e?r.ordinalNumber(n,{unit:"hour"}):E(n,e.length)},k:function(t,e,r){var n=t.getUTCHours();return 0===n&&(n=24),"ko"===e?r.ordinalNumber(n,{unit:"hour"}):E(n,e.length)},m:function(t,e,r){return"mo"===e?r.ordinalNumber(t.getUTCMinutes(),{unit:"minute"}):O.m(t,e)},s:function(t,e,r){return"so"===e?r.ordinalNumber(t.getUTCSeconds(),{unit:"second"}):O.s(t,e)},S:function(t,e){return O.S(t,e)},X:function(t,e,r,n){var a=(n._originalDate||t).getTimezoneOffset();if(0===a)return"Z";switch(e){case"X":return et(a);case"XXXX":case"XX":return rt(a);default:return rt(a,":")}},x:function(t,e,r,n){var a=(n._originalDate||t).getTimezoneOffset();switch(e){case"x":return et(a);case"xxxx":case"xx":return rt(a);default:return rt(a,":")}},O:function(t,e,r,n){var a=(n._originalDate||t).getTimezoneOffset();switch(e){case"O":case"OO":case"OOO":return"GMT"+tt(a,":");default:return"GMT"+rt(a,":")}},z:function(t,e,r,n){var a=(n._originalDate||t).getTimezoneOffset();switch(e){case"z":case"zz":case"zzz":return"GMT"+tt(a,":");default:return"GMT"+rt(a,":")}},t:function(t,e,r,n){var a=n._originalDate||t;return E(Math.floor(a.getTime()/1e3),e.length)},T:function(t,e,r,n){return E((n._originalDate||t).getTime(),e.length)}};function tt(t,e){var r=t>0?"-":"+",n=Math.abs(t),a=Math.floor(n/60),i=n%60;if(0===i)return r+String(a);var o=e||"";return r+String(a)+o+E(i,2)}function et(t,e){return t%60==0?(t>0?"-":"+")+E(Math.abs(t)/60,2):rt(t,e)}function rt(t,e){var r=e||"",n=t>0?"-":"+",a=Math.abs(t);return n+E(Math.floor(a/60),2)+r+E(a%60,2)}var nt=V;function at(t,e){switch(t){case"P":return e.date({width:"short"});case"PP":return e.date({width:"medium"});case"PPP":return e.date({width:"long"});default:return e.date({width:"full"})}}function it(t,e){switch(t){case"p":return e.time({width:"short"});case"pp":return e.time({width:"medium"});case"ppp":return e.time({width:"long"});default:return e.time({width:"full"})}}var ot={p:it,P:function(t,e){var r,n=t.match(/(P+)(p+)?/),a=n[1],i=n[2];if(!i)return at(t,e);switch(a){case"P":r=e.dateTime({width:"short"});break;case"PP":r=e.dateTime({width:"medium"});break;case"PPP":r=e.dateTime({width:"long"});break;default:r=e.dateTime({width:"full"})}return r.replace("{{date}}",at(a,e)).replace("{{time}}",it(i,e))}},ut=ot,st=["D","DD"],ct=["YY","YYYY"];function dt(t){return-1!==st.indexOf(t)}function lt(t){return-1!==ct.indexOf(t)}function ft(t,e,r){if("YYYY"===t)throw new RangeError("Use `yyyy` instead of `YYYY` (in `".concat(e,"`) for formatting years to the input `").concat(r,"`; see: https://git.io/fxCyr"));if("YY"===t)throw new RangeError("Use `yy` instead of `YY` (in `".concat(e,"`) for formatting years to the input `").concat(r,"`; see: https://git.io/fxCyr"));if("D"===t)throw new RangeError("Use `d` instead of `D` (in `".concat(e,"`) for formatting days of the month to the input `").concat(r,"`; see: https://git.io/fxCyr"));if("DD"===t)throw new RangeError("Use `dd` instead of `DD` (in `".concat(e,"`) for formatting days of the month to the input `").concat(r,"`; see: https://git.io/fxCyr"))}var ht=/[yYQqMLwIdDecihHKkms]o|(\w)\1*|''|'(''|[^'])+('|$)|./g,mt=/P+p+|P+|p+|''|'(''|[^'])+('|$)|./g,wt=/^'([^]*?)'?$/,gt=/''/g,vt=/[a-zA-Z]/;function yt(t){return t.match(wt)[1].replace(gt,"'")}function bt(t,e){if(null==t)throw new TypeError("assign requires that input parameter not be null or undefined");for(var r in e=e||{})e.hasOwnProperty(r)&&(t[r]=e[r]);return t}function Tt(t,a,i){r(2,arguments);var o=i||{},u=o.locale,s=u&&u.options&&u.options.weekStartsOn,c=null==s?0:e(s),d=null==o.weekStartsOn?c:e(o.weekStartsOn);if(!(d>=0&&d<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");var l=n(t),f=e(a),h=l.getUTCDay(),m=f%7,w=(m+7)%7,g=(w<d?7:0)+f-h;return l.setUTCDate(l.getUTCDate()+g),l}var pt=/^(1[0-2]|0?\d)/,Ct=/^(3[0-1]|[0-2]?\d)/,Mt=/^(36[0-6]|3[0-5]\d|[0-2]?\d?\d)/,Dt=/^(5[0-3]|[0-4]?\d)/,xt=/^(2[0-3]|[0-1]?\d)/,kt=/^(2[0-4]|[0-1]?\d)/,Ut=/^(1[0-1]|0?\d)/,Yt=/^(1[0-2]|0?\d)/,Nt=/^[0-5]?\d/,St=/^[0-5]?\d/,Pt=/^\d/,qt=/^\d{1,2}/,Ht=/^\d{1,3}/,Et=/^\d{1,4}/,Ot=/^-?\d+/,Ft=/^-?\d/,Wt=/^-?\d{1,2}/,Lt=/^-?\d{1,3}/,Qt=/^-?\d{1,4}/,Rt=/^([+-])(\d{2})(\d{2})?|Z/,It=/^([+-])(\d{2})(\d{2})|Z/,Gt=/^([+-])(\d{2})(\d{2})((\d{2}))?|Z/,Xt=/^([+-])(\d{2}):(\d{2})|Z/,jt=/^([+-])(\d{2}):(\d{2})(:(\d{2}))?|Z/;function Bt(t,e,r){var n=e.match(t);if(!n)return null;var a=parseInt(n[0],10);return{value:r?r(a):a,rest:e.slice(n[0].length)}}function zt(t,e){var r=e.match(t);return r?"Z"===r[0]?{value:0,rest:e.slice(1)}:{value:("+"===r[1]?1:-1)*(36e5*(r[2]?parseInt(r[2],10):0)+6e4*(r[3]?parseInt(r[3],10):0)+1e3*(r[5]?parseInt(r[5],10):0)),rest:e.slice(r[0].length)}:null}function At(t,e){return Bt(Ot,t,e)}function Zt(t,e,r){switch(t){case 1:return Bt(Pt,e,r);case 2:return Bt(qt,e,r);case 3:return Bt(Ht,e,r);case 4:return Bt(Et,e,r);default:return Bt(new RegExp("^\\d{1,"+t+"}"),e,r)}}function Kt(t,e,r){switch(t){case 1:return Bt(Ft,e,r);case 2:return Bt(Wt,e,r);case 3:return Bt(Lt,e,r);case 4:return Bt(Qt,e,r);default:return Bt(new RegExp("^-?\\d{1,"+t+"}"),e,r)}}function $t(t){switch(t){case"morning":return 4;case"evening":return 17;case"pm":case"noon":case"afternoon":return 12;default:return 0}}function _t(t,e){var r,n=e>0,a=n?e:1-e;if(a<=50)r=t||100;else{var i=a+50;r=t+100*Math.floor(i/100)-(t>=i%100?100:0)}return n?r:1-r}var Jt=[31,28,31,30,31,30,31,31,30,31,30,31],Vt=[31,29,31,30,31,30,31,31,30,31,30,31];function te(t){return t%400==0||t%4==0&&t%100!=0}var ee={G:{priority:140,parse:function(t,e,r,n){switch(e){case"G":case"GG":case"GGG":return r.era(t,{width:"abbreviated"})||r.era(t,{width:"narrow"});case"GGGGG":return r.era(t,{width:"narrow"});default:return r.era(t,{width:"wide"})||r.era(t,{width:"abbreviated"})||r.era(t,{width:"narrow"})}},set:function(t,e,r,n){return e.era=r,t.setUTCFullYear(r,0,1),t.setUTCHours(0,0,0,0),t},incompatibleTokens:["R","u","t","T"]},y:{priority:130,parse:function(t,e,r,n){var a=function(t){return{year:t,isTwoDigitYear:"yy"===e}};switch(e){case"y":return Zt(4,t,a);case"yo":return r.ordinalNumber(t,{unit:"year",valueCallback:a});default:return Zt(e.length,t,a)}},validate:function(t,e,r){return e.isTwoDigitYear||e.year>0},set:function(t,e,r,n){var a=t.getUTCFullYear();if(r.isTwoDigitYear){var i=_t(r.year,a);return t.setUTCFullYear(i,0,1),t.setUTCHours(0,0,0,0),t}var o="era"in e&&1!==e.era?1-r.year:r.year;return t.setUTCFullYear(o,0,1),t.setUTCHours(0,0,0,0),t},incompatibleTokens:["Y","R","u","w","I","i","e","c","t","T"]},Y:{priority:130,parse:function(t,e,r,n){var a=function(t){return{year:t,isTwoDigitYear:"YY"===e}};switch(e){case"Y":return Zt(4,t,a);case"Yo":return r.ordinalNumber(t,{unit:"year",valueCallback:a});default:return Zt(e.length,t,a)}},validate:function(t,e,r){return e.isTwoDigitYear||e.year>0},set:function(t,e,r,n){var a=X(t,n);if(r.isTwoDigitYear){var i=_t(r.year,a);return t.setUTCFullYear(i,0,n.firstWeekContainsDate),t.setUTCHours(0,0,0,0),G(t,n)}var o="era"in e&&1!==e.era?1-r.year:r.year;return t.setUTCFullYear(o,0,n.firstWeekContainsDate),t.setUTCHours(0,0,0,0),G(t,n)},incompatibleTokens:["y","R","u","Q","q","M","L","I","d","D","i","t","T"]},R:{priority:130,parse:function(t,e,r,n){return Kt("R"===e?4:e.length,t)},set:function(t,e,r,n){var a=new Date(0);return a.setUTCFullYear(r,0,4),a.setUTCHours(0,0,0,0),W(a)},incompatibleTokens:["G","y","Y","u","Q","q","M","L","w","d","D","e","c","t","T"]},u:{priority:130,parse:function(t,e,r,n){return Kt("u"===e?4:e.length,t)},set:function(t,e,r,n){return t.setUTCFullYear(r,0,1),t.setUTCHours(0,0,0,0),t},incompatibleTokens:["G","y","Y","R","w","I","i","e","c","t","T"]},Q:{priority:120,parse:function(t,e,r,n){switch(e){case"Q":case"QQ":return Zt(e.length,t);case"Qo":return r.ordinalNumber(t,{unit:"quarter"});case"QQQ":return r.quarter(t,{width:"abbreviated",context:"formatting"})||r.quarter(t,{width:"narrow",context:"formatting"});case"QQQQQ":return r.quarter(t,{width:"narrow",context:"formatting"});default:return r.quarter(t,{width:"wide",context:"formatting"})||r.quarter(t,{width:"abbreviated",context:"formatting"})||r.quarter(t,{width:"narrow",context:"formatting"})}},validate:function(t,e,r){return e>=1&&e<=4},set:function(t,e,r,n){return t.setUTCMonth(3*(r-1),1),t.setUTCHours(0,0,0,0),t},incompatibleTokens:["Y","R","q","M","L","w","I","d","D","i","e","c","t","T"]},q:{priority:120,parse:function(t,e,r,n){switch(e){case"q":case"qq":return Zt(e.length,t);case"qo":return r.ordinalNumber(t,{unit:"quarter"});case"qqq":return r.quarter(t,{width:"abbreviated",context:"standalone"})||r.quarter(t,{width:"narrow",context:"standalone"});case"qqqqq":return r.quarter(t,{width:"narrow",context:"standalone"});default:return r.quarter(t,{width:"wide",context:"standalone"})||r.quarter(t,{width:"abbreviated",context:"standalone"})||r.quarter(t,{width:"narrow",context:"standalone"})}},validate:function(t,e,r){return e>=1&&e<=4},set:function(t,e,r,n){return t.setUTCMonth(3*(r-1),1),t.setUTCHours(0,0,0,0),t},incompatibleTokens:["Y","R","Q","M","L","w","I","d","D","i","e","c","t","T"]},M:{priority:110,parse:function(t,e,r,n){var a=function(t){return t-1};switch(e){case"M":return Bt(pt,t,a);case"MM":return Zt(2,t,a);case"Mo":return r.ordinalNumber(t,{unit:"month",valueCallback:a});case"MMM":return r.month(t,{width:"abbreviated",context:"formatting"})||r.month(t,{width:"narrow",context:"formatting"});case"MMMMM":return r.month(t,{width:"narrow",context:"formatting"});default:return r.month(t,{width:"wide",context:"formatting"})||r.month(t,{width:"abbreviated",context:"formatting"})||r.month(t,{width:"narrow",context:"formatting"})}},validate:function(t,e,r){return e>=0&&e<=11},set:function(t,e,r,n){return t.setUTCMonth(r,1),t.setUTCHours(0,0,0,0),t},incompatibleTokens:["Y","R","q","Q","L","w","I","D","i","e","c","t","T"]},L:{priority:110,parse:function(t,e,r,n){var a=function(t){return t-1};switch(e){case"L":return Bt(pt,t,a);case"LL":return Zt(2,t,a);case"Lo":return r.ordinalNumber(t,{unit:"month",valueCallback:a});case"LLL":return r.month(t,{width:"abbreviated",context:"standalone"})||r.month(t,{width:"narrow",context:"standalone"});case"LLLLL":return r.month(t,{width:"narrow",context:"standalone"});default:return r.month(t,{width:"wide",context:"standalone"})||r.month(t,{width:"abbreviated",context:"standalone"})||r.month(t,{width:"narrow",context:"standalone"})}},validate:function(t,e,r){return e>=0&&e<=11},set:function(t,e,r,n){return t.setUTCMonth(r,1),t.setUTCHours(0,0,0,0),t},incompatibleTokens:["Y","R","q","Q","M","w","I","D","i","e","c","t","T"]},w:{priority:100,parse:function(t,e,r,n){switch(e){case"w":return Bt(Dt,t);case"wo":return r.ordinalNumber(t,{unit:"week"});default:return Zt(e.length,t)}},validate:function(t,e,r){return e>=1&&e<=53},set:function(t,a,i,o){return G(function(t,a,i){r(2,arguments);var o=n(t),u=e(a),s=z(o,i)-u;return o.setUTCDate(o.getUTCDate()-7*s),o}(t,i,o),o)},incompatibleTokens:["y","R","u","q","Q","M","L","I","d","D","i","t","T"]},I:{priority:100,parse:function(t,e,r,n){switch(e){case"I":return Bt(Dt,t);case"Io":return r.ordinalNumber(t,{unit:"week"});default:return Zt(e.length,t)}},validate:function(t,e,r){return e>=1&&e<=53},set:function(t,a,i,o){return W(function(t,a){r(2,arguments);var i=n(t),o=e(a),u=I(i)-o;return i.setUTCDate(i.getUTCDate()-7*u),i}(t,i,o),o)},incompatibleTokens:["y","Y","u","q","Q","M","L","w","d","D","e","c","t","T"]},d:{priority:90,subPriority:1,parse:function(t,e,r,n){switch(e){case"d":return Bt(Ct,t);case"do":return r.ordinalNumber(t,{unit:"date"});default:return Zt(e.length,t)}},validate:function(t,e,r){var n=te(t.getUTCFullYear()),a=t.getUTCMonth();return n?e>=1&&e<=Vt[a]:e>=1&&e<=Jt[a]},set:function(t,e,r,n){return t.setUTCDate(r),t.setUTCHours(0,0,0,0),t},incompatibleTokens:["Y","R","q","Q","w","I","D","i","e","c","t","T"]},D:{priority:90,subPriority:1,parse:function(t,e,r,n){switch(e){case"D":case"DD":return Bt(Mt,t);case"Do":return r.ordinalNumber(t,{unit:"date"});default:return Zt(e.length,t)}},validate:function(t,e,r){return te(t.getUTCFullYear())?e>=1&&e<=366:e>=1&&e<=365},set:function(t,e,r,n){return t.setUTCMonth(0,r),t.setUTCHours(0,0,0,0),t},incompatibleTokens:["Y","R","q","Q","M","L","w","I","d","E","i","e","c","t","T"]},E:{priority:90,parse:function(t,e,r,n){switch(e){case"E":case"EE":case"EEE":return r.day(t,{width:"abbreviated",context:"formatting"})||r.day(t,{width:"short",context:"formatting"})||r.day(t,{width:"narrow",context:"formatting"});case"EEEEE":return r.day(t,{width:"narrow",context:"formatting"});case"EEEEEE":return r.day(t,{width:"short",context:"formatting"})||r.day(t,{width:"narrow",context:"formatting"});default:return r.day(t,{width:"wide",context:"formatting"})||r.day(t,{width:"abbreviated",context:"formatting"})||r.day(t,{width:"short",context:"formatting"})||r.day(t,{width:"narrow",context:"formatting"})}},validate:function(t,e,r){return e>=0&&e<=6},set:function(t,e,r,n){return(t=Tt(t,r,n)).setUTCHours(0,0,0,0),t},incompatibleTokens:["D","i","e","c","t","T"]},e:{priority:90,parse:function(t,e,r,n){var a=function(t){var e=7*Math.floor((t-1)/7);return(t+n.weekStartsOn+6)%7+e};switch(e){case"e":case"ee":return Zt(e.length,t,a);case"eo":return r.ordinalNumber(t,{unit:"day",valueCallback:a});case"eee":return r.day(t,{width:"abbreviated",context:"formatting"})||r.day(t,{width:"short",context:"formatting"})||r.day(t,{width:"narrow",context:"formatting"});case"eeeee":return r.day(t,{width:"narrow",context:"formatting"});case"eeeeee":return r.day(t,{width:"short",context:"formatting"})||r.day(t,{width:"narrow",context:"formatting"});default:return r.day(t,{width:"wide",context:"formatting"})||r.day(t,{width:"abbreviated",context:"formatting"})||r.day(t,{width:"short",context:"formatting"})||r.day(t,{width:"narrow",context:"formatting"})}},validate:function(t,e,r){return e>=0&&e<=6},set:function(t,e,r,n){return(t=Tt(t,r,n)).setUTCHours(0,0,0,0),t},incompatibleTokens:["y","R","u","q","Q","M","L","I","d","D","E","i","c","t","T"]},c:{priority:90,parse:function(t,e,r,n){var a=function(t){var e=7*Math.floor((t-1)/7);return(t+n.weekStartsOn+6)%7+e};switch(e){case"c":case"cc":return Zt(e.length,t,a);case"co":return r.ordinalNumber(t,{unit:"day",valueCallback:a});case"ccc":return r.day(t,{width:"abbreviated",context:"standalone"})||r.day(t,{width:"short",context:"standalone"})||r.day(t,{width:"narrow",context:"standalone"});case"ccccc":return r.day(t,{width:"narrow",context:"standalone"});case"cccccc":return r.day(t,{width:"short",context:"standalone"})||r.day(t,{width:"narrow",context:"standalone"});default:return r.day(t,{width:"wide",context:"standalone"})||r.day(t,{width:"abbreviated",context:"standalone"})||r.day(t,{width:"short",context:"standalone"})||r.day(t,{width:"narrow",context:"standalone"})}},validate:function(t,e,r){return e>=0&&e<=6},set:function(t,e,r,n){return(t=Tt(t,r,n)).setUTCHours(0,0,0,0),t},incompatibleTokens:["y","R","u","q","Q","M","L","I","d","D","E","i","e","t","T"]},i:{priority:90,parse:function(t,e,r,n){var a=function(t){return 0===t?7:t};switch(e){case"i":case"ii":return Zt(e.length,t);case"io":return r.ordinalNumber(t,{unit:"day"});case"iii":return r.day(t,{width:"abbreviated",context:"formatting",valueCallback:a})||r.day(t,{width:"short",context:"formatting",valueCallback:a})||r.day(t,{width:"narrow",context:"formatting",valueCallback:a});case"iiiii":return r.day(t,{width:"narrow",context:"formatting",valueCallback:a});case"iiiiii":return r.day(t,{width:"short",context:"formatting",valueCallback:a})||r.day(t,{width:"narrow",context:"formatting",valueCallback:a});default:return r.day(t,{width:"wide",context:"formatting",valueCallback:a})||r.day(t,{width:"abbreviated",context:"formatting",valueCallback:a})||r.day(t,{width:"short",context:"formatting",valueCallback:a})||r.day(t,{width:"narrow",context:"formatting",valueCallback:a})}},validate:function(t,e,r){return e>=1&&e<=7},set:function(t,a,i,o){return t=function(t,a){r(2,arguments);var i=e(a);i%7==0&&(i-=7);var o=1,u=n(t),s=u.getUTCDay(),c=((i%7+7)%7<o?7:0)+i-s;return u.setUTCDate(u.getUTCDate()+c),u}(t,i,o),t.setUTCHours(0,0,0,0),t},incompatibleTokens:["y","Y","u","q","Q","M","L","w","d","D","E","e","c","t","T"]},a:{priority:80,parse:function(t,e,r,n){switch(e){case"a":case"aa":case"aaa":return r.dayPeriod(t,{width:"abbreviated",context:"formatting"})||r.dayPeriod(t,{width:"narrow",context:"formatting"});case"aaaaa":return r.dayPeriod(t,{width:"narrow",context:"formatting"});default:return r.dayPeriod(t,{width:"wide",context:"formatting"})||r.dayPeriod(t,{width:"abbreviated",context:"formatting"})||r.dayPeriod(t,{width:"narrow",context:"formatting"})}},set:function(t,e,r,n){return t.setUTCHours($t(r),0,0,0),t},incompatibleTokens:["b","B","H","K","k","t","T"]},b:{priority:80,parse:function(t,e,r,n){switch(e){case"b":case"bb":case"bbb":return r.dayPeriod(t,{width:"abbreviated",context:"formatting"})||r.dayPeriod(t,{width:"narrow",context:"formatting"});case"bbbbb":return r.dayPeriod(t,{width:"narrow",context:"formatting"});default:return r.dayPeriod(t,{width:"wide",context:"formatting"})||r.dayPeriod(t,{width:"abbreviated",context:"formatting"})||r.dayPeriod(t,{width:"narrow",context:"formatting"})}},set:function(t,e,r,n){return t.setUTCHours($t(r),0,0,0),t},incompatibleTokens:["a","B","H","K","k","t","T"]},B:{priority:80,parse:function(t,e,r,n){switch(e){case"B":case"BB":case"BBB":return r.dayPeriod(t,{width:"abbreviated",context:"formatting"})||r.dayPeriod(t,{width:"narrow",context:"formatting"});case"BBBBB":return r.dayPeriod(t,{width:"narrow",context:"formatting"});default:return r.dayPeriod(t,{width:"wide",context:"formatting"})||r.dayPeriod(t,{width:"abbreviated",context:"formatting"})||r.dayPeriod(t,{width:"narrow",context:"formatting"})}},set:function(t,e,r,n){return t.setUTCHours($t(r),0,0,0),t},incompatibleTokens:["a","b","t","T"]},h:{priority:70,parse:function(t,e,r,n){switch(e){case"h":return Bt(Yt,t);case"ho":return r.ordinalNumber(t,{unit:"hour"});default:return Zt(e.length,t)}},validate:function(t,e,r){return e>=1&&e<=12},set:function(t,e,r,n){var a=t.getUTCHours()>=12;return a&&r<12?t.setUTCHours(r+12,0,0,0):a||12!==r?t.setUTCHours(r,0,0,0):t.setUTCHours(0,0,0,0),t},incompatibleTokens:["H","K","k","t","T"]},H:{priority:70,parse:function(t,e,r,n){switch(e){case"H":return Bt(xt,t);case"Ho":return r.ordinalNumber(t,{unit:"hour"});default:return Zt(e.length,t)}},validate:function(t,e,r){return e>=0&&e<=23},set:function(t,e,r,n){return t.setUTCHours(r,0,0,0),t},incompatibleTokens:["a","b","h","K","k","t","T"]},K:{priority:70,parse:function(t,e,r,n){switch(e){case"K":return Bt(Ut,t);case"Ko":return r.ordinalNumber(t,{unit:"hour"});default:return Zt(e.length,t)}},validate:function(t,e,r){return e>=0&&e<=11},set:function(t,e,r,n){return t.getUTCHours()>=12&&r<12?t.setUTCHours(r+12,0,0,0):t.setUTCHours(r,0,0,0),t},incompatibleTokens:["a","b","h","H","k","t","T"]},k:{priority:70,parse:function(t,e,r,n){switch(e){case"k":return Bt(kt,t);case"ko":return r.ordinalNumber(t,{unit:"hour"});default:return Zt(e.length,t)}},validate:function(t,e,r){return e>=1&&e<=24},set:function(t,e,r,n){var a=r<=24?r%24:r;return t.setUTCHours(a,0,0,0),t},incompatibleTokens:["a","b","h","H","K","t","T"]},m:{priority:60,parse:function(t,e,r,n){switch(e){case"m":return Bt(Nt,t);case"mo":return r.ordinalNumber(t,{unit:"minute"});default:return Zt(e.length,t)}},validate:function(t,e,r){return e>=0&&e<=59},set:function(t,e,r,n){return t.setUTCMinutes(r,0,0),t},incompatibleTokens:["t","T"]},s:{priority:50,parse:function(t,e,r,n){switch(e){case"s":return Bt(St,t);case"so":return r.ordinalNumber(t,{unit:"second"});default:return Zt(e.length,t)}},validate:function(t,e,r){return e>=0&&e<=59},set:function(t,e,r,n){return t.setUTCSeconds(r,0),t},incompatibleTokens:["t","T"]},S:{priority:30,parse:function(t,e,r,n){return Zt(e.length,t,(function(t){return Math.floor(t*Math.pow(10,3-e.length))}))},set:function(t,e,r,n){return t.setUTCMilliseconds(r),t},incompatibleTokens:["t","T"]},X:{priority:10,parse:function(t,e,r,n){switch(e){case"X":return zt(Rt,t);case"XX":return zt(It,t);case"XXXX":return zt(Gt,t);case"XXXXX":return zt(jt,t);default:return zt(Xt,t)}},set:function(t,e,r,n){return e.timestampIsSet?t:new Date(t.getTime()-r)},incompatibleTokens:["t","T","x"]},x:{priority:10,parse:function(t,e,r,n){switch(e){case"x":return zt(Rt,t);case"xx":return zt(It,t);case"xxxx":return zt(Gt,t);case"xxxxx":return zt(jt,t);default:return zt(Xt,t)}},set:function(t,e,r,n){return e.timestampIsSet?t:new Date(t.getTime()-r)},incompatibleTokens:["t","T","X"]},t:{priority:40,parse:function(t,e,r,n){return At(t)},set:function(t,e,r,n){return[new Date(1e3*r),{timestampIsSet:!0}]},incompatibleTokens:"*"},T:{priority:20,parse:function(t,e,r,n){return At(t)},set:function(t,e,r,n){return[new Date(r),{timestampIsSet:!0}]},incompatibleTokens:"*"}},re=ee,ne=/[yYQqMLwIdDecihHKkms]o|(\w)\1*|''|'(''|[^'])+('|$)|./g,ae=/P+p+|P+|p+|''|'(''|[^'])+('|$)|./g,ie=/^'([^]*?)'?$/,oe=/''/g,ue=/\S/,se=/[a-zA-Z]/;function ce(t,e){if(e.timestampIsSet)return t;var r=new Date(0);return r.setFullYear(t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDate()),r.setHours(t.getUTCHours(),t.getUTCMinutes(),t.getUTCSeconds(),t.getUTCMilliseconds()),r}function de(t){return t.match(ie)[1].replace(oe,"'")}var le=36e5,fe={dateTimeDelimiter:/[T ]/,timeZoneDelimiter:/[Z ]/i,timezone:/([Z+-].*)$/},he=/^-?(?:(\d{3})|(\d{2})(?:-?(\d{2}))?|W(\d{2})(?:-?(\d{1}))?|)$/,me=/^(\d{2}(?:[.,]\d*)?)(?::?(\d{2}(?:[.,]\d*)?))?(?::?(\d{2}(?:[.,]\d*)?))?$/,we=/^([+-])(\d{2})(?::?(\d{2}))?$/;function ge(t){var e,r={},n=t.split(fe.dateTimeDelimiter);if(n.length>2)return r;if(/:/.test(n[0])?(r.date=null,e=n[0]):(r.date=n[0],e=n[1],fe.timeZoneDelimiter.test(r.date)&&(r.date=t.split(fe.timeZoneDelimiter)[0],e=t.substr(r.date.length,t.length))),e){var a=fe.timezone.exec(e);a?(r.time=e.replace(a[1],""),r.timezone=a[1]):r.time=e}return r}function ve(t,e){var r=new RegExp("^(?:(\\d{4}|[+-]\\d{"+(4+e)+"})|(\\d{2}|[+-]\\d{"+(2+e)+"})$)"),n=t.match(r);if(!n)return{year:null};var a=n[1]&&parseInt(n[1]),i=n[2]&&parseInt(n[2]);return{year:null==i?a:100*i,restDateString:t.slice((n[1]||n[2]).length)}}function ye(t,e){if(null===e)return null;var r=t.match(he);if(!r)return null;var n=!!r[4],a=be(r[1]),i=be(r[2])-1,o=be(r[3]),u=be(r[4]),s=be(r[5])-1;if(n)return function(t,e,r){return e>=1&&e<=53&&r>=0&&r<=6}(0,u,s)?function(t,e,r){var n=new Date(0);n.setUTCFullYear(t,0,4);var a=n.getUTCDay()||7,i=7*(e-1)+r+1-a;return n.setUTCDate(n.getUTCDate()+i),n}(e,u,s):new Date(NaN);var c=new Date(0);return function(t,e,r){return e>=0&&e<=11&&r>=1&&r<=(Me[e]||(De(t)?29:28))}(e,i,o)&&function(t,e){return e>=1&&e<=(De(t)?366:365)}(e,a)?(c.setUTCFullYear(e,i,Math.max(a,o)),c):new Date(NaN)}function be(t){return t?parseInt(t):1}function Te(t){var e=t.match(me);if(!e)return null;var r=pe(e[1]),n=pe(e[2]),a=pe(e[3]);return function(t,e,r){if(24===t)return 0===e&&0===r;return r>=0&&r<60&&e>=0&&e<60&&t>=0&&t<25}(r,n,a)?r*le+6e4*n+1e3*a:NaN}function pe(t){return t&&parseFloat(t.replace(",","."))||0}function Ce(t){if("Z"===t)return 0;var e=t.match(we);if(!e)return 0;var r="+"===e[1]?-1:1,n=parseInt(e[2]),a=e[3]&&parseInt(e[3])||0;return function(t,e){return e>=0&&e<=59}(0,a)?r*(n*le+6e4*a):NaN}var Me=[31,null,31,30,31,30,31,31,30,31,30,31];function De(t){return t%400==0||t%4==0&&t%100}const xe={datetime:"MMM d, yyyy, h:mm:ss aaaa",millisecond:"h:mm:ss.SSS aaaa",second:"h:mm:ss aaaa",minute:"h:mm aaaa",hour:"ha",day:"MMM d",week:"PP",month:"MMM yyyy",quarter:"qqq - yyyy",year:"yyyy"};t._adapters._date.override({_id:"date-fns",formats:function(){return xe},parse:function(t,a){if(null==t)return null;const i=typeof t;return"number"===i||t instanceof Date?t=n(t):"string"===i&&(t="string"==typeof a?function(t,a,i,o){r(3,arguments);var u=String(t),s=String(a),d=o||{},l=d.locale||q;if(!l.match)throw new RangeError("locale must contain match property");var f=l.options&&l.options.firstWeekContainsDate,h=null==f?1:e(f),m=null==d.firstWeekContainsDate?h:e(d.firstWeekContainsDate);if(!(m>=1&&m<=7))throw new RangeError("firstWeekContainsDate must be between 1 and 7 inclusively");var w=l.options&&l.options.weekStartsOn,g=null==w?0:e(w),v=null==d.weekStartsOn?g:e(d.weekStartsOn);if(!(v>=0&&v<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");if(""===s)return""===u?n(i):new Date(NaN);var y,b={firstWeekContainsDate:m,weekStartsOn:v,locale:l},T=[{priority:10,subPriority:-1,set:ce,index:0}],p=s.match(ae).map((function(t){var e=t[0];return"p"===e||"P"===e?(0,ut[e])(t,l.formatLong,b):t})).join("").match(ne),C=[];for(y=0;y<p.length;y++){var M=p[y];!d.useAdditionalWeekYearTokens&&lt(M)&&ft(M,s,t),!d.useAdditionalDayOfYearTokens&&dt(M)&&ft(M,s,t);var D=M[0],x=re[D];if(x){var k=x.incompatibleTokens;if(Array.isArray(k)){for(var U=void 0,Y=0;Y<C.length;Y++){var N=C[Y].token;if(-1!==k.indexOf(N)||N===D){U=C[Y];break}}if(U)throw new RangeError("The format string mustn't contain `".concat(U.fullToken,"` and `").concat(M,"` at the same time"))}else if("*"===x.incompatibleTokens&&C.length)throw new RangeError("The format string mustn't contain `".concat(M,"` and any other token at the same time"));C.push({token:D,fullToken:M});var S=x.parse(u,M,l.match,b);if(!S)return new Date(NaN);T.push({priority:x.priority,subPriority:x.subPriority||0,set:x.set,validate:x.validate,value:S.value,index:T.length}),u=S.rest}else{if(D.match(se))throw new RangeError("Format string contains an unescaped latin alphabet character `"+D+"`");if("''"===M?M="'":"'"===D&&(M=de(M)),0!==u.indexOf(M))return new Date(NaN);u=u.slice(M.length)}}if(u.length>0&&ue.test(u))return new Date(NaN);var P=T.map((function(t){return t.priority})).sort((function(t,e){return e-t})).filter((function(t,e,r){return r.indexOf(t)===e})).map((function(t){return T.filter((function(e){return e.priority===t})).sort((function(t,e){return e.subPriority-t.subPriority}))})).map((function(t){return t[0]})),E=n(i);if(isNaN(E))return new Date(NaN);var O=H(E,c(E)),F={};for(y=0;y<P.length;y++){var W=P[y];if(W.validate&&!W.validate(O,W.value,b))return new Date(NaN);var L=W.set(O,F,W.value,b);L[0]?(O=L[0],bt(F,L[1])):O=L}return O}(t,a,new Date,this.options):function(t,n){r(1,arguments);var a=n||{},i=null==a.additionalDigits?2:e(a.additionalDigits);if(2!==i&&1!==i&&0!==i)throw new RangeError("additionalDigits must be 0, 1 or 2");if("string"!=typeof t&&"[object String]"!==Object.prototype.toString.call(t))return new Date(NaN);var o,u=ge(t);if(u.date){var s=ve(u.date,i);o=ye(s.restDateString,s.year)}if(isNaN(o)||!o)return new Date(NaN);var c,d=o.getTime(),l=0;if(u.time&&(l=Te(u.time),isNaN(l)||null===l))return new Date(NaN);if(!u.timezone){var f=new Date(d+l),h=new Date(0);return h.setFullYear(f.getUTCFullYear(),f.getUTCMonth(),f.getUTCDate()),h.setHours(f.getUTCHours(),f.getUTCMinutes(),f.getUTCSeconds(),f.getUTCMilliseconds()),h}return c=Ce(u.timezone),isNaN(c)?new Date(NaN):new Date(d+l+c)}(t,this.options)),m(t)?t.getTime():null},format:function(t,a){return function(t,a,i){r(2,arguments);var o=String(a),u=i||{},s=u.locale||q,d=s.options&&s.options.firstWeekContainsDate,l=null==d?1:e(d),f=null==u.firstWeekContainsDate?l:e(u.firstWeekContainsDate);if(!(f>=1&&f<=7))throw new RangeError("firstWeekContainsDate must be between 1 and 7 inclusively");var h=s.options&&s.options.weekStartsOn,w=null==h?0:e(h),g=null==u.weekStartsOn?w:e(u.weekStartsOn);if(!(g>=0&&g<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");if(!s.localize)throw new RangeError("locale must contain localize property");if(!s.formatLong)throw new RangeError("locale must contain formatLong property");var v=n(t);if(!m(v))throw new RangeError("Invalid time value");var y=c(v),b=H(v,y),T={firstWeekContainsDate:f,weekStartsOn:g,locale:s,_originalDate:v},p=o.match(mt).map((function(t){var e=t[0];return"p"===e||"P"===e?(0,ut[e])(t,s.formatLong,T):t})).join("").match(ht).map((function(e){if("''"===e)return"'";var r=e[0];if("'"===r)return yt(e);var n=nt[r];if(n)return!u.useAdditionalWeekYearTokens&&lt(e)&&ft(e,a,t),!u.useAdditionalDayOfYearTokens&&dt(e)&&ft(e,a,t),n(b,e,s.localize,T);if(r.match(vt))throw new RangeError("Format string contains an unescaped latin alphabet character `"+r+"`");return e})).join("");return p}(t,a,this.options)},add:function(t,n,s){switch(s){case"millisecond":return o(t,n);case"second":return function(t,n){r(2,arguments);var a=e(n);return o(t,1e3*a)}(t,n);case"minute":return function(t,n){r(2,arguments);var a=e(n);return o(t,6e4*a)}(t,n);case"hour":return function(t,n){r(2,arguments);var a=e(n);return o(t,a*u)}(t,n);case"day":return a(t,n);case"week":return function(t,n){r(2,arguments);var i=e(n),o=7*i;return a(t,o)}(t,n);case"month":return i(t,n);case"quarter":return function(t,n){r(2,arguments);var a=e(n),o=3*a;return i(t,o)}(t,n);case"year":return function(t,n){r(2,arguments);var a=e(n);return i(t,12*a)}(t,n);default:return t}},diff:function(t,e,a){switch(a){case"millisecond":return b(t,e);case"second":return function(t,e){r(2,arguments);var n=b(t,e)/1e3;return n>0?Math.floor(n):Math.ceil(n)}(t,e);case"minute":return function(t,e){r(2,arguments);var n=b(t,e)/6e4;return n>0?Math.floor(n):Math.ceil(n)}(t,e);case"hour":return function(t,e){r(2,arguments);var n=b(t,e)/T;return n>0?Math.floor(n):Math.ceil(n)}(t,e);case"day":return y(t,e);case"week":return function(t,e){r(2,arguments);var n=y(t,e)/7;return n>0?Math.floor(n):Math.ceil(n)}(t,e);case"month":return D(t,e);case"quarter":return function(t,e){r(2,arguments);var n=D(t,e)/3;return n>0?Math.floor(n):Math.ceil(n)}(t,e);case"year":return function(t,e){r(2,arguments);var a=n(t),i=n(e),o=h(a,i),u=Math.abs(g(a,i));a.setFullYear("1584"),i.setFullYear("1584");var s=h(a,i)===-o,c=o*(u-s);return 0===c?0:c}(t,e);default:return 0}},startOf:function(t,e,a){switch(e){case"second":return function(t){r(1,arguments);var e=n(t);return e.setMilliseconds(0),e}(t);case"minute":return function(t){r(1,arguments);var e=n(t);return e.setSeconds(0,0),e}(t);case"hour":return function(t){r(1,arguments);var e=n(t);return e.setMinutes(0,0,0),e}(t);case"day":return d(t);case"week":return s(t);case"isoWeek":return s(t,{weekStartsOn:+a});case"month":return function(t){r(1,arguments);var e=n(t);return e.setDate(1),e.setHours(0,0,0,0),e}(t);case"quarter":return function(t){r(1,arguments);var e=n(t),a=e.getMonth(),i=a-a%3;return e.setMonth(i,1),e.setHours(0,0,0,0),e}(t);case"year":return function(t){r(1,arguments);var e=n(t),a=new Date(0);return a.setFullYear(e.getFullYear(),0,1),a.setHours(0,0,0,0),a}(t);default:return t}},endOf:function(t,a){switch(a){case"second":return function(t){r(1,arguments);var e=n(t);return e.setMilliseconds(999),e}(t);case"minute":return function(t){r(1,arguments);var e=n(t);return e.setSeconds(59,999),e}(t);case"hour":return function(t){r(1,arguments);var e=n(t);return e.setMinutes(59,59,999),e}(t);case"day":return p(t);case"week":return function(t,a){r(1,arguments);var i=a||{},o=i.locale,u=o&&o.options&&o.options.weekStartsOn,s=null==u?0:e(u),c=null==i.weekStartsOn?s:e(i.weekStartsOn);if(!(c>=0&&c<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");var d=n(t),l=d.getDay(),f=6+(l<c?-7:0)-(l-c);return d.setDate(d.getDate()+f),d.setHours(23,59,59,999),d}(t);case"month":return C(t);case"quarter":return function(t){r(1,arguments);var e=n(t),a=e.getMonth(),i=a-a%3+3;return e.setMonth(i,0),e.setHours(23,59,59,999),e}(t);case"year":return function(t){r(1,arguments);var e=n(t),a=e.getFullYear();return e.setFullYear(a+1,0,0),e.setHours(23,59,59,999),e}(t);default:return t}}})}));
@@ -0,0 +1,2 @@
1
+ /*! Chartkick.js v5.0.1 | MIT License */
2
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Chartkick=e()}(this,(function(){"use strict";function t(t){return"[object Array]"===Object.prototype.toString.call(t)}function e(t){return t instanceof Function}function r(t){return"[object Object]"===Object.prototype.toString.call(t)&&!e(t)&&t instanceof Object}function n(e,o){for(var a in o)"__proto__"!==a&&(r(o[a])||t(o[a])?(r(o[a])&&!r(e[a])&&(e[a]={}),t(o[a])&&!t(e[a])&&(e[a]=[]),n(e[a],o[a])):void 0!==o[a]&&(e[a]=o[a]))}function o(t,e){var r={};return n(r,t),n(r,e),r}var a=/^(\d\d\d\d)(?:-)?(\d\d)(?:-)?(\d\d)$/i;function i(t){return""+t}function s(t){return parseFloat(t)}function l(t){if(t instanceof Date)return t;if("number"==typeof t)return new Date(1e3*t);var e=i(t),r=e.match(a);if(r){var n=parseInt(r[1],10),o=parseInt(r[2],10)-1,s=parseInt(r[3],10);return new Date(n,o,s)}var l=e.replace(/ /,"T").replace(" ","").replace("UTC","Z");return new Date(Date.parse(l)||e)}function c(e){if(t(e))return e;var r=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&r.push([n,e[n]]);return r}function p(t,e,r,n,a,i,s,l){return function(c,p,u){var d=c.data,h=o({},t);return h=o(h,u||{}),(c.singleSeriesFormat||"legend"in p)&&e(h,p.legend,c.singleSeriesFormat),p.title&&r(h,p.title),"min"in p?n(h,p.min):function(t){for(var e=0;e<t.length;e++)for(var r=t[e].data,n=0;n<r.length;n++)if(r[n][1]<0)return!0;return!1}(d)||n(h,0),p.max&&a(h,p.max),"stacked"in p&&i(h,p.stacked),p.colors&&(h.colors=p.colors),p.xtitle&&s(h,p.xtitle),p.ytitle&&l(h,p.ytitle),h=o(h,p.library||{})}}function u(t,e){return t[0].getTime()-e[0].getTime()}function d(t,e){return t[0]-e[0]}function h(t,e){return t-e}function f(t,e){for(var r=0;r<t.length;r++)if(!e(t[r]))return!1;return!0}function y(t,e){if(void 0===e&&(e=!1),0===t.length)return null;if(!f(t,(function(t){return 0===t.getMilliseconds()&&0===t.getSeconds()})))return null;if(!f(t,(function(t){return 0===t.getMinutes()})))return"minute";if(!f(t,(function(t){return 0===t.getHours()})))return"hour";if(e)return"day";if(!f(t,(function(t){return 1===t.getDate()}))){var r=t[0].getDay();return f(t,(function(t){return t.getDay()===r}))?"week":"day"}return f(t,(function(t){return 0===t.getMonth()}))?"year":"month"}function m(t){return!isNaN(l(t))&&i(t).length>=6}function v(t){return"number"==typeof t}var g=["bytes","KB","MB","GB","TB","PB","EB"];function b(t,e,r,n){t=t||"",r.prefix&&(e<0&&(e*=-1,t+="-"),t+=r.prefix);var o=r.suffix||"",a=r.precision,s=r.round;if(r.byteScale){var l=e>=0;l||(e*=-1);var c,p=n?r.byteScale:e;p>=0x1000000000000000?(e/=0x1000000000000000,c=6):p>=0x4000000000000?(e/=0x4000000000000,c=5):p>=1099511627776?(e/=1099511627776,c=4):p>=1073741824?(e/=1073741824,c=3):p>=1048576?(e/=1048576,c=2):p>=1024?(e/=1024,c=1):c=0,void 0===a&&void 0===s&&(e>=1023.5&&c<g.length-1&&(e=1,c+=1),a=e>=1e3?4:3),o=" "+g[c],l||(e*=-1)}if(void 0!==a&&void 0!==s)throw Error("Use either round or precision, not both");if(!n&&(void 0!==a&&(e=e.toPrecision(a),r.zeros||(e=parseFloat(e))),void 0!==s))if(s<0){var u=Math.pow(10,-1*s);e=parseInt((1*e/u).toFixed(0))*u}else e=e.toFixed(s),r.zeros||(e=parseFloat(e));if(r.thousands||r.decimal){var d=(e=i(e)).split(".");e=d[0],r.thousands&&(e=e.replace(/\B(?=(\d{3})+(?!\d))/g,r.thousands)),d.length>1&&(e+=(r.decimal||".")+d[1])}return t+e+o}function x(t,e,r){return r in e?e[r]:r in t.options?t.options[r]:null}var w={maintainAspectRatio:!1,animation:!1,plugins:{legend:{},tooltip:{displayColors:!1,callbacks:{}},title:{font:{size:20},color:"#333"}},interaction:{}},C={scales:{y:{ticks:{maxTicksLimit:4},title:{font:{size:16},color:"#333"},grid:{}},x:{grid:{drawOnChartArea:!1},title:{font:{size:16},color:"#333"},time:{},ticks:{}}}},_=["#3366CC","#DC3912","#FF9900","#109618","#990099","#3B3EAC","#0099C6","#DD4477","#66AA00","#B82E2E","#316395","#994499","#22AA99","#AAAA11","#6633CC","#E67300","#8B0707","#329262","#5574A6","#651067"];function k(t,e,r){void 0!==e?(t.plugins.legend.display=!!e,e&&!0!==e&&(t.plugins.legend.position=e)):r&&(t.plugins.legend.display=!1)}function S(t,e){t.plugins.title.display=!0,t.plugins.title.text=e}function A(t,e){null!==e&&(t.scales.x.min=s(e))}function T(t,e){t.scales.x.max=s(e)}function D(t,e){t.scales.x.stacked=!!e,t.scales.y.stacked=!!e}function O(t,e){t.scales.x.title.display=!0,t.scales.x.title.text=e}function L(t,e){t.scales.y.title.display=!0,t.scales.y.title.text=e}function z(t,e){var r=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return r?"rgba("+parseInt(r[1],16)+", "+parseInt(r[2],16)+", "+parseInt(r[3],16)+", "+e+")":t}function E(t){return null!=t}function F(t){for(var e=1,r=function(t){for(var e=0,r=0;r<t.length;r++)for(var n=t[r].data,o=0;o<n.length;o++){var a=Math.abs(n[o][1]);a>e&&(e=a)}return e}(t);r>=1024;)e*=1024,r/=1024;return e}function j(t,e,r){var n={thousands:t.options.thousands,decimal:t.options.decimal},a=o({prefix:t.options.prefix,suffix:t.options.suffix,precision:t.options.precision,round:t.options.round,zeros:t.options.zeros},n);if(t.options.bytes){var s=t.data;"pie"===r&&(s=[{data:s}]),a.byteScale=F(s)}if("pie"!==r){var l=e.scales.y;"bar"===r&&(l=e.scales.x),a.byteScale&&(l.ticks.stepSize||(l.ticks.stepSize=a.byteScale/2),l.ticks.maxTicksLimit||(l.ticks.maxTicksLimit=4)),l.ticks.callback||(l.ticks.callback=function(t){return b("",t,a,!0)}),"scatter"!==r&&"bubble"!==r||e.scales.x.ticks.callback||(e.scales.x.ticks.callback=function(t){return b("",t,n,!0)})}if(!e.plugins.tooltip.callbacks.label)if("scatter"===r)e.plugins.tooltip.callbacks.label=function(t){var e=t.dataset.label||"";e&&(e+=": ");var r=t.parsed;return e+"("+b("",r.x,n)+", "+b("",r.y,a)+")"};else if("bubble"===r)e.plugins.tooltip.callbacks.label=function(t){var e=t.dataset.label||"";e&&(e+=": ");var r=t.raw;return e+"("+b("",r.x,n)+", "+b("",r.y,a)+", "+b("",r.v,n)+")"};else if("pie"===r)e.plugins.tooltip.callbacks.label=function(t){return b("",t.parsed,a)};else{var c="bar"===r?"x":"y";e.plugins.tooltip.callbacks.label=function(t){if(null!==t.parsed[c]){var e=t.dataset.label||"";return e&&(e+=": "),b(e,t.parsed[c],a)}}}"line"!==r&&"area"!==r||"number"!==t.xtype||(e.scales.x.ticks.callback||(e.scales.x.ticks.callback=function(t){return i(t)}),e.plugins.tooltip.callbacks.title||(e.plugins.tooltip.callbacks.title=function(t){return i(t[0].parsed.x)}))}var B=p(o(w,C),k,S,(function(t,e){null!==e&&(t.scales.y.min=s(e))}),(function(t,e){t.scales.y.max=s(e)}),D,O,L);function N(t,e){return"bubble"===e?function(t){for(var e=t.data,r=[],n=function(t){for(var e=0,r=0;r<t.length;r++)for(var n=t[r].data,o=0;o<n.length;o++){var a=n[o][2];a>e&&(e=a)}return e}(e),o=0;o<e.length;o++){for(var a=e[o].data,i=[],s=0;s<a.length;s++){var l=a[s];i.push({x:l[0],y:l[1],r:20*l[2]/n,v:l[2]})}r.push(i)}return{labels:[],values:r}}(t):"number"===t.xtype&&"bar"!==e&&"column"!==e?function(t){for(var e=t.data,r=[],n=0;n<e.length;n++){var o=e[n].data;o.sort(d);for(var a=[],i=0;i<o.length;i++){var s=o[i];a.push({x:s[0],y:s[1]})}r.push(a)}return{labels:[],values:r}}(t):function(t){for(var e=t.data,r={},n=[],o=[],a=[],i=0;i<e.length;i++)for(var s=e[i].data,l=0;l<s.length;l++){var c=s[l],p="datetime"===t.xtype?c[0].getTime():c[0];r[p]||(r[p]=new Array(e.length),n.push(p)),r[p][i]=c[1]}"datetime"!==t.xtype&&"number"!==t.xtype||n.sort(h);for(var u=0;u<e.length;u++)a.push([]);for(var d=0;d<n.length;d++){var f=n[d],y="datetime"===t.xtype?new Date(f):f;o.push(y);for(var m=r[f],v=0;v<e.length;v++){var g=m[v];a[v].push(void 0===g?null:g)}}return{labels:o,values:a}}(t)}function I(e,r,n){for(var a=N(e,n),i=a.labels,s=a.values,c=e.data,p=[],u=e.options.colors||_,d=0;d<c.length;d++){var h=c[d],f=void 0,m=void 0;if(!e.options.colors||!e.singleSeriesFormat||"bar"!==n&&"column"!==n||h.color||!t(e.options.colors)||t(e.options.colors[0]))f=h.color||u[d],m="line"!==n?z(f,.5):f;else{f=u,m=[];for(var v=0;v<u.length;v++)m[v]=z(f[v],.5)}var g={label:h.name||"",data:s[d],fill:"area"===n,borderColor:f,backgroundColor:m,borderWidth:2},b="line"===n||"area"===n||"scatter"===n||"bubble"===n;b&&(g.pointBackgroundColor=f,g.pointHoverBackgroundColor=f,g.pointHitRadius=50),"bubble"===n&&(g.pointBackgroundColor=m,g.pointHoverBackgroundColor=m,g.pointHoverBorderWidth=2),h.stack&&(g.stack=h.stack),!1===x(e,h,"curve")?g.tension=0:b&&(g.tension=.4),!1===x(e,h,"points")&&(g.pointRadius=0,g.pointHoverRadius=0),g=o(g,e.options.dataset||{}),g=o(g,h.library||{}),g=o(g,h.dataset||{}),p.push(g)}var w=e.options.xmin,C=e.options.xmax;if("datetime"===e.xtype?(E(w)&&(r.scales.x.min=l(w).getTime()),E(C)&&(r.scales.x.max=l(C).getTime())):"number"===e.xtype&&(E(w)&&(r.scales.x.min=w),E(C)&&(r.scales.x.max=C)),"datetime"===e.xtype){var k=y(i);if(0===i.length&&(E(w)&&i.push(l(w)),E(C)&&i.push(l(C))),i.length>0){for(var S=(E(w)?l(w):i[0]).getTime(),A=(E(C)?l(C):i[0]).getTime(),T=1;T<i.length;T++){var D=i[T].getTime();D<S&&(S=D),D>A&&(A=D)}var O,L=(A-S)/864e5;if(!r.scales.x.time.unit)if("year"===k||L>3650?(r.scales.x.time.unit="year",O=365):"month"===k||L>300?(r.scales.x.time.unit="month",O=30):"week"===k||"day"===k||L>10?(r.scales.x.time.unit="day",O=1):"hour"===k||L>.5?(r.scales.x.time.displayFormats={hour:"MMM d, h a"},r.scales.x.time.unit="hour",O=1/24):"minute"===k&&(r.scales.x.time.displayFormats={minute:"h:mm a"},r.scales.x.time.unit="minute",O=1/24/60),O&&L>0){var F=e.element.offsetWidth;if(F>0){var j=Math.ceil(L/O/(F/100));"week"===k&&1===O&&(j=7*Math.ceil(j/7)),r.scales.x.ticks.stepSize=j}}r.scales.x.time.tooltipFormat||("year"===k?r.scales.x.time.tooltipFormat="yyyy":"month"===k?r.scales.x.time.tooltipFormat="MMM yyyy":"week"===k||"day"===k?r.scales.x.time.tooltipFormat="PP":"hour"===k?r.scales.x.time.tooltipFormat="MMM d, h a":"minute"===k&&(r.scales.x.time.tooltipFormat="h:mm a"))}}return{labels:i,datasets:p}}var M=function(t){this.name="chartjs",this.library=t};M.prototype.renderLineChart=function(t,e){e||(e="line");var r=B(t,o({},t.options));j(t,r,e);var n=I(t,r,e);"number"===t.xtype?(r.scales.x.type=r.scales.x.type||"linear",r.scales.x.position=r.scales.x.position||"bottom"):r.scales.x.type="string"===t.xtype?"category":"time",this.drawChart(t,"line",n,r)},M.prototype.renderPieChart=function(t){var e=o({},w);t.options.donut&&(e.cutout="50%"),"legend"in t.options&&k(e,t.options.legend),t.options.title&&S(e,t.options.title),j(t,e=o(e,t.options.library||{}),"pie");for(var r=[],n=[],a=0;a<t.data.length;a++){var i=t.data[a];r.push(i[0]),n.push(i[1])}var s={data:n,backgroundColor:t.options.colors||_},l={labels:r,datasets:[s=o(s,t.options.dataset||{})]};this.drawChart(t,"pie",l,e)},M.prototype.renderColumnChart=function(t,e){var r;if("bar"===e){var n=o(w,C);n.indexAxis="y",n.scales.x.grid.drawOnChartArea=!0,n.scales.y.grid.drawOnChartArea=!1,delete n.scales.y.ticks.maxTicksLimit,r=p(n,k,S,A,T,D,O,L)(t,t.options)}else r=B(t,t.options);j(t,r,e);var a=I(t,r,"column");"bar"!==e&&function(t,e,r){var n=Math.ceil(t.element.offsetWidth/4/e.labels.length);n>25?n=25:n<10&&(n=10),r.scales.x.ticks.callback||(r.scales.x.ticks.callback=function(t){return(t=i(this.getLabelForValue(t))).length>n?t.substring(0,n-2)+"...":t})}(t,a,r),"mode"in r.interaction||(r.interaction.mode="index"),this.drawChart(t,"bar",a,r)},M.prototype.renderAreaChart=function(t){this.renderLineChart(t,"area")},M.prototype.renderBarChart=function(t){this.renderColumnChart(t,"bar")},M.prototype.renderScatterChart=function(t,e){e=e||"scatter";var r=B(t,t.options);j(t,r,e),"showLine"in r||(r.showLine=!1);var n=I(t,r,e);r.scales.x.type=r.scales.x.type||"linear",r.scales.x.position=r.scales.x.position||"bottom","mode"in r.interaction||(r.interaction.mode="nearest"),this.drawChart(t,e,n,r)},M.prototype.renderBubbleChart=function(t){this.renderScatterChart(t,"bubble")},M.prototype.destroy=function(t){t.chart&&t.chart.destroy()},M.prototype.drawChart=function(t,e,r,n){if(this.destroy(t),!t.destroyed){var o={type:e,data:r,options:n};t.options.code&&window.console.log("new Chart(ctx, "+JSON.stringify(o)+");"),t.element.innerHTML="<canvas></canvas>";var a=t.element.getElementsByTagName("CANVAS")[0];t.chart=new this.library(a,o)}};var R={chart:{},xAxis:{title:{text:null},labels:{style:{fontSize:"12px"}}},yAxis:{title:{text:null},labels:{style:{fontSize:"12px"}}},title:{text:null},credits:{enabled:!1},legend:{borderWidth:0},tooltip:{style:{fontSize:"12px"}},plotOptions:{areaspline:{},area:{},series:{marker:{}}},time:{useUTC:!1}};function H(t,e,r){void 0!==e?(t.legend.enabled=!!e,e&&!0!==e&&("top"===e||"bottom"===e?t.legend.verticalAlign=e:(t.legend.layout="vertical",t.legend.verticalAlign="middle",t.legend.align=e))):r&&(t.legend.enabled=!1)}function P(t,e){t.title.text=e}var W=p(R,H,P,(function(t,e){t.yAxis.min=e}),(function(t,e){t.yAxis.max=e}),(function(t,e){var r=e?!0===e?"normal":e:null;t.plotOptions.series.stacking=r,t.plotOptions.area.stacking=r,t.plotOptions.areaspline.stacking=r}),(function(t,e){t.xAxis.title.text=e}),(function(t,e){t.yAxis.title.text=e}));function V(e,r,n){var o={prefix:e.options.prefix,suffix:e.options.suffix,thousands:e.options.thousands,decimal:e.options.decimal,precision:e.options.precision,round:e.options.round,zeros:e.options.zeros};"pie"===n||t(r.yAxis)||r.yAxis.labels.formatter||(r.yAxis.labels.formatter=function(){return b("",this.value,o)}),r.tooltip.pointFormatter||r.tooltip.pointFormat||(r.tooltip.pointFormatter=function(){return'<span style="color:'+this.color+'">●</span> '+b(this.series.name+": <b>",this.y,o)+"</b><br/>"})}var G=function(t){this.name="highcharts",this.library=t};G.prototype.renderLineChart=function(t,e){var r={};"areaspline"===(e=e||"spline")&&(r={plotOptions:{areaspline:{stacking:"normal"},area:{stacking:"normal"},series:{marker:{enabled:!1}}}}),!1===t.options.curve&&("areaspline"===e?e="area":"spline"===e&&(e="line"));var n=W(t,t.options,r);"number"===t.xtype?n.xAxis.type=n.xAxis.type||"linear":n.xAxis.type="string"===t.xtype?"category":"datetime",n.chart.type||(n.chart.type=e),V(t,n,e);for(var o=t.data,a=0;a<o.length;a++){o[a].name=o[a].name||"Value";var i=o[a].data;if("datetime"===t.xtype)for(var s=0;s<i.length;s++)i[s][0]=i[s][0].getTime();else"number"===t.xtype&&i.sort(d);o[a].marker={symbol:"circle"},!1===t.options.points&&(o[a].marker.enabled=!1)}this.drawChart(t,o,n)},G.prototype.renderScatterChart=function(t){var e=W(t,t.options,{});e.chart.type="scatter",this.drawChart(t,t.data,e)},G.prototype.renderPieChart=function(t){var e=o(R,{});t.options.colors&&(e.colors=t.options.colors),t.options.donut&&(e.plotOptions={pie:{innerSize:"50%"}}),"legend"in t.options&&H(e,t.options.legend),t.options.title&&P(e,t.options.title);var r=o(e,t.options.library||{});V(t,r,"pie");var n=[{type:"pie",name:t.options.label||"Value",data:t.data}];this.drawChart(t,n,r)},G.prototype.renderColumnChart=function(t,e){e=e||"column";var r=t.data,n=W(t,t.options),o=[],a=[];n.chart.type=e,V(t,n,e);for(var i=0;i<r.length;i++)for(var s=r[i],l=0;l<s.data.length;l++){var c=s.data[l];o[c[0]]||(o[c[0]]=new Array(r.length),a.push(c[0])),o[c[0]][i]=c[1]}"number"===t.xtype&&a.sort(h),n.xAxis.categories=a;for(var p=[],u=0;u<r.length;u++){for(var d=[],f=0;f<a.length;f++)d.push(o[a[f]][u]||0);var y={name:r[u].name||"Value",data:d};r[u].stack&&(y.stack=r[u].stack),p.push(y)}this.drawChart(t,p,n)},G.prototype.renderBarChart=function(t){this.renderColumnChart(t,"bar")},G.prototype.renderAreaChart=function(t){this.renderLineChart(t,"areaspline")},G.prototype.destroy=function(t){t.chart&&t.chart.destroy()},G.prototype.drawChart=function(t,e,r){this.destroy(t),t.destroyed||(r.chart.renderTo=t.element.id,r.series=e,t.options.code&&window.console.log("new Highcharts.Chart("+JSON.stringify(r)+");"),t.chart=new this.library.Chart(r))};var U={},J=[],K={chartArea:{},fontName:"'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif",pointSize:6,legend:{textStyle:{fontSize:12,color:"#444"},alignment:"center",position:"right"},curveType:"function",hAxis:{textStyle:{color:"#666",fontSize:12},titleTextStyle:{},gridlines:{color:"transparent"},baselineColor:"#ccc",viewWindow:{}},vAxis:{textStyle:{color:"#666",fontSize:12},titleTextStyle:{},baselineColor:"#ccc",viewWindow:{}},tooltip:{textStyle:{color:"#666",fontSize:12}}};function q(t,e,r){var n;void 0!==e?(n=e?!0===e?"right":e:"none",t.legend.position=n):r&&(t.legend.position="none")}function $(t,e){t.title=e,t.titleTextStyle={color:"#333",fontSize:"20px"}}function X(t,e){t.hAxis.viewWindow.min=e}function Y(t,e){t.hAxis.viewWindow.max=e}function Z(t,e){t.isStacked=e||!1}function Q(t,e){t.hAxis.title=e,t.hAxis.titleTextStyle.italic=!1}function tt(t,e){t.vAxis.title=e,t.vAxis.titleTextStyle.italic=!1}var et=p(K,q,$,(function(t,e){t.vAxis.viewWindow.min=e}),(function(t,e){t.vAxis.viewWindow.max=e}),Z,Q,tt);var rt=function(t){this.name="google",this.library=t};rt.prototype.renderLineChart=function(t){var e=this;this.waitForLoaded(t,(function(){var r={};!1===t.options.curve&&(r.curveType="none"),!1===t.options.points&&(r.pointSize=0);var n=et(t,t.options,r),o=e.createDataTable(t.data,t.xtype);e.drawChart(t,"LineChart",o,n)}))},rt.prototype.renderPieChart=function(t){var e=this;this.waitForLoaded(t,(function(){var r={chartArea:{top:"10%",height:"80%"},legend:{}};t.options.colors&&(r.colors=t.options.colors),t.options.donut&&(r.pieHole=.5),"legend"in t.options&&q(r,t.options.legend),t.options.title&&$(r,t.options.title);var n=o(o(K,r),t.options.library||{}),a=new e.library.visualization.DataTable;a.addColumn("string",""),a.addColumn("number","Value"),a.addRows(t.data),e.drawChart(t,"PieChart",a,n)}))},rt.prototype.renderColumnChart=function(t){var e=this;this.waitForLoaded(t,(function(){var r=et(t,t.options),n=e.createDataTable(t.data,t.xtype);e.drawChart(t,"ColumnChart",n,r)}))},rt.prototype.renderBarChart=function(t){var e=this;this.waitForLoaded(t,(function(){var r=p(K,q,$,X,Y,Z,Q,tt)(t,t.options,{hAxis:{gridlines:{color:"#ccc"}}}),n=e.createDataTable(t.data,t.xtype);e.drawChart(t,"BarChart",n,r)}))},rt.prototype.renderAreaChart=function(t){var e=this;this.waitForLoaded(t,(function(){var r=et(t,t.options,{isStacked:!0,pointSize:0,areaOpacity:.5}),n=e.createDataTable(t.data,t.xtype);e.drawChart(t,"AreaChart",n,r)}))},rt.prototype.renderGeoChart=function(t){var e=this;this.waitForLoaded(t,"geochart",(function(){var r={legend:"none",colorAxis:{colors:t.options.colors||["#f6c7b6","#ce502d"]}},n=o(o(K,r),t.options.library||{}),a=new e.library.visualization.DataTable;a.addColumn("string",""),a.addColumn("number",t.options.label||"Value"),a.addRows(t.data),e.drawChart(t,"GeoChart",a,n)}))},rt.prototype.renderScatterChart=function(t){var e=this;this.waitForLoaded(t,(function(){for(var r=et(t,t.options,{}),n=t.data,o=[],a=0;a<n.length;a++){n[a].name=n[a].name||"Value";for(var i=n[a].data,s=0;s<i.length;s++){var l=new Array(n.length+1);l[0]=i[s][0],l[a+1]=i[s][1],o.push(l)}}var c=new e.library.visualization.DataTable;c.addColumn("number","");for(var p=0;p<n.length;p++)c.addColumn("number",n[p].name);c.addRows(o),e.drawChart(t,"ScatterChart",c,r)}))},rt.prototype.renderTimeline=function(t){var e=this;this.waitForLoaded(t,"timeline",(function(){var r={legend:"none"};t.options.colors&&(r.colors=t.options.colors);var n=o(o(K,r),t.options.library||{}),a=new e.library.visualization.DataTable;a.addColumn({type:"string",id:"Name"}),a.addColumn({type:"date",id:"Start"}),a.addColumn({type:"date",id:"End"}),a.addRows(t.data),t.element.style.lineHeight="normal",e.drawChart(t,"Timeline",a,n)}))},rt.prototype.destroy=function(t){t.chart&&t.chart.clearChart()},rt.prototype.drawChart=function(t,e,r,n){var o;(this.destroy(t),t.destroyed)||(t.options.code&&window.console.log("var data = new google.visualization.DataTable("+r.toJSON()+");\nvar chart = new google.visualization."+e+"(element);\nchart.draw(data, "+JSON.stringify(n)+");"),t.chart=new this.library.visualization[e](t.element),o=function(){t.chart.draw(r,n)},window.attachEvent?window.attachEvent("onresize",o):window.addEventListener&&window.addEventListener("resize",o,!0),o())},rt.prototype.waitForLoaded=function(t,e,r){var n=this;if(r||(r=e,e="corechart"),J.push({pack:e,callback:r}),U[e])this.runCallbacks();else{U[e]=!0;var o={packages:[e],callback:function(){n.runCallbacks()}},a=t.__config();a.language&&(o.language=a.language),"geochart"===e&&a.mapsApiKey&&(o.mapsApiKey=a.mapsApiKey),this.library.charts.load("current",o)}},rt.prototype.runCallbacks=function(){for(var t=0;t<J.length;t++){var e=J[t];this.library.visualization&&("corechart"===e.pack&&this.library.visualization.LineChart||"timeline"===e.pack&&this.library.visualization.Timeline||"geochart"===e.pack&&this.library.visualization.GeoChart)&&(e.callback(),J.splice(t,1),t--)}},rt.prototype.createDataTable=function(t,e){for(var r=[],n=[],o=0;o<t.length;o++){var a=t[o];t[o].name=t[o].name||"Value";for(var s=0;s<a.data.length;s++){var l=a.data[s],c="datetime"===e?l[0].getTime():l[0];r[c]||(r[c]=new Array(t.length),n.push(c)),r[c][o]=l[1]}}for(var p=[],h=[],f=0;f<n.length;f++){var m=n[f],v=void 0;"datetime"===e?(v=new Date(m),h.push(v)):v=m,p.push([v].concat(r[m]))}var g=!0;if("datetime"===e)p.sort(u),g=function(t){return"day"===t||"week"===t||"month"===t||"year"===t}(y(h,!0));else if("number"===e){p.sort(d);for(var b=0;b<p.length;b++)p[b][0]=i(p[b][0]);e="string"}var x=new this.library.visualization.DataTable;e="datetime"===e&&g?"date":e,x.addColumn(e,"");for(var w=0;w<t.length;w++)x.addColumn("number",t[w].name);return x.addRows(p),x};var nt=[];function ot(t){for(var r=function(t){if(t){if("Highcharts"===t.product)return G;if(t.charts)return rt;if(e(t))return M}throw new Error("Unknown adapter")}(t),n=0;n<nt.length;n++)if(nt[n].library===t)return;nt.push(new r(t))}function at(t,r){var n="render"+t,o=r.options.adapter;"Chart"in window&&ot(window.Chart),"Highcharts"in window&&ot(window.Highcharts),window.google&&window.google.charts&&ot(window.google);for(var a=0;a<nt.length;a++){var i=nt[a];if((!o||o===i.name)&&e(i[n]))return r.adapter=i.name,r.__adapterObject=i,i[n](r)}throw nt.length>0?new Error("No charting library found for "+t):new Error("No charting libraries found - be sure to include one before your charts")}var it={charts:{},configure:function(t){for(var e in t)Object.prototype.hasOwnProperty.call(t,e)&&(it.config[e]=t[e])},setDefaultOptions:function(t){it.options=t},eachChart:function(t){for(var e in it.charts)Object.prototype.hasOwnProperty.call(it.charts,e)&&t(it.charts[e])},destroyAll:function(){for(var t in it.charts)Object.prototype.hasOwnProperty.call(it.charts,t)&&(it.charts[t].destroy(),delete it.charts[t])},config:{},options:{},adapters:nt,addAdapter:ot,use:function(t){return ot(t),it}};function st(t,e){if("bubble"===e)return function(t){for(var e=[],r=0;r<t.length;r++)e.push([s(t[r][0]),s(t[r][1]),s(t[r][2])]);return e}(t);var r;r="number"===e?s:"datetime"===e?l:i;for(var n=[],o=0;o<t.length;o++)n.push([r(t[o][0]),s(t[o][1])]);return n}function lt(t,e){for(var r=0;r<t.length;r++)for(var n=c(t[r].data),o=0;o<n.length;o++)if(!e(n[o][0]))return!1;return!0}function ct(e,n,o){var a=e.options,i=e.rawData;e.singleSeriesFormat=!t(i)||!r(i[0]),e.singleSeriesFormat&&(i=[{name:a.label,data:i}]),i=function(t){for(var e=[],r=0;r<t.length;r++){var n={};for(var o in t[r])Object.prototype.hasOwnProperty.call(t[r],o)&&(n[o]=t[r][o]);e.push(n)}return e}(i);for(var s=0;s<i.length;s++)i[s].data=c(i[s].data);e.xtype=n||(a.discrete?"string":function(t,e,r){return ut(t)?!r.xmin&&!r.xmax||r.xmin&&!m(r.xmin)||r.xmax&&!m(r.xmax)?"number":"datetime":lt(t,v)?"number":!e&&lt(t,m)?"datetime":"string"}(i,o,a));for(var l=0;l<i.length;l++)i[l].data=st(i[l].data,e.xtype);return i}function pt(t){for(var e=c(t.rawData),r=0;r<e.length;r++)e[r]=[i(e[r][0]),s(e[r][1])];return e}function ut(t,e){if("PieChart"===e||"GeoChart"===e||"Timeline"===e)return 0===t.length;for(var r=0;r<t.length;r++)if(t[r].data.length>0)return!1;return!0}var dt=[],ht=0;function ft(){if(ht<4){var t=dt.shift();t&&(ht++,e=t[0],r=t[1],n=t[2],(o=new XMLHttpRequest).open("GET",e,!0),o.setRequestHeader("Content-Type","application/json"),o.onload=function(){ht--,ft(),200===o.status?r(JSON.parse(o.responseText)):n(o.statusText)},o.send(),ft())}var e,r,n,o}function yt(t,e){t.textContent=e}function mt(t,e,r){r||(e="Error Loading Chart: "+e),yt(t,e),t.style.color="#ff0000"}function vt(t){try{t.__render()}catch(e){throw mt(t.element,e.message),e}}function gt(t,e,r){if(r&&t.options.loading&&("string"==typeof e||"function"==typeof e)&&yt(t.element,t.options.loading),"string"==typeof e)n=e,o=function(e){t.rawData=e,vt(t)},a=function(e){mt(t.element,e)},dt.push([n,o,a]),ft();else if("function"==typeof e)try{e((function(e){t.rawData=e,vt(t)}),(function(e){mt(t.element,e,!0)}))}catch(e){mt(t.element,e,!0)}else t.rawData=e,vt(t);var n,o,a}function bt(t,e){if(ut(e.data,t)){var r=e.options.empty||e.options.messages&&e.options.messages.empty||"No data";yt(e.element,r)}else at(t,e),e.options.download&&!e.__downloadAttached&&"chartjs"===e.adapter&&function(t){var e=t.options.download;!0===e?e={}:"string"==typeof e&&(e={filename:e});var r=document.createElement("a");r.download=e.filename||"chart.png",r.style.position="absolute",r.style.top="20px",r.style.right="20px",r.style.zIndex=1e3,r.style.lineHeight="20px",r.target="_blank";var n=document.createElement("img");n.src="data:image/svg+xml;utf8,"+encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">\x3c!--! Font Awesome Free 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --\x3e<path fill="#CCCCCC" d="M344 240h-56L287.1 152c0-13.25-10.75-24-24-24h-16C234.7 128 223.1 138.8 223.1 152L224 240h-56c-9.531 0-18.16 5.656-22 14.38C142.2 263.1 143.9 273.3 150.4 280.3l88.75 96C243.7 381.2 250.1 384 256.8 384c7.781-.3125 13.25-2.875 17.75-7.844l87.25-96c6.406-7.031 8.031-17.19 4.188-25.88S353.5 240 344 240zM256 0C114.6 0 0 114.6 0 256s114.6 256 256 256s256-114.6 256-256S397.4 0 256 0zM256 464c-114.7 0-208-93.31-208-208S141.3 48 256 48s208 93.31 208 208S370.7 464 256 464z"/></svg>'),n.alt="Download",n.style.width="20px",n.style.height="20px",n.style.border="none",r.appendChild(n);var o=t.element;o.style.position="relative",t.__downloadAttached=!0,t.__enterEvent=o.addEventListener("mouseover",(function(n){var a=n.relatedTarget;a&&(a===this||this.contains(a))||!t.options.download||(r.href=t.toImage(e),o.appendChild(r))})),t.__leaveEvent=o.addEventListener("mouseout",(function(t){var e=t.relatedTarget;e&&(e===this||this.contains(e))||r.parentNode&&r.parentNode.removeChild(r)}))}(e)}var xt=function(t,e,r){this.element=function(t){if("string"==typeof t){var e=t;if(!(t=document.getElementById(t)))throw new Error("No element with id "+e)}return t}(t),this.options=o(it.options,r||{}),this.dataSource=e,this.element.id&&(it.charts[this.element.id]=this),gt(this,e,!0),this.options.refresh&&this.startRefresh()};xt.prototype.getElement=function(){return this.element},xt.prototype.getDataSource=function(){return this.dataSource},xt.prototype.getData=function(){return this.data},xt.prototype.getOptions=function(){return this.options},xt.prototype.getChartObject=function(){return this.chart},xt.prototype.getAdapter=function(){return this.adapter},xt.prototype.updateData=function(t,e){this.dataSource=t,e&&this.__updateOptions(e),gt(this,t,!0)},xt.prototype.setOptions=function(t){this.__updateOptions(t),this.redraw()},xt.prototype.redraw=function(){gt(this,this.rawData)},xt.prototype.refreshData=function(){if("string"==typeof this.dataSource){var t=-1===this.dataSource.indexOf("?")?"?":"&";gt(this,this.dataSource+t+"_="+(new Date).getTime())}else"function"==typeof this.dataSource&&gt(this,this.dataSource)},xt.prototype.startRefresh=function(){var t=this,e=this.options.refresh;if(e&&"string"!=typeof this.dataSource&&"function"!=typeof this.dataSource)throw new Error("Data source must be a URL or callback for refresh");if(!this.intervalId){if(!e)throw new Error("No refresh interval");this.intervalId=setInterval((function(){t.refreshData()}),1e3*e)}},xt.prototype.stopRefresh=function(){this.intervalId&&(clearInterval(this.intervalId),this.intervalId=null)},xt.prototype.toImage=function(t){if("chartjs"===this.adapter){if(t&&t.background&&"transparent"!==t.background){var e=this.chart.canvas,r=this.chart.ctx,n=document.createElement("canvas"),o=n.getContext("2d");return n.width=r.canvas.width,n.height=r.canvas.height,o.fillStyle=t.background,o.fillRect(0,0,n.width,n.height),o.drawImage(e,0,0),n.toDataURL("image/png")}return this.chart.toBase64Image()}throw new Error("Feature only available for Chart.js")},xt.prototype.destroy=function(){this.destroyed=!0,this.stopRefresh(),this.__adapterObject&&this.__adapterObject.destroy(this),this.__enterEvent&&this.element.removeEventListener("mouseover",this.__enterEvent),this.__leaveEvent&&this.element.removeEventListener("mouseout",this.__leaveEvent)},xt.prototype.__updateOptions=function(t){var e=t.refresh&&t.refresh!==this.options.refresh;this.options=o(it.options,t),e&&(this.stopRefresh(),this.startRefresh())},xt.prototype.__render=function(){this.data=this.__processData(),bt(this.__chartName(),this)},xt.prototype.__config=function(){return it.config};var wt=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.__processData=function(){return ct(this)},e.prototype.__chartName=function(){return"LineChart"},e}(xt),Ct=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.__processData=function(){return pt(this)},e.prototype.__chartName=function(){return"PieChart"},e}(xt),_t=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.__processData=function(){return ct(this,null,!0)},e.prototype.__chartName=function(){return"ColumnChart"},e}(xt),kt=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.__processData=function(){return ct(this,null,!0)},e.prototype.__chartName=function(){return"BarChart"},e}(xt),St=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.__processData=function(){return ct(this)},e.prototype.__chartName=function(){return"AreaChart"},e}(xt),At=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.__processData=function(){return pt(this)},e.prototype.__chartName=function(){return"GeoChart"},e}(xt),Tt=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.__processData=function(){return ct(this,"number")},e.prototype.__chartName=function(){return"ScatterChart"},e}(xt),Dt=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.__processData=function(){return ct(this,"bubble")},e.prototype.__chartName=function(){return"BubbleChart"},e}(xt),Ot=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.__processData=function(){for(var t=this.rawData,e=0;e<t.length;e++)t[e][1]=l(t[e][1]),t[e][2]=l(t[e][2]);return t},e.prototype.__chartName=function(){return"Timeline"},e}(xt);return it.LineChart=wt,it.PieChart=Ct,it.ColumnChart=_t,it.BarChart=kt,it.AreaChart=St,it.GeoChart=At,it.ScatterChart=Tt,it.BubbleChart=Dt,it.Timeline=Ot,"undefined"==typeof window||window.Chartkick||(window.Chartkick=it,document.addEventListener("turbolinks:before-render",(function(){!1!==it.config.autoDestroy&&it.destroyAll()})),document.addEventListener("turbo:before-render",(function(){!1!==it.config.autoDestroy&&it.destroyAll()})),setTimeout((function(){window.dispatchEvent(new Event("chartkick:load"))}),0)),it.default=it,it}));
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,29 @@
1
+ module SolidLoop
2
+ class ApplicationController < ActionController::Base
3
+ layout "solid_loop/admin"
4
+
5
+ private
6
+
7
+ def paginate(scope, per_page: 50)
8
+ current_page = params.fetch(:page, 1).to_i
9
+ current_page = 1 if current_page < 1
10
+
11
+ total_count = scope.count
12
+ total_pages = (total_count.to_f / per_page).ceil
13
+ current_page = total_pages if total_pages.positive? && current_page > total_pages
14
+ current_page = 1 if current_page < 1
15
+
16
+ records = scope.limit(per_page).offset((current_page - 1) * per_page)
17
+
18
+ {
19
+ records: records,
20
+ current_page: current_page,
21
+ prev_page: current_page > 1 ? current_page - 1 : nil,
22
+ next_page: current_page < total_pages ? current_page + 1 : nil,
23
+ total_count: total_count,
24
+ total_pages: total_pages,
25
+ per_page: per_page
26
+ }
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,104 @@
1
+ module SolidLoop
2
+ class DashboardController < ApplicationController
3
+ def index
4
+ @period = params[:period] || "hour"
5
+ end
6
+
7
+ def stats
8
+ period = params[:period] || "hour"
9
+
10
+ render json: {
11
+ period: period,
12
+ llm_calls: llm_calls_by_period(period),
13
+ tool_calls: tool_calls_by_period(period),
14
+ cost: cost_by_period(period),
15
+ tokens: tokens_by_period(period),
16
+ top_agents: top_agents_by_cost(period),
17
+ failed: failed_by_period(period),
18
+ summary: summary_stats(period)
19
+ }
20
+ end
21
+
22
+ private
23
+
24
+ def sql_period(period)
25
+ case period
26
+ when "day" then "date_trunc('day', created_at)"
27
+ when "week" then "date_trunc('week', created_at)"
28
+ else "date_trunc('hour', created_at)"
29
+ end
30
+ end
31
+
32
+ def interval(period)
33
+ case period
34
+ when "day" then 30.days.ago
35
+ when "week" then 12.weeks.ago
36
+ else 24.hours.ago
37
+ end
38
+ end
39
+
40
+ def llm_calls_by_period(period)
41
+ SolidLoop::Event.where(name: "llm_completion").where("created_at > ?", interval(period))
42
+ .group(sql_period(period)).count
43
+ end
44
+
45
+ def tool_calls_by_period(period)
46
+ SolidLoop::Event.where(name: "mcp_tool_call").where("created_at > ?", interval(period))
47
+ .group(sql_period(period)).count
48
+ end
49
+
50
+ def cost_by_period(period)
51
+ SolidLoop::Loop.where("created_at > ?", interval(period))
52
+ .group(sql_period(period)).sum(:cost)
53
+ end
54
+
55
+ def tokens_by_period(period)
56
+ # Simulating stacked token counts
57
+ loops = SolidLoop::Loop.where("created_at > ?", interval(period))
58
+ .group(sql_period(period))
59
+ .sum(:tokens_total)
60
+ # Not fully stacked without separate prompt/completion, but good enough for now
61
+ [{ name: "Tokens", data: loops }]
62
+ end
63
+
64
+ def top_agents_by_cost(period)
65
+ SolidLoop::Loop.where("created_at > ?", interval(period))
66
+ .group(:agent_class_name)
67
+ .order(Arel.sql("sum_cost DESC"))
68
+ .limit(5)
69
+ .sum(:cost)
70
+ end
71
+
72
+ def failed_by_period(period)
73
+ SolidLoop::Loop.where(status: "failed").where("created_at > ?", interval(period))
74
+ .group(sql_period(period)).count
75
+ end
76
+
77
+ def summary_stats(period)
78
+ failed_counts = failed_split(period)
79
+
80
+ {
81
+ llm_calls: SolidLoop::Event.where(name: "llm_completion").where("created_at > ?", interval(period)).count,
82
+ tool_calls: SolidLoop::Event.where(name: "mcp_tool_call").where("created_at > ?", interval(period)).count,
83
+ cost: SolidLoop::Loop.where("created_at > ?", interval(period)).sum(:cost).to_f.round(3),
84
+ failed: failed_counts[:agent] + failed_counts[:infra],
85
+ failed_agent: failed_counts[:agent],
86
+ failed_infra: failed_counts[:infra]
87
+ }
88
+ end
89
+
90
+ # Split failed loops into genuine agent-logic failures vs. infra/provider
91
+ # (transport, HTTP error envelope, PII-redaction) failures by classifying
92
+ # the captured terminal error message. Read-only, no schema change.
93
+ def failed_split(period)
94
+ messages = SolidLoop::Loop
95
+ .where(status: "failed")
96
+ .where("created_at > ?", interval(period))
97
+ .pluck(:error_message)
98
+
99
+ messages.each_with_object(agent: 0, infra: 0) do |msg, acc|
100
+ acc[SolidLoop::ApplicationHelper.classify_failure(msg)] += 1
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,12 @@
1
+ module SolidLoop
2
+ class EventsController < ApplicationController
3
+ def index
4
+ @pagination = paginate(SolidLoop::Admin::EventsQuery.new(params).call)
5
+ @events = @pagination[:records]
6
+ end
7
+
8
+ def show
9
+ @event = SolidLoop::Event.find(params[:id])
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,77 @@
1
+ module SolidLoop
2
+ class LoopsController < ApplicationController
3
+ before_action :set_loop, only: %i[show observe freeze unfreeze force_stop]
4
+
5
+ def index
6
+ query = SolidLoop::Admin::LoopsQuery.new(params)
7
+ return redirect_to(loop_path(query.exact_match)) if query.exact_match
8
+
9
+ @pagination = paginate(query.call)
10
+ @loops = @pagination[:records]
11
+ end
12
+
13
+ def show
14
+ messages_scope = SolidLoop::Admin::MessagesQuery
15
+ .new(params, scope: @loop.messages.includes(:tool_calls).order(Arel.sql("COALESCE(conversation_order, id)")))
16
+ .call
17
+
18
+ @messages_pagination = paginate(messages_scope, per_page: 100)
19
+ @messages = @messages_pagination[:records]
20
+ end
21
+
22
+ def observe
23
+ @loop.update!(observe_enabled: !@loop.observe_enabled)
24
+ redirect_to loop_path(@loop), notice: "Observe mode toggled."
25
+ end
26
+
27
+ def freeze
28
+ @loop.with_lock do
29
+ attributes = { frozen_at: Time.current }
30
+ if SolidLoop::Loop::ACTIVE_STATUSES.include?(@loop.status)
31
+ # Cleanup 4 + 6 — freezing an active loop pauses it: clear the LLM lease
32
+ # (non-`running` target must NULL lease_expires_at so the DB CHECK holds
33
+ # and the reaper stops re-selecting it) and synchronously fail+hide any
34
+ # orphaned `processing` assistant shell so no paused loop keeps one.
35
+ attributes.merge!(status: :paused, execution_token: nil, lease_expires_at: nil)
36
+ fail_and_hide_processing_shells!(@loop)
37
+ end
38
+ @loop.update!(attributes)
39
+ end
40
+ redirect_to loop_path(@loop), notice: "Loop frozen."
41
+ end
42
+
43
+ def unfreeze
44
+ @loop.update!(frozen_at: nil)
45
+ redirect_to loop_path(@loop), notice: "Loop unfrozen."
46
+ end
47
+
48
+ def force_stop
49
+ # Cleanup 6 — force-stop synchronously fails+hides the loop's processing
50
+ # shell(s) inside the same transition txn, so no terminal loop retains an
51
+ # orphaned hidden `processing` shell. The block runs under the loop lock.
52
+ @loop.transition_status(
53
+ from: SolidLoop::Loop::STOPPABLE_STATUSES,
54
+ to: :failed,
55
+ error_message: "Stopped by admin UI",
56
+ execution_token: nil,
57
+ lease_expires_at: nil
58
+ ) { fail_and_hide_processing_shells!(@loop) }
59
+ redirect_to loop_path(@loop), alert: "Loop force stopped."
60
+ end
61
+
62
+ private
63
+
64
+ # Fail + hide any `processing` assistant/streaming shell for the loop
65
+ # (born-hidden shell protocol): partial content is kept for audit but never
66
+ # shown as canonical history. Mirrors Reaper#fail_and_hide_processing_shells!.
67
+ def fail_and_hide_processing_shells!(loop)
68
+ loop.messages.where(role: "assistant", status: "processing").find_each do |shell|
69
+ shell.update!(status: "failed", is_hidden: true)
70
+ end
71
+ end
72
+
73
+ def set_loop
74
+ @loop = SolidLoop::Loop.find(params[:id])
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,13 @@
1
+ module SolidLoop
2
+ class McpInboundSessionsController < ApplicationController
3
+ def index
4
+ @pagination = paginate(SolidLoop::Admin::McpInboundSessionsQuery.new(params).call)
5
+ @mcp_inbound_sessions = @pagination[:records]
6
+ end
7
+
8
+ def show
9
+ @mcp_inbound_session = SolidLoop::McpInboundSession.find(params[:id])
10
+ @recent_events = @mcp_inbound_session.events.order(created_at: :desc).limit(20)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,68 @@
1
+ module SolidLoop
2
+ class McpSessionsController < ApplicationController
3
+ before_action :set_session, only: %i[show inspector run_tool]
4
+
5
+ def index
6
+ @pagination = paginate(SolidLoop::Admin::McpSessionsQuery.new(params).call)
7
+ @mcp_sessions = @pagination[:records]
8
+ end
9
+
10
+ def show
11
+ @mcp_tools = @mcp_session.mcp_tools.order(:name)
12
+ @recent_tool_calls = SolidLoop::ToolCall.where(mcp_session_id: @mcp_session.id).order(created_at: :desc).limit(20)
13
+ end
14
+
15
+ def inspector
16
+ @tools = @mcp_session.mcp_tools.order(:name)
17
+ @selected_tool = params[:tool_name].present? ? @tools.find_by(name: params[:tool_name]) : @tools.first
18
+
19
+ if params[:replay_tool_call_id].present?
20
+ tc = SolidLoop::ToolCall.find(params[:replay_tool_call_id])
21
+ @replay_arguments = tc.arguments
22
+ @selected_tool = @tools.find_by(name: tc.function_name) || @selected_tool
23
+ end
24
+ end
25
+
26
+ def run_tool
27
+ tool_name = params[:tool_name]
28
+ arguments = params[:arguments]&.to_unsafe_h || {}
29
+
30
+ @tools = @mcp_session.mcp_tools.order(:name)
31
+ @tool = @mcp_session.mcp_tools.find_by!(name: tool_name)
32
+ @selected_tool = @tool
33
+ agent = @mcp_session.loop&.agent
34
+
35
+ start_time = Time.current
36
+ result_hash = @tool.call(agent: agent, arguments: arguments)
37
+ duration = Time.current - start_time
38
+
39
+ @result = result_hash[:result]
40
+ @is_error = !result_hash[:success]
41
+ @duration = result_hash[:duration] || duration
42
+ @log = result_hash[:log]
43
+
44
+ respond_to do |format|
45
+ format.turbo_stream do
46
+ content = render_to_string(
47
+ partial: "solid_loop/mcp_sessions/tool_output",
48
+ formats: [ :html ],
49
+ locals: { result: @result, is_error: @is_error, duration: @duration, log: @log }
50
+ )
51
+
52
+ render html: <<~HTML.html_safe, content_type: "text/vnd.turbo-stream.html"
53
+ <turbo-stream action="update" target="sl-inspector-output">
54
+ <template>#{content}</template>
55
+ </turbo-stream>
56
+ HTML
57
+ end
58
+ format.html { render :inspector }
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def set_session
65
+ @mcp_session = SolidLoop::McpSession.find(params[:id])
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,16 @@
1
+ module SolidLoop
2
+ class McpToolsController < ApplicationController
3
+ def index
4
+ @pagination = paginate(SolidLoop::Admin::McpToolsQuery.new(params).call)
5
+ @mcp_tools = @pagination[:records]
6
+ end
7
+
8
+ def show
9
+ @mcp_tool = SolidLoop::McpTool.find(params[:id])
10
+ @recent_tool_calls = SolidLoop::ToolCall
11
+ .where(mcp_session_id: @mcp_tool.mcp_session_id, function_name: @mcp_tool.name)
12
+ .order(created_at: :desc)
13
+ .limit(20)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ module SolidLoop
2
+ class MessagesController < ApplicationController
3
+ def index
4
+ @pagination = paginate(SolidLoop::Admin::MessagesQuery.new(params).call)
5
+ @messages = @pagination[:records]
6
+ end
7
+
8
+ def show
9
+ @message = SolidLoop::Message.find(params[:id])
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module SolidLoop
2
+ class ToolCallsController < ApplicationController
3
+ def index
4
+ @pagination = paginate(SolidLoop::Admin::ToolCallsQuery.new(params).call)
5
+ @tool_calls = @pagination[:records]
6
+ end
7
+
8
+ def show
9
+ @tool_call = SolidLoop::ToolCall.find(params[:id])
10
+ end
11
+ end
12
+ end