inferno_core 0.6.8 → 0.6.10

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 (61) 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/main.rb +5 -1
  6. data/lib/inferno/apps/cli/requirements.rb +28 -0
  7. data/lib/inferno/apps/cli/requirements_exporter.rb +194 -0
  8. data/lib/inferno/apps/cli/suite.rb +21 -0
  9. data/lib/inferno/apps/cli/templates/lib/%library_name%/example_suite/patient_group.rb.tt +141 -0
  10. data/lib/inferno/apps/cli/templates/lib/%library_name%/example_suite.rb.tt +128 -0
  11. data/lib/inferno/apps/cli/templates/lib/%library_name%/metadata.rb.tt +65 -3
  12. data/lib/inferno/apps/cli/templates/lib/%library_name%/suite.rb.tt +2 -2
  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/controllers/requirements/show.rb +18 -0
  16. data/lib/inferno/apps/web/controllers/test_suites/requirements/index.rb +29 -0
  17. data/lib/inferno/apps/web/router.rb +7 -0
  18. data/lib/inferno/apps/web/serializers/input.rb +1 -0
  19. data/lib/inferno/apps/web/serializers/requirement.rb +18 -0
  20. data/lib/inferno/apps/web/serializers/requirement_set.rb +13 -0
  21. data/lib/inferno/apps/web/serializers/test.rb +1 -0
  22. data/lib/inferno/apps/web/serializers/test_group.rb +1 -0
  23. data/lib/inferno/apps/web/serializers/test_suite.rb +11 -0
  24. data/lib/inferno/config/boot/requirements.rb +40 -0
  25. data/lib/inferno/config/boot/suites.rb +3 -0
  26. data/lib/inferno/dsl/fhir_evaluation/default.yml +68 -0
  27. data/lib/inferno/dsl/fhir_evaluation/evaluator.rb +3 -5
  28. data/lib/inferno/dsl/fhir_evaluation/rules/all_defined_extensions_have_examples.rb +2 -2
  29. data/lib/inferno/dsl/fhir_evaluation/rules/all_extensions_used.rb +76 -0
  30. data/lib/inferno/dsl/fhir_evaluation/rules/all_must_supports_present.rb +1 -1
  31. data/lib/inferno/dsl/fhir_evaluation/rules/all_profiles_have_examples.rb +1 -1
  32. data/lib/inferno/dsl/fhir_evaluation/rules/all_references_resolve.rb +2 -2
  33. data/lib/inferno/dsl/fhir_evaluation/rules/all_resources_reachable.rb +2 -2
  34. data/lib/inferno/dsl/fhir_evaluation/rules/all_search_parameters_have_examples.rb +22 -11
  35. data/lib/inferno/dsl/fhir_evaluation/rules/differential_content_has_examples.rb +124 -0
  36. data/lib/inferno/dsl/fhir_evaluation/rules/value_sets_demonstrate.rb +233 -0
  37. data/lib/inferno/dsl/fhir_resource_navigation.rb +11 -2
  38. data/lib/inferno/dsl/fhir_resource_validation.rb +25 -3
  39. data/lib/inferno/dsl/fhirpath_evaluation.rb +25 -1
  40. data/lib/inferno/dsl/input_output_handling.rb +1 -0
  41. data/lib/inferno/dsl/must_support_assessment.rb +15 -3
  42. data/lib/inferno/dsl/requirement_set.rb +82 -0
  43. data/lib/inferno/dsl/runnable.rb +27 -0
  44. data/lib/inferno/dsl/short_id_manager.rb +55 -0
  45. data/lib/inferno/dsl/suite_requirements.rb +46 -0
  46. data/lib/inferno/entities/ig.rb +4 -0
  47. data/lib/inferno/entities/input.rb +14 -5
  48. data/lib/inferno/entities/requirement.rb +75 -0
  49. data/lib/inferno/entities/test.rb +3 -1
  50. data/lib/inferno/entities/test_group.rb +3 -1
  51. data/lib/inferno/entities/test_suite.rb +4 -0
  52. data/lib/inferno/exceptions.rb +6 -0
  53. data/lib/inferno/public/237.bundle.js +1 -1
  54. data/lib/inferno/public/bundle.js +54 -54
  55. data/lib/inferno/public/bundle.js.LICENSE.txt +3 -36
  56. data/lib/inferno/repositories/igs.rb +1 -2
  57. data/lib/inferno/repositories/requirements.rb +120 -0
  58. data/lib/inferno/version.rb +1 -1
  59. data/spec/shared/test_kit_examples.rb +32 -0
  60. metadata +36 -3
  61. data/lib/inferno/apps/cli/templates/lib/%library_name%/patient_group.rb.tt +0 -44
