inferno_core 0.6.9 → 0.6.11

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/lib/inferno/apps/cli/evaluate/database.yml +15 -0
  3. data/lib/inferno/apps/cli/evaluate/docker-compose.evaluate.yml +16 -0
  4. data/lib/inferno/apps/cli/evaluate.rb +52 -4
  5. data/lib/inferno/apps/cli/execute.rb +17 -21
  6. data/lib/inferno/apps/cli/main.rb +5 -1
  7. data/lib/inferno/apps/cli/requirements.rb +28 -0
  8. data/lib/inferno/apps/cli/requirements_exporter.rb +194 -0
  9. data/lib/inferno/apps/cli/suite.rb +21 -0
  10. data/lib/inferno/apps/cli/templates/lib/%library_name%/example_suite/patient_group.rb.tt +141 -0
  11. data/lib/inferno/apps/cli/templates/lib/%library_name%/example_suite.rb.tt +128 -0
  12. data/lib/inferno/apps/cli/templates/lib/%library_name%/metadata.rb.tt +65 -3
  13. data/lib/inferno/apps/cli/templates/lib/%library_name%/version.rb.tt +1 -0
  14. data/lib/inferno/apps/cli/templates/lib/%library_name%.rb.tt +1 -1
  15. data/lib/inferno/apps/web/router.rb +10 -5
  16. data/lib/inferno/apps/web/serializers/input.rb +1 -0
  17. data/lib/inferno/apps/web/serializers/serializer.rb +7 -0
  18. data/lib/inferno/apps/web/serializers/test.rb +1 -0
  19. data/lib/inferno/apps/web/serializers/test_group.rb +1 -0
  20. data/lib/inferno/apps/web/serializers/test_suite.rb +2 -1
  21. data/lib/inferno/config/boot/suites.rb +3 -0
  22. data/lib/inferno/dsl/fhir_evaluation/default.yml +68 -0
  23. data/lib/inferno/dsl/fhir_evaluation/evaluator.rb +3 -5
  24. data/lib/inferno/dsl/fhir_evaluation/rules/all_defined_extensions_have_examples.rb +2 -2
  25. data/lib/inferno/dsl/fhir_evaluation/rules/all_extensions_used.rb +2 -2
  26. data/lib/inferno/dsl/fhir_evaluation/rules/all_must_supports_present.rb +1 -1
  27. data/lib/inferno/dsl/fhir_evaluation/rules/all_profiles_have_examples.rb +1 -1
  28. data/lib/inferno/dsl/fhir_evaluation/rules/all_references_resolve.rb +2 -2
  29. data/lib/inferno/dsl/fhir_evaluation/rules/all_resources_reachable.rb +2 -2
  30. data/lib/inferno/dsl/fhir_evaluation/rules/all_search_parameters_have_examples.rb +22 -11
  31. data/lib/inferno/dsl/fhir_evaluation/rules/differential_content_has_examples.rb +2 -2
  32. data/lib/inferno/dsl/fhir_evaluation/rules/value_sets_demonstrate.rb +4 -4
  33. data/lib/inferno/dsl/fhir_resource_validation.rb +25 -3
  34. data/lib/inferno/dsl/fhirpath_evaluation.rb +25 -1
  35. data/lib/inferno/dsl/input_output_handling.rb +1 -0
  36. data/lib/inferno/dsl/runnable.rb +5 -0
  37. data/lib/inferno/dsl/short_id_manager.rb +55 -0
  38. data/lib/inferno/entities/input.rb +14 -5
  39. data/lib/inferno/entities/requirement.rb +15 -3
  40. data/lib/inferno/entities/test.rb +3 -1
  41. data/lib/inferno/entities/test_group.rb +3 -1
  42. data/lib/inferno/entities/test_suite.rb +2 -0
  43. data/lib/inferno/exceptions.rb +6 -0
  44. data/lib/inferno/feature.rb +9 -0
  45. data/lib/inferno/public/237.bundle.js +1 -1
  46. data/lib/inferno/public/bundle.js +54 -54
  47. data/lib/inferno/public/bundle.js.LICENSE.txt +3 -36
  48. data/lib/inferno/repositories/requirements.rb +6 -2
  49. data/lib/inferno/version.rb +1 -1
  50. data/spec/shared/test_kit_examples.rb +32 -0
  51. metadata +25 -4
  52. data/lib/inferno/apps/cli/templates/lib/%library_name%/patient_group.rb.tt +0 -44
  53. data/spec/features_helper.rb +0 -12
