@defra/forms-engine-plugin 4.23.0 → 5.0.0-alpha

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 (309) hide show
  1. package/.server/server/forms/register-as-a-unicorn-breeder.yaml +0 -14
  2. package/.server/server/forms/simple-form.yaml +106 -3
  3. package/.server/server/plugins/engine/components/AutocompleteField.d.ts +11 -11
  4. package/.server/server/plugins/engine/components/AutocompleteField.js +2 -2
  5. package/.server/server/plugins/engine/components/AutocompleteField.js.map +1 -1
  6. package/.server/server/plugins/engine/components/CheckboxesField.d.ts +3 -2
  7. package/.server/server/plugins/engine/components/CheckboxesField.js +4 -9
  8. package/.server/server/plugins/engine/components/CheckboxesField.js.map +1 -1
  9. package/.server/server/plugins/engine/components/ComponentCollection.d.ts +8 -7
  10. package/.server/server/plugins/engine/components/ComponentCollection.js +106 -51
  11. package/.server/server/plugins/engine/components/ComponentCollection.js.map +1 -1
  12. package/.server/server/plugins/engine/components/DatePartsField.d.ts +8 -6
  13. package/.server/server/plugins/engine/components/DatePartsField.js +27 -9
  14. package/.server/server/plugins/engine/components/DatePartsField.js.map +1 -1
  15. package/.server/server/plugins/engine/components/DeclarationField.d.ts +13 -11
  16. package/.server/server/plugins/engine/components/DeclarationField.js +31 -9
  17. package/.server/server/plugins/engine/components/DeclarationField.js.map +1 -1
  18. package/.server/server/plugins/engine/components/EastingNorthingField.d.ts +6 -5
  19. package/.server/server/plugins/engine/components/EastingNorthingField.js +42 -22
  20. package/.server/server/plugins/engine/components/EastingNorthingField.js.map +1 -1
  21. package/.server/server/plugins/engine/components/EmailAddressField.d.ts +11 -14
  22. package/.server/server/plugins/engine/components/EmailAddressField.js +2 -2
  23. package/.server/server/plugins/engine/components/EmailAddressField.js.map +1 -1
  24. package/.server/server/plugins/engine/components/FileUploadField.d.ts +14 -12
  25. package/.server/server/plugins/engine/components/FileUploadField.js +22 -12
  26. package/.server/server/plugins/engine/components/FileUploadField.js.map +1 -1
  27. package/.server/server/plugins/engine/components/FormComponent.d.ts +21 -12
  28. package/.server/server/plugins/engine/components/FormComponent.js +33 -14
  29. package/.server/server/plugins/engine/components/FormComponent.js.map +1 -1
  30. package/.server/server/plugins/engine/components/GeospatialField.d.ts +14 -12
  31. package/.server/server/plugins/engine/components/GeospatialField.js +19 -13
  32. package/.server/server/plugins/engine/components/GeospatialField.js.map +1 -1
  33. package/.server/server/plugins/engine/components/LatLongField.d.ts +6 -5
  34. package/.server/server/plugins/engine/components/LatLongField.js +32 -20
  35. package/.server/server/plugins/engine/components/LatLongField.js.map +1 -1
  36. package/.server/server/plugins/engine/components/ListFormComponent.d.ts +7 -6
  37. package/.server/server/plugins/engine/components/ListFormComponent.js +19 -7
  38. package/.server/server/plugins/engine/components/ListFormComponent.js.map +1 -1
  39. package/.server/server/plugins/engine/components/LocationFieldBase.d.ts +17 -16
  40. package/.server/server/plugins/engine/components/LocationFieldBase.js +2 -2
  41. package/.server/server/plugins/engine/components/LocationFieldBase.js.map +1 -1
  42. package/.server/server/plugins/engine/components/LocationFieldHelpers.d.ts +3 -3
  43. package/.server/server/plugins/engine/components/LocationFieldHelpers.js +2 -2
  44. package/.server/server/plugins/engine/components/LocationFieldHelpers.js.map +1 -1
  45. package/.server/server/plugins/engine/components/Markdown.d.ts +8 -7
  46. package/.server/server/plugins/engine/components/Markdown.js +5 -2
  47. package/.server/server/plugins/engine/components/Markdown.js.map +1 -1
  48. package/.server/server/plugins/engine/components/MonthYearField.d.ts +9 -7
  49. package/.server/server/plugins/engine/components/MonthYearField.js +26 -8
  50. package/.server/server/plugins/engine/components/MonthYearField.js.map +1 -1
  51. package/.server/server/plugins/engine/components/MultilineTextField.d.ts +10 -9
  52. package/.server/server/plugins/engine/components/MultilineTextField.js +2 -2
  53. package/.server/server/plugins/engine/components/MultilineTextField.js.map +1 -1
  54. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.d.ts +2 -1
  55. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js +14 -6
  56. package/.server/server/plugins/engine/components/NationalGridFieldNumberField.js.map +1 -1
  57. package/.server/server/plugins/engine/components/NumberField.d.ts +10 -9
  58. package/.server/server/plugins/engine/components/NumberField.js +2 -2
  59. package/.server/server/plugins/engine/components/NumberField.js.map +1 -1
  60. package/.server/server/plugins/engine/components/OsGridRefField.d.ts +2 -1
  61. package/.server/server/plugins/engine/components/OsGridRefField.js +14 -6
  62. package/.server/server/plugins/engine/components/OsGridRefField.js.map +1 -1
  63. package/.server/server/plugins/engine/components/PaymentField.d.ts +12 -10
  64. package/.server/server/plugins/engine/components/PaymentField.js +21 -8
  65. package/.server/server/plugins/engine/components/PaymentField.js.map +1 -1
  66. package/.server/server/plugins/engine/components/SelectField.d.ts +11 -11
  67. package/.server/server/plugins/engine/components/SelectField.js +2 -2
  68. package/.server/server/plugins/engine/components/SelectField.js.map +1 -1
  69. package/.server/server/plugins/engine/components/SelectionControlField.d.ts +4 -4
  70. package/.server/server/plugins/engine/components/SelectionControlField.js +2 -2
  71. package/.server/server/plugins/engine/components/SelectionControlField.js.map +1 -1
  72. package/.server/server/plugins/engine/components/TelephoneNumberField.d.ts +10 -9
  73. package/.server/server/plugins/engine/components/TelephoneNumberField.js +2 -2
  74. package/.server/server/plugins/engine/components/TelephoneNumberField.js.map +1 -1
  75. package/.server/server/plugins/engine/components/UkAddressField.d.ts +12 -10
  76. package/.server/server/plugins/engine/components/UkAddressField.js +29 -17
  77. package/.server/server/plugins/engine/components/UkAddressField.js.map +1 -1
  78. package/.server/server/plugins/engine/components/YesNoField.d.ts +3 -0
  79. package/.server/server/plugins/engine/components/YesNoField.js +9 -0
  80. package/.server/server/plugins/engine/components/YesNoField.js.map +1 -1
  81. package/.server/server/plugins/engine/components/helpers/components.d.ts +3 -2
  82. package/.server/server/plugins/engine/components/helpers/components.js +11 -8
  83. package/.server/server/plugins/engine/components/helpers/components.js.map +1 -1
  84. package/.server/server/plugins/engine/components/types.d.ts +8 -1
  85. package/.server/server/plugins/engine/components/types.js.map +1 -1
  86. package/.server/server/plugins/engine/configureEnginePlugin.js +8 -1
  87. package/.server/server/plugins/engine/configureEnginePlugin.js.map +1 -1
  88. package/.server/server/plugins/engine/form-context.d.ts +1 -0
  89. package/.server/server/plugins/engine/form-context.js +4 -2
  90. package/.server/server/plugins/engine/form-context.js.map +1 -1
  91. package/.server/server/plugins/engine/helpers.d.ts +1 -1
  92. package/.server/server/plugins/engine/helpers.js +8 -13
  93. package/.server/server/plugins/engine/helpers.js.map +1 -1
  94. package/.server/server/plugins/engine/i18n/buildValidationMessages.d.ts +39 -0
  95. package/.server/server/plugins/engine/i18n/buildValidationMessages.js +50 -0
  96. package/.server/server/plugins/engine/i18n/buildValidationMessages.js.map +1 -0
  97. package/.server/server/plugins/engine/i18n/createFormTranslator.d.ts +5 -0
  98. package/.server/server/plugins/engine/i18n/createFormTranslator.js +18 -0
  99. package/.server/server/plugins/engine/i18n/createFormTranslator.js.map +1 -0
  100. package/.server/server/plugins/engine/i18n/createTranslator.d.ts +9 -0
  101. package/.server/server/plugins/engine/i18n/createTranslator.js +51 -0
  102. package/.server/server/plugins/engine/i18n/createTranslator.js.map +1 -0
  103. package/.server/server/plugins/engine/i18n/extractBaseTranslations.d.ts +5 -0
  104. package/.server/server/plugins/engine/i18n/extractBaseTranslations.js +57 -0
  105. package/.server/server/plugins/engine/i18n/extractBaseTranslations.js.map +1 -0
  106. package/.server/server/plugins/engine/i18n/index.d.ts +18 -0
  107. package/.server/server/plugins/engine/i18n/index.js +71 -0
  108. package/.server/server/plugins/engine/i18n/index.js.map +1 -0
  109. package/.server/server/plugins/engine/i18n/translations/cy.json +271 -0
  110. package/.server/server/plugins/engine/i18n/translations/en-GB.json +271 -0
  111. package/.server/server/plugins/engine/i18n/types.d.ts +41 -0
  112. package/.server/server/plugins/engine/i18n/types.js +2 -0
  113. package/.server/server/plugins/engine/i18n/types.js.map +1 -0
  114. package/.server/server/plugins/engine/index.js +3 -2
  115. package/.server/server/plugins/engine/index.js.map +1 -1
  116. package/.server/server/plugins/engine/models/FormModel.d.ts +9 -1
  117. package/.server/server/plugins/engine/models/FormModel.js +44 -18
  118. package/.server/server/plugins/engine/models/FormModel.js.map +1 -1
  119. package/.server/server/plugins/engine/models/SummaryViewModel.d.ts +5 -2
  120. package/.server/server/plugins/engine/models/SummaryViewModel.js +44 -18
  121. package/.server/server/plugins/engine/models/SummaryViewModel.js.map +1 -1
  122. package/.server/server/plugins/engine/options.js +2 -1
  123. package/.server/server/plugins/engine/options.js.map +1 -1
  124. package/.server/server/plugins/engine/outputFormatters/adapter/v1.js +4 -0
  125. package/.server/server/plugins/engine/outputFormatters/adapter/v1.js.map +1 -1
  126. package/.server/server/plugins/engine/outputFormatters/human/v1.js +2 -1
  127. package/.server/server/plugins/engine/outputFormatters/human/v1.js.map +1 -1
  128. package/.server/server/plugins/engine/outputFormatters/machine/v1.js +7 -6
  129. package/.server/server/plugins/engine/outputFormatters/machine/v1.js.map +1 -1
  130. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.d.ts +2 -1
  131. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js +6 -3
  132. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js.map +1 -1
  133. package/.server/server/plugins/engine/pageControllers/PageController.d.ts +3 -1
  134. package/.server/server/plugins/engine/pageControllers/PageController.js +11 -1
  135. package/.server/server/plugins/engine/pageControllers/PageController.js.map +1 -1
  136. package/.server/server/plugins/engine/pageControllers/QuestionPageController.d.ts +4 -2
  137. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js +52 -21
  138. package/.server/server/plugins/engine/pageControllers/QuestionPageController.js.map +1 -1
  139. package/.server/server/plugins/engine/pageControllers/RepeatPageController.d.ts +3 -2
  140. package/.server/server/plugins/engine/pageControllers/RepeatPageController.js +63 -26
  141. package/.server/server/plugins/engine/pageControllers/RepeatPageController.js.map +1 -1
  142. package/.server/server/plugins/engine/pageControllers/StartPageController.d.ts +3 -1
  143. package/.server/server/plugins/engine/pageControllers/StartPageController.js +2 -2
  144. package/.server/server/plugins/engine/pageControllers/StartPageController.js.map +1 -1
  145. package/.server/server/plugins/engine/pageControllers/StatusPageController.js +12 -2
  146. package/.server/server/plugins/engine/pageControllers/StatusPageController.js.map +1 -1
  147. package/.server/server/plugins/engine/pageControllers/SummaryPageController.d.ts +4 -3
  148. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js +44 -28
  149. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js.map +1 -1
  150. package/.server/server/plugins/engine/pageControllers/__stubs__/translator.d.ts +2 -0
  151. package/.server/server/plugins/engine/pageControllers/__stubs__/translator.js +24 -0
  152. package/.server/server/plugins/engine/pageControllers/__stubs__/translator.js.map +1 -0
  153. package/.server/server/plugins/engine/pageControllers/errors.d.ts +1 -1
  154. package/.server/server/plugins/engine/pageControllers/errors.js +3 -2
  155. package/.server/server/plugins/engine/pageControllers/errors.js.map +1 -1
  156. package/.server/server/plugins/engine/pageControllers/helpers/submission.d.ts +3 -2
  157. package/.server/server/plugins/engine/pageControllers/helpers/submission.js +4 -4
  158. package/.server/server/plugins/engine/pageControllers/helpers/submission.js.map +1 -1
  159. package/.server/server/plugins/engine/pageControllers/validationOptions.d.ts +7 -3
  160. package/.server/server/plugins/engine/pageControllers/validationOptions.js +34 -33
  161. package/.server/server/plugins/engine/pageControllers/validationOptions.js.map +1 -1
  162. package/.server/server/plugins/engine/plugin.js +2 -0
  163. package/.server/server/plugins/engine/plugin.js.map +1 -1
  164. package/.server/server/plugins/engine/routes/index.js +4 -1
  165. package/.server/server/plugins/engine/routes/index.js.map +1 -1
  166. package/.server/server/plugins/engine/routes/questions.js +5 -2
  167. package/.server/server/plugins/engine/routes/questions.js.map +1 -1
  168. package/.server/server/plugins/engine/types/index.d.ts +1 -0
  169. package/.server/server/plugins/engine/types/index.js.map +1 -1
  170. package/.server/server/plugins/engine/types/schema.js +1 -0
  171. package/.server/server/plugins/engine/types/schema.js.map +1 -1
  172. package/.server/server/plugins/engine/types.d.ts +12 -1
  173. package/.server/server/plugins/engine/types.js.map +1 -1
  174. package/.server/server/plugins/engine/views/components/_location-field-base.html +1 -1
  175. package/.server/server/plugins/engine/views/components/fileuploadfield.html +3 -3
  176. package/.server/server/plugins/engine/views/components/nationalgridfieldnumberfield.html +1 -1
  177. package/.server/server/plugins/engine/views/components/osgridreffield.html +1 -1
  178. package/.server/server/plugins/engine/views/components/paymentfield.html +8 -8
  179. package/.server/server/plugins/engine/views/components/ukaddressfield.html +4 -4
  180. package/.server/server/plugins/engine/views/confirmation.html +4 -4
  181. package/.server/server/plugins/engine/views/exit.html +4 -4
  182. package/.server/server/plugins/engine/views/file-upload.html +3 -3
  183. package/.server/server/plugins/engine/views/index.html +3 -3
  184. package/.server/server/plugins/engine/views/item-delete.html +1 -1
  185. package/.server/server/plugins/engine/views/partials/form.html +3 -3
  186. package/.server/server/plugins/engine/views/partials/preview-banner.html +4 -4
  187. package/.server/server/plugins/engine/views/partials/warn-missing-notification-email.html +4 -5
  188. package/.server/server/plugins/engine/views/repeat-list-summary.html +4 -4
  189. package/.server/server/plugins/engine/views/summary.html +14 -7
  190. package/.server/server/plugins/nunjucks/enviroment.test.js +10 -0
  191. package/.server/server/plugins/nunjucks/enviroment.test.js.map +1 -1
  192. package/.server/server/plugins/nunjucks/environment.d.ts +8 -0
  193. package/.server/server/plugins/nunjucks/environment.js +13 -0
  194. package/.server/server/plugins/nunjucks/environment.js.map +1 -1
  195. package/.server/server/plugins/nunjucks/filters/answer.js +9 -1
  196. package/.server/server/plugins/nunjucks/filters/answer.js.map +1 -1
  197. package/.server/server/plugins/nunjucks/filters/answer.test.js +13 -2
  198. package/.server/server/plugins/nunjucks/filters/answer.test.js.map +1 -1
  199. package/.server/server/plugins/nunjucks/filters/field.d.ts +1 -1
  200. package/.server/server/plugins/postcode-lookup/models/index.d.ts +24 -19
  201. package/.server/server/plugins/postcode-lookup/models/index.js +83 -76
  202. package/.server/server/plugins/postcode-lookup/models/index.js.map +1 -1
  203. package/.server/server/plugins/postcode-lookup/routes/index.js +7 -13
  204. package/.server/server/plugins/postcode-lookup/routes/index.js.map +1 -1
  205. package/.server/server/plugins/postcode-lookup/types.d.ts +1 -0
  206. package/.server/server/plugins/postcode-lookup/types.js +1 -0
  207. package/.server/server/plugins/postcode-lookup/types.js.map +1 -1
  208. package/.server/server/plugins/postcode-lookup/views/postcode-lookup-details.html +3 -3
  209. package/.server/server/types.d.ts +2 -1
  210. package/.server/server/types.js.map +1 -1
  211. package/.server/server/utils/utils.d.ts +5 -0
  212. package/.server/server/utils/utils.js +16 -0
  213. package/.server/server/utils/utils.js.map +1 -1
  214. package/.server/typings/hapi/index.d.js.map +1 -1
  215. package/package.json +3 -2
  216. package/src/server/forms/register-as-a-unicorn-breeder.yaml +0 -14
  217. package/src/server/forms/simple-form.yaml +106 -3
  218. package/src/server/plugins/engine/components/AutocompleteField.ts +3 -6
  219. package/src/server/plugins/engine/components/CheckboxesField.ts +12 -11
  220. package/src/server/plugins/engine/components/ComponentCollection.ts +143 -61
  221. package/src/server/plugins/engine/components/DatePartsField.ts +33 -11
  222. package/src/server/plugins/engine/components/DeclarationField.ts +37 -14
  223. package/src/server/plugins/engine/components/EastingNorthingField.ts +83 -22
  224. package/src/server/plugins/engine/components/EmailAddressField.ts +4 -7
  225. package/src/server/plugins/engine/components/FileUploadField.ts +28 -22
  226. package/src/server/plugins/engine/components/FormComponent.ts +49 -12
  227. package/src/server/plugins/engine/components/GeospatialField.ts +36 -21
  228. package/src/server/plugins/engine/components/LatLongField.ts +52 -21
  229. package/src/server/plugins/engine/components/ListFormComponent.ts +26 -10
  230. package/src/server/plugins/engine/components/LocationFieldBase.ts +5 -8
  231. package/src/server/plugins/engine/components/LocationFieldHelpers.ts +3 -3
  232. package/src/server/plugins/engine/components/Markdown.ts +7 -3
  233. package/src/server/plugins/engine/components/MonthYearField.ts +32 -10
  234. package/src/server/plugins/engine/components/MultilineTextField.ts +5 -8
  235. package/src/server/plugins/engine/components/NationalGridFieldNumberField.ts +25 -11
  236. package/src/server/plugins/engine/components/NumberField.ts +3 -4
  237. package/src/server/plugins/engine/components/OsGridRefField.ts +25 -9
  238. package/src/server/plugins/engine/components/PaymentField.ts +22 -12
  239. package/src/server/plugins/engine/components/SelectField.ts +3 -6
  240. package/src/server/plugins/engine/components/SelectionControlField.ts +7 -8
  241. package/src/server/plugins/engine/components/TelephoneNumberField.ts +4 -7
  242. package/src/server/plugins/engine/components/UkAddressField.ts +33 -18
  243. package/src/server/plugins/engine/components/YesNoField.ts +10 -0
  244. package/src/server/plugins/engine/components/helpers/components.ts +13 -6
  245. package/src/server/plugins/engine/components/types.ts +9 -0
  246. package/src/server/plugins/engine/configureEnginePlugin.ts +12 -1
  247. package/src/server/plugins/engine/form-context.ts +8 -2
  248. package/src/server/plugins/engine/helpers.ts +10 -18
  249. package/src/server/plugins/engine/i18n/buildValidationMessages.ts +69 -0
  250. package/src/server/plugins/engine/i18n/createFormTranslator.ts +33 -0
  251. package/src/server/plugins/engine/i18n/createTranslator.ts +61 -0
  252. package/src/server/plugins/engine/i18n/extractBaseTranslations.ts +61 -0
  253. package/src/server/plugins/engine/i18n/index.ts +80 -0
  254. package/src/server/plugins/engine/i18n/translations/cy.json +271 -0
  255. package/src/server/plugins/engine/i18n/translations/en-GB.json +271 -0
  256. package/src/server/plugins/engine/i18n/types.ts +62 -0
  257. package/src/server/plugins/engine/index.ts +4 -2
  258. package/src/server/plugins/engine/models/FormModel.ts +59 -23
  259. package/src/server/plugins/engine/models/SummaryViewModel.ts +68 -25
  260. package/src/server/plugins/engine/options.js +2 -1
  261. package/src/server/plugins/engine/outputFormatters/adapter/v1.ts +5 -0
  262. package/src/server/plugins/engine/outputFormatters/human/v1.ts +2 -3
  263. package/src/server/plugins/engine/outputFormatters/machine/v1.ts +9 -8
  264. package/src/server/plugins/engine/pageControllers/FileUploadPageController.ts +7 -3
  265. package/src/server/plugins/engine/pageControllers/PageController.ts +12 -1
  266. package/src/server/plugins/engine/pageControllers/QuestionPageController.ts +53 -21
  267. package/src/server/plugins/engine/pageControllers/RepeatPageController.ts +66 -29
  268. package/src/server/plugins/engine/pageControllers/StartPageController.ts +7 -2
  269. package/src/server/plugins/engine/pageControllers/StatusPageController.ts +10 -2
  270. package/src/server/plugins/engine/pageControllers/SummaryPageController.ts +48 -22
  271. package/src/server/plugins/engine/pageControllers/__stubs__/translator.ts +28 -0
  272. package/src/server/plugins/engine/pageControllers/errors.ts +4 -2
  273. package/src/server/plugins/engine/pageControllers/helpers/submission.ts +11 -4
  274. package/src/server/plugins/engine/pageControllers/validationOptions.ts +43 -53
  275. package/src/server/plugins/engine/plugin.ts +2 -0
  276. package/src/server/plugins/engine/routes/index.ts +9 -1
  277. package/src/server/plugins/engine/routes/questions.ts +5 -1
  278. package/src/server/plugins/engine/types/index.ts +5 -0
  279. package/src/server/plugins/engine/types/schema.ts +1 -0
  280. package/src/server/plugins/engine/types.ts +10 -0
  281. package/src/server/plugins/engine/views/components/_location-field-base.html +1 -1
  282. package/src/server/plugins/engine/views/components/fileuploadfield.html +3 -3
  283. package/src/server/plugins/engine/views/components/nationalgridfieldnumberfield.html +1 -1
  284. package/src/server/plugins/engine/views/components/osgridreffield.html +1 -1
  285. package/src/server/plugins/engine/views/components/paymentfield.html +8 -8
  286. package/src/server/plugins/engine/views/components/ukaddressfield.html +4 -4
  287. package/src/server/plugins/engine/views/confirmation.html +4 -4
  288. package/src/server/plugins/engine/views/exit.html +4 -4
  289. package/src/server/plugins/engine/views/file-upload.html +3 -3
  290. package/src/server/plugins/engine/views/index.html +3 -3
  291. package/src/server/plugins/engine/views/item-delete.html +1 -1
  292. package/src/server/plugins/engine/views/partials/form.html +3 -3
  293. package/src/server/plugins/engine/views/partials/preview-banner.html +4 -4
  294. package/src/server/plugins/engine/views/partials/warn-missing-notification-email.html +4 -5
  295. package/src/server/plugins/engine/views/repeat-list-summary.html +4 -4
  296. package/src/server/plugins/engine/views/summary.html +14 -7
  297. package/src/server/plugins/nunjucks/environment.js +14 -0
  298. package/src/server/plugins/nunjucks/filters/answer.js +12 -1
  299. package/src/server/plugins/postcode-lookup/models/index.js +144 -87
  300. package/src/server/plugins/postcode-lookup/routes/index.js +13 -16
  301. package/src/server/plugins/postcode-lookup/types.js +1 -0
  302. package/src/server/plugins/postcode-lookup/views/postcode-lookup-details.html +3 -3
  303. package/src/server/types.ts +2 -0
  304. package/src/server/utils/utils.js +14 -0
  305. package/src/typings/hapi/index.d.ts +1 -0
  306. package/.server/server/plugins/engine/components/constants.d.ts +0 -1
  307. package/.server/server/plugins/engine/components/constants.js +0 -2
  308. package/.server/server/plugins/engine/components/constants.js.map +0 -1
  309. package/src/server/plugins/engine/components/constants.ts +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"PageController.js","names":["ControllerPath","Boom","getSaveAndExitHelpers","getStartPath","normalisePath","PageController","def","name","model","pageDef","id","title","section","condition","events","collection","viewName","allowSaveAndExit","constructor","getSection","conditions","view","path","href","getHref","keys","getRouteOptions","postRouteOptions","viewModel","showTitle","pageTitle","sectionTitle","hideTitle","page","isStartPage","serviceUrl","feedbackLink","phaseTag","options","disableUserFeedback","undefined","formId","phaseBanner","phase","basePath","relativeTargetPath","startsWith","substring","finalPath","replace","getSummaryPath","Summary","valueOf","getStatusPath","Status","makeGetRouteHandler","request","context","h","makePostRouteHandler","badRequest","getStateKeys","_component","shouldShowSaveAndExit","server"],"sources":["../../../../../src/server/plugins/engine/pageControllers/PageController.ts"],"sourcesContent":["import {\n ControllerPath,\n type Events,\n type FormDefinition,\n type Page,\n type Section\n} from '@defra/forms-model'\nimport Boom from '@hapi/boom'\nimport { type Lifecycle, type RouteOptions, type Server } from '@hapi/hapi'\n\nimport { type ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'\nimport { type FormComponent } from '~/src/server/plugins/engine/components/FormComponent.js'\nimport {\n getSaveAndExitHelpers,\n getStartPath,\n normalisePath\n} from '~/src/server/plugins/engine/helpers.js'\nimport { type FormModel } from '~/src/server/plugins/engine/models/index.js'\nimport { type ExecutableCondition } from '~/src/server/plugins/engine/models/types.js'\nimport {\n type FormContext,\n type PageViewModelBase\n} from '~/src/server/plugins/engine/types.js'\nimport {\n type FormRequest,\n type FormRequestPayload,\n type FormRequestPayloadRefs,\n type FormRequestRefs,\n type FormResponseToolkit\n} from '~/src/server/routes/types.js'\n\nexport class PageController {\n /**\n * The base class for all page controllers. Page controllers are responsible for generating the get and post route handlers when a user navigates to `/{id}/{path*}`.\n */\n def: FormDefinition\n name?: string\n model: FormModel\n pageDef: Page\n id?: string\n title: string\n section?: Section\n condition?: ExecutableCondition\n events?: Events\n collection?: ComponentCollection\n viewName = 'index'\n allowSaveAndExit = false\n\n constructor(model: FormModel, pageDef: Page) {\n const { def } = model\n\n this.def = def\n this.name = def.name\n this.model = model\n this.pageDef = pageDef\n this.id = pageDef.id\n this.title = pageDef.title\n this.events = pageDef.events\n\n // Resolve section\n if (pageDef.section) {\n this.section = model.getSection(pageDef.section)\n }\n\n // Resolve condition\n if (pageDef.condition) {\n this.condition = model.conditions[pageDef.condition]\n }\n\n // Override view name\n if (pageDef.view) {\n this.viewName = pageDef.view\n }\n }\n\n get path() {\n return this.pageDef.path\n }\n\n get href() {\n const { path } = this\n return this.getHref(`/${normalisePath(path)}`)\n }\n\n get keys() {\n return this.collection?.keys ?? []\n }\n\n /**\n * {@link https://hapi.dev/api/?v=20.1.2#route-options}\n */\n get getRouteOptions(): RouteOptions<FormRequestRefs> {\n return {}\n }\n\n /**\n * {@link https://hapi.dev/api/?v=20.1.2#route-options}\n */\n get postRouteOptions(): RouteOptions<FormRequestPayloadRefs> {\n return {}\n }\n\n get viewModel(): PageViewModelBase {\n const { name, section, title } = this\n\n const showTitle = true\n const pageTitle = title\n const sectionTitle = section?.hideTitle !== true ? section?.title : ''\n\n return {\n name,\n page: this,\n pageTitle,\n sectionTitle,\n showTitle,\n isStartPage: false,\n serviceUrl: this.getHref('/'),\n feedbackLink: this.feedbackLink,\n phaseTag: this.phaseTag\n }\n }\n\n get feedbackLink() {\n return this.def.options?.disableUserFeedback\n ? undefined\n : `/form/feedback?formId=${this.model.formId}`\n }\n\n get phaseTag() {\n const { def } = this\n return def.phaseBanner?.phase\n }\n\n getHref(path: string): string {\n const basePath = this.model.basePath\n\n if (path === '/') {\n return `/${basePath}`\n }\n\n // if ever the path is not prefixed with a slash, add it\n const relativeTargetPath = path.startsWith('/') ? path.substring(1) : path\n let finalPath = `/${basePath}`\n if (relativeTargetPath) {\n finalPath += `/${relativeTargetPath}`\n }\n finalPath = finalPath.replace(/\\/{2,}/g, '/')\n\n return finalPath\n }\n\n getStartPath() {\n return getStartPath(this.model)\n }\n\n getSummaryPath() {\n return ControllerPath.Summary.valueOf()\n }\n\n getStatusPath() {\n return ControllerPath.Status.valueOf()\n }\n\n makeGetRouteHandler(): (\n request: FormRequest,\n context: FormContext,\n h: FormResponseToolkit\n ) => ReturnType<Lifecycle.Method<FormRequestRefs>> {\n return (request, context, h) => {\n const { viewModel, viewName } = this\n return h.view(viewName, viewModel)\n }\n }\n\n makePostRouteHandler(): (\n request: FormRequestPayload,\n context: FormContext,\n h: FormResponseToolkit\n ) => ReturnType<Lifecycle.Method<FormRequestPayloadRefs>> {\n throw Boom.badRequest('Unsupported POST route handler for this page')\n }\n\n /**\n * Get supplementary state keys for clearing component state.\n *\n * This method returns page controller-level state keys only. The core component's\n * state key (the component's name) is managed separately by the framework and should\n * NOT be included in the returned array.\n *\n * Returns an empty array by default. Override in subclasses to provide\n * page-specific supplementary state keys (e.g., upload state, cached data).\n * @param _component - The component to get supplementary state keys for (optional)\n * @returns Array of supplementary state keys to clear (excluding the component name itself)\n */\n getStateKeys(_component?: FormComponent): string[] {\n return []\n }\n\n shouldShowSaveAndExit(server: Server): boolean {\n return getSaveAndExitHelpers(server) !== undefined && this.allowSaveAndExit\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"PageController.js","names":["ControllerPath","Boom","getSaveAndExitHelpers","getStartPath","normalisePath","resolveLanguage","PageController","def","name","model","pageDef","id","title","section","condition","events","collection","viewName","allowSaveAndExit","constructor","getSection","conditions","view","path","href","getHref","keys","getRouteOptions","postRouteOptions","viewModel","showTitle","pageTitle","sectionTitle","hideTitle","page","isStartPage","serviceUrl","feedbackLink","phaseTag","options","disableUserFeedback","undefined","formId","phaseBanner","phase","basePath","relativeTargetPath","startsWith","substring","finalPath","replace","getSummaryPath","Summary","valueOf","getStatusPath","Status","getTranslator","request","createTranslator","makeGetRouteHandler","context","h","t","makePostRouteHandler","badRequest","getStateKeys","_component","shouldShowSaveAndExit","server"],"sources":["../../../../../src/server/plugins/engine/pageControllers/PageController.ts"],"sourcesContent":["import {\n ControllerPath,\n type Events,\n type FormDefinition,\n type Page,\n type Section\n} from '@defra/forms-model'\nimport Boom from '@hapi/boom'\nimport { type Lifecycle, type RouteOptions, type Server } from '@hapi/hapi'\n\nimport { type ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'\nimport { type FormComponent } from '~/src/server/plugins/engine/components/FormComponent.js'\nimport {\n getSaveAndExitHelpers,\n getStartPath,\n normalisePath\n} from '~/src/server/plugins/engine/helpers.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport { type FormModel } from '~/src/server/plugins/engine/models/index.js'\nimport { type ExecutableCondition } from '~/src/server/plugins/engine/models/types.js'\nimport {\n type AnyFormRequest,\n type FormContext,\n type PageViewModelBase\n} from '~/src/server/plugins/engine/types.js'\nimport {\n type FormRequest,\n type FormRequestPayload,\n type FormRequestPayloadRefs,\n type FormRequestRefs,\n type FormResponseToolkit\n} from '~/src/server/routes/types.js'\nimport { resolveLanguage } from '~/src/server/utils/utils.js'\n\nexport class PageController {\n /**\n * The base class for all page controllers. Page controllers are responsible for generating the get and post route handlers when a user navigates to `/{id}/{path*}`.\n */\n def: FormDefinition\n name?: string\n model: FormModel\n pageDef: Page\n id?: string\n title: string\n section?: Section\n condition?: ExecutableCondition\n events?: Events\n collection?: ComponentCollection\n viewName = 'index'\n allowSaveAndExit = false\n\n constructor(model: FormModel, pageDef: Page) {\n const { def } = model\n\n this.def = def\n this.name = def.name\n this.model = model\n this.pageDef = pageDef\n this.id = pageDef.id\n this.title = pageDef.title\n this.events = pageDef.events\n\n // Resolve section\n if (pageDef.section) {\n this.section = model.getSection(pageDef.section)\n }\n\n // Resolve condition\n if (pageDef.condition) {\n this.condition = model.conditions[pageDef.condition]\n }\n\n // Override view name\n if (pageDef.view) {\n this.viewName = pageDef.view\n }\n }\n\n get path() {\n return this.pageDef.path\n }\n\n get href() {\n const { path } = this\n return this.getHref(`/${normalisePath(path)}`)\n }\n\n get keys() {\n return this.collection?.keys ?? []\n }\n\n /**\n * {@link https://hapi.dev/api/?v=20.1.2#route-options}\n */\n get getRouteOptions(): RouteOptions<FormRequestRefs> {\n return {}\n }\n\n /**\n * {@link https://hapi.dev/api/?v=20.1.2#route-options}\n */\n get postRouteOptions(): RouteOptions<FormRequestPayloadRefs> {\n return {}\n }\n\n get viewModel(): PageViewModelBase {\n const { name, section, title } = this\n\n const showTitle = true\n const pageTitle = title\n const sectionTitle = section?.hideTitle !== true ? section?.title : ''\n\n return {\n name,\n page: this,\n pageTitle,\n sectionTitle,\n showTitle,\n isStartPage: false,\n serviceUrl: this.getHref('/'),\n feedbackLink: this.feedbackLink,\n phaseTag: this.phaseTag\n }\n }\n\n get feedbackLink() {\n return this.def.options?.disableUserFeedback\n ? undefined\n : `/form/feedback?formId=${this.model.formId}`\n }\n\n get phaseTag() {\n const { def } = this\n return def.phaseBanner?.phase\n }\n\n getHref(path: string): string {\n const basePath = this.model.basePath\n\n if (path === '/') {\n return `/${basePath}`\n }\n\n // if ever the path is not prefixed with a slash, add it\n const relativeTargetPath = path.startsWith('/') ? path.substring(1) : path\n let finalPath = `/${basePath}`\n if (relativeTargetPath) {\n finalPath += `/${relativeTargetPath}`\n }\n finalPath = finalPath.replace(/\\/{2,}/g, '/')\n\n return finalPath\n }\n\n getStartPath() {\n return getStartPath(this.model)\n }\n\n getSummaryPath() {\n return ControllerPath.Summary.valueOf()\n }\n\n getStatusPath() {\n return ControllerPath.Status.valueOf()\n }\n\n protected getTranslator(request: AnyFormRequest): Translator {\n return this.model.createTranslator(resolveLanguage(request))\n }\n\n makeGetRouteHandler(): (\n request: FormRequest,\n context: FormContext,\n h: FormResponseToolkit\n ) => ReturnType<Lifecycle.Method<FormRequestRefs>> {\n return (request, context, h) => {\n const { viewModel, viewName } = this\n const { t } = this.getTranslator(request)\n return h.view(viewName, {\n ...viewModel,\n t\n })\n }\n }\n\n makePostRouteHandler(): (\n request: FormRequestPayload,\n context: FormContext,\n h: FormResponseToolkit\n ) => ReturnType<Lifecycle.Method<FormRequestPayloadRefs>> {\n throw Boom.badRequest('Unsupported POST route handler for this page')\n }\n\n /**\n * Get supplementary state keys for clearing component state.\n *\n * This method returns page controller-level state keys only. The core component's\n * state key (the component's name) is managed separately by the framework and should\n * NOT be included in the returned array.\n *\n * Returns an empty array by default. Override in subclasses to provide\n * page-specific supplementary state keys (e.g., upload state, cached data).\n * @param _component - The component to get supplementary state keys for (optional)\n * @returns Array of supplementary state keys to clear (excluding the component name itself)\n */\n getStateKeys(_component?: FormComponent): string[] {\n return []\n }\n\n shouldShowSaveAndExit(server: Server): boolean {\n return getSaveAndExitHelpers(server) !== undefined && this.allowSaveAndExit\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -3,6 +3,7 @@ import { type RouteOptions } from '@hapi/hapi';
3
3
  import { type ValidationErrorItem } from 'joi';
4
4
  import { ComponentCollection } from '../../../../server/plugins/engine/components/ComponentCollection.js';
5
5
  import { type BackLink } from '../../../../server/plugins/engine/components/types.js';
6
+ import { type Translator } from '../../../../server/plugins/engine/i18n/types.js';
6
7
  import { type FormModel } from '../../../../server/plugins/engine/models/index.js';
7
8
  import { PageController } from '../../../../server/plugins/engine/pageControllers/PageController.js';
8
9
  import { type AnyFormRequest, type FormContext, type FormContextRequest, type FormPageViewModel, type FormPayload, type FormPayloadParams, type FormState, type FormStateValue, type FormSubmissionState } from '../../../../server/plugins/engine/types.js';
@@ -19,8 +20,9 @@ export declare class QuestionPageController extends PageController {
19
20
  * Used for mapping form payloads and errors to govuk-frontend's template api, so a page can be rendered
20
21
  * @param request - the hapi request
21
22
  * @param context - the form context
23
+ * @param translator - optional per-request translator pair
22
24
  */
23
- getViewModel(request: FormContextRequest, context: FormContext): FormPageViewModel;
25
+ getViewModel(request: FormContextRequest, context: FormContext, translator: Translator): FormPageViewModel;
24
26
  getRelevantPath(request: AnyFormRequest, context: FormContext): string;
25
27
  /**
26
28
  * Apply conditions to evaluation state to determine next page path
@@ -45,7 +47,7 @@ export declare class QuestionPageController extends PageController {
45
47
  /**
46
48
  * Get the back link for a given progress.
47
49
  */
48
- protected getBackLink(request: FormContextRequest, context: FormContext): BackLink | undefined;
50
+ protected getBackLink(request: FormContextRequest, context: FormContext, t: (key: string, opts?: Record<string, unknown>) => string): BackLink | undefined;
49
51
  makePostRouteHandler(): (request: FormRequestPayload, context: FormContext, h: FormResponseToolkit) => Promise<import("@hapi/hapi").ResponseObject>;
50
52
  private dispatchExternal;
51
53
  proceed(request: FormContextRequest, h: FormResponseToolkit, nextPath?: string): import("@hapi/hapi").ResponseObject;
@@ -3,7 +3,6 @@ import Boom from '@hapi/boom';
3
3
  import { COMPONENT_STATE_ERROR, EXTERNAL_STATE_APPENDAGE, EXTERNAL_STATE_PAYLOAD, PAYMENT_EXPIRED_NOTIFICATION } from "../../../constants.js";
4
4
  import { ComponentCollection } from "../components/ComponentCollection.js";
5
5
  import { PaymentField } from "../components/PaymentField.js";
6
- import { optionalText } from "../components/constants.js";
7
6
  import { checkFormStatus, getCacheService, getErrors, getSaveAndExitHelpers, normalisePath, proceed } from "../helpers.js";
8
7
  import { PageController } from "./PageController.js";
9
8
  import { prefillStateFromQueryParameters } from "./helpers/state.js";
@@ -66,24 +65,35 @@ export class QuestionPageController extends PageController {
66
65
  * Used for mapping form payloads and errors to govuk-frontend's template api, so a page can be rendered
67
66
  * @param request - the hapi request
68
67
  * @param context - the form context
68
+ * @param translator - optional per-request translator pair
69
69
  */
70
- getViewModel(request, context) {
70
+ getViewModel(request, context, translator) {
71
71
  const {
72
72
  collection,
73
73
  viewModel
74
74
  } = this;
75
- const {
76
- query
77
- } = request;
78
75
  const {
79
76
  payload,
80
77
  errors
81
78
  } = context;
79
+ const {
80
+ t,
81
+ tPage,
82
+ tSection
83
+ } = translator;
82
84
  let {
83
- pageTitle,
84
- showTitle
85
+ showTitle,
86
+ sectionTitle
85
87
  } = viewModel;
86
- const components = collection.getViewModel(payload, errors, query);
88
+ let pageTitle = this.pageDef.title ? tPage(this.pageDef, 'title') : '';
89
+ if (this.section) {
90
+ sectionTitle = this.section.hideTitle !== true ? tSection(this.section, 'title') : '';
91
+ }
92
+ const components = collection.getViewModel({
93
+ payload,
94
+ errors,
95
+ translator
96
+ });
87
97
  const formComponents = components.filter(({
88
98
  isFormComponent
89
99
  }) => isFormComponent);
@@ -113,10 +123,15 @@ export class QuestionPageController extends PageController {
113
123
 
114
124
  // Check for optional in label
115
125
  const isOptional = this.collection.fields.at(0)?.options.required === false;
116
- if (pageTitle) {
117
- labelOrLegend.text = isOptional ? `${pageTitle}${optionalText}` : pageTitle;
126
+ if (!pageTitle) {
127
+ pageTitle = labelOrLegend.text;
118
128
  }
119
- pageTitle = pageTitle || labelOrLegend.text;
129
+ labelOrLegend.text = isOptional ? `${pageTitle} ${t('common.optional')}` : pageTitle;
130
+ }
131
+
132
+ // Fallback if still no pageTitle set
133
+ if (!pageTitle) {
134
+ pageTitle = labelOrLegend.text;
120
135
  }
121
136
  }
122
137
  showTitle = !isPageHeading;
@@ -158,8 +173,10 @@ export class QuestionPageController extends PageController {
158
173
  });
159
174
  return {
160
175
  ...viewModel,
161
- backLink: this.getBackLink(request, context),
176
+ backLink: this.getBackLink(request, context, t),
162
177
  context,
178
+ pageTitle,
179
+ sectionTitle,
163
180
  showTitle,
164
181
  components,
165
182
  errors,
@@ -355,14 +372,18 @@ export class QuestionPageController extends PageController {
355
372
  const {
356
373
  evaluationState
357
374
  } = context;
375
+ const translator = this.getTranslator(request);
376
+ const {
377
+ t
378
+ } = translator;
358
379
 
359
380
  // Copy any URL params into the form state (if not already done so)
360
381
  if (await prefillStateFromQueryParameters(request, this)) {
361
382
  // Forward to same page without query string
362
383
  return h.redirect(request.url.pathname);
363
384
  }
364
- const viewModel = this.getViewModel(request, context);
365
- viewModel.errors = collection.getViewErrors(viewModel.errors);
385
+ const viewModel = this.getViewModel(request, context, translator);
386
+ viewModel.errors = collection.getViewErrors(translator, viewModel.errors);
366
387
  const flashedError = request.yar.flash(COMPONENT_STATE_ERROR);
367
388
  const flashedErrors = !Array.isArray(flashedError) ? [flashedError] : [];
368
389
  viewModel.errors = (viewModel.errors ?? []).concat(flashedErrors);
@@ -376,7 +397,10 @@ export class QuestionPageController extends PageController {
376
397
  // Filter our components based on their conditions using our evaluated state
377
398
  viewModel.components = this.filterConditionalComponents(viewModel, model, evaluationState);
378
399
  viewModel.hasMissingNotificationEmail = await this.hasMissingNotificationEmail(request, context);
379
- return h.view(viewName, viewModel);
400
+ return h.view(viewName, {
401
+ ...viewModel,
402
+ t
403
+ });
380
404
  };
381
405
  }
382
406
  async hasMissingNotificationEmail(request, context) {
@@ -411,7 +435,7 @@ export class QuestionPageController extends PageController {
411
435
  /**
412
436
  * Get the back link for a given progress.
413
437
  */
414
- getBackLink(request, context) {
438
+ getBackLink(request, context, t) {
415
439
  const {
416
440
  pageDef
417
441
  } = this;
@@ -430,7 +454,7 @@ export class QuestionPageController extends PageController {
430
454
  // Check answers back link
431
455
  if (returnUrl) {
432
456
  return {
433
- text: hasRepeater(pageDef) && itemId ? 'Go back to add another' : 'Go back to check answers',
457
+ text: hasRepeater(pageDef) && itemId ? t('pages.question.backToAddAnother') : t('pages.question.backToCheckAnswers'),
434
458
  href: returnUrl
435
459
  };
436
460
  }
@@ -446,7 +470,7 @@ export class QuestionPageController extends PageController {
446
470
 
447
471
  // Default back link
448
472
  return {
449
- text: 'Back',
473
+ text: t('common.back'),
450
474
  href: this.getHref(backPath)
451
475
  };
452
476
  }
@@ -463,6 +487,10 @@ export class QuestionPageController extends PageController {
463
487
  evaluationState
464
488
  } = context;
465
489
  const action = request.payload.action;
490
+ const translator = this.getTranslator(request);
491
+ const {
492
+ t
493
+ } = translator;
466
494
  if (action?.startsWith(FormAction.External)) {
467
495
  return await this.dispatchExternal(request, h, context);
468
496
  }
@@ -472,12 +500,15 @@ export class QuestionPageController extends PageController {
472
500
  * @todo Refactor to match POST REDIRECT GET pattern
473
501
  */
474
502
  if (context.errors || isForceAccess) {
475
- const viewModel = this.getViewModel(request, context);
476
- viewModel.errors = collection.getViewErrors(viewModel.errors);
503
+ const viewModel = this.getViewModel(request, context, translator);
504
+ viewModel.errors = collection.getViewErrors(translator, viewModel.errors);
477
505
 
478
506
  // Filter our components based on their conditions using our evaluated state
479
507
  viewModel.components = this.filterConditionalComponents(viewModel, model, evaluationState);
480
- return h.view(viewName, viewModel);
508
+ return h.view(viewName, {
509
+ ...viewModel,
510
+ t
511
+ });
481
512
  }
482
513
 
483
514
  // Save state
@@ -1 +1 @@
1
- {"version":3,"file":"QuestionPageController.js","names":["ComponentType","ControllerType","Engine","hasComponents","hasNext","hasRepeater","isPaymentPage","Boom","COMPONENT_STATE_ERROR","EXTERNAL_STATE_APPENDAGE","EXTERNAL_STATE_PAYLOAD","PAYMENT_EXPIRED_NOTIFICATION","ComponentCollection","PaymentField","optionalText","checkFormStatus","getCacheService","getErrors","getSaveAndExitHelpers","normalisePath","proceed","PageController","prefillStateFromQueryParameters","getComponentsByType","formatCurrency","FormAction","FormStatus","actionSchema","crumbSchema","paramsSchema","merge","QuestionPageController","collection","errorSummaryTitle","allowSaveAndExit","constructor","model","pageDef","components","page","formSchema","keys","crumb","action","next","def","filter","path","linkPath","pages","some","pagePath","allowContinue","engine","V2","controller","Terminal","length","getItemId","request","itemId","getFormParams","params","getViewModel","context","viewModel","query","payload","errors","pageTitle","showTitle","formComponents","isFormComponent","fieldset","label","isPageHeading","labelOrLegend","legend","size","classes","isOptional","fields","at","options","required","text","comp","paymentField","find","f","resolvedAmount","resolveAmount","evaluationState","amount","hasIncompletePayment","paymentState","preAuth","status","backLink","getBackLink","shouldShowSaveAndExit","server","showSubmitButton","getRelevantPath","paths","startPath","getStartPath","relevantPath","getNextPath","summaryPath","getSummaryPath","statusPath","getStatusPath","defaultPath","undefined","pageIndex","indexOf","nextPage","slice","condition","conditionResult","fn","nextLink","link","conditions","getFormDataFromState","state","result","validate","abortEarly","stripUnknown","value","getStateFromValidForm","details","getState","cacheService","setState","mergeState","update","updated","filterConditionalComponents","filtered","component","content","type","Details","map","evaluatedComponent","Array","isArray","item","items","makeGetRouteHandler","h","viewName","redirect","url","pathname","getViewErrors","flashedError","yar","flash","flashedErrors","concat","paymentExpiredFlash","showPaymentExpiredNotification","hasMissingNotificationEmail","view","isForceAccess","formsService","services","getFormMetadata","includes","notificationEmail","slug","returnUrl","href","backPath","endsWith","getHref","makePostRouteHandler","startsWith","External","dispatchExternal","SaveAndExit","handleSaveAndExit","externalComponents","externalActionsWithArgs","split","externalActionArgs","arg","args","Object","fromEntries","componentName","componentDefMap","get","componentType","internal","selectedComponent","stashedPayload","clear","isPreview","isLive","Live","dispatcher","sourceUrl","search","actionArgs","nextPath","nextUrl","saveAndExit","getRouteOptions","ext","onPostHandler","method","_request","continue","postRouteOptions","parse","maxBytes","Number","MAX_SAFE_INTEGER","failAction"],"sources":["../../../../../src/server/plugins/engine/pageControllers/QuestionPageController.ts"],"sourcesContent":["import {\n ComponentType,\n ControllerType,\n Engine,\n hasComponents,\n hasNext,\n hasRepeater,\n isPaymentPage,\n type Link,\n type Page\n} from '@defra/forms-model'\nimport Boom from '@hapi/boom'\nimport { type RouteOptions } from '@hapi/hapi'\nimport { type ValidationErrorItem } from 'joi'\n\nimport {\n COMPONENT_STATE_ERROR,\n EXTERNAL_STATE_APPENDAGE,\n EXTERNAL_STATE_PAYLOAD,\n PAYMENT_EXPIRED_NOTIFICATION\n} from '~/src/server/constants.js'\nimport { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'\nimport { PaymentField } from '~/src/server/plugins/engine/components/PaymentField.js'\nimport { optionalText } from '~/src/server/plugins/engine/components/constants.js'\nimport { type BackLink } from '~/src/server/plugins/engine/components/types.js'\nimport {\n checkFormStatus,\n getCacheService,\n getErrors,\n getSaveAndExitHelpers,\n normalisePath,\n proceed\n} from '~/src/server/plugins/engine/helpers.js'\nimport { type FormModel } from '~/src/server/plugins/engine/models/index.js'\nimport { PageController } from '~/src/server/plugins/engine/pageControllers/PageController.js'\nimport { prefillStateFromQueryParameters } from '~/src/server/plugins/engine/pageControllers/helpers/state.js'\nimport {\n type AnyFormRequest,\n type FormContext,\n type FormContextRequest,\n type FormPageViewModel,\n type FormPayload,\n type FormPayloadParams,\n type FormState,\n type FormStateValue,\n type FormSubmissionState\n} from '~/src/server/plugins/engine/types.js'\nimport { getComponentsByType } from '~/src/server/plugins/engine/validationHelpers.js'\nimport { formatCurrency } from '~/src/server/plugins/payment/helper.js'\nimport {\n FormAction,\n FormStatus,\n type FormRequest,\n type FormRequestPayload,\n type FormRequestPayloadRefs,\n type FormRequestRefs,\n type FormResponseToolkit\n} from '~/src/server/routes/types.js'\nimport {\n actionSchema,\n crumbSchema,\n paramsSchema\n} from '~/src/server/schemas/index.js'\nimport { merge } from '~/src/server/services/cacheService.js'\n\nexport class QuestionPageController extends PageController {\n collection: ComponentCollection\n errorSummaryTitle = 'There is a problem'\n allowSaveAndExit = true\n\n constructor(model: FormModel, pageDef: Page) {\n super(model, pageDef)\n\n // Components collection\n this.collection = new ComponentCollection(\n hasComponents(pageDef) ? pageDef.components : [],\n { model, page: this }\n )\n\n this.collection.formSchema = this.collection.formSchema.keys({\n crumb: crumbSchema,\n action: actionSchema\n })\n }\n\n get next(): Link[] {\n const { def, pageDef } = this\n\n if (!hasNext(pageDef)) {\n return []\n }\n\n // Remove stale links\n return pageDef.next.filter(({ path }) => {\n const linkPath = normalisePath(path)\n\n return def.pages.some((page) => {\n const pagePath = normalisePath(page.path)\n return pagePath === linkPath\n })\n })\n }\n\n get allowContinue(): boolean {\n if (this.model.engine === Engine.V2) {\n return this.pageDef.controller !== ControllerType.Terminal\n }\n\n return this.next.length > 0\n }\n\n getItemId(request?: FormContextRequest) {\n const { itemId } = this.getFormParams(request)\n return itemId ?? request?.params.itemId\n }\n\n /**\n * Used for mapping form payloads and errors to govuk-frontend's template api, so a page can be rendered\n * @param request - the hapi request\n * @param context - the form context\n */\n getViewModel(\n request: FormContextRequest,\n context: FormContext\n ): FormPageViewModel {\n const { collection, viewModel } = this\n const { query } = request\n const { payload, errors } = context\n\n let { pageTitle, showTitle } = viewModel\n\n const components = collection.getViewModel(payload, errors, query)\n const formComponents = components.filter(\n ({ isFormComponent }) => isFormComponent\n )\n\n // Single form component? Hide title and customise label or legend instead\n if (formComponents.length === 1) {\n const { model } = formComponents[0]\n const { fieldset, label } = model\n\n // Set as page heading when not following other content\n const isPageHeading = formComponents[0] === components[0]\n\n // Check for legend or label\n const labelOrLegend = fieldset?.legend ?? label\n\n // Use legend or label as page heading\n if (labelOrLegend) {\n const size = isPageHeading ? 'l' : 'm'\n\n labelOrLegend.classes =\n labelOrLegend === label\n ? `govuk-label--${size}`\n : `govuk-fieldset__legend--${size}`\n\n if (isPageHeading) {\n labelOrLegend.isPageHeading = isPageHeading\n\n // Check for optional in label\n const isOptional =\n this.collection.fields.at(0)?.options.required === false\n\n if (pageTitle) {\n labelOrLegend.text = isOptional\n ? `${pageTitle}${optionalText}`\n : pageTitle\n }\n\n pageTitle = pageTitle || labelOrLegend.text\n }\n }\n\n showTitle = !isPageHeading\n } else if (formComponents.length > 1) {\n // When there is more than one form component,\n // adjust the label/legends to give equal prominence\n for (const { model } of formComponents) {\n if (model.fieldset?.legend) {\n model.fieldset.legend.classes = 'govuk-fieldset__legend--m'\n }\n if (model.label) {\n model.label.classes = 'govuk-label--m'\n }\n }\n }\n\n // Override payment amount display with resolved conditional amount\n // getViewModel() only has the current page's payload, not full form state.\n // The full state is available via context.evaluationState.\n for (const comp of components) {\n if ('amount' in comp.model && 'paymentState' in comp.model) {\n const paymentField = this.collection.fields.find(\n (f): f is PaymentField => f instanceof PaymentField\n )\n if (paymentField) {\n const resolvedAmount = PaymentField.resolveAmount(\n paymentField.options,\n this.model,\n context.evaluationState\n )\n comp.model.amount = formatCurrency(resolvedAmount)\n }\n }\n }\n\n const hasIncompletePayment = components.some(({ model }) => {\n if ('paymentState' in model) {\n const paymentState = model.paymentState as\n | { preAuth?: { status?: string } }\n | undefined\n return !paymentState?.preAuth?.status\n }\n return false\n })\n\n return {\n ...viewModel,\n backLink: this.getBackLink(request, context),\n context,\n showTitle,\n components,\n errors,\n allowSaveAndExit:\n this.shouldShowSaveAndExit(request.server) &&\n !isPaymentPage(this.pageDef),\n showSubmitButton: !hasIncompletePayment\n }\n }\n\n getRelevantPath(request: AnyFormRequest, context: FormContext) {\n const { paths } = context\n\n const startPath = this.getStartPath()\n const relevantPath = paths.at(-1) ?? startPath\n\n return !paths.length\n ? startPath // First possible path\n : relevantPath // Last possible path\n }\n\n /**\n * Apply conditions to evaluation state to determine next page path\n */\n getNextPath(context: FormContext) {\n const { model, next, path } = this\n const { evaluationState } = context\n\n const summaryPath = this.getSummaryPath()\n const statusPath = this.getStatusPath()\n\n // Walk from summary page (no next links) to status page\n let defaultPath = path === summaryPath ? statusPath : undefined\n\n if (model.engine === Engine.V2) {\n if (this.pageDef.controller !== ControllerType.Terminal) {\n const { pages } = this.model\n const pageIndex = pages.indexOf(this)\n\n // The \"next\" page is the first found after the current which is\n // either unconditional or has a condition that evaluates to \"true\"\n const nextPage = pages.slice(pageIndex + 1).find((page) => {\n const { condition } = page\n\n if (condition) {\n const conditionResult = condition.fn(evaluationState)\n\n if (!conditionResult) {\n return false\n }\n }\n\n // Skip payment pages in the normal page walk.\n // Users reach the payment page via \"Pay and submit\" on CYA,\n // not by navigating forward through the form.\n if (isPaymentPage(page.pageDef)) {\n return false\n }\n\n return true\n })\n\n return nextPage?.path ?? defaultPath\n } else {\n return defaultPath\n }\n }\n\n const nextLink = next.find((link) => {\n const { condition } = link\n\n if (condition) {\n return model.conditions[condition]?.fn(evaluationState) ?? false\n }\n\n defaultPath = link.path\n return false\n })\n\n return nextLink?.path ?? defaultPath\n }\n\n /**\n * Gets the form payload (from state) for this page only\n */\n getFormDataFromState(\n request: FormContextRequest | undefined,\n state: FormSubmissionState\n ): FormPayload {\n const { collection } = this\n\n // Form params from request\n const params = this.getFormParams(request)\n\n // Form payload from state\n const payload = collection.getFormDataFromState(state)\n\n return {\n ...params,\n ...payload\n }\n }\n\n /**\n * Gets form params (from payload) for this page only\n */\n getFormParams(request?: FormContextRequest): FormPayloadParams {\n const { payload } = request ?? {}\n\n const result = paramsSchema.validate(payload, {\n abortEarly: false,\n stripUnknown: true\n })\n\n return result.value as FormPayloadParams\n }\n\n getStateFromValidForm(\n request: FormContextRequest,\n state: FormSubmissionState,\n payload: FormPayload\n ): FormState {\n return this.collection.getStateFromValidForm(payload)\n }\n\n getErrors(details?: ValidationErrorItem[]) {\n return getErrors(details)\n }\n\n async getState(request: AnyFormRequest) {\n const { query } = request\n\n // Skip get for preview URL direct access\n if ('force' in query) {\n return {}\n }\n\n const cacheService = getCacheService(request.server)\n\n return cacheService.getState(request)\n }\n\n async setState(request: AnyFormRequest, state: FormSubmissionState) {\n const { query } = request\n\n // Skip set for preview URL direct access\n if ('force' in query) {\n return state\n }\n\n const cacheService = getCacheService(request.server)\n\n return cacheService.setState(request, state)\n }\n\n async mergeState(\n request: AnyFormRequest,\n state: FormSubmissionState,\n update: object\n ) {\n const { query } = request\n\n // Merge state before set\n const updated = merge(state, update)\n\n // Skip set for preview URL direct access\n if ('force' in query) {\n return updated\n }\n\n const cacheService = getCacheService(request.server)\n\n return cacheService.setState(request, updated)\n }\n\n filterConditionalComponents(\n viewModel: FormPageViewModel,\n model: FormModel,\n evaluationState: Partial<Record<string, FormStateValue>>\n ) {\n // Filter our components based on their conditions using our evaluated state\n let filtered = viewModel.components.filter((component) => {\n if (\n (!!component.model.content ||\n component.type === ComponentType.Details) &&\n component.model.condition\n ) {\n const condition = model.conditions[component.model.condition]\n return condition?.fn(evaluationState)\n }\n return true\n })\n\n /**\n * For conditional reveal components (which we no longer support until GDS resolves the related accessibility issues {@link https://github.com/alphagov/govuk-frontend/issues/1991}\n */\n filtered = filtered.map((component) => {\n const evaluatedComponent = component\n const content = evaluatedComponent.model.content\n if (Array.isArray(content)) {\n evaluatedComponent.model.content = content.filter((item) =>\n item.condition\n ? model.conditions[item.condition]?.fn(evaluationState)\n : true\n )\n }\n // apply condition to items for radios, checkboxes etc\n const items = evaluatedComponent.model.items\n\n if (Array.isArray(items)) {\n evaluatedComponent.model.items = items.filter((item) =>\n item.condition\n ? model.conditions[item.condition]?.fn(evaluationState)\n : true\n )\n }\n\n return evaluatedComponent\n })\n\n return filtered\n }\n\n makeGetRouteHandler() {\n return async (\n request: FormRequest,\n context: FormContext,\n h: FormResponseToolkit\n ) => {\n const { collection, model, viewName } = this\n const { evaluationState } = context\n\n // Copy any URL params into the form state (if not already done so)\n if (await prefillStateFromQueryParameters(request, this)) {\n // Forward to same page without query string\n return h.redirect(request.url.pathname)\n }\n\n const viewModel = this.getViewModel(request, context)\n viewModel.errors = collection.getViewErrors(viewModel.errors)\n\n const flashedError = request.yar.flash(COMPONENT_STATE_ERROR)\n const flashedErrors = !Array.isArray(flashedError) ? [flashedError] : []\n\n viewModel.errors = (viewModel.errors ?? []).concat(flashedErrors)\n\n const paymentExpiredFlash = request.yar.flash(\n PAYMENT_EXPIRED_NOTIFICATION\n )\n viewModel.showPaymentExpiredNotification =\n !Array.isArray(paymentExpiredFlash)\n\n /**\n * Content components can be hidden based on a condition. If the condition evaluates to true, it is safe to be kept, otherwise discard it\n */\n\n // Filter our components based on their conditions using our evaluated state\n viewModel.components = this.filterConditionalComponents(\n viewModel,\n model,\n evaluationState\n )\n\n viewModel.hasMissingNotificationEmail =\n await this.hasMissingNotificationEmail(request, context)\n\n return h.view(viewName, viewModel)\n }\n }\n\n async hasMissingNotificationEmail(\n request: FormRequest,\n context: FormContext\n ) {\n const { path } = this\n const { params } = request\n const { isForceAccess } = context\n\n const startPath = this.getStartPath()\n const summaryPath = this.getSummaryPath()\n const { formsService } = this.model.services\n const { getFormMetadata } = formsService\n\n // Warn the user if the form has no notification email set only on start page and summary page\n if ([startPath, summaryPath].includes(path) && !isForceAccess) {\n const { notificationEmail } = await getFormMetadata(params.slug)\n return !notificationEmail\n }\n\n return false\n }\n\n /**\n * Get the back link for a given progress.\n */\n protected getBackLink(\n request: FormContextRequest,\n context: FormContext\n ): BackLink | undefined {\n const { pageDef } = this\n const { path, query } = request\n const { returnUrl } = query\n const { paths } = context\n\n const itemId = this.getItemId(request)\n\n // Check answers back link\n if (returnUrl) {\n return {\n text:\n hasRepeater(pageDef) && itemId\n ? 'Go back to add another'\n : 'Go back to check answers',\n href: returnUrl\n }\n }\n\n // Item delete pages etc\n const backPath =\n itemId && !path.endsWith(itemId)\n ? paths.at(-1) // Back to main page\n : paths.at(-2) // Back to previous page\n\n // No back link\n if (!backPath) {\n return\n }\n\n // Default back link\n return {\n text: 'Back',\n href: this.getHref(backPath)\n }\n }\n\n makePostRouteHandler() {\n return async (\n request: FormRequestPayload,\n context: FormContext,\n h: FormResponseToolkit\n ) => {\n const { collection, viewName, model } = this\n const { isForceAccess, state, evaluationState } = context\n const action = request.payload.action\n\n if (action?.startsWith(FormAction.External)) {\n return await this.dispatchExternal(request, h, context)\n }\n\n /**\n * If there are any errors, render the page with the parsed errors\n * @todo Refactor to match POST REDIRECT GET pattern\n */\n if (context.errors || isForceAccess) {\n const viewModel = this.getViewModel(request, context)\n viewModel.errors = collection.getViewErrors(viewModel.errors)\n\n // Filter our components based on their conditions using our evaluated state\n viewModel.components = this.filterConditionalComponents(\n viewModel,\n model,\n evaluationState\n )\n\n return h.view(viewName, viewModel)\n }\n\n // Save state\n await this.setState(request, state)\n\n // Check if this is a save-and-exit action\n if (action === FormAction.SaveAndExit) {\n return this.handleSaveAndExit(request, context, h)\n }\n\n // Proceed to the next page\n return this.proceed(request, h, this.getNextPath(context))\n }\n }\n\n private async dispatchExternal(\n request: FormRequestPayload,\n h: FormResponseToolkit,\n context: FormContext\n ) {\n const { externalComponents } = getComponentsByType()\n const action = request.payload.action ?? ''\n\n // Find the external action and arguments\n // `external-{componentName}--{argname1}:{argvalue1}--{argname2}:{argvalue2}`\n // E.g. external-abcdef--amount:10--step:manual\n const externalActionsWithArgs = action\n .slice(`${FormAction.External}-`.length)\n .split('--')\n\n const externalActionArgs = externalActionsWithArgs\n .slice(1)\n .map((arg) => arg.split(':'))\n\n const args = Object.fromEntries(externalActionArgs) as Record<\n string,\n string\n >\n\n const componentName = externalActionsWithArgs[0]\n const component = this.model.componentDefMap.get(componentName)\n const componentType = component?.type\n\n if (!componentType) {\n throw Boom.internal(\n `External component of type ${componentType} not found`\n )\n }\n\n const selectedComponent = externalComponents.get(componentType)\n\n if (!selectedComponent) {\n throw Boom.internal(`External component ${componentName} not found`)\n }\n\n // Stash payload without crumb and action\n const stashedPayload = {\n ...context.payload,\n crumb: undefined,\n action: undefined\n }\n request.yar.flash(EXTERNAL_STATE_PAYLOAD, stashedPayload, true)\n\n // Clear any previous state appendage\n request.yar.clear(EXTERNAL_STATE_APPENDAGE)\n\n // Determine if this is a live form (not preview/draft)\n const { state, isPreview } = checkFormStatus(request.params)\n const isLive = state === FormStatus.Live\n\n return await selectedComponent.dispatcher(request, h, {\n component,\n controller: this,\n sourceUrl: `${request.url.pathname}${request.url.search}`,\n actionArgs: args,\n isLive,\n isPreview\n })\n }\n\n proceed(\n request: FormContextRequest,\n h: FormResponseToolkit,\n nextPath?: string\n ) {\n const nextUrl = nextPath\n ? this.getHref(nextPath) // Redirect to next page\n : this.href // Redirect to current page (refresh)\n\n return proceed(request, h, nextUrl)\n }\n\n /**\n * Handle save-and-exit action\n */\n handleSaveAndExit(\n request: FormRequestPayload,\n context: FormContext,\n h: FormResponseToolkit\n ) {\n const saveAndExit = getSaveAndExitHelpers(request.server)\n\n if (!saveAndExit) {\n throw Boom.internal('Server misconfigured for save and exit')\n }\n\n return saveAndExit(request, h, context)\n }\n\n /**\n * {@link https://hapi.dev/api/?v=20.1.2#route-options}\n */\n get getRouteOptions(): RouteOptions<FormRequestRefs> {\n return {\n ext: {\n onPostHandler: {\n method(_request, h) {\n return h.continue\n }\n }\n }\n }\n }\n\n /**\n * {@link https://hapi.dev/api/?v=20.1.2#route-options}\n */\n get postRouteOptions(): RouteOptions<FormRequestPayloadRefs> {\n return {\n payload: {\n parse: true,\n maxBytes: Number.MAX_SAFE_INTEGER,\n failAction: 'ignore'\n },\n ext: {\n onPostHandler: {\n method(_request, h) {\n return h.continue\n }\n }\n }\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"QuestionPageController.js","names":["ComponentType","ControllerType","Engine","hasComponents","hasNext","hasRepeater","isPaymentPage","Boom","COMPONENT_STATE_ERROR","EXTERNAL_STATE_APPENDAGE","EXTERNAL_STATE_PAYLOAD","PAYMENT_EXPIRED_NOTIFICATION","ComponentCollection","PaymentField","checkFormStatus","getCacheService","getErrors","getSaveAndExitHelpers","normalisePath","proceed","PageController","prefillStateFromQueryParameters","getComponentsByType","formatCurrency","FormAction","FormStatus","actionSchema","crumbSchema","paramsSchema","merge","QuestionPageController","collection","errorSummaryTitle","allowSaveAndExit","constructor","model","pageDef","components","page","formSchema","keys","crumb","action","next","def","filter","path","linkPath","pages","some","pagePath","allowContinue","engine","V2","controller","Terminal","length","getItemId","request","itemId","getFormParams","params","getViewModel","context","translator","viewModel","payload","errors","t","tPage","tSection","showTitle","sectionTitle","pageTitle","title","section","hideTitle","formComponents","isFormComponent","fieldset","label","isPageHeading","labelOrLegend","legend","size","classes","isOptional","fields","at","options","required","text","comp","paymentField","find","f","resolvedAmount","resolveAmount","evaluationState","amount","hasIncompletePayment","paymentState","preAuth","status","backLink","getBackLink","shouldShowSaveAndExit","server","showSubmitButton","getRelevantPath","paths","startPath","getStartPath","relevantPath","getNextPath","summaryPath","getSummaryPath","statusPath","getStatusPath","defaultPath","undefined","pageIndex","indexOf","nextPage","slice","condition","conditionResult","fn","nextLink","link","conditions","getFormDataFromState","state","result","validate","abortEarly","stripUnknown","value","getStateFromValidForm","details","getState","query","cacheService","setState","mergeState","update","updated","filterConditionalComponents","filtered","component","content","type","Details","map","evaluatedComponent","Array","isArray","item","items","makeGetRouteHandler","h","viewName","getTranslator","redirect","url","pathname","getViewErrors","flashedError","yar","flash","flashedErrors","concat","paymentExpiredFlash","showPaymentExpiredNotification","hasMissingNotificationEmail","view","isForceAccess","formsService","services","getFormMetadata","includes","notificationEmail","slug","returnUrl","href","backPath","endsWith","getHref","makePostRouteHandler","startsWith","External","dispatchExternal","SaveAndExit","handleSaveAndExit","externalComponents","externalActionsWithArgs","split","externalActionArgs","arg","args","Object","fromEntries","componentName","componentDefMap","get","componentType","internal","selectedComponent","stashedPayload","clear","isPreview","isLive","Live","dispatcher","sourceUrl","search","actionArgs","nextPath","nextUrl","saveAndExit","getRouteOptions","ext","onPostHandler","method","_request","continue","postRouteOptions","parse","maxBytes","Number","MAX_SAFE_INTEGER","failAction"],"sources":["../../../../../src/server/plugins/engine/pageControllers/QuestionPageController.ts"],"sourcesContent":["import {\n ComponentType,\n ControllerType,\n Engine,\n hasComponents,\n hasNext,\n hasRepeater,\n isPaymentPage,\n type Link,\n type Page\n} from '@defra/forms-model'\nimport Boom from '@hapi/boom'\nimport { type RouteOptions } from '@hapi/hapi'\nimport { type ValidationErrorItem } from 'joi'\n\nimport {\n COMPONENT_STATE_ERROR,\n EXTERNAL_STATE_APPENDAGE,\n EXTERNAL_STATE_PAYLOAD,\n PAYMENT_EXPIRED_NOTIFICATION\n} from '~/src/server/constants.js'\nimport { ComponentCollection } from '~/src/server/plugins/engine/components/ComponentCollection.js'\nimport { PaymentField } from '~/src/server/plugins/engine/components/PaymentField.js'\nimport { type BackLink } from '~/src/server/plugins/engine/components/types.js'\nimport {\n checkFormStatus,\n getCacheService,\n getErrors,\n getSaveAndExitHelpers,\n normalisePath,\n proceed\n} from '~/src/server/plugins/engine/helpers.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport { type FormModel } from '~/src/server/plugins/engine/models/index.js'\nimport { PageController } from '~/src/server/plugins/engine/pageControllers/PageController.js'\nimport { prefillStateFromQueryParameters } from '~/src/server/plugins/engine/pageControllers/helpers/state.js'\nimport {\n type AnyFormRequest,\n type FormContext,\n type FormContextRequest,\n type FormPageViewModel,\n type FormPayload,\n type FormPayloadParams,\n type FormState,\n type FormStateValue,\n type FormSubmissionState\n} from '~/src/server/plugins/engine/types.js'\nimport { getComponentsByType } from '~/src/server/plugins/engine/validationHelpers.js'\nimport { formatCurrency } from '~/src/server/plugins/payment/helper.js'\nimport {\n FormAction,\n FormStatus,\n type FormRequest,\n type FormRequestPayload,\n type FormRequestPayloadRefs,\n type FormRequestRefs,\n type FormResponseToolkit\n} from '~/src/server/routes/types.js'\nimport {\n actionSchema,\n crumbSchema,\n paramsSchema\n} from '~/src/server/schemas/index.js'\nimport { merge } from '~/src/server/services/cacheService.js'\n\nexport class QuestionPageController extends PageController {\n collection: ComponentCollection\n errorSummaryTitle = 'There is a problem'\n allowSaveAndExit = true\n\n constructor(model: FormModel, pageDef: Page) {\n super(model, pageDef)\n\n // Components collection\n this.collection = new ComponentCollection(\n hasComponents(pageDef) ? pageDef.components : [],\n { model, page: this }\n )\n\n this.collection.formSchema = this.collection.formSchema.keys({\n crumb: crumbSchema,\n action: actionSchema\n })\n }\n\n get next(): Link[] {\n const { def, pageDef } = this\n\n if (!hasNext(pageDef)) {\n return []\n }\n\n // Remove stale links\n return pageDef.next.filter(({ path }) => {\n const linkPath = normalisePath(path)\n\n return def.pages.some((page) => {\n const pagePath = normalisePath(page.path)\n return pagePath === linkPath\n })\n })\n }\n\n get allowContinue(): boolean {\n if (this.model.engine === Engine.V2) {\n return this.pageDef.controller !== ControllerType.Terminal\n }\n\n return this.next.length > 0\n }\n\n getItemId(request?: FormContextRequest) {\n const { itemId } = this.getFormParams(request)\n return itemId ?? request?.params.itemId\n }\n\n /**\n * Used for mapping form payloads and errors to govuk-frontend's template api, so a page can be rendered\n * @param request - the hapi request\n * @param context - the form context\n * @param translator - optional per-request translator pair\n */\n getViewModel(\n request: FormContextRequest,\n context: FormContext,\n translator: Translator\n ): FormPageViewModel {\n const { collection, viewModel } = this\n const { payload, errors } = context\n\n const { t, tPage, tSection } = translator\n\n let { showTitle, sectionTitle } = viewModel\n\n let pageTitle = this.pageDef.title ? tPage(this.pageDef, 'title') : ''\n\n if (this.section) {\n sectionTitle =\n this.section.hideTitle !== true ? tSection(this.section, 'title') : ''\n }\n\n const components = collection.getViewModel({ payload, errors, translator })\n const formComponents = components.filter(\n ({ isFormComponent }) => isFormComponent\n )\n\n // Single form component? Hide title and customise label or legend instead\n if (formComponents.length === 1) {\n const { model } = formComponents[0]\n const { fieldset, label } = model\n\n // Set as page heading when not following other content\n const isPageHeading = formComponents[0] === components[0]\n\n // Check for legend or label\n const labelOrLegend = fieldset?.legend ?? label\n\n // Use legend or label as page heading\n if (labelOrLegend) {\n const size = isPageHeading ? 'l' : 'm'\n\n labelOrLegend.classes =\n labelOrLegend === label\n ? `govuk-label--${size}`\n : `govuk-fieldset__legend--${size}`\n\n if (isPageHeading) {\n labelOrLegend.isPageHeading = isPageHeading\n\n // Check for optional in label\n const isOptional =\n this.collection.fields.at(0)?.options.required === false\n\n if (!pageTitle) {\n pageTitle = labelOrLegend.text\n }\n labelOrLegend.text = isOptional\n ? `${pageTitle} ${t('common.optional')}`\n : pageTitle\n }\n\n // Fallback if still no pageTitle set\n if (!pageTitle) {\n pageTitle = labelOrLegend.text\n }\n }\n\n showTitle = !isPageHeading\n } else if (formComponents.length > 1) {\n // When there is more than one form component,\n // adjust the label/legends to give equal prominence\n for (const { model } of formComponents) {\n if (model.fieldset?.legend) {\n model.fieldset.legend.classes = 'govuk-fieldset__legend--m'\n }\n if (model.label) {\n model.label.classes = 'govuk-label--m'\n }\n }\n }\n\n // Override payment amount display with resolved conditional amount\n // getViewModel() only has the current page's payload, not full form state.\n // The full state is available via context.evaluationState.\n for (const comp of components) {\n if ('amount' in comp.model && 'paymentState' in comp.model) {\n const paymentField = this.collection.fields.find(\n (f): f is PaymentField => f instanceof PaymentField\n )\n if (paymentField) {\n const resolvedAmount = PaymentField.resolveAmount(\n paymentField.options,\n this.model,\n context.evaluationState\n )\n comp.model.amount = formatCurrency(resolvedAmount)\n }\n }\n }\n\n const hasIncompletePayment = components.some(({ model }) => {\n if ('paymentState' in model) {\n const paymentState = model.paymentState as\n | { preAuth?: { status?: string } }\n | undefined\n return !paymentState?.preAuth?.status\n }\n return false\n })\n\n return {\n ...viewModel,\n backLink: this.getBackLink(request, context, t),\n context,\n pageTitle,\n sectionTitle,\n showTitle,\n components,\n errors,\n allowSaveAndExit:\n this.shouldShowSaveAndExit(request.server) &&\n !isPaymentPage(this.pageDef),\n showSubmitButton: !hasIncompletePayment\n }\n }\n\n getRelevantPath(request: AnyFormRequest, context: FormContext) {\n const { paths } = context\n\n const startPath = this.getStartPath()\n const relevantPath = paths.at(-1) ?? startPath\n\n return !paths.length\n ? startPath // First possible path\n : relevantPath // Last possible path\n }\n\n /**\n * Apply conditions to evaluation state to determine next page path\n */\n getNextPath(context: FormContext) {\n const { model, next, path } = this\n const { evaluationState } = context\n\n const summaryPath = this.getSummaryPath()\n const statusPath = this.getStatusPath()\n\n // Walk from summary page (no next links) to status page\n let defaultPath = path === summaryPath ? statusPath : undefined\n\n if (model.engine === Engine.V2) {\n if (this.pageDef.controller !== ControllerType.Terminal) {\n const { pages } = this.model\n const pageIndex = pages.indexOf(this)\n\n // The \"next\" page is the first found after the current which is\n // either unconditional or has a condition that evaluates to \"true\"\n const nextPage = pages.slice(pageIndex + 1).find((page) => {\n const { condition } = page\n\n if (condition) {\n const conditionResult = condition.fn(evaluationState)\n\n if (!conditionResult) {\n return false\n }\n }\n\n // Skip payment pages in the normal page walk.\n // Users reach the payment page via \"Pay and submit\" on CYA,\n // not by navigating forward through the form.\n if (isPaymentPage(page.pageDef)) {\n return false\n }\n\n return true\n })\n\n return nextPage?.path ?? defaultPath\n } else {\n return defaultPath\n }\n }\n\n const nextLink = next.find((link) => {\n const { condition } = link\n\n if (condition) {\n return model.conditions[condition]?.fn(evaluationState) ?? false\n }\n\n defaultPath = link.path\n return false\n })\n\n return nextLink?.path ?? defaultPath\n }\n\n /**\n * Gets the form payload (from state) for this page only\n */\n getFormDataFromState(\n request: FormContextRequest | undefined,\n state: FormSubmissionState\n ): FormPayload {\n const { collection } = this\n\n // Form params from request\n const params = this.getFormParams(request)\n\n // Form payload from state\n const payload = collection.getFormDataFromState(state)\n\n return {\n ...params,\n ...payload\n }\n }\n\n /**\n * Gets form params (from payload) for this page only\n */\n getFormParams(request?: FormContextRequest): FormPayloadParams {\n const { payload } = request ?? {}\n\n const result = paramsSchema.validate(payload, {\n abortEarly: false,\n stripUnknown: true\n })\n\n return result.value as FormPayloadParams\n }\n\n getStateFromValidForm(\n request: FormContextRequest,\n state: FormSubmissionState,\n payload: FormPayload\n ): FormState {\n return this.collection.getStateFromValidForm(payload)\n }\n\n getErrors(details?: ValidationErrorItem[]) {\n return getErrors(details)\n }\n\n async getState(request: AnyFormRequest) {\n const { query } = request\n\n // Skip get for preview URL direct access\n if ('force' in query) {\n return {}\n }\n\n const cacheService = getCacheService(request.server)\n\n return cacheService.getState(request)\n }\n\n async setState(request: AnyFormRequest, state: FormSubmissionState) {\n const { query } = request\n\n // Skip set for preview URL direct access\n if ('force' in query) {\n return state\n }\n\n const cacheService = getCacheService(request.server)\n\n return cacheService.setState(request, state)\n }\n\n async mergeState(\n request: AnyFormRequest,\n state: FormSubmissionState,\n update: object\n ) {\n const { query } = request\n\n // Merge state before set\n const updated = merge(state, update)\n\n // Skip set for preview URL direct access\n if ('force' in query) {\n return updated\n }\n\n const cacheService = getCacheService(request.server)\n\n return cacheService.setState(request, updated)\n }\n\n filterConditionalComponents(\n viewModel: FormPageViewModel,\n model: FormModel,\n evaluationState: Partial<Record<string, FormStateValue>>\n ) {\n // Filter our components based on their conditions using our evaluated state\n let filtered = viewModel.components.filter((component) => {\n if (\n (!!component.model.content ||\n component.type === ComponentType.Details) &&\n component.model.condition\n ) {\n const condition = model.conditions[component.model.condition]\n return condition?.fn(evaluationState)\n }\n return true\n })\n\n /**\n * For conditional reveal components (which we no longer support until GDS resolves the related accessibility issues {@link https://github.com/alphagov/govuk-frontend/issues/1991}\n */\n filtered = filtered.map((component) => {\n const evaluatedComponent = component\n const content = evaluatedComponent.model.content\n if (Array.isArray(content)) {\n evaluatedComponent.model.content = content.filter((item) =>\n item.condition\n ? model.conditions[item.condition]?.fn(evaluationState)\n : true\n )\n }\n // apply condition to items for radios, checkboxes etc\n const items = evaluatedComponent.model.items\n\n if (Array.isArray(items)) {\n evaluatedComponent.model.items = items.filter((item) =>\n item.condition\n ? model.conditions[item.condition]?.fn(evaluationState)\n : true\n )\n }\n\n return evaluatedComponent\n })\n\n return filtered\n }\n\n makeGetRouteHandler() {\n return async (\n request: FormRequest,\n context: FormContext,\n h: FormResponseToolkit\n ) => {\n const { collection, model, viewName } = this\n const { evaluationState } = context\n\n const translator = this.getTranslator(request)\n const { t } = translator\n\n // Copy any URL params into the form state (if not already done so)\n if (await prefillStateFromQueryParameters(request, this)) {\n // Forward to same page without query string\n return h.redirect(request.url.pathname)\n }\n\n const viewModel = this.getViewModel(request, context, translator)\n viewModel.errors = collection.getViewErrors(translator, viewModel.errors)\n\n const flashedError = request.yar.flash(COMPONENT_STATE_ERROR)\n const flashedErrors = !Array.isArray(flashedError) ? [flashedError] : []\n\n viewModel.errors = (viewModel.errors ?? []).concat(flashedErrors)\n\n const paymentExpiredFlash = request.yar.flash(\n PAYMENT_EXPIRED_NOTIFICATION\n )\n viewModel.showPaymentExpiredNotification =\n !Array.isArray(paymentExpiredFlash)\n\n /**\n * Content components can be hidden based on a condition. If the condition evaluates to true, it is safe to be kept, otherwise discard it\n */\n\n // Filter our components based on their conditions using our evaluated state\n viewModel.components = this.filterConditionalComponents(\n viewModel,\n model,\n evaluationState\n )\n\n viewModel.hasMissingNotificationEmail =\n await this.hasMissingNotificationEmail(request, context)\n\n return h.view(viewName, {\n ...viewModel,\n t\n })\n }\n }\n\n async hasMissingNotificationEmail(\n request: FormRequest,\n context: FormContext\n ) {\n const { path } = this\n const { params } = request\n const { isForceAccess } = context\n\n const startPath = this.getStartPath()\n const summaryPath = this.getSummaryPath()\n const { formsService } = this.model.services\n const { getFormMetadata } = formsService\n\n // Warn the user if the form has no notification email set only on start page and summary page\n if ([startPath, summaryPath].includes(path) && !isForceAccess) {\n const { notificationEmail } = await getFormMetadata(params.slug)\n return !notificationEmail\n }\n\n return false\n }\n\n /**\n * Get the back link for a given progress.\n */\n protected getBackLink(\n request: FormContextRequest,\n context: FormContext,\n t: (key: string, opts?: Record<string, unknown>) => string\n ): BackLink | undefined {\n const { pageDef } = this\n const { path, query } = request\n const { returnUrl } = query\n const { paths } = context\n\n const itemId = this.getItemId(request)\n\n // Check answers back link\n if (returnUrl) {\n return {\n text:\n hasRepeater(pageDef) && itemId\n ? t('pages.question.backToAddAnother')\n : t('pages.question.backToCheckAnswers'),\n href: returnUrl\n }\n }\n\n // Item delete pages etc\n const backPath =\n itemId && !path.endsWith(itemId)\n ? paths.at(-1) // Back to main page\n : paths.at(-2) // Back to previous page\n\n // No back link\n if (!backPath) {\n return\n }\n\n // Default back link\n return {\n text: t('common.back'),\n href: this.getHref(backPath)\n }\n }\n\n makePostRouteHandler() {\n return async (\n request: FormRequestPayload,\n context: FormContext,\n h: FormResponseToolkit\n ) => {\n const { collection, viewName, model } = this\n const { isForceAccess, state, evaluationState } = context\n const action = request.payload.action\n\n const translator = this.getTranslator(request)\n const { t } = translator\n\n if (action?.startsWith(FormAction.External)) {\n return await this.dispatchExternal(request, h, context)\n }\n\n /**\n * If there are any errors, render the page with the parsed errors\n * @todo Refactor to match POST REDIRECT GET pattern\n */\n if (context.errors || isForceAccess) {\n const viewModel = this.getViewModel(request, context, translator)\n viewModel.errors = collection.getViewErrors(\n translator,\n viewModel.errors\n )\n\n // Filter our components based on their conditions using our evaluated state\n viewModel.components = this.filterConditionalComponents(\n viewModel,\n model,\n evaluationState\n )\n\n return h.view(viewName, {\n ...viewModel,\n t\n })\n }\n\n // Save state\n await this.setState(request, state)\n\n // Check if this is a save-and-exit action\n if (action === FormAction.SaveAndExit) {\n return this.handleSaveAndExit(request, context, h)\n }\n\n // Proceed to the next page\n return this.proceed(request, h, this.getNextPath(context))\n }\n }\n\n private async dispatchExternal(\n request: FormRequestPayload,\n h: FormResponseToolkit,\n context: FormContext\n ) {\n const { externalComponents } = getComponentsByType()\n const action = request.payload.action ?? ''\n\n // Find the external action and arguments\n // `external-{componentName}--{argname1}:{argvalue1}--{argname2}:{argvalue2}`\n // E.g. external-abcdef--amount:10--step:manual\n const externalActionsWithArgs = action\n .slice(`${FormAction.External}-`.length)\n .split('--')\n\n const externalActionArgs = externalActionsWithArgs\n .slice(1)\n .map((arg) => arg.split(':'))\n\n const args = Object.fromEntries(externalActionArgs) as Record<\n string,\n string\n >\n\n const componentName = externalActionsWithArgs[0]\n const component = this.model.componentDefMap.get(componentName)\n const componentType = component?.type\n\n if (!componentType) {\n throw Boom.internal(\n `External component of type ${componentType} not found`\n )\n }\n\n const selectedComponent = externalComponents.get(componentType)\n\n if (!selectedComponent) {\n throw Boom.internal(`External component ${componentName} not found`)\n }\n\n // Stash payload without crumb and action\n const stashedPayload = {\n ...context.payload,\n crumb: undefined,\n action: undefined\n }\n request.yar.flash(EXTERNAL_STATE_PAYLOAD, stashedPayload, true)\n\n // Clear any previous state appendage\n request.yar.clear(EXTERNAL_STATE_APPENDAGE)\n\n // Determine if this is a live form (not preview/draft)\n const { state, isPreview } = checkFormStatus(request.params)\n const isLive = state === FormStatus.Live\n\n return await selectedComponent.dispatcher(request, h, {\n component,\n controller: this,\n sourceUrl: `${request.url.pathname}${request.url.search}`,\n actionArgs: args,\n isLive,\n isPreview\n })\n }\n\n proceed(\n request: FormContextRequest,\n h: FormResponseToolkit,\n nextPath?: string\n ) {\n const nextUrl = nextPath\n ? this.getHref(nextPath) // Redirect to next page\n : this.href // Redirect to current page (refresh)\n\n return proceed(request, h, nextUrl)\n }\n\n /**\n * Handle save-and-exit action\n */\n handleSaveAndExit(\n request: FormRequestPayload,\n context: FormContext,\n h: FormResponseToolkit\n ) {\n const saveAndExit = getSaveAndExitHelpers(request.server)\n\n if (!saveAndExit) {\n throw Boom.internal('Server misconfigured for save and exit')\n }\n\n return saveAndExit(request, h, context)\n }\n\n /**\n * {@link https://hapi.dev/api/?v=20.1.2#route-options}\n */\n get getRouteOptions(): RouteOptions<FormRequestRefs> {\n return {\n ext: {\n onPostHandler: {\n method(_request, h) {\n return h.continue\n }\n }\n }\n }\n }\n\n /**\n * {@link https://hapi.dev/api/?v=20.1.2#route-options}\n */\n get postRouteOptions(): RouteOptions<FormRequestPayloadRefs> {\n return {\n payload: {\n parse: true,\n maxBytes: Number.MAX_SAFE_INTEGER,\n failAction: 'ignore'\n },\n ext: {\n onPostHandler: {\n method(_request, h) {\n return h.continue\n }\n }\n }\n }\n }\n}\n"],"mappings":"AAAA,SACEA,aAAa,EACbC,cAAc,EACdC,MAAM,EACNC,aAAa,EACbC,OAAO,EACPC,WAAW,EACXC,aAAa,QAGR,oBAAoB;AAC3B,OAAOC,IAAI,MAAM,YAAY;AAI7B,SACEC,qBAAqB,EACrBC,wBAAwB,EACxBC,sBAAsB,EACtBC,4BAA4B;AAE9B,SAASC,mBAAmB;AAC5B,SAASC,YAAY;AAErB,SACEC,eAAe,EACfC,eAAe,EACfC,SAAS,EACTC,qBAAqB,EACrBC,aAAa,EACbC,OAAO;AAIT,SAASC,cAAc;AACvB,SAASC,+BAA+B;AAYxC,SAASC,mBAAmB;AAC5B,SAASC,cAAc;AACvB,SACEC,UAAU,EACVC,UAAU;AAOZ,SACEC,YAAY,EACZC,WAAW,EACXC,YAAY;AAEd,SAASC,KAAK;AAEd,OAAO,MAAMC,sBAAsB,SAASV,cAAc,CAAC;EACzDW,UAAU;EACVC,iBAAiB,GAAG,oBAAoB;EACxCC,gBAAgB,GAAG,IAAI;EAEvBC,WAAWA,CAACC,KAAgB,EAAEC,OAAa,EAAE;IAC3C,KAAK,CAACD,KAAK,EAAEC,OAAO,CAAC;;IAErB;IACA,IAAI,CAACL,UAAU,GAAG,IAAInB,mBAAmB,CACvCT,aAAa,CAACiC,OAAO,CAAC,GAAGA,OAAO,CAACC,UAAU,GAAG,EAAE,EAChD;MAAEF,KAAK;MAAEG,IAAI,EAAE;IAAK,CACtB,CAAC;IAED,IAAI,CAACP,UAAU,CAACQ,UAAU,GAAG,IAAI,CAACR,UAAU,CAACQ,UAAU,CAACC,IAAI,CAAC;MAC3DC,KAAK,EAAEd,WAAW;MAClBe,MAAM,EAAEhB;IACV,CAAC,CAAC;EACJ;EAEA,IAAIiB,IAAIA,CAAA,EAAW;IACjB,MAAM;MAAEC,GAAG;MAAER;IAAQ,CAAC,GAAG,IAAI;IAE7B,IAAI,CAAChC,OAAO,CAACgC,OAAO,CAAC,EAAE;MACrB,OAAO,EAAE;IACX;;IAEA;IACA,OAAOA,OAAO,CAACO,IAAI,CAACE,MAAM,CAAC,CAAC;MAAEC;IAAK,CAAC,KAAK;MACvC,MAAMC,QAAQ,GAAG7B,aAAa,CAAC4B,IAAI,CAAC;MAEpC,OAAOF,GAAG,CAACI,KAAK,CAACC,IAAI,CAAEX,IAAI,IAAK;QAC9B,MAAMY,QAAQ,GAAGhC,aAAa,CAACoB,IAAI,CAACQ,IAAI,CAAC;QACzC,OAAOI,QAAQ,KAAKH,QAAQ;MAC9B,CAAC,CAAC;IACJ,CAAC,CAAC;EACJ;EAEA,IAAII,aAAaA,CAAA,EAAY;IAC3B,IAAI,IAAI,CAAChB,KAAK,CAACiB,MAAM,KAAKlD,MAAM,CAACmD,EAAE,EAAE;MACnC,OAAO,IAAI,CAACjB,OAAO,CAACkB,UAAU,KAAKrD,cAAc,CAACsD,QAAQ;IAC5D;IAEA,OAAO,IAAI,CAACZ,IAAI,CAACa,MAAM,GAAG,CAAC;EAC7B;EAEAC,SAASA,CAACC,OAA4B,EAAE;IACtC,MAAM;MAAEC;IAAO,CAAC,GAAG,IAAI,CAACC,aAAa,CAACF,OAAO,CAAC;IAC9C,OAAOC,MAAM,IAAID,OAAO,EAAEG,MAAM,CAACF,MAAM;EACzC;;EAEA;AACF;AACA;AACA;AACA;AACA;EACEG,YAAYA,CACVJ,OAA2B,EAC3BK,OAAoB,EACpBC,UAAsB,EACH;IACnB,MAAM;MAAEjC,UAAU;MAAEkC;IAAU,CAAC,GAAG,IAAI;IACtC,MAAM;MAAEC,OAAO;MAAEC;IAAO,CAAC,GAAGJ,OAAO;IAEnC,MAAM;MAAEK,CAAC;MAAEC,KAAK;MAAEC;IAAS,CAAC,GAAGN,UAAU;IAEzC,IAAI;MAAEO,SAAS;MAAEC;IAAa,CAAC,GAAGP,SAAS;IAE3C,IAAIQ,SAAS,GAAG,IAAI,CAACrC,OAAO,CAACsC,KAAK,GAAGL,KAAK,CAAC,IAAI,CAACjC,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE;IAEtE,IAAI,IAAI,CAACuC,OAAO,EAAE;MAChBH,YAAY,GACV,IAAI,CAACG,OAAO,CAACC,SAAS,KAAK,IAAI,GAAGN,QAAQ,CAAC,IAAI,CAACK,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE;IAC1E;IAEA,MAAMtC,UAAU,GAAGN,UAAU,CAAC+B,YAAY,CAAC;MAAEI,OAAO;MAAEC,MAAM;MAAEH;IAAW,CAAC,CAAC;IAC3E,MAAMa,cAAc,GAAGxC,UAAU,CAACQ,MAAM,CACtC,CAAC;MAAEiC;IAAgB,CAAC,KAAKA,eAC3B,CAAC;;IAED;IACA,IAAID,cAAc,CAACrB,MAAM,KAAK,CAAC,EAAE;MAC/B,MAAM;QAAErB;MAAM,CAAC,GAAG0C,cAAc,CAAC,CAAC,CAAC;MACnC,MAAM;QAAEE,QAAQ;QAAEC;MAAM,CAAC,GAAG7C,KAAK;;MAEjC;MACA,MAAM8C,aAAa,GAAGJ,cAAc,CAAC,CAAC,CAAC,KAAKxC,UAAU,CAAC,CAAC,CAAC;;MAEzD;MACA,MAAM6C,aAAa,GAAGH,QAAQ,EAAEI,MAAM,IAAIH,KAAK;;MAE/C;MACA,IAAIE,aAAa,EAAE;QACjB,MAAME,IAAI,GAAGH,aAAa,GAAG,GAAG,GAAG,GAAG;QAEtCC,aAAa,CAACG,OAAO,GACnBH,aAAa,KAAKF,KAAK,GACnB,gBAAgBI,IAAI,EAAE,GACtB,2BAA2BA,IAAI,EAAE;QAEvC,IAAIH,aAAa,EAAE;UACjBC,aAAa,CAACD,aAAa,GAAGA,aAAa;;UAE3C;UACA,MAAMK,UAAU,GACd,IAAI,CAACvD,UAAU,CAACwD,MAAM,CAACC,EAAE,CAAC,CAAC,CAAC,EAAEC,OAAO,CAACC,QAAQ,KAAK,KAAK;UAE1D,IAAI,CAACjB,SAAS,EAAE;YACdA,SAAS,GAAGS,aAAa,CAACS,IAAI;UAChC;UACAT,aAAa,CAACS,IAAI,GAAGL,UAAU,GAC3B,GAAGb,SAAS,IAAIL,CAAC,CAAC,iBAAiB,CAAC,EAAE,GACtCK,SAAS;QACf;;QAEA;QACA,IAAI,CAACA,SAAS,EAAE;UACdA,SAAS,GAAGS,aAAa,CAACS,IAAI;QAChC;MACF;MAEApB,SAAS,GAAG,CAACU,aAAa;IAC5B,CAAC,MAAM,IAAIJ,cAAc,CAACrB,MAAM,GAAG,CAAC,EAAE;MACpC;MACA;MACA,KAAK,MAAM;QAAErB;MAAM,CAAC,IAAI0C,cAAc,EAAE;QACtC,IAAI1C,KAAK,CAAC4C,QAAQ,EAAEI,MAAM,EAAE;UAC1BhD,KAAK,CAAC4C,QAAQ,CAACI,MAAM,CAACE,OAAO,GAAG,2BAA2B;QAC7D;QACA,IAAIlD,KAAK,CAAC6C,KAAK,EAAE;UACf7C,KAAK,CAAC6C,KAAK,CAACK,OAAO,GAAG,gBAAgB;QACxC;MACF;IACF;;IAEA;IACA;IACA;IACA,KAAK,MAAMO,IAAI,IAAIvD,UAAU,EAAE;MAC7B,IAAI,QAAQ,IAAIuD,IAAI,CAACzD,KAAK,IAAI,cAAc,IAAIyD,IAAI,CAACzD,KAAK,EAAE;QAC1D,MAAM0D,YAAY,GAAG,IAAI,CAAC9D,UAAU,CAACwD,MAAM,CAACO,IAAI,CAC7CC,CAAC,IAAwBA,CAAC,YAAYlF,YACzC,CAAC;QACD,IAAIgF,YAAY,EAAE;UAChB,MAAMG,cAAc,GAAGnF,YAAY,CAACoF,aAAa,CAC/CJ,YAAY,CAACJ,OAAO,EACpB,IAAI,CAACtD,KAAK,EACV4B,OAAO,CAACmC,eACV,CAAC;UACDN,IAAI,CAACzD,KAAK,CAACgE,MAAM,GAAG5E,cAAc,CAACyE,cAAc,CAAC;QACpD;MACF;IACF;IAEA,MAAMI,oBAAoB,GAAG/D,UAAU,CAACY,IAAI,CAAC,CAAC;MAAEd;IAAM,CAAC,KAAK;MAC1D,IAAI,cAAc,IAAIA,KAAK,EAAE;QAC3B,MAAMkE,YAAY,GAAGlE,KAAK,CAACkE,YAEd;QACb,OAAO,CAACA,YAAY,EAAEC,OAAO,EAAEC,MAAM;MACvC;MACA,OAAO,KAAK;IACd,CAAC,CAAC;IAEF,OAAO;MACL,GAAGtC,SAAS;MACZuC,QAAQ,EAAE,IAAI,CAACC,WAAW,CAAC/C,OAAO,EAAEK,OAAO,EAAEK,CAAC,CAAC;MAC/CL,OAAO;MACPU,SAAS;MACTD,YAAY;MACZD,SAAS;MACTlC,UAAU;MACV8B,MAAM;MACNlC,gBAAgB,EACd,IAAI,CAACyE,qBAAqB,CAAChD,OAAO,CAACiD,MAAM,CAAC,IAC1C,CAACrG,aAAa,CAAC,IAAI,CAAC8B,OAAO,CAAC;MAC9BwE,gBAAgB,EAAE,CAACR;IACrB,CAAC;EACH;EAEAS,eAAeA,CAACnD,OAAuB,EAAEK,OAAoB,EAAE;IAC7D,MAAM;MAAE+C;IAAM,CAAC,GAAG/C,OAAO;IAEzB,MAAMgD,SAAS,GAAG,IAAI,CAACC,YAAY,CAAC,CAAC;IACrC,MAAMC,YAAY,GAAGH,KAAK,CAACtB,EAAE,CAAC,CAAC,CAAC,CAAC,IAAIuB,SAAS;IAE9C,OAAO,CAACD,KAAK,CAACtD,MAAM,GAChBuD,SAAS,CAAC;IAAA,EACVE,YAAY,EAAC;EACnB;;EAEA;AACF;AACA;EACEC,WAAWA,CAACnD,OAAoB,EAAE;IAChC,MAAM;MAAE5B,KAAK;MAAEQ,IAAI;MAAEG;IAAK,CAAC,GAAG,IAAI;IAClC,MAAM;MAAEoD;IAAgB,CAAC,GAAGnC,OAAO;IAEnC,MAAMoD,WAAW,GAAG,IAAI,CAACC,cAAc,CAAC,CAAC;IACzC,MAAMC,UAAU,GAAG,IAAI,CAACC,aAAa,CAAC,CAAC;;IAEvC;IACA,IAAIC,WAAW,GAAGzE,IAAI,KAAKqE,WAAW,GAAGE,UAAU,GAAGG,SAAS;IAE/D,IAAIrF,KAAK,CAACiB,MAAM,KAAKlD,MAAM,CAACmD,EAAE,EAAE;MAC9B,IAAI,IAAI,CAACjB,OAAO,CAACkB,UAAU,KAAKrD,cAAc,CAACsD,QAAQ,EAAE;QACvD,MAAM;UAAEP;QAAM,CAAC,GAAG,IAAI,CAACb,KAAK;QAC5B,MAAMsF,SAAS,GAAGzE,KAAK,CAAC0E,OAAO,CAAC,IAAI,CAAC;;QAErC;QACA;QACA,MAAMC,QAAQ,GAAG3E,KAAK,CAAC4E,KAAK,CAACH,SAAS,GAAG,CAAC,CAAC,CAAC3B,IAAI,CAAExD,IAAI,IAAK;UACzD,MAAM;YAAEuF;UAAU,CAAC,GAAGvF,IAAI;UAE1B,IAAIuF,SAAS,EAAE;YACb,MAAMC,eAAe,GAAGD,SAAS,CAACE,EAAE,CAAC7B,eAAe,CAAC;YAErD,IAAI,CAAC4B,eAAe,EAAE;cACpB,OAAO,KAAK;YACd;UACF;;UAEA;UACA;UACA;UACA,IAAIxH,aAAa,CAACgC,IAAI,CAACF,OAAO,CAAC,EAAE;YAC/B,OAAO,KAAK;UACd;UAEA,OAAO,IAAI;QACb,CAAC,CAAC;QAEF,OAAOuF,QAAQ,EAAE7E,IAAI,IAAIyE,WAAW;MACtC,CAAC,MAAM;QACL,OAAOA,WAAW;MACpB;IACF;IAEA,MAAMS,QAAQ,GAAGrF,IAAI,CAACmD,IAAI,CAAEmC,IAAI,IAAK;MACnC,MAAM;QAAEJ;MAAU,CAAC,GAAGI,IAAI;MAE1B,IAAIJ,SAAS,EAAE;QACb,OAAO1F,KAAK,CAAC+F,UAAU,CAACL,SAAS,CAAC,EAAEE,EAAE,CAAC7B,eAAe,CAAC,IAAI,KAAK;MAClE;MAEAqB,WAAW,GAAGU,IAAI,CAACnF,IAAI;MACvB,OAAO,KAAK;IACd,CAAC,CAAC;IAEF,OAAOkF,QAAQ,EAAElF,IAAI,IAAIyE,WAAW;EACtC;;EAEA;AACF;AACA;EACEY,oBAAoBA,CAClBzE,OAAuC,EACvC0E,KAA0B,EACb;IACb,MAAM;MAAErG;IAAW,CAAC,GAAG,IAAI;;IAE3B;IACA,MAAM8B,MAAM,GAAG,IAAI,CAACD,aAAa,CAACF,OAAO,CAAC;;IAE1C;IACA,MAAMQ,OAAO,GAAGnC,UAAU,CAACoG,oBAAoB,CAACC,KAAK,CAAC;IAEtD,OAAO;MACL,GAAGvE,MAAM;MACT,GAAGK;IACL,CAAC;EACH;;EAEA;AACF;AACA;EACEN,aAAaA,CAACF,OAA4B,EAAqB;IAC7D,MAAM;MAAEQ;IAAQ,CAAC,GAAGR,OAAO,IAAI,CAAC,CAAC;IAEjC,MAAM2E,MAAM,GAAGzG,YAAY,CAAC0G,QAAQ,CAACpE,OAAO,EAAE;MAC5CqE,UAAU,EAAE,KAAK;MACjBC,YAAY,EAAE;IAChB,CAAC,CAAC;IAEF,OAAOH,MAAM,CAACI,KAAK;EACrB;EAEAC,qBAAqBA,CACnBhF,OAA2B,EAC3B0E,KAA0B,EAC1BlE,OAAoB,EACT;IACX,OAAO,IAAI,CAACnC,UAAU,CAAC2G,qBAAqB,CAACxE,OAAO,CAAC;EACvD;EAEAlD,SAASA,CAAC2H,OAA+B,EAAE;IACzC,OAAO3H,SAAS,CAAC2H,OAAO,CAAC;EAC3B;EAEA,MAAMC,QAAQA,CAAClF,OAAuB,EAAE;IACtC,MAAM;MAAEmF;IAAM,CAAC,GAAGnF,OAAO;;IAEzB;IACA,IAAI,OAAO,IAAImF,KAAK,EAAE;MACpB,OAAO,CAAC,CAAC;IACX;IAEA,MAAMC,YAAY,GAAG/H,eAAe,CAAC2C,OAAO,CAACiD,MAAM,CAAC;IAEpD,OAAOmC,YAAY,CAACF,QAAQ,CAAClF,OAAO,CAAC;EACvC;EAEA,MAAMqF,QAAQA,CAACrF,OAAuB,EAAE0E,KAA0B,EAAE;IAClE,MAAM;MAAES;IAAM,CAAC,GAAGnF,OAAO;;IAEzB;IACA,IAAI,OAAO,IAAImF,KAAK,EAAE;MACpB,OAAOT,KAAK;IACd;IAEA,MAAMU,YAAY,GAAG/H,eAAe,CAAC2C,OAAO,CAACiD,MAAM,CAAC;IAEpD,OAAOmC,YAAY,CAACC,QAAQ,CAACrF,OAAO,EAAE0E,KAAK,CAAC;EAC9C;EAEA,MAAMY,UAAUA,CACdtF,OAAuB,EACvB0E,KAA0B,EAC1Ba,MAAc,EACd;IACA,MAAM;MAAEJ;IAAM,CAAC,GAAGnF,OAAO;;IAEzB;IACA,MAAMwF,OAAO,GAAGrH,KAAK,CAACuG,KAAK,EAAEa,MAAM,CAAC;;IAEpC;IACA,IAAI,OAAO,IAAIJ,KAAK,EAAE;MACpB,OAAOK,OAAO;IAChB;IAEA,MAAMJ,YAAY,GAAG/H,eAAe,CAAC2C,OAAO,CAACiD,MAAM,CAAC;IAEpD,OAAOmC,YAAY,CAACC,QAAQ,CAACrF,OAAO,EAAEwF,OAAO,CAAC;EAChD;EAEAC,2BAA2BA,CACzBlF,SAA4B,EAC5B9B,KAAgB,EAChB+D,eAAwD,EACxD;IACA;IACA,IAAIkD,QAAQ,GAAGnF,SAAS,CAAC5B,UAAU,CAACQ,MAAM,CAAEwG,SAAS,IAAK;MACxD,IACE,CAAC,CAAC,CAACA,SAAS,CAAClH,KAAK,CAACmH,OAAO,IACxBD,SAAS,CAACE,IAAI,KAAKvJ,aAAa,CAACwJ,OAAO,KAC1CH,SAAS,CAAClH,KAAK,CAAC0F,SAAS,EACzB;QACA,MAAMA,SAAS,GAAG1F,KAAK,CAAC+F,UAAU,CAACmB,SAAS,CAAClH,KAAK,CAAC0F,SAAS,CAAC;QAC7D,OAAOA,SAAS,EAAEE,EAAE,CAAC7B,eAAe,CAAC;MACvC;MACA,OAAO,IAAI;IACb,CAAC,CAAC;;IAEF;AACJ;AACA;IACIkD,QAAQ,GAAGA,QAAQ,CAACK,GAAG,CAAEJ,SAAS,IAAK;MACrC,MAAMK,kBAAkB,GAAGL,SAAS;MACpC,MAAMC,OAAO,GAAGI,kBAAkB,CAACvH,KAAK,CAACmH,OAAO;MAChD,IAAIK,KAAK,CAACC,OAAO,CAACN,OAAO,CAAC,EAAE;QAC1BI,kBAAkB,CAACvH,KAAK,CAACmH,OAAO,GAAGA,OAAO,CAACzG,MAAM,CAAEgH,IAAI,IACrDA,IAAI,CAAChC,SAAS,GACV1F,KAAK,CAAC+F,UAAU,CAAC2B,IAAI,CAAChC,SAAS,CAAC,EAAEE,EAAE,CAAC7B,eAAe,CAAC,GACrD,IACN,CAAC;MACH;MACA;MACA,MAAM4D,KAAK,GAAGJ,kBAAkB,CAACvH,KAAK,CAAC2H,KAAK;MAE5C,IAAIH,KAAK,CAACC,OAAO,CAACE,KAAK,CAAC,EAAE;QACxBJ,kBAAkB,CAACvH,KAAK,CAAC2H,KAAK,GAAGA,KAAK,CAACjH,MAAM,CAAEgH,IAAI,IACjDA,IAAI,CAAChC,SAAS,GACV1F,KAAK,CAAC+F,UAAU,CAAC2B,IAAI,CAAChC,SAAS,CAAC,EAAEE,EAAE,CAAC7B,eAAe,CAAC,GACrD,IACN,CAAC;MACH;MAEA,OAAOwD,kBAAkB;IAC3B,CAAC,CAAC;IAEF,OAAON,QAAQ;EACjB;EAEAW,mBAAmBA,CAAA,EAAG;IACpB,OAAO,OACLrG,OAAoB,EACpBK,OAAoB,EACpBiG,CAAsB,KACnB;MACH,MAAM;QAAEjI,UAAU;QAAEI,KAAK;QAAE8H;MAAS,CAAC,GAAG,IAAI;MAC5C,MAAM;QAAE/D;MAAgB,CAAC,GAAGnC,OAAO;MAEnC,MAAMC,UAAU,GAAG,IAAI,CAACkG,aAAa,CAACxG,OAAO,CAAC;MAC9C,MAAM;QAAEU;MAAE,CAAC,GAAGJ,UAAU;;MAExB;MACA,IAAI,MAAM3C,+BAA+B,CAACqC,OAAO,EAAE,IAAI,CAAC,EAAE;QACxD;QACA,OAAOsG,CAAC,CAACG,QAAQ,CAACzG,OAAO,CAAC0G,GAAG,CAACC,QAAQ,CAAC;MACzC;MAEA,MAAMpG,SAAS,GAAG,IAAI,CAACH,YAAY,CAACJ,OAAO,EAAEK,OAAO,EAAEC,UAAU,CAAC;MACjEC,SAAS,CAACE,MAAM,GAAGpC,UAAU,CAACuI,aAAa,CAACtG,UAAU,EAAEC,SAAS,CAACE,MAAM,CAAC;MAEzE,MAAMoG,YAAY,GAAG7G,OAAO,CAAC8G,GAAG,CAACC,KAAK,CAACjK,qBAAqB,CAAC;MAC7D,MAAMkK,aAAa,GAAG,CAACf,KAAK,CAACC,OAAO,CAACW,YAAY,CAAC,GAAG,CAACA,YAAY,CAAC,GAAG,EAAE;MAExEtG,SAAS,CAACE,MAAM,GAAG,CAACF,SAAS,CAACE,MAAM,IAAI,EAAE,EAAEwG,MAAM,CAACD,aAAa,CAAC;MAEjE,MAAME,mBAAmB,GAAGlH,OAAO,CAAC8G,GAAG,CAACC,KAAK,CAC3C9J,4BACF,CAAC;MACDsD,SAAS,CAAC4G,8BAA8B,GACtC,CAAClB,KAAK,CAACC,OAAO,CAACgB,mBAAmB,CAAC;;MAErC;AACN;AACA;;MAEM;MACA3G,SAAS,CAAC5B,UAAU,GAAG,IAAI,CAAC8G,2BAA2B,CACrDlF,SAAS,EACT9B,KAAK,EACL+D,eACF,CAAC;MAEDjC,SAAS,CAAC6G,2BAA2B,GACnC,MAAM,IAAI,CAACA,2BAA2B,CAACpH,OAAO,EAAEK,OAAO,CAAC;MAE1D,OAAOiG,CAAC,CAACe,IAAI,CAACd,QAAQ,EAAE;QACtB,GAAGhG,SAAS;QACZG;MACF,CAAC,CAAC;IACJ,CAAC;EACH;EAEA,MAAM0G,2BAA2BA,CAC/BpH,OAAoB,EACpBK,OAAoB,EACpB;IACA,MAAM;MAAEjB;IAAK,CAAC,GAAG,IAAI;IACrB,MAAM;MAAEe;IAAO,CAAC,GAAGH,OAAO;IAC1B,MAAM;MAAEsH;IAAc,CAAC,GAAGjH,OAAO;IAEjC,MAAMgD,SAAS,GAAG,IAAI,CAACC,YAAY,CAAC,CAAC;IACrC,MAAMG,WAAW,GAAG,IAAI,CAACC,cAAc,CAAC,CAAC;IACzC,MAAM;MAAE6D;IAAa,CAAC,GAAG,IAAI,CAAC9I,KAAK,CAAC+I,QAAQ;IAC5C,MAAM;MAAEC;IAAgB,CAAC,GAAGF,YAAY;;IAExC;IACA,IAAI,CAAClE,SAAS,EAAEI,WAAW,CAAC,CAACiE,QAAQ,CAACtI,IAAI,CAAC,IAAI,CAACkI,aAAa,EAAE;MAC7D,MAAM;QAAEK;MAAkB,CAAC,GAAG,MAAMF,eAAe,CAACtH,MAAM,CAACyH,IAAI,CAAC;MAChE,OAAO,CAACD,iBAAiB;IAC3B;IAEA,OAAO,KAAK;EACd;;EAEA;AACF;AACA;EACY5E,WAAWA,CACnB/C,OAA2B,EAC3BK,OAAoB,EACpBK,CAA0D,EACpC;IACtB,MAAM;MAAEhC;IAAQ,CAAC,GAAG,IAAI;IACxB,MAAM;MAAEU,IAAI;MAAE+F;IAAM,CAAC,GAAGnF,OAAO;IAC/B,MAAM;MAAE6H;IAAU,CAAC,GAAG1C,KAAK;IAC3B,MAAM;MAAE/B;IAAM,CAAC,GAAG/C,OAAO;IAEzB,MAAMJ,MAAM,GAAG,IAAI,CAACF,SAAS,CAACC,OAAO,CAAC;;IAEtC;IACA,IAAI6H,SAAS,EAAE;MACb,OAAO;QACL5F,IAAI,EACFtF,WAAW,CAAC+B,OAAO,CAAC,IAAIuB,MAAM,GAC1BS,CAAC,CAAC,iCAAiC,CAAC,GACpCA,CAAC,CAAC,mCAAmC,CAAC;QAC5CoH,IAAI,EAAED;MACR,CAAC;IACH;;IAEA;IACA,MAAME,QAAQ,GACZ9H,MAAM,IAAI,CAACb,IAAI,CAAC4I,QAAQ,CAAC/H,MAAM,CAAC,GAC5BmD,KAAK,CAACtB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAAA,EACbsB,KAAK,CAACtB,EAAE,CAAC,CAAC,CAAC,CAAC,EAAC;;IAEnB;IACA,IAAI,CAACiG,QAAQ,EAAE;MACb;IACF;;IAEA;IACA,OAAO;MACL9F,IAAI,EAAEvB,CAAC,CAAC,aAAa,CAAC;MACtBoH,IAAI,EAAE,IAAI,CAACG,OAAO,CAACF,QAAQ;IAC7B,CAAC;EACH;EAEAG,oBAAoBA,CAAA,EAAG;IACrB,OAAO,OACLlI,OAA2B,EAC3BK,OAAoB,EACpBiG,CAAsB,KACnB;MACH,MAAM;QAAEjI,UAAU;QAAEkI,QAAQ;QAAE9H;MAAM,CAAC,GAAG,IAAI;MAC5C,MAAM;QAAE6I,aAAa;QAAE5C,KAAK;QAAElC;MAAgB,CAAC,GAAGnC,OAAO;MACzD,MAAMrB,MAAM,GAAGgB,OAAO,CAACQ,OAAO,CAACxB,MAAM;MAErC,MAAMsB,UAAU,GAAG,IAAI,CAACkG,aAAa,CAACxG,OAAO,CAAC;MAC9C,MAAM;QAAEU;MAAE,CAAC,GAAGJ,UAAU;MAExB,IAAItB,MAAM,EAAEmJ,UAAU,CAACrK,UAAU,CAACsK,QAAQ,CAAC,EAAE;QAC3C,OAAO,MAAM,IAAI,CAACC,gBAAgB,CAACrI,OAAO,EAAEsG,CAAC,EAAEjG,OAAO,CAAC;MACzD;;MAEA;AACN;AACA;AACA;MACM,IAAIA,OAAO,CAACI,MAAM,IAAI6G,aAAa,EAAE;QACnC,MAAM/G,SAAS,GAAG,IAAI,CAACH,YAAY,CAACJ,OAAO,EAAEK,OAAO,EAAEC,UAAU,CAAC;QACjEC,SAAS,CAACE,MAAM,GAAGpC,UAAU,CAACuI,aAAa,CACzCtG,UAAU,EACVC,SAAS,CAACE,MACZ,CAAC;;QAED;QACAF,SAAS,CAAC5B,UAAU,GAAG,IAAI,CAAC8G,2BAA2B,CACrDlF,SAAS,EACT9B,KAAK,EACL+D,eACF,CAAC;QAED,OAAO8D,CAAC,CAACe,IAAI,CAACd,QAAQ,EAAE;UACtB,GAAGhG,SAAS;UACZG;QACF,CAAC,CAAC;MACJ;;MAEA;MACA,MAAM,IAAI,CAAC2E,QAAQ,CAACrF,OAAO,EAAE0E,KAAK,CAAC;;MAEnC;MACA,IAAI1F,MAAM,KAAKlB,UAAU,CAACwK,WAAW,EAAE;QACrC,OAAO,IAAI,CAACC,iBAAiB,CAACvI,OAAO,EAAEK,OAAO,EAAEiG,CAAC,CAAC;MACpD;;MAEA;MACA,OAAO,IAAI,CAAC7I,OAAO,CAACuC,OAAO,EAAEsG,CAAC,EAAE,IAAI,CAAC9C,WAAW,CAACnD,OAAO,CAAC,CAAC;IAC5D,CAAC;EACH;EAEA,MAAcgI,gBAAgBA,CAC5BrI,OAA2B,EAC3BsG,CAAsB,EACtBjG,OAAoB,EACpB;IACA,MAAM;MAAEmI;IAAmB,CAAC,GAAG5K,mBAAmB,CAAC,CAAC;IACpD,MAAMoB,MAAM,GAAGgB,OAAO,CAACQ,OAAO,CAACxB,MAAM,IAAI,EAAE;;IAE3C;IACA;IACA;IACA,MAAMyJ,uBAAuB,GAAGzJ,MAAM,CACnCkF,KAAK,CAAC,GAAGpG,UAAU,CAACsK,QAAQ,GAAG,CAACtI,MAAM,CAAC,CACvC4I,KAAK,CAAC,IAAI,CAAC;IAEd,MAAMC,kBAAkB,GAAGF,uBAAuB,CAC/CvE,KAAK,CAAC,CAAC,CAAC,CACR6B,GAAG,CAAE6C,GAAG,IAAKA,GAAG,CAACF,KAAK,CAAC,GAAG,CAAC,CAAC;IAE/B,MAAMG,IAAI,GAAGC,MAAM,CAACC,WAAW,CAACJ,kBAAkB,CAGjD;IAED,MAAMK,aAAa,GAAGP,uBAAuB,CAAC,CAAC,CAAC;IAChD,MAAM9C,SAAS,GAAG,IAAI,CAAClH,KAAK,CAACwK,eAAe,CAACC,GAAG,CAACF,aAAa,CAAC;IAC/D,MAAMG,aAAa,GAAGxD,SAAS,EAAEE,IAAI;IAErC,IAAI,CAACsD,aAAa,EAAE;MAClB,MAAMtM,IAAI,CAACuM,QAAQ,CACjB,8BAA8BD,aAAa,YAC7C,CAAC;IACH;IAEA,MAAME,iBAAiB,GAAGb,kBAAkB,CAACU,GAAG,CAACC,aAAa,CAAC;IAE/D,IAAI,CAACE,iBAAiB,EAAE;MACtB,MAAMxM,IAAI,CAACuM,QAAQ,CAAC,sBAAsBJ,aAAa,YAAY,CAAC;IACtE;;IAEA;IACA,MAAMM,cAAc,GAAG;MACrB,GAAGjJ,OAAO,CAACG,OAAO;MAClBzB,KAAK,EAAE+E,SAAS;MAChB9E,MAAM,EAAE8E;IACV,CAAC;IACD9D,OAAO,CAAC8G,GAAG,CAACC,KAAK,CAAC/J,sBAAsB,EAAEsM,cAAc,EAAE,IAAI,CAAC;;IAE/D;IACAtJ,OAAO,CAAC8G,GAAG,CAACyC,KAAK,CAACxM,wBAAwB,CAAC;;IAE3C;IACA,MAAM;MAAE2H,KAAK;MAAE8E;IAAU,CAAC,GAAGpM,eAAe,CAAC4C,OAAO,CAACG,MAAM,CAAC;IAC5D,MAAMsJ,MAAM,GAAG/E,KAAK,KAAK3G,UAAU,CAAC2L,IAAI;IAExC,OAAO,MAAML,iBAAiB,CAACM,UAAU,CAAC3J,OAAO,EAAEsG,CAAC,EAAE;MACpDX,SAAS;MACT/F,UAAU,EAAE,IAAI;MAChBgK,SAAS,EAAE,GAAG5J,OAAO,CAAC0G,GAAG,CAACC,QAAQ,GAAG3G,OAAO,CAAC0G,GAAG,CAACmD,MAAM,EAAE;MACzDC,UAAU,EAAEjB,IAAI;MAChBY,MAAM;MACND;IACF,CAAC,CAAC;EACJ;EAEA/L,OAAOA,CACLuC,OAA2B,EAC3BsG,CAAsB,EACtByD,QAAiB,EACjB;IACA,MAAMC,OAAO,GAAGD,QAAQ,GACpB,IAAI,CAAC9B,OAAO,CAAC8B,QAAQ,CAAC,CAAC;IAAA,EACvB,IAAI,CAACjC,IAAI,EAAC;;IAEd,OAAOrK,OAAO,CAACuC,OAAO,EAAEsG,CAAC,EAAE0D,OAAO,CAAC;EACrC;;EAEA;AACF;AACA;EACEzB,iBAAiBA,CACfvI,OAA2B,EAC3BK,OAAoB,EACpBiG,CAAsB,EACtB;IACA,MAAM2D,WAAW,GAAG1M,qBAAqB,CAACyC,OAAO,CAACiD,MAAM,CAAC;IAEzD,IAAI,CAACgH,WAAW,EAAE;MAChB,MAAMpN,IAAI,CAACuM,QAAQ,CAAC,wCAAwC,CAAC;IAC/D;IAEA,OAAOa,WAAW,CAACjK,OAAO,EAAEsG,CAAC,EAAEjG,OAAO,CAAC;EACzC;;EAEA;AACF;AACA;EACE,IAAI6J,eAAeA,CAAA,EAAkC;IACnD,OAAO;MACLC,GAAG,EAAE;QACHC,aAAa,EAAE;UACbC,MAAMA,CAACC,QAAQ,EAAEhE,CAAC,EAAE;YAClB,OAAOA,CAAC,CAACiE,QAAQ;UACnB;QACF;MACF;IACF,CAAC;EACH;;EAEA;AACF;AACA;EACE,IAAIC,gBAAgBA,CAAA,EAAyC;IAC3D,OAAO;MACLhK,OAAO,EAAE;QACPiK,KAAK,EAAE,IAAI;QACXC,QAAQ,EAAEC,MAAM,CAACC,gBAAgB;QACjCC,UAAU,EAAE;MACd,CAAC;MACDV,GAAG,EAAE;QACHC,aAAa,EAAE;UACbC,MAAMA,CAACC,QAAQ,EAAEhE,CAAC,EAAE;YAClB,OAAOA,CAAC,CAACiE,QAAQ;UACnB;QACF;MACF;IACF,CAAC;EACH;AACF","ignoreList":[]}
@@ -1,4 +1,5 @@
1
1
  import { type PageRepeat, type Repeat } from '@defra/forms-model';
2
+ import { type Translator } from '../../../../server/plugins/engine/i18n/types.js';
2
3
  import { type FormModel } from '../../../../server/plugins/engine/models/index.js';
3
4
  import { QuestionPageController } from '../../../../server/plugins/engine/pageControllers/QuestionPageController.js';
4
5
  import { type FormContext, type FormContextRequest, type FormPageViewModel, type FormPayload, type FormSubmissionState, type RepeatItemState, type RepeatListState, type RepeaterSummaryPageViewModel } from '../../../../server/plugins/engine/types.js';
@@ -29,7 +30,7 @@ export declare class RepeatPageController extends QuestionPageController {
29
30
  makePostListSummaryRouteHandler(): (request: FormRequestPayload, context: FormContext, h: FormResponseToolkit) => import("@hapi/hapi").ResponseObject;
30
31
  makeGetItemDeleteRouteHandler(): (request: FormRequest, context: FormContext, h: FormResponseToolkit) => import("@hapi/hapi").ResponseObject;
31
32
  makePostItemDeleteRouteHandler(): (request: FormRequestPayload, context: FormContext, h: FormResponseToolkit) => Promise<import("@hapi/hapi").ResponseObject>;
32
- getViewModel(request: FormContextRequest, context: FormContext): FormPageViewModel;
33
- getListSummaryViewModel(request: FormContextRequest, context: FormContext, list: RepeatListState): RepeaterSummaryPageViewModel;
33
+ getViewModel(request: FormContextRequest, context: FormContext, translator: Translator): FormPageViewModel;
34
+ getListSummaryViewModel(request: FormContextRequest, context: FormContext, list: RepeatListState, translator: Translator): RepeaterSummaryPageViewModel;
34
35
  getSummaryPath(request?: FormContextRequest): string;
35
36
  }