@@ -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
@@ -0,0 +1,46 @@
1
+ require_relative 'requirement_set'
2
+
3
+ module Inferno
4
+ module DSL
5
+ module SuiteRequirements
6
+ # Get/Set the sets of requirments tested by a suite.
7
+ #
8
+ # @param sets [Array<Inferno::DSL::RequirementSet>]
9
+ # @return [Array<Inferno::DSL::RequirementSet>]
10
+ #
11
+ # @example
12
+ # class Suite < Inferno::TestSuite
13
+ # requirement_sets(
14
+ # {
15
+ # identifier: 'example-regulation-1',
16
+ # title: 'Example Regulation 1',
17
+ # actor: 'Provider' # Only include requirements for the 'Provider'
18
+ # # actor
19
+ # },
20
+ # {
21
+ # identifier: 'example-ig-1',
22
+ # title: 'Example Implementation Guide 1',
23
+ # actor: 'Provider',
24
+ # requirements: '2, 4-5' # Only include these specific requirements
25
+ # },
26
+ # {
27
+ # identifier: 'example-ig-2',
28
+ # title: 'Example Implementation Guide 2',
29
+ # requirements: 'Referenced', # Only include requirements from this
30
+ # # set that are referenced by other
31
+ # # included requirements
32
+ # actor: 'Server',
33
+ # suite_options: { # Only include these requirements if the ig
34
+ # ig_version: '3.0.0' # version 3.0.0 suite option is selected
35
+ # }
36
+ # }
37
+ # )
38
+ # end
39
+ def requirement_sets(*sets)
40
+ @requirement_sets = sets.map { |set| RequirementSet.new(**set) } if sets.present?
41
+
42
+ @requirement_sets || []
43
+ end
44
+ end
45
+ end
46
+ end
@@ -126,6 +126,10 @@ module Inferno
126
126
  "#{ig_resource.id}##{ig_resource.version || 'current'}"
127
127
  end
128
128
 
129
+ def value_sets
130
+ resources_by_type['ValueSet']
131
+ end
132
+
129
133
  def profiles
130
134
  resources_by_type['StructureDefinition'].filter { |sd| sd.type != 'Extension' }
131
135
  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) }
@@ -0,0 +1,75 @@
1
+ require_relative 'attributes'
2
+ require_relative 'entity'
3
+
4
+ module Inferno
5
+ module Entities
6
+ # A `Requirement` represents the specific rule or behavior a runnable is testing.
7
+ class Requirement < Entity
8
+ ATTRIBUTES = [
9
+ :id,
10
+ :requirement_set,
11
+ :url,
12
+ :requirement,
13
+ :conformance,
14
+ :actor,
15
+ :sub_requirements,
16
+ :conditionality,
17
+ :not_tested_reason,
18
+ :not_tested_details
19
+ ].freeze
20
+
21
+ include Inferno::Entities::Attributes
22
+
23
+ def initialize(params)
24
+ super(params, ATTRIBUTES)
25
+
26
+ self.requirement_set = id.split('@').first if requirement_set.blank? && id&.include?('@')
27
+ end
28
+
29
+ # Expand a comma-delimited list of requirement id references into an Array
30
+ # of full requirement ids
31
+ #
32
+ # @param requirement_id_string [String] A comma-delimited list of
33
+ # requirement id references
34
+ # @param default_set [String] The requirement set identifier which will be
35
+ # used if none is included in the `requirement_id_string`
36
+ #
37
+ # @example
38
+ # expand_requirement_ids('example-ig@1,3,5-7')
39
+ # # => ['example-ig@1','example-ig@3','example-ig@5','example-ig@6','example-ig@7']
40
+ # expand_requirement_ids('example-ig')
41
+ # # => []
42
+ # expand_requirement_ids('1,3,5-7', 'example-ig')
43
+ # # => ['example-ig@1','example-ig@3','example-ig@5','example-ig@6','example-ig@7']
44
+ def self.expand_requirement_ids(requirement_id_string, default_set = nil) # rubocop:disable Metrics/CyclomaticComplexity
45
+ return [] if requirement_id_string.blank?
46
+
47
+ current_set = default_set
48
+ requirement_id_string
49
+ .split(',')
50
+ .map(&:strip)
51
+ .flat_map do |requirement_string|
52
+ current_set, requirement_string = requirement_string.split('@') if requirement_string.include?('@')
53
+
54
+ requirement_ids =
55
+ if requirement_string.include? '-'
56
+ start_id, end_id = requirement_string.split('-')
57
+ if start_id.match?(/^\d+$/) && end_id.match?(/^\d+$/)
58
+ (start_id..end_id).to_a
59
+ else
60
+ []
61
+ end
62
+ else
63
+ [requirement_string]
64
+ end
65
+
66
+ requirement_ids.map { |id| "#{current_set}@#{id}" }
67
+ end
68
+ end
69
+
70
+ def tested?
71
+ not_tested_reason.blank?
72
+ end
73
+ end
74
+ end
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'
@@ -1,11 +1,13 @@
1
1
  require_relative 'test_group'
2
2
  require_relative '../dsl/runnable'
3
3
  require_relative '../dsl/suite_option'
4
+ require_relative '../dsl/suite_requirements'
4
5
  require_relative '../dsl/messages'
5
6
  require_relative '../dsl/links'
6
7
  require_relative '../repositories/test_groups'
7
8
  require_relative '../repositories/test_suites'
8
9
  require_relative '../result_collection'
10
+ require_relative '../dsl/short_id_manager'
9
11
 
10
12
  module Inferno
11
13
  module Entities
@@ -16,6 +18,8 @@ module Inferno
16
18
  extend DSL::Links
17
19
  extend DSL::FHIRClient::ClassMethods
18
20
  extend DSL::HTTPClient::ClassMethods
21
+ extend DSL::SuiteRequirements
22
+ extend DSL::ShortIDManager
19
23
  include DSL::FHIRValidation
20
24
  include DSL::FHIRResourceValidation
21
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]}'.")
@@ -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()})))}))}}}]);