@@ -175,10 +175,10 @@ module Inferno
175
175
  begin
176
176
  response = call_validator(resource, profile_url)
177
177
  rescue StandardError => e
178
- # This could be a complete failure to connect (validator isn't running)
179
- # or a timeout (validator took too long to respond).
180
178
  runnable.add_message('error', e.message)
181
- raise Inferno::Exceptions::ErrorInValidatorException, "Unable to connect to validator at #{url}."
179
+ Application[:logger].error(e.message)
180
+
181
+ raise Inferno::Exceptions::ErrorInValidatorException, validator_error_message(e)
182
182
  end
183
183
 
184
184
  outcome = operation_outcome_from_validator_response(response, runnable)
@@ -340,6 +340,28 @@ module Inferno
340
340
  'Validator response was an unexpected format. ' \
341
341
  'Review Messages tab or validator service logs for more information.'
342
342
  end
343
+
344
+ # Add a specific error message for specific network problems to help the user
345
+ #
346
+ # @private
347
+ # @param error [Exception] An error exception that happened during evaluator connection
348
+ # @return [String] A readable error message describing the specific network problem
349
+ def validator_error_message(error)
350
+ case error
351
+ when Faraday::ConnectionFailed
352
+ "Connection failed to validator at #{url}."
353
+ when Faraday::TimeoutError
354
+ "Timeout while connecting to validator at #{url}."
355
+ when Faraday::SSLError
356
+ "SSL error connecting to validator at #{url}."
357
+ when Faraday::ClientError # these are 400s
358
+ "Client error (4xx) connecting to validator at #{url}."
359
+ when Faraday::ServerError # these are 500s
360
+ "Server error (5xx) from validator at #{url}."
361
+ else
362
+ "Unable to connect to validator at #{url}."
363
+ end
364
+ end
343
365
  end
344
366
 
345
367
  # @private
@@ -67,7 +67,9 @@ module Inferno
67
67
  # This could be a complete failure to connect (fhirpath service isn't running)
68
68
  # or a timeout (fhirpath service took too long to respond).
69
69
  runnable.add_message('error', e.message)
70
- raise Inferno::Exceptions::ErrorInFhirpathException, "Unable to connect to FHIRPath service at #{url}."
70
+ Application[:logger].error(e.message)
71
+
72
+ raise Inferno::Exceptions::ErrorInFhirpathException, evaluator_error_message(e)
71
73
  end
72
74
 
73
75
  sanitized_body = remove_invalid_characters(response.body)
@@ -108,6 +110,28 @@ module Inferno
108
110
  def remove_invalid_characters(string)
109
111
  string.gsub(/[^[:print:]\r\n]+/, '')
110
112
  end
113
+
114
+ # Add a specific error message for specific network problems to help the user
115
+ #
116
+ # @private
117
+ # @param error [Exception] An error exception that happened during evaluator connection
118
+ # @return [String] A readable error message describing the specific network problem
119
+ def evaluator_error_message(error)
120
+ case error
121
+ when Faraday::ConnectionFailed
122
+ "Connection failed to evaluator at #{url}."
123
+ when Faraday::TimeoutError
124
+ "Timeout while connecting to evaluator at #{url}."
125
+ when Faraday::SSLError
126
+ "SSL error connecting to evaluator at #{url}."
127
+ when Faraday::ClientError # these are 400s
128
+ "Client error (4xx) connecting to evaluator at #{url}."
129
+ when Faraday::ServerError # these are 500s
130
+ "Server error (5xx) from evaluator at #{url}."
131
+ else
132
+ "Unable to connect to FHIRPath service at #{url}."
133
+ end
134
+ end
111
135
  end
112
136
 
113
137
  module ClassMethods
@@ -12,6 +12,7 @@ module Inferno
12
12
  # @option input_params [String] :default The default value for the input
13
13
  # @option input_params [Boolean] :optional Set to true to not require input for test execution
14
14
  # @option input_params [Boolean] :locked If true, the user can not alter the value
15
+ # @option input_params [Boolean] :hidden If true, the input will not be visible to the user in the UI
15
16
  # @option input_params [Hash] :options Possible input option formats based on input type
16
17
  # @option options [Array] :list_options Array of options for input formats
17
18
  # that require a list of possible values (radio and checkbox)
@@ -346,6 +346,11 @@ module Inferno
346
346
  @all_children ||= []
347
347
  end
348
348
 
349
+ # @private
350
+ def all_descendants
351
+ children.flat_map { |child| [child] + child.all_descendants }
352
+ end
353
+
349
354
  # @private
350
355
  def suite
351
356
  return self if ancestors.include? Inferno::Entities::TestSuite
@@ -0,0 +1,55 @@
1
+ module Inferno
2
+ module DSL
3
+ # This module manages and locks short IDs, ensuring that short IDs
4
+ # remain stable and do not change unexpectedly.
5
+ module ShortIDManager
6
+ def base_short_id_file_folder
7
+ File.join(Dir.pwd, 'lib', name.split('::').first.underscore)
8
+ end
9
+
10
+ def short_id_file_name
11
+ "#{name.demodulize.underscore}_short_id_map.yml"
12
+ end
13
+
14
+ def short_id_file_path
15
+ File.join(base_short_id_file_folder, short_id_file_name).freeze
16
+ end
17
+
18
+ # Loads and memoizes the short ID map from the YAML file.
19
+ #
20
+ # @return [Hash] mapping of runnable IDs to their locked short IDs
21
+ def short_id_map
22
+ return unless File.exist?(short_id_file_path)
23
+
24
+ @short_id_map ||= YAML.load_file(short_id_file_path)
25
+ end
26
+
27
+ # @private
28
+ # Assigns locked short IDs to all descendant runnables based on the short ID map.
29
+ #
30
+ # This method is called at boot time.
31
+ #
32
+ # @return [void]
33
+ def assign_short_ids
34
+ return unless short_id_map
35
+
36
+ all_descendants.each do |runnable|
37
+ new_short_id = short_id_map.fetch(runnable.id)
38
+ runnable.short_id(new_short_id)
39
+ rescue KeyError
40
+ Inferno::Application['logger'].warn("No short id defined for #{runnable.id}")
41
+ end
42
+ end
43
+
44
+ # Builds and memoizes the current mapping of runnable IDs to their short IDs.
45
+ #
46
+ # @return [Hash] current short ID mapping
47
+ def current_short_id_map
48
+ @current_short_id_map ||=
49
+ all_descendants.each_with_object({}) do |runnable, mapping|
50
+ mapping[runnable.id] = runnable.short_id
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -14,6 +14,7 @@ module Inferno
14
14
  :optional,
15
15
  :options,
16
16
  :locked,
17
+ :hidden,
17
18
  :value
18
19
  ].freeze
19
20
  include Entities::Attributes
@@ -21,15 +22,15 @@ module Inferno
21
22
  # These attributes require special handling when merging input
22
23
  # definitions.
23
24
  UNINHERITABLE_ATTRIBUTES = [
24
- # Locking an input only has meaning at the level it is locked.
25
+ # Locking or hiding an input only has meaning at the level it is applied.
25
26
  # Consider:
26
27
  # - ParentGroup
27
28
  # - Group 1, input :a
28
- # - Group 2, input :a, locked: true
29
- # The input 'a' should be only be locked when running Group 2 in
30
- # isolation. It should not be locked when running Group 1 or the
31
- # ParentGroup.
29
+ # - Group 2, input :a, locked: true, hidden: true, optional: true
30
+ # The input 'a' should only be locked or hidden when running Group 2 in isolation.
31
+ # It should not be locked or hidden when running Group 1 or the ParentGroup.
32
32
  :locked,
33
+ :hidden,
33
34
  # Input type is sometimes only a UI concern (e.g. text vs. textarea), so
34
35
  # it is common to not redeclare the type everywhere it's used and needs
35
36
  # special handling to avoid clobbering the type with the default (text)
@@ -50,6 +51,14 @@ module Inferno
50
51
 
51
52
  raise Exceptions::UnknownAttributeException.new(bad_params, self.class) if bad_params.present?
52
53
 
54
+ if params[:hidden] && !params[:optional] && !params[:locked]
55
+ raise Exceptions::InvalidAttributeException.new(
56
+ :hidden,
57
+ self.class,
58
+ "Input '#{params[:name]}' cannot be hidden unless it is optional or locked."
59
+ )
60
+ end
61
+
53
62
  params
54
63
  .compact
55
64
  .each { |key, value| send("#{key}=", value) }
@@ -13,7 +13,9 @@ module Inferno
13
13
  :conformance,
14
14
  :actor,
15
15
  :sub_requirements,
16
- :conditionality
16
+ :conditionality,
17
+ :not_tested_reason,
18
+ :not_tested_details
17
19
  ].freeze
18
20
 
19
21
  include Inferno::Entities::Attributes
@@ -35,9 +37,11 @@ module Inferno
35
37
  # @example
36
38
  # expand_requirement_ids('example-ig@1,3,5-7')
37
39
  # # => ['example-ig@1','example-ig@3','example-ig@5','example-ig@6','example-ig@7']
40
+ # expand_requirement_ids('example-ig')
41
+ # # => []
38
42
  # expand_requirement_ids('1,3,5-7', 'example-ig')
39
43
  # # => ['example-ig@1','example-ig@3','example-ig@5','example-ig@6','example-ig@7']
40
- def self.expand_requirement_ids(requirement_id_string, default_set = nil)
44
+ def self.expand_requirement_ids(requirement_id_string, default_set = nil) # rubocop:disable Metrics/CyclomaticComplexity
41
45
  return [] if requirement_id_string.blank?
42
46
 
43
47
  current_set = default_set
@@ -50,7 +54,11 @@ module Inferno
50
54
  requirement_ids =
51
55
  if requirement_string.include? '-'
52
56
  start_id, end_id = requirement_string.split('-')
53
- (start_id..end_id).to_a
57
+ if start_id.match?(/^\d+$/) && end_id.match?(/^\d+$/)
58
+ (start_id..end_id).to_a
59
+ else
60
+ []
61
+ end
54
62
  else
55
63
  [requirement_string]
56
64
  end
@@ -58,6 +66,10 @@ module Inferno
58
66
  requirement_ids.map { |id| "#{current_set}@#{id}" }
59
67
  end
60
68
  end
69
+
70
+ def tested?
71
+ not_tested_reason.blank?
72
+ end
61
73
  end
62
74
  end
63
75
  end
@@ -103,7 +103,9 @@ module Inferno
103
103
  Inferno::Repositories::Tests.new
104
104
  end
105
105
 
106
- def short_id
106
+ def short_id(new_short_id = nil)
107
+ return @short_id = new_short_id if new_short_id
108
+
107
109
  @short_id ||= begin
108
110
  prefix = parent.respond_to?(:short_id) ? "#{parent.short_id}." : ''
109
111
  suffix = parent ? (parent.tests.find_index(self) + 1).to_s.rjust(2, '0') : 'x'
@@ -96,7 +96,9 @@ module Inferno
96
96
  end
97
97
 
98
98
  # @return [String] A short numeric id which is displayed in the UI
99
- def short_id
99
+ def short_id(new_short_id = nil)
100
+ return @short_id = new_short_id if new_short_id
101
+
100
102
  @short_id ||= begin
101
103
  prefix = parent.respond_to?(:short_id) ? "#{parent.short_id}." : ''
102
104
  suffix = parent ? (parent.groups.find_index(self) + 1).to_s : 'X'
@@ -7,6 +7,7 @@ require_relative '../dsl/links'
7
7
  require_relative '../repositories/test_groups'
8
8
  require_relative '../repositories/test_suites'
9
9
  require_relative '../result_collection'
10
+ require_relative '../dsl/short_id_manager'
10
11
 
11
12
  module Inferno
12
13
  module Entities
@@ -18,6 +19,7 @@ module Inferno
18
19
  extend DSL::FHIRClient::ClassMethods
19
20
  extend DSL::HTTPClient::ClassMethods
20
21
  extend DSL::SuiteRequirements
22
+ extend DSL::ShortIDManager
21
23
  include DSL::FHIRValidation
22
24
  include DSL::FHIRResourceValidation
23
25
  include DSL::FhirpathEvaluation
@@ -102,6 +102,12 @@ module Inferno
102
102
  end
103
103
  end
104
104
 
105
+ class InvalidAttributeException < RuntimeError
106
+ def initialize(attribute, klass, message)
107
+ super("Invalid attribute '#{attribute}' for #{klass.name}: #{message}")
108
+ end
109
+ end
110
+
105
111
  class UnknownSessionDataType < RuntimeError
106
112
  def initialize(output)
107
113
  super("Unknown type '#{output[:type]}' for '#{output[:name]}'.")
@@ -0,0 +1,9 @@
1
+ module Inferno
2
+ module Feature
3
+ class << self
4
+ def requirements_enabled?
5
+ ENV.fetch('ENABLE_REQUIREMENTS', 'false')&.casecmp?('true')
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1 +1 @@
1
- "use strict";(self.webpackChunkinferno_web_app=self.webpackChunkinferno_web_app||[]).push([[237],{237:(e,n,t)=>{t.r(n),t.d(n,{CLSThresholds:()=>P,FCPThresholds:()=>w,FIDThresholds:()=>ne,INPThresholds:()=>j,LCPThresholds:()=>G,TTFBThresholds:()=>Q,onCLS:()=>A,onFCP:()=>I,onFID:()=>te,onINP:()=>z,onLCP:()=>K,onTTFB:()=>V});var r,i,o,a,c,u=-1,s=function(e){addEventListener("pageshow",(function(n){n.persisted&&(u=n.timeStamp,e(n))}),!0)},f=function(){var e=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(e&&e.responseStart>0&&e.responseStart<performance.now())return e},d=function(){var e=f();return e&&e.activationStart||0},l=function(e,n){var t=f(),r="navigate";return u>=0?r="back-forward-cache":t&&(document.prerendering||d()>0?r="prerender":document.wasDiscarded?r="restore":t.type&&(r=t.type.replace(/_/g,"-"))),{name:e,value:void 0===n?-1:n,rating:"good",delta:0,entries:[],id:"v4-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:r}},p=function(e,n,t){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){var r=new PerformanceObserver((function(e){Promise.resolve().then((function(){n(e.getEntries())}))}));return r.observe(Object.assign({type:e,buffered:!0},t||{})),r}}catch(e){}},v=function(e,n,t,r){var i,o;return function(a){n.value>=0&&(a||r)&&((o=n.value-(i||0))||void 0===i)&&(i=n.value,n.delta=o,n.rating=function(e,n){return e>n[1]?"poor":e>n[0]?"needs-improvement":"good"}(n.value,t),e(n))}},m=function(e){requestAnimationFrame((function(){return requestAnimationFrame((function(){return e()}))}))},h=function(e){document.addEventListener("visibilitychange",(function(){"hidden"===document.visibilityState&&e()}))},g=function(e){var n=!1;return function(){n||(e(),n=!0)}},T=-1,y=function(){return"hidden"!==document.visibilityState||document.prerendering?1/0:0},E=function(e){"hidden"===document.visibilityState&&T>-1&&(T="visibilitychange"===e.type?e.timeStamp:0,b())},C=function(){addEventListener("visibilitychange",E,!0),addEventListener("prerenderingchange",E,!0)},b=function(){removeEventListener("visibilitychange",E,!0),removeEventListener("prerenderingchange",E,!0)},L=function(){return T<0&&(T=y(),C(),s((function(){setTimeout((function(){T=y(),C()}),0)}))),{get firstHiddenTime(){return T}}},S=function(e){document.prerendering?addEventListener("prerenderingchange",(function(){return e()}),!0):e()},w=[1800,3e3],I=function(e,n){n=n||{},S((function(){var t,r=L(),i=l("FCP"),o=p("paint",(function(e){e.forEach((function(e){"first-contentful-paint"===e.name&&(o.disconnect(),e.startTime<r.firstHiddenTime&&(i.value=Math.max(e.startTime-d(),0),i.entries.push(e),t(!0)))}))}));o&&(t=v(e,i,w,n.reportAllChanges),s((function(r){i=l("FCP"),t=v(e,i,w,n.reportAllChanges),m((function(){i.value=performance.now()-r.timeStamp,t(!0)}))})))}))},P=[.1,.25],A=function(e,n){n=n||{},I(g((function(){var t,r=l("CLS",0),i=0,o=[],a=function(e){e.forEach((function(e){if(!e.hadRecentInput){var n=o[0],t=o[o.length-1];i&&e.startTime-t.startTime<1e3&&e.startTime-n.startTime<5e3?(i+=e.value,o.push(e)):(i=e.value,o=[e])}})),i>r.value&&(r.value=i,r.entries=o,t())},c=p("layout-shift",a);c&&(t=v(e,r,P,n.reportAllChanges),h((function(){a(c.takeRecords()),t(!0)})),s((function(){i=0,r=l("CLS",0),t=v(e,r,P,n.reportAllChanges),m((function(){return t()}))})),setTimeout(t,0))})))},F=0,k=1/0,M=0,D=function(e){e.forEach((function(e){e.interactionId&&(k=Math.min(k,e.interactionId),M=Math.max(M,e.interactionId),F=M?(M-k)/7+1:0)}))},B=function(){return r?F:performance.interactionCount||0},R=function(){"interactionCount"in performance||r||(r=p("event",D,{type:"event",buffered:!0,durationThreshold:0}))},_=[],x=new Map,H=0,N=[],q=function(e){if(N.forEach((function(n){return n(e)})),e.interactionId||"first-input"===e.entryType){var n=_[_.length-1],t=x.get(e.interactionId);if(t||_.length<10||e.duration>n.latency){if(t)e.duration>t.latency?(t.entries=[e],t.latency=e.duration):e.duration===t.latency&&e.startTime===t.entries[0].startTime&&t.entries.push(e);else{var r={id:e.interactionId,latency:e.duration,entries:[e]};x.set(r.id,r),_.push(r)}_.sort((function(e,n){return n.latency-e.latency})),_.length>10&&_.splice(10).forEach((function(e){return x.delete(e.id)}))}}},O=function(e){var n=self.requestIdleCallback||self.setTimeout,t=-1;return e=g(e),"hidden"===document.visibilityState?e():(t=n(e),h(e)),t},j=[200,500],z=function(e,n){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(n=n||{},S((function(){var t;R();var r,i=l("INP"),o=function(e){O((function(){e.forEach(q);var n=function(){var e=Math.min(_.length-1,Math.floor((B()-H)/50));return _[e]}();n&&n.latency!==i.value&&(i.value=n.latency,i.entries=n.entries,r())}))},a=p("event",o,{durationThreshold:null!==(t=n.durationThreshold)&&void 0!==t?t:40});r=v(e,i,j,n.reportAllChanges),a&&(a.observe({type:"first-input",buffered:!0}),h((function(){o(a.takeRecords()),r(!0)})),s((function(){H=B(),_.length=0,x.clear(),i=l("INP"),r=v(e,i,j,n.reportAllChanges)})))})))},G=[2500,4e3],J={},K=function(e,n){n=n||{},S((function(){var t,r=L(),i=l("LCP"),o=function(e){n.reportAllChanges||(e=e.slice(-1)),e.forEach((function(e){e.startTime<r.firstHiddenTime&&(i.value=Math.max(e.startTime-d(),0),i.entries=[e],t())}))},a=p("largest-contentful-paint",o);if(a){t=v(e,i,G,n.reportAllChanges);var c=g((function(){J[i.id]||(o(a.takeRecords()),a.disconnect(),J[i.id]=!0,t(!0))}));["keydown","click"].forEach((function(e){addEventListener(e,(function(){return O(c)}),!0)})),h(c),s((function(r){i=l("LCP"),t=v(e,i,G,n.reportAllChanges),m((function(){i.value=performance.now()-r.timeStamp,J[i.id]=!0,t(!0)}))}))}}))},Q=[800,1800],U=function e(n){document.prerendering?S((function(){return e(n)})):"complete"!==document.readyState?addEventListener("load",(function(){return e(n)}),!0):setTimeout(n,0)},V=function(e,n){n=n||{};var t=l("TTFB"),r=v(e,t,Q,n.reportAllChanges);U((function(){var i=f();i&&(t.value=Math.max(i.responseStart-d(),0),t.entries=[i],r(!0),s((function(){t=l("TTFB",0),(r=v(e,t,Q,n.reportAllChanges))(!0)})))}))},W={passive:!0,capture:!0},X=new Date,Y=function(e,n){i||(i=n,o=e,a=new Date,ee(removeEventListener),Z())},Z=function(){if(o>=0&&o<a-X){var e={entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+o};c.forEach((function(n){n(e)})),c=[]}},$=function(e){if(e.cancelable){var n=(e.timeStamp>1e12?new Date:performance.now())-e.timeStamp;"pointerdown"==e.type?function(e,n){var t=function(){Y(e,n),i()},r=function(){i()},i=function(){removeEventListener("pointerup",t,W),removeEventListener("pointercancel",r,W)};addEventListener("pointerup",t,W),addEventListener("pointercancel",r,W)}(n,e):Y(n,e)}},ee=function(e){["mousedown","keydown","touchstart","pointerdown"].forEach((function(n){return e(n,$,W)}))},ne=[100,300],te=function(e,n){n=n||{},S((function(){var t,r=L(),a=l("FID"),u=function(e){e.startTime<r.firstHiddenTime&&(a.value=e.processingStart-e.startTime,a.entries.push(e),t(!0))},f=function(e){e.forEach(u)},d=p("first-input",f);t=v(e,a,ne,n.reportAllChanges),d&&(h(g((function(){f(d.takeRecords()),d.disconnect()}))),s((function(){var r;a=l("FID"),t=v(e,a,ne,n.reportAllChanges),c=[],o=-1,i=null,ee(addEventListener),r=u,c.push(r),Z()})))}))}}}]);
1
+ "use strict";(self.webpackChunkinferno_web_app=self.webpackChunkinferno_web_app||[]).push([[237],{237:(e,n,t)=>{t.r(n),t.d(n,{CLSThresholds:()=>P,FCPThresholds:()=>w,FIDThresholds:()=>ne,INPThresholds:()=>j,LCPThresholds:()=>G,TTFBThresholds:()=>Q,onCLS:()=>A,onFCP:()=>I,onFID:()=>te,onINP:()=>z,onLCP:()=>K,onTTFB:()=>V});var r,i,o,a,c,u=-1,s=function(e){addEventListener("pageshow",(function(n){n.persisted&&(u=n.timeStamp,e(n))}),!0)},f=function(){var e=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(e&&e.responseStart>0&&e.responseStart<performance.now())return e},d=function(){var e=f();return e&&e.activationStart||0},l=function(e,n){var t=f(),r="navigate";return u>=0?r="back-forward-cache":t&&(document.prerendering||d()>0?r="prerender":document.wasDiscarded?r="restore":t.type&&(r=t.type.replace(/_/g,"-"))),{name:e,value:void 0===n?-1:n,rating:"good",delta:0,entries:[],id:"v4-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:r}},p=function(e,n,t){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){var r=new PerformanceObserver((function(e){Promise.resolve().then((function(){n(e.getEntries())}))}));return r.observe(Object.assign({type:e,buffered:!0},t||{})),r}}catch(e){}},v=function(e,n,t,r){var i,o;return function(a){n.value>=0&&(a||r)&&((o=n.value-(i||0))||void 0===i)&&(i=n.value,n.delta=o,n.rating=function(e,n){return e>n[1]?"poor":e>n[0]?"needs-improvement":"good"}(n.value,t),e(n))}},m=function(e){requestAnimationFrame((function(){return requestAnimationFrame((function(){return e()}))}))},h=function(e){document.addEventListener("visibilitychange",(function(){"hidden"===document.visibilityState&&e()}))},g=function(e){var n=!1;return function(){n||(e(),n=!0)}},T=-1,y=function(){return"hidden"!==document.visibilityState||document.prerendering?1/0:0},E=function(e){"hidden"===document.visibilityState&&T>-1&&(T="visibilitychange"===e.type?e.timeStamp:0,b())},C=function(){addEventListener("visibilitychange",E,!0),addEventListener("prerenderingchange",E,!0)},b=function(){removeEventListener("visibilitychange",E,!0),removeEventListener("prerenderingchange",E,!0)},L=function(){return T<0&&(T=y(),C(),s((function(){setTimeout((function(){T=y(),C()}),0)}))),{get firstHiddenTime(){return T}}},S=function(e){document.prerendering?addEventListener("prerenderingchange",(function(){return e()}),!0):e()},w=[1800,3e3],I=function(e,n){n=n||{},S((function(){var t,r=L(),i=l("FCP"),o=p("paint",(function(e){e.forEach((function(e){"first-contentful-paint"===e.name&&(o.disconnect(),e.startTime<r.firstHiddenTime&&(i.value=Math.max(e.startTime-d(),0),i.entries.push(e),t(!0)))}))}));o&&(t=v(e,i,w,n.reportAllChanges),s((function(r){i=l("FCP"),t=v(e,i,w,n.reportAllChanges),m((function(){i.value=performance.now()-r.timeStamp,t(!0)}))})))}))},P=[.1,.25],A=function(e,n){n=n||{},I(g((function(){var t,r=l("CLS",0),i=0,o=[],a=function(e){e.forEach((function(e){if(!e.hadRecentInput){var n=o[0],t=o[o.length-1];i&&e.startTime-t.startTime<1e3&&e.startTime-n.startTime<5e3?(i+=e.value,o.push(e)):(i=e.value,o=[e])}})),i>r.value&&(r.value=i,r.entries=o,t())},c=p("layout-shift",a);c&&(t=v(e,r,P,n.reportAllChanges),h((function(){a(c.takeRecords()),t(!0)})),s((function(){i=0,r=l("CLS",0),t=v(e,r,P,n.reportAllChanges),m((function(){return t()}))})),setTimeout(t,0))})))},F=0,k=1/0,M=0,D=function(e){e.forEach((function(e){e.interactionId&&(k=Math.min(k,e.interactionId),M=Math.max(M,e.interactionId),F=M?(M-k)/7+1:0)}))},B=function(){return r?F:performance.interactionCount||0},R=function(){"interactionCount"in performance||r||(r=p("event",D,{type:"event",buffered:!0,durationThreshold:0}))},_=[],x=new Map,H=0,N=[],q=function(e){if(N.forEach((function(n){return n(e)})),e.interactionId||"first-input"===e.entryType){var n=_[_.length-1],t=x.get(e.interactionId);if(t||_.length<10||e.duration>n.latency){if(t)e.duration>t.latency?(t.entries=[e],t.latency=e.duration):e.duration===t.latency&&e.startTime===t.entries[0].startTime&&t.entries.push(e);else{var r={id:e.interactionId,latency:e.duration,entries:[e]};x.set(r.id,r),_.push(r)}_.sort((function(e,n){return n.latency-e.latency})),_.length>10&&_.splice(10).forEach((function(e){return x.delete(e.id)}))}}},O=function(e){var n=self.requestIdleCallback||self.setTimeout,t=-1;return e=g(e),"hidden"===document.visibilityState?e():(t=n(e),h(e)),t},j=[200,500],z=function(e,n){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(n=n||{},S((function(){var t;R();var r,i=l("INP"),o=function(e){O((function(){e.forEach(q);var n=function(){var e=Math.min(_.length-1,Math.floor((B()-H)/50));return _[e]}();n&&n.latency!==i.value&&(i.value=n.latency,i.entries=n.entries,r())}))},a=p("event",o,{durationThreshold:null!==(t=n.durationThreshold)&&void 0!==t?t:40});r=v(e,i,j,n.reportAllChanges),a&&(a.observe({type:"first-input",buffered:!0}),h((function(){o(a.takeRecords()),r(!0)})),s((function(){H=B(),_.length=0,x.clear(),i=l("INP"),r=v(e,i,j,n.reportAllChanges)})))})))},G=[2500,4e3],J={},K=function(e,n){n=n||{},S((function(){var t,r=L(),i=l("LCP"),o=function(e){n.reportAllChanges||(e=e.slice(-1)),e.forEach((function(e){e.startTime<r.firstHiddenTime&&(i.value=Math.max(e.startTime-d(),0),i.entries=[e],t())}))},a=p("largest-contentful-paint",o);if(a){t=v(e,i,G,n.reportAllChanges);var c=g((function(){J[i.id]||(o(a.takeRecords()),a.disconnect(),J[i.id]=!0,t(!0))}));["keydown","click"].forEach((function(e){addEventListener(e,(function(){return O(c)}),{once:!0,capture:!0})})),h(c),s((function(r){i=l("LCP"),t=v(e,i,G,n.reportAllChanges),m((function(){i.value=performance.now()-r.timeStamp,J[i.id]=!0,t(!0)}))}))}}))},Q=[800,1800],U=function e(n){document.prerendering?S((function(){return e(n)})):"complete"!==document.readyState?addEventListener("load",(function(){return e(n)}),!0):setTimeout(n,0)},V=function(e,n){n=n||{};var t=l("TTFB"),r=v(e,t,Q,n.reportAllChanges);U((function(){var i=f();i&&(t.value=Math.max(i.responseStart-d(),0),t.entries=[i],r(!0),s((function(){t=l("TTFB",0),(r=v(e,t,Q,n.reportAllChanges))(!0)})))}))},W={passive:!0,capture:!0},X=new Date,Y=function(e,n){i||(i=n,o=e,a=new Date,ee(removeEventListener),Z())},Z=function(){if(o>=0&&o<a-X){var e={entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+o};c.forEach((function(n){n(e)})),c=[]}},$=function(e){if(e.cancelable){var n=(e.timeStamp>1e12?new Date:performance.now())-e.timeStamp;"pointerdown"==e.type?function(e,n){var t=function(){Y(e,n),i()},r=function(){i()},i=function(){removeEventListener("pointerup",t,W),removeEventListener("pointercancel",r,W)};addEventListener("pointerup",t,W),addEventListener("pointercancel",r,W)}(n,e):Y(n,e)}},ee=function(e){["mousedown","keydown","touchstart","pointerdown"].forEach((function(n){return e(n,$,W)}))},ne=[100,300],te=function(e,n){n=n||{},S((function(){var t,r=L(),a=l("FID"),u=function(e){e.startTime<r.firstHiddenTime&&(a.value=e.processingStart-e.startTime,a.entries.push(e),t(!0))},f=function(e){e.forEach(u)},d=p("first-input",f);t=v(e,a,ne,n.reportAllChanges),d&&(h(g((function(){f(d.takeRecords()),d.disconnect()}))),s((function(){var r;a=l("FID"),t=v(e,a,ne,n.reportAllChanges),c=[],o=-1,i=null,ee(addEventListener),r=u,c.push(r),Z()})))}))}}}]);