@sunbird-cb/toc 0.0.9 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (495) hide show
  1. package/esm2022/lib/_collection/_common/attendance-card/attendance-card.component.mjs +55 -55
  2. package/esm2022/lib/_collection/_common/attendance-card/attendance-card.module.mjs +126 -126
  3. package/esm2022/lib/_collection/_common/attendance-helper/attendance-helper.component.mjs +32 -32
  4. package/esm2022/lib/_collection/_common/attendance-helper/attendance-helper.module.mjs +85 -85
  5. package/esm2022/lib/_collection/_common/avatar-photo/avatar-photo.component.mjs +100 -100
  6. package/esm2022/lib/_collection/_common/avatar-photo/avatar-photo.module.mjs +48 -48
  7. package/esm2022/lib/_collection/_common/certificate-dialog/certificate-dialog.component.mjs +120 -120
  8. package/esm2022/lib/_collection/_common/certificate-dialog/certificate-dialog.module.mjs +92 -92
  9. package/esm2022/lib/_collection/_common/certificate-dialog/svg-to-pdf.component.mjs +48 -48
  10. package/esm2022/lib/_collection/_common/confirm-dialog/confirm-dialog.component.mjs +25 -25
  11. package/esm2022/lib/_collection/_common/confirm-dialog/confirm-dialog.module.mjs +41 -41
  12. package/esm2022/lib/_collection/_common/connection-hover-card/connection-hover-card.component.mjs +89 -89
  13. package/esm2022/lib/_collection/_common/connection-hover-card/connection-hover.module.mjs +42 -42
  14. package/esm2022/lib/_collection/_common/connection-hover-card/connection-hover.servive.mjs +41 -41
  15. package/esm2022/lib/_collection/_common/connection-name/connection-name.component.mjs +78 -78
  16. package/esm2022/lib/_collection/_common/connection-name/connection-name.module.mjs +45 -45
  17. package/esm2022/lib/_collection/_common/connection-name/profile-v2.model.mjs +2 -2
  18. package/esm2022/lib/_collection/_common/content-progress/content-progress.component.mjs +70 -70
  19. package/esm2022/lib/_collection/_common/content-progress/content-progress.module.mjs +28 -28
  20. package/esm2022/lib/_collection/_common/content-rating-v2-dialog/content-rating-v2-dialog.component.mjs +187 -187
  21. package/esm2022/lib/_collection/_common/content-rating-v2-dialog/content-rating-v2-dialog.module.mjs +86 -86
  22. package/esm2022/lib/_collection/_common/content-toc/ai-tutor-confirm-popup/ai-tutor-confirm-popup.component.mjs +31 -31
  23. package/esm2022/lib/_collection/_common/content-toc/app-toc-about/app-toc-about.component.mjs +941 -941
  24. package/esm2022/lib/_collection/_common/content-toc/app-toc-assignment-viewer/app-toc-assignment-viewer.component.mjs +183 -183
  25. package/esm2022/lib/_collection/_common/content-toc/app-toc-assignment-viewerV2/app-toc-assignment-viewerV2.component.mjs +327 -327
  26. package/esm2022/lib/_collection/_common/content-toc/app-toc-batch-assignments/app-toc-batch-assignments.component.mjs +297 -297
  27. package/esm2022/lib/_collection/_common/content-toc/app-toc-content/app-toc-content.component.mjs +261 -248
  28. package/esm2022/lib/_collection/_common/content-toc/app-toc-content-card-v2/app-toc-content-card-v2.component.mjs +1177 -1148
  29. package/esm2022/lib/_collection/_common/content-toc/app-toc-content-card-v2-skeleton/app-toc-content-card-v2-skeleton.component.mjs +16 -16
  30. package/esm2022/lib/_collection/_common/content-toc/app-toc-reference-notes/app-toc-reference-notes.component.mjs +43 -43
  31. package/esm2022/lib/_collection/_common/content-toc/app-toc-session-card-new/app-toc-session-card-new.component.mjs +133 -133
  32. package/esm2022/lib/_collection/_common/content-toc/app-toc-sessions-new/app-toc-sessions-new.component.mjs +66 -66
  33. package/esm2022/lib/_collection/_common/content-toc/app-toc-teachers-notes/app-toc-teachers-notes.component.mjs +278 -278
  34. package/esm2022/lib/_collection/_common/content-toc/content-services/handle-claim.service.mjs +21 -21
  35. package/esm2022/lib/_collection/_common/content-toc/content-services/review-component-data.service.mjs +21 -21
  36. package/esm2022/lib/_collection/_common/content-toc/content-toc.component.mjs +847 -847
  37. package/esm2022/lib/_collection/_common/content-toc/content-toc.module.mjs +219 -219
  38. package/esm2022/lib/_collection/_common/content-toc/karma-points/karma-points.component.mjs +209 -209
  39. package/esm2022/lib/_collection/_common/content-toc/karma-points/karma-points.module.mjs +26 -26
  40. package/esm2022/lib/_collection/_common/content-toc/pipes/replace-nbsp.pipe.mjs +19 -19
  41. package/esm2022/lib/_collection/_common/content-toc/pipes/truncate.pipe.mjs +23 -23
  42. package/esm2022/lib/_collection/_common/content-toc/reviews-content/reviews-content.component.mjs +113 -113
  43. package/esm2022/lib/_collection/_common/content-toc/samuhik-charcha-content/samuhik-charcha-content/samuhik-charcha-content.component.mjs +110 -110
  44. package/esm2022/lib/_collection/_common/display-content-type/display-content-type.component.mjs +26 -26
  45. package/esm2022/lib/_collection/_common/display-content-type/display-content-type.module.mjs +19 -19
  46. package/esm2022/lib/_collection/_common/display-content-type-icon/display-content-type-icon.component.mjs +67 -67
  47. package/esm2022/lib/_collection/_common/display-content-type-icon/display-content-type-icon.module.mjs +28 -28
  48. package/esm2022/lib/_collection/_common/mark-as-complete/mark-as-complete.component.mjs +77 -77
  49. package/esm2022/lib/_collection/_common/mark-as-complete/mark-as-complete.model.mjs +2 -2
  50. package/esm2022/lib/_collection/_common/mark-as-complete/mark-as-complete.module.mjs +61 -61
  51. package/esm2022/lib/_collection/_common/pipe-content-route/pipe-content-route.module.mjs +20 -20
  52. package/esm2022/lib/_collection/_common/pipe-content-route/pipe-content-route.pipe.mjs +67 -67
  53. package/esm2022/lib/_collection/_common/player-brief/player-brief.component.mjs +139 -139
  54. package/esm2022/lib/_collection/_common/player-brief/player-brief.module.mjs +71 -71
  55. package/esm2022/lib/_collection/_common/rating-summary/rating-summary.component.mjs +34 -34
  56. package/esm2022/lib/_collection/_common/rating-summary/rating-summary.module.mjs +56 -56
  57. package/esm2022/lib/_collection/_common/skeleton-loader/skeleton-loader.component.mjs +25 -25
  58. package/esm2022/lib/_collection/_common/skeleton-loader/skeleton-loader.module.mjs +37 -37
  59. package/esm2022/lib/_collection/_common/tips-for-learner/tips-for-learner-card/tips-for-learner-card.component.mjs +32 -32
  60. package/esm2022/lib/_collection/_common/tips-for-learner/tips-for-learner.module.mjs +30 -30
  61. package/esm2022/lib/_collection/_common/toc-kpi-values/toc-kpi-values.component.mjs +38 -38
  62. package/esm2022/lib/_collection/_common/toc-kpi-values/toc-kpi-values.module.mjs +51 -51
  63. package/esm2022/lib/_collection/_common/user-autocomplete/user-autocomplete.component.mjs +115 -115
  64. package/esm2022/lib/_collection/_common/user-autocomplete/user-autocomplete.model.mjs +12 -12
  65. package/esm2022/lib/_collection/_common/user-autocomplete/user-autocomplete.module.mjs +51 -51
  66. package/esm2022/lib/_collection/_common/user-autocomplete/user-autocomplete.service.mjs +61 -61
  67. package/esm2022/lib/_collection/_common/user-content-rating/user-content-rating.component.mjs +87 -87
  68. package/esm2022/lib/_collection/_common/user-content-rating/user-content-rating.module.mjs +36 -36
  69. package/esm2022/lib/_collection/_common/user-image/user-image.component.mjs +62 -62
  70. package/esm2022/lib/_collection/_common/user-image/user-image.module.mjs +24 -24
  71. package/esm2022/lib/_collection/btn-page-back/btn-page-back.component.mjs +192 -192
  72. package/esm2022/lib/_collection/btn-page-back/btn-page-back.module.mjs +44 -44
  73. package/esm2022/lib/_collection/btn-page-back/btn-page-back.service.mjs +99 -99
  74. package/esm2022/lib/_collection/card-rating-comment/card-rating-comment.component.mjs +58 -58
  75. package/esm2022/lib/_collection/card-rating-comment/card-rating-comment.module.mjs +67 -67
  76. package/esm2022/lib/_collection/sliders-dynamic/sliders-dynamic.component.mjs +112 -112
  77. package/esm2022/lib/_collection/sliders-dynamic/sliders-dynamic.model.mjs +2 -2
  78. package/esm2022/lib/_collection/sliders-dynamic/sliders-dynamic.module.mjs +69 -69
  79. package/esm2022/lib/_collection-api.mjs +57 -57
  80. package/esm2022/lib/_constants/widget-content.constants.mjs +19 -19
  81. package/esm2022/lib/_directives/tooltip.directive.mjs +68 -68
  82. package/esm2022/lib/_models/common.model.mjs +2 -2
  83. package/esm2022/lib/_models/error.model.mjs +2 -2
  84. package/esm2022/lib/_pipes/highlight.pipe.mjs +24 -24
  85. package/esm2022/lib/_services/rating.service.mjs +89 -89
  86. package/esm2022/lib/_services/samuhik-charcha.service.mjs +29 -29
  87. package/esm2022/lib/_services/viewer-route-util.mjs +103 -103
  88. package/esm2022/lib/_services/widget-content.model.mjs +247 -247
  89. package/esm2022/lib/_services/widget-content.service.mjs +594 -594
  90. package/esm2022/lib/_shared/translate-loader.factory.mjs +9 -9
  91. package/esm2022/lib/app-toc-lib.module.mjs +499 -499
  92. package/esm2022/lib/collection.config.mjs +161 -161
  93. package/esm2022/lib/components/app-toc-analytics-tiles/app-toc-analytics-tiles.component.mjs +37 -37
  94. package/esm2022/lib/components/app-toc-banner/app-toc-banner.component.mjs +1436 -1436
  95. package/esm2022/lib/components/app-toc-cios-home/app-toc-cios-home.component.mjs +475 -475
  96. package/esm2022/lib/components/app-toc-cios-home/consent-dialog.component.mjs +119 -119
  97. package/esm2022/lib/components/app-toc-cohorts/app-toc-cohorts.component.mjs +80 -80
  98. package/esm2022/lib/components/app-toc-content-card/app-toc-content-card.component.mjs +249 -249
  99. package/esm2022/lib/components/app-toc-dialog-intro-video/app-toc-dialog-intro-video.component.mjs +39 -39
  100. package/esm2022/lib/components/app-toc-discussion/app-toc-discussion.component.mjs +58 -58
  101. package/esm2022/lib/components/app-toc-home/app-toc-home.component.mjs +2229 -2229
  102. package/esm2022/lib/components/app-toc-home-v2/app-toc-home-v2.component.mjs +2938 -2907
  103. package/esm2022/lib/components/app-toc-overview/app-toc-overview.component.mjs +157 -157
  104. package/esm2022/lib/components/app-toc-session-card/app-toc-session-card.component.mjs +48 -48
  105. package/esm2022/lib/components/app-toc-sessions/app-toc-sessions.component.mjs +47 -47
  106. package/esm2022/lib/components/app-toc-single-page/app-toc-single-page.component.mjs +766 -766
  107. package/esm2022/lib/components/completion-survey-form/completion-survey-form.component.mjs +243 -243
  108. package/esm2022/lib/components/create-batch-dialog/create-batch-dialog.component.mjs +116 -116
  109. package/esm2022/lib/components/enroll-language-dialogue/enroll-language-dialogue.component.mjs +44 -44
  110. package/esm2022/lib/components/enroll-profile-form/enroll-profile-form.component.mjs +1838 -1838
  111. package/esm2022/lib/components/enroll-questionnaire/enroll-questionnaire.component.mjs +236 -236
  112. package/esm2022/lib/components/knowledge-artifact-details/knowledge-artifact-details.component.mjs +213 -213
  113. package/esm2022/lib/components/non-relevent-feedback-dialog/non-relevent-feedback-dialog.component.mjs +36 -36
  114. package/esm2022/lib/components/public-survey-form/public-survey-form.component.mjs +256 -256
  115. package/esm2022/lib/components/survey-form-question/survey-form-question.component.mjs +133 -133
  116. package/esm2022/lib/components/survey-form-section/survey-form-section.component.mjs +36 -36
  117. package/esm2022/lib/models/app-toc-analytics.model.mjs +2 -2
  118. package/esm2022/lib/models/app-toc.model.mjs +38 -38
  119. package/esm2022/lib/models/auto-complete.model.mjs +2 -2
  120. package/esm2022/lib/models/card-content.model.mjs +13 -13
  121. package/esm2022/lib/models/content-strip-with-tabs.model.mjs +2 -2
  122. package/esm2022/lib/models/discussion-forum.model.mjs +14 -14
  123. package/esm2022/lib/models/goal.model.mjs +2 -2
  124. package/esm2022/lib/models/meta-tag.model.mjs +8 -8
  125. package/esm2022/lib/models/playlist.model.mjs +2 -2
  126. package/esm2022/lib/models/profile-revamp.model.mjs +2 -2
  127. package/esm2022/lib/models/rating.model.mjs +2 -2
  128. package/esm2022/lib/models/user-profile.model.mjs +21 -21
  129. package/esm2022/lib/resolvers/app-toc-cios-resolver.service.mjs +24 -24
  130. package/esm2022/lib/resolvers/app-toc-cios-user-enroll-resolver.service.mjs +24 -24
  131. package/esm2022/lib/resolvers/app-toc-content-read-resolver.service.mjs +60 -60
  132. package/esm2022/lib/resolvers/app-toc-ext-public-resolver.service.mjs +25 -25
  133. package/esm2022/lib/resolvers/app-toc-resolver.service.mjs +106 -106
  134. package/esm2022/lib/resolvers/config-resolver.service.mjs +25 -25
  135. package/esm2022/lib/resolvers/profile-resolver.service.mjs +25 -25
  136. package/esm2022/lib/resolvers/restricted-features-resolver.service.mjs +25 -25
  137. package/esm2022/lib/routes/app-toc-home/app-toc-home.component.mjs +51 -51
  138. package/esm2022/lib/routes/app-toc-home/app-toc-home.directive.mjs +16 -16
  139. package/esm2022/lib/routes/app-toc-home/app-toc-home.service.mjs +18 -18
  140. package/esm2022/lib/services/access-control.service.mjs +56 -56
  141. package/esm2022/lib/services/action.service.mjs +23 -23
  142. package/esm2022/lib/services/app-toc-v2.service.mjs +332 -313
  143. package/esm2022/lib/services/app-toc.service.mjs +1647 -1613
  144. package/esm2022/lib/services/certificate.service.mjs +69 -69
  145. package/esm2022/lib/services/discuss-utils.service.mjs +58 -58
  146. package/esm2022/lib/services/editor.service.mjs +34 -34
  147. package/esm2022/lib/services/load-check.service.mjs +21 -21
  148. package/esm2022/lib/services/loader.service.mjs +33 -33
  149. package/esm2022/lib/services/mobile-apps.service.mjs +67 -67
  150. package/esm2022/lib/services/netcore.service.mjs +56 -56
  151. package/esm2022/lib/services/nps-grid.service.mjs +31 -31
  152. package/esm2022/lib/services/otp.service.mjs +43 -43
  153. package/esm2022/lib/services/profile-v2.service.mjs +43 -43
  154. package/esm2022/lib/services/reset-ratings.service.mjs +19 -19
  155. package/esm2022/lib/services/resource-download-helper.service.mjs +64 -64
  156. package/esm2022/lib/services/timer.service.mjs +23 -23
  157. package/esm2022/lib/services/title-tag.service.mjs +71 -71
  158. package/esm2022/lib/services/user-profile.service.mjs +55 -55
  159. package/esm2022/lib/services/viewer-data.service.mjs +64 -64
  160. package/esm2022/lib/services/viewer-util.service.mjs +599 -590
  161. package/esm2022/lib/share-toc/share-toc/share-toc.component.mjs +291 -291
  162. package/esm2022/lib/share-toc/share-toc.module.mjs +119 -119
  163. package/esm2022/public-api.mjs +73 -71
  164. package/esm2022/sunbird-cb-toc.mjs +4 -4
  165. package/fesm2022/sunbird-cb-toc.mjs +24901 -24766
  166. package/fesm2022/sunbird-cb-toc.mjs.map +1 -1
  167. package/index.d.ts +6 -5
  168. package/lib/_collection/_common/attendance-card/attendance-card.component.d.ts +17 -16
  169. package/lib/_collection/_common/attendance-card/attendance-card.component.d.ts.map +1 -0
  170. package/lib/_collection/_common/attendance-card/attendance-card.module.d.ts +32 -31
  171. package/lib/_collection/_common/attendance-card/attendance-card.module.d.ts.map +1 -0
  172. package/lib/_collection/_common/attendance-helper/attendance-helper.component.d.ts +16 -15
  173. package/lib/_collection/_common/attendance-helper/attendance-helper.component.d.ts.map +1 -0
  174. package/lib/_collection/_common/attendance-helper/attendance-helper.module.d.ts +21 -20
  175. package/lib/_collection/_common/attendance-helper/attendance-helper.module.d.ts.map +1 -0
  176. package/lib/_collection/_common/avatar-photo/avatar-photo.component.d.ts +23 -22
  177. package/lib/_collection/_common/avatar-photo/avatar-photo.component.d.ts.map +1 -0
  178. package/lib/_collection/_common/avatar-photo/avatar-photo.module.d.ts +16 -15
  179. package/lib/_collection/_common/avatar-photo/avatar-photo.module.d.ts.map +1 -0
  180. package/lib/_collection/_common/certificate-dialog/certificate-dialog.component.d.ts +23 -22
  181. package/lib/_collection/_common/certificate-dialog/certificate-dialog.component.d.ts.map +1 -0
  182. package/lib/_collection/_common/certificate-dialog/certificate-dialog.module.d.ts +23 -22
  183. package/lib/_collection/_common/certificate-dialog/certificate-dialog.module.d.ts.map +1 -0
  184. package/lib/_collection/_common/certificate-dialog/svg-to-pdf.component.d.ts +10 -9
  185. package/lib/_collection/_common/certificate-dialog/svg-to-pdf.component.d.ts.map +1 -0
  186. package/lib/_collection/_common/confirm-dialog/confirm-dialog.component.d.ts +12 -11
  187. package/lib/_collection/_common/confirm-dialog/confirm-dialog.component.d.ts.map +1 -0
  188. package/lib/_collection/_common/confirm-dialog/confirm-dialog.module.d.ts +13 -12
  189. package/lib/_collection/_common/confirm-dialog/confirm-dialog.module.d.ts.map +1 -0
  190. package/lib/_collection/_common/connection-hover-card/connection-hover-card.component.d.ts +19 -18
  191. package/lib/_collection/_common/connection-hover-card/connection-hover-card.component.d.ts.map +1 -0
  192. package/lib/_collection/_common/connection-hover-card/connection-hover.module.d.ts +15 -14
  193. package/lib/_collection/_common/connection-hover-card/connection-hover.module.d.ts.map +1 -0
  194. package/lib/_collection/_common/connection-hover-card/connection-hover.servive.d.ts +12 -11
  195. package/lib/_collection/_common/connection-hover-card/connection-hover.servive.d.ts.map +1 -0
  196. package/lib/_collection/_common/connection-name/connection-name.component.d.ts +18 -17
  197. package/lib/_collection/_common/connection-name/connection-name.component.d.ts.map +1 -0
  198. package/lib/_collection/_common/connection-name/connection-name.module.d.ts +15 -14
  199. package/lib/_collection/_common/connection-name/connection-name.module.d.ts.map +1 -0
  200. package/lib/_collection/_common/connection-name/profile-v2.model.d.ts +200 -199
  201. package/lib/_collection/_common/connection-name/profile-v2.model.d.ts.map +1 -0
  202. package/lib/_collection/_common/content-progress/content-progress.component.d.ts +17 -16
  203. package/lib/_collection/_common/content-progress/content-progress.component.d.ts.map +1 -0
  204. package/lib/_collection/_common/content-progress/content-progress.module.d.ts +11 -10
  205. package/lib/_collection/_common/content-progress/content-progress.module.d.ts.map +1 -0
  206. package/lib/_collection/_common/content-rating-v2-dialog/content-rating-v2-dialog.component.d.ts +39 -38
  207. package/lib/_collection/_common/content-rating-v2-dialog/content-rating-v2-dialog.component.d.ts.map +1 -0
  208. package/lib/_collection/_common/content-rating-v2-dialog/content-rating-v2-dialog.module.d.ts +20 -19
  209. package/lib/_collection/_common/content-rating-v2-dialog/content-rating-v2-dialog.module.d.ts.map +1 -0
  210. package/lib/_collection/_common/content-toc/ai-tutor-confirm-popup/ai-tutor-confirm-popup.component.d.ts +12 -11
  211. package/lib/_collection/_common/content-toc/ai-tutor-confirm-popup/ai-tutor-confirm-popup.component.d.ts.map +1 -0
  212. package/lib/_collection/_common/content-toc/app-toc-about/app-toc-about.component.d.ts +184 -183
  213. package/lib/_collection/_common/content-toc/app-toc-about/app-toc-about.component.d.ts.map +1 -0
  214. package/lib/_collection/_common/content-toc/app-toc-assignment-viewer/app-toc-assignment-viewer.component.d.ts +42 -41
  215. package/lib/_collection/_common/content-toc/app-toc-assignment-viewer/app-toc-assignment-viewer.component.d.ts.map +1 -0
  216. package/lib/_collection/_common/content-toc/app-toc-assignment-viewerV2/app-toc-assignment-viewerV2.component.d.ts +55 -54
  217. package/lib/_collection/_common/content-toc/app-toc-assignment-viewerV2/app-toc-assignment-viewerV2.component.d.ts.map +1 -0
  218. package/lib/_collection/_common/content-toc/app-toc-batch-assignments/app-toc-batch-assignments.component.d.ts +48 -47
  219. package/lib/_collection/_common/content-toc/app-toc-batch-assignments/app-toc-batch-assignments.component.d.ts.map +1 -0
  220. package/lib/_collection/_common/content-toc/app-toc-content/app-toc-content.component.d.ts +51 -49
  221. package/lib/_collection/_common/content-toc/app-toc-content/app-toc-content.component.d.ts.map +1 -0
  222. package/lib/_collection/_common/content-toc/app-toc-content-card-v2/app-toc-content-card-v2.component.d.ts +175 -171
  223. package/lib/_collection/_common/content-toc/app-toc-content-card-v2/app-toc-content-card-v2.component.d.ts.map +1 -0
  224. package/lib/_collection/_common/content-toc/app-toc-content-card-v2-skeleton/app-toc-content-card-v2-skeleton.component.d.ts +9 -8
  225. package/lib/_collection/_common/content-toc/app-toc-content-card-v2-skeleton/app-toc-content-card-v2-skeleton.component.d.ts.map +1 -0
  226. package/lib/_collection/_common/content-toc/app-toc-reference-notes/app-toc-reference-notes.component.d.ts +17 -16
  227. package/lib/_collection/_common/content-toc/app-toc-reference-notes/app-toc-reference-notes.component.d.ts.map +1 -0
  228. package/lib/_collection/_common/content-toc/app-toc-session-card-new/app-toc-session-card-new.component.d.ts +41 -40
  229. package/lib/_collection/_common/content-toc/app-toc-session-card-new/app-toc-session-card-new.component.d.ts.map +1 -0
  230. package/lib/_collection/_common/content-toc/app-toc-sessions-new/app-toc-sessions-new.component.d.ts +22 -21
  231. package/lib/_collection/_common/content-toc/app-toc-sessions-new/app-toc-sessions-new.component.d.ts.map +1 -0
  232. package/lib/_collection/_common/content-toc/app-toc-teachers-notes/app-toc-teachers-notes.component.d.ts +46 -45
  233. package/lib/_collection/_common/content-toc/app-toc-teachers-notes/app-toc-teachers-notes.component.d.ts.map +1 -0
  234. package/lib/_collection/_common/content-toc/content-services/handle-claim.service.d.ts +11 -10
  235. package/lib/_collection/_common/content-toc/content-services/handle-claim.service.d.ts.map +1 -0
  236. package/lib/_collection/_common/content-toc/content-services/review-component-data.service.d.ts +11 -10
  237. package/lib/_collection/_common/content-toc/content-services/review-component-data.service.d.ts.map +1 -0
  238. package/lib/_collection/_common/content-toc/content-toc.component.d.ts +129 -128
  239. package/lib/_collection/_common/content-toc/content-toc.component.d.ts.map +1 -0
  240. package/lib/_collection/_common/content-toc/content-toc.module.d.ts +52 -51
  241. package/lib/_collection/_common/content-toc/content-toc.module.d.ts.map +1 -0
  242. package/lib/_collection/_common/content-toc/karma-points/karma-points.component.d.ts +30 -29
  243. package/lib/_collection/_common/content-toc/karma-points/karma-points.component.d.ts.map +1 -0
  244. package/lib/_collection/_common/content-toc/karma-points/karma-points.module.d.ts +10 -9
  245. package/lib/_collection/_common/content-toc/karma-points/karma-points.module.d.ts.map +1 -0
  246. package/lib/_collection/_common/content-toc/pipes/replace-nbsp.pipe.d.ts +8 -7
  247. package/lib/_collection/_common/content-toc/pipes/replace-nbsp.pipe.d.ts.map +1 -0
  248. package/lib/_collection/_common/content-toc/pipes/truncate.pipe.d.ts +8 -7
  249. package/lib/_collection/_common/content-toc/pipes/truncate.pipe.d.ts.map +1 -0
  250. package/lib/_collection/_common/content-toc/reviews-content/reviews-content.component.d.ts +29 -28
  251. package/lib/_collection/_common/content-toc/reviews-content/reviews-content.component.d.ts.map +1 -0
  252. package/lib/_collection/_common/content-toc/samuhik-charcha-content/samuhik-charcha-content/samuhik-charcha-content.component.d.ts +25 -24
  253. package/lib/_collection/_common/content-toc/samuhik-charcha-content/samuhik-charcha-content/samuhik-charcha-content.component.d.ts.map +1 -0
  254. package/lib/_collection/_common/display-content-type/display-content-type.component.d.ts +15 -14
  255. package/lib/_collection/_common/display-content-type/display-content-type.component.d.ts.map +1 -0
  256. package/lib/_collection/_common/display-content-type/display-content-type.module.d.ts +10 -9
  257. package/lib/_collection/_common/display-content-type/display-content-type.module.d.ts.map +1 -0
  258. package/lib/_collection/_common/display-content-type-icon/display-content-type-icon.component.d.ts +13 -12
  259. package/lib/_collection/_common/display-content-type-icon/display-content-type-icon.component.d.ts.map +1 -0
  260. package/lib/_collection/_common/display-content-type-icon/display-content-type-icon.module.d.ts +11 -10
  261. package/lib/_collection/_common/display-content-type-icon/display-content-type-icon.module.d.ts.map +1 -0
  262. package/lib/_collection/_common/mark-as-complete/mark-as-complete.component.d.ts +23 -22
  263. package/lib/_collection/_common/mark-as-complete/mark-as-complete.component.d.ts.map +1 -0
  264. package/lib/_collection/_common/mark-as-complete/mark-as-complete.model.d.ts +9 -8
  265. package/lib/_collection/_common/mark-as-complete/mark-as-complete.model.d.ts.map +1 -0
  266. package/lib/_collection/_common/mark-as-complete/mark-as-complete.module.d.ts +19 -18
  267. package/lib/_collection/_common/mark-as-complete/mark-as-complete.module.d.ts.map +1 -0
  268. package/lib/_collection/_common/pipe-content-route/pipe-content-route.module.d.ts +9 -8
  269. package/lib/_collection/_common/pipe-content-route/pipe-content-route.module.d.ts.map +1 -0
  270. package/lib/_collection/_common/pipe-content-route/pipe-content-route.pipe.d.ts +16 -15
  271. package/lib/_collection/_common/pipe-content-route/pipe-content-route.pipe.d.ts.map +1 -0
  272. package/lib/_collection/_common/player-brief/player-brief.component.d.ts +36 -35
  273. package/lib/_collection/_common/player-brief/player-brief.component.d.ts.map +1 -0
  274. package/lib/_collection/_common/player-brief/player-brief.module.d.ts +20 -19
  275. package/lib/_collection/_common/player-brief/player-brief.module.d.ts.map +1 -0
  276. package/lib/_collection/_common/rating-summary/rating-summary.component.d.ts +15 -14
  277. package/lib/_collection/_common/rating-summary/rating-summary.component.d.ts.map +1 -0
  278. package/lib/_collection/_common/rating-summary/rating-summary.module.d.ts +14 -13
  279. package/lib/_collection/_common/rating-summary/rating-summary.module.d.ts.map +1 -0
  280. package/lib/_collection/_common/skeleton-loader/skeleton-loader.component.d.ts +12 -11
  281. package/lib/_collection/_common/skeleton-loader/skeleton-loader.component.d.ts.map +1 -0
  282. package/lib/_collection/_common/skeleton-loader/skeleton-loader.module.d.ts +12 -11
  283. package/lib/_collection/_common/skeleton-loader/skeleton-loader.module.d.ts.map +1 -0
  284. package/lib/_collection/_common/tips-for-learner/tips-for-learner-card/tips-for-learner-card.component.d.ts +16 -15
  285. package/lib/_collection/_common/tips-for-learner/tips-for-learner-card/tips-for-learner-card.component.d.ts.map +1 -0
  286. package/lib/_collection/_common/tips-for-learner/tips-for-learner.module.d.ts +11 -10
  287. package/lib/_collection/_common/tips-for-learner/tips-for-learner.module.d.ts.map +1 -0
  288. package/lib/_collection/_common/toc-kpi-values/toc-kpi-values.component.d.ts +17 -16
  289. package/lib/_collection/_common/toc-kpi-values/toc-kpi-values.component.d.ts.map +1 -0
  290. package/lib/_collection/_common/toc-kpi-values/toc-kpi-values.module.d.ts +12 -11
  291. package/lib/_collection/_common/toc-kpi-values/toc-kpi-values.module.d.ts.map +1 -0
  292. package/lib/_collection/_common/user-autocomplete/user-autocomplete.component.d.ts +35 -34
  293. package/lib/_collection/_common/user-autocomplete/user-autocomplete.component.d.ts.map +1 -0
  294. package/lib/_collection/_common/user-autocomplete/user-autocomplete.model.d.ts +18 -17
  295. package/lib/_collection/_common/user-autocomplete/user-autocomplete.model.d.ts.map +1 -0
  296. package/lib/_collection/_common/user-autocomplete/user-autocomplete.module.d.ts +16 -15
  297. package/lib/_collection/_common/user-autocomplete/user-autocomplete.module.d.ts.map +1 -0
  298. package/lib/_collection/_common/user-autocomplete/user-autocomplete.service.d.ts +16 -15
  299. package/lib/_collection/_common/user-autocomplete/user-autocomplete.service.d.ts.map +1 -0
  300. package/lib/_collection/_common/user-content-rating/user-content-rating.component.d.ts +22 -21
  301. package/lib/_collection/_common/user-content-rating/user-content-rating.component.d.ts.map +1 -0
  302. package/lib/_collection/_common/user-content-rating/user-content-rating.module.d.ts +13 -12
  303. package/lib/_collection/_common/user-content-rating/user-content-rating.module.d.ts.map +1 -0
  304. package/lib/_collection/_common/user-image/user-image.component.d.ts +22 -21
  305. package/lib/_collection/_common/user-image/user-image.component.d.ts.map +1 -0
  306. package/lib/_collection/_common/user-image/user-image.module.d.ts +10 -9
  307. package/lib/_collection/_common/user-image/user-image.module.d.ts.map +1 -0
  308. package/lib/_collection/btn-page-back/btn-page-back.component.d.ts +48 -47
  309. package/lib/_collection/btn-page-back/btn-page-back.component.d.ts.map +1 -0
  310. package/lib/_collection/btn-page-back/btn-page-back.module.d.ts +15 -14
  311. package/lib/_collection/btn-page-back/btn-page-back.module.d.ts.map +1 -0
  312. package/lib/_collection/btn-page-back/btn-page-back.service.d.ts +23 -22
  313. package/lib/_collection/btn-page-back/btn-page-back.service.d.ts.map +1 -0
  314. package/lib/_collection/card-rating-comment/card-rating-comment.component.d.ts +20 -19
  315. package/lib/_collection/card-rating-comment/card-rating-comment.component.d.ts.map +1 -0
  316. package/lib/_collection/card-rating-comment/card-rating-comment.module.d.ts +16 -15
  317. package/lib/_collection/card-rating-comment/card-rating-comment.module.d.ts.map +1 -0
  318. package/lib/_collection/sliders-dynamic/sliders-dynamic.component.d.ts +26 -25
  319. package/lib/_collection/sliders-dynamic/sliders-dynamic.component.d.ts.map +1 -0
  320. package/lib/_collection/sliders-dynamic/sliders-dynamic.model.d.ts +22 -21
  321. package/lib/_collection/sliders-dynamic/sliders-dynamic.model.d.ts.map +1 -0
  322. package/lib/_collection/sliders-dynamic/sliders-dynamic.module.d.ts +19 -18
  323. package/lib/_collection/sliders-dynamic/sliders-dynamic.module.d.ts.map +1 -0
  324. package/lib/_collection-api.d.ts +35 -34
  325. package/lib/_collection-api.d.ts.map +1 -0
  326. package/lib/_constants/widget-content.constants.d.ts +8 -7
  327. package/lib/_constants/widget-content.constants.d.ts.map +1 -0
  328. package/lib/_directives/tooltip.directive.d.ts +18 -17
  329. package/lib/_directives/tooltip.directive.d.ts.map +1 -0
  330. package/lib/_models/common.model.d.ts +4 -3
  331. package/lib/_models/common.model.d.ts.map +1 -0
  332. package/lib/_models/error.model.d.ts +6 -5
  333. package/lib/_models/error.model.d.ts.map +1 -0
  334. package/lib/_pipes/highlight.pipe.d.ts +11 -10
  335. package/lib/_pipes/highlight.pipe.d.ts.map +1 -0
  336. package/lib/_services/rating.service.d.ts +19 -18
  337. package/lib/_services/rating.service.d.ts.map +1 -0
  338. package/lib/_services/samuhik-charcha.service.d.ts +14 -13
  339. package/lib/_services/samuhik-charcha.service.d.ts.map +1 -0
  340. package/lib/_services/viewer-route-util.d.ts +9 -8
  341. package/lib/_services/viewer-route-util.d.ts.map +1 -0
  342. package/lib/_services/widget-content.model.d.ts +516 -515
  343. package/lib/_services/widget-content.model.d.ts.map +1 -0
  344. package/lib/_services/widget-content.service.d.ts +102 -101
  345. package/lib/_services/widget-content.service.d.ts.map +1 -0
  346. package/lib/_shared/translate-loader.factory.d.ts +8 -7
  347. package/lib/_shared/translate-loader.factory.d.ts.map +1 -0
  348. package/lib/app-toc-lib.module.d.ts +89 -88
  349. package/lib/app-toc-lib.module.d.ts.map +1 -0
  350. package/lib/collection.config.d.ts +160 -159
  351. package/lib/collection.config.d.ts.map +1 -0
  352. package/lib/components/app-toc-analytics-tiles/app-toc-analytics-tiles.component.d.ts +18 -17
  353. package/lib/components/app-toc-analytics-tiles/app-toc-analytics-tiles.component.d.ts.map +1 -0
  354. package/lib/components/app-toc-banner/app-toc-banner.component.d.ts +226 -225
  355. package/lib/components/app-toc-banner/app-toc-banner.component.d.ts.map +1 -0
  356. package/lib/components/app-toc-cios-home/app-toc-cios-home.component.d.ts +79 -78
  357. package/lib/components/app-toc-cios-home/app-toc-cios-home.component.d.ts.map +1 -0
  358. package/lib/components/app-toc-cios-home/consent-dialog.component.d.ts +23 -22
  359. package/lib/components/app-toc-cios-home/consent-dialog.component.d.ts.map +1 -0
  360. package/lib/components/app-toc-cohorts/app-toc-cohorts.component.d.ts +32 -31
  361. package/lib/components/app-toc-cohorts/app-toc-cohorts.component.d.ts.map +1 -0
  362. package/lib/components/app-toc-content-card/app-toc-content-card.component.d.ts +48 -47
  363. package/lib/components/app-toc-content-card/app-toc-content-card.component.d.ts.map +1 -0
  364. package/lib/components/app-toc-dialog-intro-video/app-toc-dialog-intro-video.component.d.ts +15 -14
  365. package/lib/components/app-toc-dialog-intro-video/app-toc-dialog-intro-video.component.d.ts.map +1 -0
  366. package/lib/components/app-toc-discussion/app-toc-discussion.component.d.ts +22 -21
  367. package/lib/components/app-toc-discussion/app-toc-discussion.component.d.ts.map +1 -0
  368. package/lib/components/app-toc-home/app-toc-home.component.d.ts +315 -314
  369. package/lib/components/app-toc-home/app-toc-home.component.d.ts.map +1 -0
  370. package/lib/components/app-toc-home-v2/app-toc-home-v2.component.d.ts +415 -408
  371. package/lib/components/app-toc-home-v2/app-toc-home-v2.component.d.ts.map +1 -0
  372. package/lib/components/app-toc-overview/app-toc-overview.component.d.ts +48 -47
  373. package/lib/components/app-toc-overview/app-toc-overview.component.d.ts.map +1 -0
  374. package/lib/components/app-toc-session-card/app-toc-session-card.component.d.ts +23 -22
  375. package/lib/components/app-toc-session-card/app-toc-session-card.component.d.ts.map +1 -0
  376. package/lib/components/app-toc-sessions/app-toc-sessions.component.d.ts +15 -14
  377. package/lib/components/app-toc-sessions/app-toc-sessions.component.d.ts.map +1 -0
  378. package/lib/components/app-toc-single-page/app-toc-single-page.component.d.ts +150 -149
  379. package/lib/components/app-toc-single-page/app-toc-single-page.component.d.ts.map +1 -0
  380. package/lib/components/completion-survey-form/completion-survey-form.component.d.ts +43 -42
  381. package/lib/components/completion-survey-form/completion-survey-form.component.d.ts.map +1 -0
  382. package/lib/components/create-batch-dialog/create-batch-dialog.component.d.ts +28 -27
  383. package/lib/components/create-batch-dialog/create-batch-dialog.component.d.ts.map +1 -0
  384. package/lib/components/enroll-language-dialogue/enroll-language-dialogue.component.d.ts +16 -15
  385. package/lib/components/enroll-language-dialogue/enroll-language-dialogue.component.d.ts.map +1 -0
  386. package/lib/components/enroll-profile-form/enroll-profile-form.component.d.ts +196 -195
  387. package/lib/components/enroll-profile-form/enroll-profile-form.component.d.ts.map +1 -0
  388. package/lib/components/enroll-questionnaire/enroll-questionnaire.component.d.ts +45 -44
  389. package/lib/components/enroll-questionnaire/enroll-questionnaire.component.d.ts.map +1 -0
  390. package/lib/components/knowledge-artifact-details/knowledge-artifact-details.component.d.ts +55 -54
  391. package/lib/components/knowledge-artifact-details/knowledge-artifact-details.component.d.ts.map +1 -0
  392. package/lib/components/non-relevent-feedback-dialog/non-relevent-feedback-dialog.component.d.ts +19 -18
  393. package/lib/components/non-relevent-feedback-dialog/non-relevent-feedback-dialog.component.d.ts.map +1 -0
  394. package/lib/components/public-survey-form/public-survey-form.component.d.ts +44 -43
  395. package/lib/components/public-survey-form/public-survey-form.component.d.ts.map +1 -0
  396. package/lib/components/survey-form-question/survey-form-question.component.d.ts +21 -20
  397. package/lib/components/survey-form-question/survey-form-question.component.d.ts.map +1 -0
  398. package/lib/components/survey-form-section/survey-form-section.component.d.ts +14 -13
  399. package/lib/components/survey-form-section/survey-form-section.component.d.ts.map +1 -0
  400. package/lib/models/app-toc-analytics.model.d.ts +153 -152
  401. package/lib/models/app-toc-analytics.model.d.ts.map +1 -0
  402. package/lib/models/app-toc.model.d.ts +85 -84
  403. package/lib/models/app-toc.model.d.ts.map +1 -0
  404. package/lib/models/auto-complete.model.d.ts +28 -27
  405. package/lib/models/auto-complete.model.d.ts.map +1 -0
  406. package/lib/models/card-content.model.d.ts +20 -19
  407. package/lib/models/card-content.model.d.ts.map +1 -0
  408. package/lib/models/content-strip-with-tabs.model.d.ts +45 -44
  409. package/lib/models/content-strip-with-tabs.model.d.ts.map +1 -0
  410. package/lib/models/discussion-forum.model.d.ts +41 -40
  411. package/lib/models/discussion-forum.model.d.ts.map +1 -0
  412. package/lib/models/goal.model.d.ts +23 -22
  413. package/lib/models/goal.model.d.ts.map +1 -0
  414. package/lib/models/meta-tag.model.d.ts +7 -6
  415. package/lib/models/meta-tag.model.d.ts.map +1 -0
  416. package/lib/models/playlist.model.d.ts +24 -23
  417. package/lib/models/playlist.model.d.ts.map +1 -0
  418. package/lib/models/profile-revamp.model.d.ts +15 -14
  419. package/lib/models/profile-revamp.model.d.ts.map +1 -0
  420. package/lib/models/rating.model.d.ts +18 -17
  421. package/lib/models/rating.model.d.ts.map +1 -0
  422. package/lib/models/user-profile.model.d.ts +38 -37
  423. package/lib/models/user-profile.model.d.ts.map +1 -0
  424. package/lib/resolvers/app-toc-cios-resolver.service.d.ts +13 -12
  425. package/lib/resolvers/app-toc-cios-resolver.service.d.ts.map +1 -0
  426. package/lib/resolvers/app-toc-cios-user-enroll-resolver.service.d.ts +13 -12
  427. package/lib/resolvers/app-toc-cios-user-enroll-resolver.service.d.ts.map +1 -0
  428. package/lib/resolvers/app-toc-content-read-resolver.service.d.ts +17 -16
  429. package/lib/resolvers/app-toc-content-read-resolver.service.d.ts.map +1 -0
  430. package/lib/resolvers/app-toc-ext-public-resolver.service.d.ts +13 -12
  431. package/lib/resolvers/app-toc-ext-public-resolver.service.d.ts.map +1 -0
  432. package/lib/resolvers/app-toc-resolver.service.d.ts +17 -16
  433. package/lib/resolvers/app-toc-resolver.service.d.ts.map +1 -0
  434. package/lib/resolvers/config-resolver.service.d.ts +12 -11
  435. package/lib/resolvers/config-resolver.service.d.ts.map +1 -0
  436. package/lib/resolvers/profile-resolver.service.d.ts +12 -11
  437. package/lib/resolvers/profile-resolver.service.d.ts.map +1 -0
  438. package/lib/resolvers/restricted-features-resolver.service.d.ts +12 -11
  439. package/lib/resolvers/restricted-features-resolver.service.d.ts.map +1 -0
  440. package/lib/routes/app-toc-home/app-toc-home.component.d.ts +20 -19
  441. package/lib/routes/app-toc-home/app-toc-home.component.d.ts.map +1 -0
  442. package/lib/routes/app-toc-home/app-toc-home.directive.d.ts +9 -8
  443. package/lib/routes/app-toc-home/app-toc-home.directive.d.ts.map +1 -0
  444. package/lib/routes/app-toc-home/app-toc-home.service.d.ts +9 -8
  445. package/lib/routes/app-toc-home/app-toc-home.service.d.ts.map +1 -0
  446. package/lib/services/access-control.service.d.ts +30 -29
  447. package/lib/services/access-control.service.d.ts.map +1 -0
  448. package/lib/services/action.service.d.ts +10 -9
  449. package/lib/services/action.service.d.ts.map +1 -0
  450. package/lib/services/app-toc-v2.service.d.ts +17 -16
  451. package/lib/services/app-toc-v2.service.d.ts.map +1 -0
  452. package/lib/services/app-toc.service.d.ts +241 -235
  453. package/lib/services/app-toc.service.d.ts.map +1 -0
  454. package/lib/services/certificate.service.d.ts +43 -42
  455. package/lib/services/certificate.service.d.ts.map +1 -0
  456. package/lib/services/discuss-utils.service.d.ts +34 -33
  457. package/lib/services/discuss-utils.service.d.ts.map +1 -0
  458. package/lib/services/editor.service.d.ts +18 -17
  459. package/lib/services/editor.service.d.ts.map +1 -0
  460. package/lib/services/load-check.service.d.ts +9 -8
  461. package/lib/services/load-check.service.d.ts.map +1 -0
  462. package/lib/services/loader.service.d.ts +17 -16
  463. package/lib/services/loader.service.d.ts.map +1 -0
  464. package/lib/services/mobile-apps.service.d.ts +39 -38
  465. package/lib/services/mobile-apps.service.d.ts.map +1 -0
  466. package/lib/services/netcore.service.d.ts +34 -33
  467. package/lib/services/netcore.service.d.ts.map +1 -0
  468. package/lib/services/nps-grid.service.d.ts +16 -15
  469. package/lib/services/nps-grid.service.d.ts.map +1 -0
  470. package/lib/services/otp.service.d.ts +21 -20
  471. package/lib/services/otp.service.d.ts.map +1 -0
  472. package/lib/services/profile-v2.service.d.ts +21 -20
  473. package/lib/services/profile-v2.service.d.ts.map +1 -0
  474. package/lib/services/reset-ratings.service.d.ts +9 -8
  475. package/lib/services/reset-ratings.service.d.ts.map +1 -0
  476. package/lib/services/resource-download-helper.service.d.ts +30 -29
  477. package/lib/services/resource-download-helper.service.d.ts.map +1 -0
  478. package/lib/services/timer.service.d.ts +10 -9
  479. package/lib/services/timer.service.d.ts.map +1 -0
  480. package/lib/services/title-tag.service.d.ts +22 -21
  481. package/lib/services/title-tag.service.d.ts.map +1 -0
  482. package/lib/services/user-profile.service.d.ts +25 -24
  483. package/lib/services/user-profile.service.d.ts.map +1 -0
  484. package/lib/services/viewer-data.service.d.ts +59 -58
  485. package/lib/services/viewer-data.service.d.ts.map +1 -0
  486. package/lib/services/viewer-util.service.d.ts +77 -76
  487. package/lib/services/viewer-util.service.d.ts.map +1 -0
  488. package/lib/share-toc/share-toc/share-toc.component.d.ts +57 -56
  489. package/lib/share-toc/share-toc/share-toc.component.d.ts.map +1 -0
  490. package/lib/share-toc/share-toc.module.d.ts +33 -32
  491. package/lib/share-toc/share-toc.module.d.ts.map +1 -0
  492. package/package.json +1 -1
  493. package/public-api.d.ts +59 -56
  494. package/public-api.d.ts.map +1 -0
  495. package/sunbird-cb-toc.d.ts.map +1 -0
@@ -1,1148 +1,1177 @@
1
- import { Component, Input } from '@angular/core';
2
- import { NsContent } from '../../../../_services/widget-content.model';
3
- import { viewerRouteGenerator } from '../../../../_services/viewer-route-util';
4
- import { WsEvents } from '@sunbird-cb/utils-v2';
5
- import { CertificateDialogComponent } from '../../certificate-dialog/certificate-dialog.component';
6
- import { animate, style, transition, trigger } from '@angular/animations';
7
- /* tslint:disable*/
8
- import _ from 'lodash';
9
- import moment from 'moment';
10
- import * as i0 from "@angular/core";
11
- import * as i1 from "@sunbird-cb/utils-v2";
12
- import * as i2 from "@angular/material/legacy-dialog";
13
- import * as i3 from "../../../../services/certificate.service";
14
- import * as i4 from "../../../../services/app-toc.service";
15
- import * as i5 from "@sunbird-cb/consumption";
16
- import * as i6 from "../../../../services/resource-download-helper.service";
17
- import * as i7 from "@angular/material/legacy-snack-bar";
18
- import * as i8 from "@angular/common";
19
- import * as i9 from "@angular/router";
20
- import * as i10 from "@angular/material/icon";
21
- import * as i11 from "@angular/material/menu";
22
- import * as i12 from "@angular/material/progress-spinner";
23
- import * as i13 from "../../content-progress/content-progress.component";
24
- import * as i14 from "ng-circle-progress";
25
- import * as i15 from "@angular/material/legacy-tooltip";
26
- import * as i16 from "@ngx-translate/core";
27
- import * as i17 from "../pipes/truncate.pipe";
28
- export class AppTocContentCardV2Component {
29
- constructor(events, dialog, renderer, certificateService, appTocSvc, contentLangSvc, resourceDownloadHelperSvc, configSvc, snackBar) {
30
- this.events = events;
31
- this.dialog = dialog;
32
- this.renderer = renderer;
33
- this.certificateService = certificateService;
34
- this.appTocSvc = appTocSvc;
35
- this.contentLangSvc = contentLangSvc;
36
- this.resourceDownloadHelperSvc = resourceDownloadHelperSvc;
37
- this.configSvc = configSvc;
38
- this.snackBar = snackBar;
39
- this.content = null;
40
- this.expandAll = false;
41
- this.forPreview = false;
42
- this.componentName = 'toc';
43
- this.expandActive = true;
44
- this.hierarchyMapData = {};
45
- this.batchData = null;
46
- this.isPreAssessment = false;
47
- this.baseContentReadData = null;
48
- this.mlCourse = null;
49
- this.parentMilestoneLocked = false; // Passed from parent when inside a locked milestone
50
- this.hasContentStructure = false;
51
- this.downloadCertificateLoading = false;
52
- this.enumContentTypes = NsContent.EDisplayContentTypes;
53
- this.contentStructure = {
54
- assessment: 0,
55
- finalTest: 0,
56
- course: 0,
57
- handsOn: 0,
58
- interactiveVideo: 0,
59
- learningModule: 0,
60
- other: 0,
61
- pdf: 0,
62
- survey: 0,
63
- podcast: 0,
64
- practiceTest: 0,
65
- quiz: 0,
66
- video: 0,
67
- webModule: 0,
68
- webPage: 0,
69
- youtube: 0,
70
- interactivecontent: 0,
71
- offlineSession: 0,
72
- };
73
- this.defaultThumbnail = '';
74
- this.viewChildren = false;
75
- this.primaryCategory = NsContent.EPrimaryCategory;
76
- this.pageScrollSubscription = null;
77
- this.achievementLoading = false;
78
- // Cached computed properties for performance optimization
79
- this._cachedIsCollection = false;
80
- this._cachedIsModule = false;
81
- this._cachedIsResource = false;
82
- this._cachedIsMilestone = false;
83
- this._cachedIsMilestoneLocked = false;
84
- this._cachedIsParentMilestoneLocked = false;
85
- this._cachedIsContentUnlocked = true;
86
- this._cachedCheckForCuratedProgram = false;
87
- this._cachedIsMilestoneAssessment = false;
88
- this._cachedIsMilestoneAssessmentLocked = false;
89
- this._cachedResourceLink = { url: '', queryParams: {} };
90
- this._cacheInitialized = false;
91
- }
92
- ngOnInit() {
93
- this.evaluateImmediateChildrenStructure();
94
- this.initializeComputedProperties();
95
- // this.route.data.subscribe(data => {
96
- // this.defaultThumbnail = data.configData.data.logos.defaultContent
97
- // }
98
- // )
99
- this.resourceScroll();
100
- }
101
- /**
102
- * Initialize all computed properties once to avoid expensive getter calculations
103
- * on every change detection cycle
104
- */
105
- initializeComputedProperties() {
106
- this.computeAllCachedProperties();
107
- }
108
- /**
109
- * Compute all cached properties at once for performance optimization
110
- */
111
- computeAllCachedProperties() {
112
- if (!this.content) {
113
- this._cacheInitialized = false;
114
- return;
115
- }
116
- const contentId = this.content.identifier;
117
- const hashData = this.hierarchyMapData && this.hierarchyMapData[contentId];
118
- // Use hashmap data if available for pre-computed values
119
- if (hashData) {
120
- this._cachedIsCollection = hashData.isCollection !== undefined ?
121
- hashData.isCollection : this.content.mimeType === NsContent.EMimeTypes.COLLECTION;
122
- this._cachedIsModule = hashData.isModule !== undefined ?
123
- hashData.isModule : this.content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
124
- this._cachedIsResource = hashData.isResource !== undefined ?
125
- hashData.isResource : this.computeIsResource();
126
- this._cachedIsMilestone = hashData.isMilestone !== undefined ?
127
- hashData.isMilestone : this.computeIsMilestone();
128
- this._cachedIsMilestoneLocked = hashData.computedIsLocked !== undefined ?
129
- hashData.computedIsLocked : this.computeIsMilestoneLocked();
130
- this._cachedIsParentMilestoneLocked = hashData.isParentMilestoneLocked !== undefined ?
131
- hashData.isParentMilestoneLocked : this.computeIsParentMilestoneLocked();
132
- }
133
- else {
134
- // Fallback to direct computation if hashmap not available
135
- this._cachedIsCollection = this.content.mimeType === NsContent.EMimeTypes.COLLECTION;
136
- this._cachedIsModule = this.content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
137
- this._cachedIsResource = this.computeIsResource();
138
- this._cachedIsMilestone = this.computeIsMilestone();
139
- this._cachedIsMilestoneLocked = this.computeIsMilestoneLocked();
140
- this._cachedIsParentMilestoneLocked = this.computeIsParentMilestoneLocked();
141
- }
142
- this._cachedCheckForCuratedProgram = this.computeCheckForCuratedProgram();
143
- this._cachedIsContentUnlocked = this.computeIsContentUnlocked();
144
- this._cachedIsMilestoneAssessment = this.computeIsMilestoneAssessment();
145
- this._cachedIsMilestoneAssessmentLocked = this.computeIsMilestoneAssessmentLocked();
146
- this._cachedResourceLink = this.computeResourceLink();
147
- this._cacheInitialized = true;
148
- }
149
- computeIsResource() {
150
- if (!this.content)
151
- return false;
152
- return (this.content.primaryCategory === NsContent.EPrimaryCategory.RESOURCE ||
153
- this.content.primaryCategory === NsContent.EPrimaryCategory.PRACTICE_RESOURCE ||
154
- this.content.primaryCategory === NsContent.EPrimaryCategory.FINAL_ASSESSMENT ||
155
- this.content.primaryCategory === NsContent.EPrimaryCategory.COMP_ASSESSMENT);
156
- }
157
- computeIsMilestone() {
158
- if (!this.content)
159
- return false;
160
- const primaryCat = this.content.primaryCategory;
161
- const courseCat = this.content.courseCategory;
162
- return primaryCat === 'Milestone' || courseCat === 'Milestone';
163
- }
164
- computeCheckForCuratedProgram() {
165
- if (this.content && this.content.parent && this.hierarchyMapData && this.hierarchyMapData[this.content.parent]) {
166
- const parentData = this.hierarchyMapData[this.content.parent];
167
- return parentData && parentData.primaryCategory === NsContent.EPrimaryCategory.CURATED_PROGRAM &&
168
- parentData.compatibilityLevel >= 5 &&
169
- parentData.contextLockingType === NsContent.EContextLockingType.COURSE_ASSESSMENT_ONLY;
170
- }
171
- return false;
172
- }
173
- computeIsContentUnlocked() {
174
- if (this._cachedCheckForCuratedProgram) {
175
- if (this.content && this.content.parent && this.hierarchyMapData && this.hierarchyMapData[this.content.parent]) {
176
- const parentData = this.hierarchyMapData[this.content.parent];
177
- let completedLeafNodes = [];
178
- parentData.leafNodes.forEach((_ele) => {
179
- if (this.hierarchyMapData && this.hierarchyMapData[_ele]) {
180
- const childData = this.hierarchyMapData[_ele];
181
- if (childData && childData.completionStatus === 2) {
182
- completedLeafNodes.push(childData);
183
- }
184
- }
185
- });
186
- return completedLeafNodes.length >= parentData.leafNodesCount - 1;
187
- }
188
- return false;
189
- }
190
- return true;
191
- }
192
- computeResourceLink() {
193
- if (this.content) {
194
- let mimeType = '';
195
- if (this.content && this.content.courseCategory === 'Pre Enrolment Assessment' &&
196
- this.content.mimeType === 'application/vnd.ekstep.content-collection') {
197
- mimeType = 'application/vnd.sunbird.questionset';
198
- this.content.mimeType = NsContent.EMimeTypes.FINAL_ASSESSMENT;
199
- }
200
- else {
201
- mimeType = this.content.mimeType;
202
- }
203
- const selectedLanguage = this.mlCourse ? this.contentLangSvc.getSelectedLanguage(this.mlCourse) : undefined;
204
- return viewerRouteGenerator(this.content.identifier, mimeType, this.baseContentReadData?.identifier || this.rootId, this.baseContentReadData?.contentType || this.rootContentType, this.forPreview, this.content.primaryCategory, this.batchId, this.content?.name || this.baseContentReadData?.name, (selectedLanguage ? selectedLanguage.langId : null), (selectedLanguage ? selectedLanguage.identifier : null));
205
- }
206
- return { url: '', queryParams: {} };
207
- }
208
- computeIsMilestoneLocked() {
209
- // Only apply milestone locking for Learning Pathway content
210
- if (!this.baseContentReadData || this.baseContentReadData.courseCategory !== 'Learning Pathway') {
211
- return false;
212
- }
213
- if (!this.content) {
214
- return false;
215
- }
216
- // Check if current content is a Milestone
217
- if (!this._cachedIsMilestone && !this.computeIsMilestone()) {
218
- return false;
219
- }
220
- // Check if hashmap has pre-computed locking status (preferred - computed by service)
221
- const hashData = this.hierarchyMapData && this.hierarchyMapData[this.content.identifier];
222
- console.log(`computeIsMilestoneLocked for ${this.content.identifier} (${this.content.name}):`, {
223
- hashData,
224
- computedIsLocked: hashData?.computedIsLocked,
225
- contentIsLocked: this.content.isLocked
226
- });
227
- if (hashData && hashData.computedIsLocked !== undefined) {
228
- return hashData.computedIsLocked;
229
- }
230
- // If milestone has isLocked flag explicitly set to false, it's unlocked
231
- if (this.content.isLocked === false) {
232
- return false;
233
- }
234
- // Fallback: All milestones are locked by default until computed otherwise
235
- // This ensures proper locking until the hashmap is updated with progress
236
- return true;
237
- }
238
- computeIsParentMilestoneLocked() {
239
- if (this.parentMilestoneLocked) {
240
- return true;
241
- }
242
- if (!this.baseContentReadData || this.baseContentReadData.courseCategory !== 'Learning Pathway') {
243
- return false;
244
- }
245
- if (!this.content || !this.hierarchyMapData) {
246
- return false;
247
- }
248
- // Check hashmap for pre-computed value
249
- const hashData = this.hierarchyMapData[this.content.identifier];
250
- if (hashData && hashData.isParentMilestoneLocked !== undefined) {
251
- return hashData.isParentMilestoneLocked;
252
- }
253
- // Traverse up the hierarchy to find if any ancestor is a locked Milestone
254
- let currentParentId = this.content.parent;
255
- const maxDepth = 5;
256
- let depth = 0;
257
- while (currentParentId && depth < maxDepth) {
258
- const parentData = this.hierarchyMapData[currentParentId];
259
- if (parentData) {
260
- if ((parentData.isMilestone || parentData.primaryCategory === 'Milestone' || parentData.courseCategory === 'Milestone') &&
261
- (parentData.computedIsLocked || parentData.isLocked)) {
262
- return true;
263
- }
264
- currentParentId = parentData.parent;
265
- }
266
- else {
267
- break;
268
- }
269
- depth++;
270
- }
271
- return false;
272
- }
273
- /**
274
- * Check if current content is a milestone assessment (Course Assessment or Final Assessment inside a Milestone)
275
- */
276
- computeIsMilestoneAssessment() {
277
- if (!this.baseContentReadData || this.baseContentReadData.courseCategory !== 'Learning Pathway') {
278
- return false;
279
- }
280
- if (!this.content || !this.hierarchyMapData) {
281
- return false;
282
- }
283
- // Check if this is an assessment
284
- const isAssessment = this.content.primaryCategory === 'Course Assessment' ||
285
- this.content.courseCategory === 'Course Assessment' ||
286
- (this.content.name && this.content.name.toLowerCase().includes('assessment'));
287
- if (!isAssessment) {
288
- return false;
289
- }
290
- // Check if the parent or grandparent is a milestone (since assessments can be inside courses inside milestones)
291
- if (this.content.parent && this.hierarchyMapData[this.content.parent]) {
292
- const parentData = this.hierarchyMapData[this.content.parent];
293
- // Check if direct parent is a milestone
294
- if (parentData.isMilestone || parentData.primaryCategory === 'Milestone' || parentData.courseCategory === 'Milestone') {
295
- return true;
296
- }
297
- // Check if grandparent is a milestone (for assessments inside courses inside milestones)
298
- if (parentData.parent && this.hierarchyMapData[parentData.parent]) {
299
- const grandparentData = this.hierarchyMapData[parentData.parent];
300
- return grandparentData.isMilestone || grandparentData.primaryCategory === 'Milestone' || grandparentData.courseCategory === 'Milestone';
301
- }
302
- }
303
- return false;
304
- }
305
- /**
306
- * Check if milestone assessment should be locked
307
- * Assessment is locked if:
308
- * 1. It's an assessment within a milestone
309
- * 2. The parent milestone is unlocked (otherwise handled by parent milestone lock)
310
- * 3. NOT all mandatory content in the same milestone is completed
311
- */
312
- computeIsMilestoneAssessmentLocked() {
313
- // Only apply to assessments within milestones
314
- if (!this._cachedIsMilestoneAssessment && !this.computeIsMilestoneAssessment()) {
315
- return false;
316
- }
317
- // Check if hashmap has pre-computed assessment locking status
318
- const hashData = this.hierarchyMapData && this.hierarchyMapData[this.content?.identifier || ''];
319
- if (hashData && hashData.isAssessmentLocked !== undefined) {
320
- return hashData.isAssessmentLocked;
321
- }
322
- // If already completed, don't lock
323
- if (this.content && (this.content.completionStatus === 2 ||
324
- (this.content.completionPercentage && this.content.completionPercentage >= 100))) {
325
- return false;
326
- }
327
- // Find the milestone ID (could be parent or grandparent)
328
- let milestoneId;
329
- let milestone;
330
- // Check if direct parent is milestone
331
- if (this.content?.parent && this.hierarchyMapData && this.hierarchyMapData[this.content.parent]) {
332
- const parentData = this.hierarchyMapData[this.content.parent];
333
- if (parentData.isMilestone || parentData.primaryCategory === 'Milestone' || parentData.courseCategory === 'Milestone') {
334
- milestoneId = this.content.parent;
335
- milestone = parentData;
336
- }
337
- else if (parentData.parent && this.hierarchyMapData[parentData.parent]) {
338
- // Check if grandparent is milestone
339
- const grandparentData = this.hierarchyMapData[parentData.parent];
340
- if (grandparentData.isMilestone || grandparentData.primaryCategory === 'Milestone' || grandparentData.courseCategory === 'Milestone') {
341
- milestoneId = parentData.parent;
342
- milestone = grandparentData;
343
- }
344
- }
345
- }
346
- if (!milestoneId || !milestone) {
347
- return false;
348
- }
349
- // If the parent milestone itself is locked, don't add additional locking
350
- // (the parent lock will handle it)
351
- if (milestone.computedIsLocked || milestone.isLocked) {
352
- return false;
353
- }
354
- // Check if all mandatory content in the milestone is completed
355
- let mandatoryCount = 0;
356
- let completedMandatoryCount = 0;
357
- // Check all items in hashmap that belong to this milestone
358
- for (const key of Object.keys(this.hierarchyMapData)) {
359
- const item = this.hierarchyMapData[key];
360
- // Check if this item belongs to the milestone (direct child or nested)
361
- // Most content will be under courses that are under milestone
362
- let itemBelongsToMilestone = false;
363
- if (item.parent === milestoneId) {
364
- itemBelongsToMilestone = true;
365
- }
366
- else if (item.parent && this.hierarchyMapData[item.parent]) {
367
- // Check if parent is a course under this milestone
368
- const parentItem = this.hierarchyMapData[item.parent];
369
- if (parentItem.parent === milestoneId && parentItem.primaryCategory === 'Course') {
370
- itemBelongsToMilestone = true;
371
- }
372
- }
373
- if (!itemBelongsToMilestone)
374
- continue;
375
- // Skip assessments - we're checking if learning content is complete
376
- const isItemAssessment = item.primaryCategory === 'Course Assessment' ||
377
- item.primaryCategory === 'Final Assessment' ||
378
- item.primaryCategory === 'Standalone Assessment' ||
379
- item.courseCategory === 'Course Assessment' ||
380
- item.mimeType === 'application/vnd.sunbird.questionset' ||
381
- item.mimeType === 'application/quiz' ||
382
- (item.name && item.name.toLowerCase().includes('assessment'));
383
- if (isItemAssessment)
384
- continue;
385
- // Check if this content is mandatory (courses and non-optional content)
386
- // By default, courses are mandatory unless explicitly marked otherwise
387
- if (item.isMandatory !== false && (item.primaryCategory === 'Course' || item.isMandatory === true)) {
388
- // Count all courses and mandatory items as they need to be completed
389
- mandatoryCount++;
390
- const isCompleted = item.completionStatus === 2 || item.status === 2 ||
391
- item.completionPercentage >= 100 || item.progress >= 100;
392
- if (isCompleted) {
393
- completedMandatoryCount++;
394
- }
395
- }
396
- }
397
- // If there are no mandatory items, assessment is unlocked
398
- if (mandatoryCount === 0) {
399
- return false;
400
- }
401
- // Lock assessment if not all mandatory items are completed
402
- const allMandatoryComplete = completedMandatoryCount >= mandatoryCount;
403
- return !allMandatoryComplete;
404
- }
405
- // FOR RIGHT SIDE RESOURCE SCROLL ON TOC PAGE
406
- resourceScroll() {
407
- this.pageScrollSubscription = this.appTocSvc.updatePageScroll.subscribe((value) => {
408
- if (value) {
409
- setTimeout(() => {
410
- this.scrollView();
411
- }, 700);
412
- }
413
- });
414
- }
415
- // TO UPDATE RESOURCE BEHAVOUR SUBJECT FOR RESOURCE SCROLL
416
- changeResource() {
417
- this.appTocSvc.getPageScroll.next(true);
418
- }
419
- ngOnChanges(changes) {
420
- let shouldRecomputeCache = false;
421
- for (const property in changes) {
422
- if (property === 'expandAll') {
423
- this.viewChildren = this.expandAll;
424
- }
425
- if (property === 'pathSet' && changes['pathSet']) {
426
- let currentValue = changes['pathSet'].currentValue;
427
- let previousValue = changes['pathSet'].previousValue;
428
- if (currentValue && previousValue) {
429
- const eqSet = (xs, ys) => xs.size === ys.size &&
430
- [...xs].every((x) => ys.has(x));
431
- if (!eqSet(previousValue, currentValue)) { }
432
- }
433
- // if(previousValue === undefined){
434
- // setTimeout(()=>{
435
- // },700)
436
- // }
437
- }
438
- // this.appTocSvc.getPageScroll.next(true)
439
- if (property === 'hierarchyMapData') {
440
- if (_.isEmpty(changes['hierarchyMapData'].currentValue)) {
441
- // this.loadingOverallPRogress = true
442
- }
443
- else {
444
- if (this.content) {
445
- this.updateChildParentMap(this.content.identifier);
446
- }
447
- shouldRecomputeCache = true;
448
- }
449
- }
450
- // Recompute cache when critical inputs change
451
- if (property === 'content' || property === 'baseContentReadData' ||
452
- property === 'batchId' || property === 'forPreview' ||
453
- property === 'parentMilestoneLocked' || property === 'mlCourse') {
454
- shouldRecomputeCache = true;
455
- }
456
- }
457
- // Recompute all cached properties if needed
458
- if (shouldRecomputeCache) {
459
- this.computeAllCachedProperties();
460
- }
461
- // console.log('pre assessment content---', this.content)
462
- // console.log('this.hierarchyMapData---', this.hierarchyMapData)
463
- }
464
- check(content) {
465
- if (this.expandActive) {
466
- content.viewChildren = this.pathSet && this.pathSet.has(content.identifier) || content.viewChildren;
467
- }
468
- return content.viewChildren;
469
- }
470
- get isCollection() {
471
- if (this._cacheInitialized) {
472
- return this._cachedIsCollection;
473
- }
474
- if (this.content) {
475
- return this.content.mimeType === NsContent.EMimeTypes.COLLECTION;
476
- }
477
- return false;
478
- }
479
- get isModule() {
480
- if (this._cacheInitialized) {
481
- return this._cachedIsModule;
482
- }
483
- if (this.content) {
484
- return this.content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
485
- }
486
- return false;
487
- }
488
- checkModule(content) {
489
- if (content) {
490
- return content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
491
- }
492
- return false;
493
- }
494
- checkIsModule(content) {
495
- if (content) {
496
- return content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
497
- }
498
- return false;
499
- }
500
- get isBatchInProgess() {
501
- if (this.batchData && (this.batchData.content && this.batchData.content.length) && this.batchData.enrolled) {
502
- const batchData = this.batchData.content[0];
503
- if (batchData && batchData.endDate) {
504
- const now = moment().format('YYYY-MM-DD');
505
- const startDate = moment(batchData.startDate).format('YYYY-MM-DD');
506
- const endDate = batchData.endDate ? moment(batchData.endDate).format('YYYY-MM-DD') : now;
507
- return (
508
- // batch.status &&
509
- moment(startDate).isSameOrBefore(now)
510
- && moment(endDate).isSameOrAfter(now));
511
- }
512
- return true;
513
- }
514
- return false;
515
- }
516
- get isResource() {
517
- if (this._cacheInitialized) {
518
- return this._cachedIsResource;
519
- }
520
- return this.computeIsResource();
521
- }
522
- get resourceLink() {
523
- if (this._cacheInitialized) {
524
- return this._cachedResourceLink;
525
- }
526
- return this.computeResourceLink();
527
- }
528
- progressColor() {
529
- // if (this.currentProgress <= 30) {
530
- // return '#D13924'
531
- // } if (this.currentProgress > 30 && this.currentProgress <= 70) {
532
- // return '#E99E38'
533
- // }
534
- // if (this.currentProgress > 70 && this.currentProgress <= 100) {
535
- // return '#1D8923'
536
- // }
537
- return '#1D8923';
538
- }
539
- progressColor2() {
540
- return '#f27d00';
541
- }
542
- evaluateImmediateChildrenStructure() {
543
- if (this.content && this.content.children && this.content.children.length) {
544
- this.content.children.forEach((child) => {
545
- if (child.primaryCategory === NsContent.EPrimaryCategory.COURSE) {
546
- this.contentStructure.course += 1;
547
- }
548
- else if (child.primaryCategory === NsContent.EPrimaryCategory.KNOWLEDGE_ARTIFACT) {
549
- this.contentStructure.other += 1;
550
- }
551
- else if (child.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
552
- this.contentStructure.learningModule += 1;
553
- }
554
- else if (child.primaryCategory === NsContent.EPrimaryCategory.OFFLINE_SESSION) {
555
- this.contentStructure.offlineSession += 1;
556
- }
557
- else if (child.primaryCategory === NsContent.EPrimaryCategory.RESOURCE) {
558
- switch (child.mimeType) {
559
- case NsContent.EMimeTypes.HANDS_ON:
560
- this.contentStructure.handsOn += 1;
561
- break;
562
- case NsContent.EMimeTypes.MP3:
563
- this.contentStructure.podcast += 1;
564
- break;
565
- case NsContent.EMimeTypes.MP4:
566
- case NsContent.EMimeTypes.M3U8:
567
- this.contentStructure.video += 1;
568
- break;
569
- case NsContent.EMimeTypes.INTERACTION:
570
- this.contentStructure.interactiveVideo += 1;
571
- break;
572
- case NsContent.EMimeTypes.PDF:
573
- this.contentStructure.pdf += 1;
574
- break;
575
- case NsContent.EMimeTypes.OFFLINE_SESSION:
576
- this.contentStructure.offlineSession += 1;
577
- break;
578
- case NsContent.EMimeTypes.SURVEY:
579
- this.contentStructure.survey += 1;
580
- break;
581
- case NsContent.EMimeTypes.HTML:
582
- this.contentStructure.webPage += 1;
583
- break;
584
- case NsContent.EMimeTypes.QUIZ:
585
- if (child.resourceType === 'Assessment') {
586
- this.contentStructure.assessment += 1;
587
- }
588
- else {
589
- this.contentStructure.quiz += 1;
590
- }
591
- break;
592
- case NsContent.EMimeTypes.PRACTICE_RESOURCE:
593
- // case NsContent.EMimeTypes.FINAL_ASSESSMENT:
594
- // case NsContent.EMimeTypes.PRACTICE_RESOURCE:
595
- this.contentStructure.practiceTest += 1;
596
- break;
597
- case NsContent.EMimeTypes.WEB_MODULE:
598
- this.contentStructure.webModule += 1;
599
- break;
600
- case NsContent.EMimeTypes.YOUTUBE:
601
- this.contentStructure.youtube += 1;
602
- break;
603
- default:
604
- this.contentStructure.other += 1;
605
- break;
606
- }
607
- }
608
- });
609
- }
610
- for (const key in this.contentStructure) {
611
- if (this.contentStructure[key] > 0) {
612
- this.hasContentStructure = true;
613
- }
614
- }
615
- }
616
- get contextPath() {
617
- return {
618
- contextId: this.rootId,
619
- contextPath: this.rootContentType,
620
- batchId: this.batchId,
621
- };
622
- }
623
- contentTrackBy(_index, content) {
624
- if (!content) {
625
- return null;
626
- }
627
- return content.identifier;
628
- }
629
- raiseTelemetry() {
630
- // if (this.forPreview) { return }
631
- if (this.content) {
632
- this.events.raiseInteractTelemetry({
633
- type: 'click',
634
- subType: `card-tocContentCard`,
635
- // id: this.content.identifier || '',
636
- }, {
637
- // contentId: this.content.identifier || '',
638
- // contentType: this.content.primaryCategory,
639
- id: this.content.identifier || '',
640
- type: this.content.primaryCategory,
641
- rollup: {
642
- l1: this.rootId || '',
643
- },
644
- ver: `${this.content.version}${''}`,
645
- }, {
646
- pageIdExt: `${_.camelCase(this.content.primaryCategory)}-card`,
647
- module: _.camelCase(this.content.primaryCategory),
648
- });
649
- }
650
- }
651
- get isAllowed() {
652
- if (this.content) {
653
- return !(NsContent.UN_SUPPORTED_DATA_TYPES_FOR_NON_BATCH_USERS.indexOf(this.content.mimeType) >= 0);
654
- }
655
- return false;
656
- }
657
- get isEnabled() {
658
- return true;
659
- }
660
- get isEnrolled() {
661
- return this.batchId ? true : false;
662
- }
663
- updateChildParentMap(identifier) {
664
- if (this.hierarchyMapData && this.hierarchyMapData[identifier]) {
665
- let localContentData = this.hierarchyMapData[identifier];
666
- if (!(localContentData.primaryCategory === NsContent.EPrimaryCategory.RESOURCE
667
- || localContentData.primaryCategory === NsContent.EPrimaryCategory.PRACTICE_RESOURCE
668
- || localContentData.primaryCategory === NsContent.EPrimaryCategory.FINAL_ASSESSMENT
669
- || localContentData.primaryCategory === NsContent.EPrimaryCategory.COMP_ASSESSMENT)) {
670
- // real percent logic
671
- // const total = localContentData.leafNodes.reduce((sum: number, childId: string) => {
672
- // return sum + Number(this.hierarchyMapData[childId].completionPercentage || 0)
673
- // }, 0)
674
- // console.log('total ', total)
675
- // if(total > 0) {
676
- // this.hierarchyMapData[identifier]['completionPercentage'] = total / _.toInteger(_.get(this.hierarchyMapData[identifier], 'leafNodesCount'))
677
- // }
678
- if (localContentData.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
679
- this.hierarchyMapData[identifier]['duration'] = this.hierarchyMapData[identifier].leafNodes.reduce((sum, childID) => {
680
- if (this.hierarchyMapData && this.hierarchyMapData[childID]) {
681
- return sum + Number(this.hierarchyMapData[childID].duration || this.hierarchyMapData[childID].expectedDuration || 0);
682
- }
683
- }, 0);
684
- }
685
- // tslint:disable
686
- const completedItems = _.filter(this.hierarchyMapData[identifier].leafNodes, r => (this.hierarchyMapData[r] && (this.hierarchyMapData[r].completionStatus === 2 || this.hierarchyMapData[r].completionPercentage === 100)));
687
- const totalCount = _.toInteger(_.get(this.hierarchyMapData[identifier], 'leafNodesCount')) || 1;
688
- this.hierarchyMapData[identifier]['completionPercentage'] = Number(((completedItems.length / totalCount) * 100).toFixed());
689
- this.hierarchyMapData[identifier]['completionStatus'] = (this.hierarchyMapData[identifier].completionPercentage >= 100) ? 2 : 1;
690
- }
691
- return this.hierarchyMapData[identifier];
692
- }
693
- return '';
694
- }
695
- getCompletionPercentage(identifier) {
696
- // console.log('getCompletionPercentage', identifier)
697
- // console.log('this.hierarchyMapData[identifier] : ', this.hierarchyMapData[identifier])
698
- // const item = this.updateChildParentMap(identifier)
699
- let percent = this.hierarchyMapData && this.hierarchyMapData[identifier] && this.hierarchyMapData[identifier].completionPercentage || 0;
700
- return this.roundIfDecimal(percent);
701
- }
702
- roundIfDecimal(value) {
703
- if (!Number.isInteger(value)) {
704
- return parseFloat(value.toFixed(2));
705
- }
706
- return value;
707
- }
708
- getCompletionStatus(identifier) {
709
- // console.log('getCompletionStatus')
710
- // const item = this.updateChildParentMap(identifier)
711
- return this.hierarchyMapData && this.hierarchyMapData[identifier] && this.hierarchyMapData[identifier].completionStatus;
712
- }
713
- openCertificateDialog(certData) {
714
- const cet = certData;
715
- this.dialog.open(CertificateDialogComponent, {
716
- // height: '400px',
717
- width: '1300px',
718
- data: { cet },
719
- // panelClass: 'custom-dialog-container',
720
- });
721
- }
722
- scrollView() {
723
- try {
724
- let errorField = this.renderer.selectRootElement('.resource-container .resource-active');
725
- if (errorField) {
726
- errorField.scrollIntoView({ behavior: "smooth", block: "start", inline: "nearest" });
727
- }
728
- if (this.componentName === 'toc') {
729
- if (errorField) {
730
- const rect = errorField.getBoundingClientRect();
731
- if (rect.top - 420 > 0) {
732
- window.scroll(420, rect.top - 148);
733
- }
734
- }
735
- }
736
- setTimeout(() => {
737
- this.appTocSvc.getPageScroll.next(false);
738
- }, 700);
739
- // else {
740
- // errorField.scrollIntoView({ behavior: "smooth", block: "start", inline: "nearest" });
741
- // const rect = errorField.getBoundingClientRect();
742
- // errorField.scroll(0,rect.top-56)
743
- // }
744
- }
745
- catch (err) {
746
- }
747
- }
748
- downloadCertificate(certificateData) {
749
- this.events.raiseInteractTelemetry({
750
- type: WsEvents.EnumInteractTypes.CLICK,
751
- id: 'view-certificate',
752
- subType: WsEvents.EnumInteractSubTypes.CERTIFICATE,
753
- }, {
754
- id: certificateData,
755
- type: WsEvents.EnumInteractSubTypes.CERTIFICATE,
756
- });
757
- if (certificateData) {
758
- this.downloadCertificateLoading = true;
759
- let certData = certificateData;
760
- this.certificateService.downloadCertificate_v2(certData).subscribe((res) => {
761
- this.downloadCertificateLoading = false;
762
- const cet = res.result.printUri;
763
- this.dialog.open(CertificateDialogComponent, {
764
- width: '1300px',
765
- data: { cet, certId: certData.identifier },
766
- });
767
- });
768
- }
769
- else {
770
- this.downloadCertificateLoading = false;
771
- }
772
- }
773
- ngOnDestroy() {
774
- if (this.pageScrollSubscription) {
775
- this.pageScrollSubscription.unsubscribe();
776
- }
777
- }
778
- get checkForCuratedProgram() {
779
- if (this._cacheInitialized) {
780
- return this._cachedCheckForCuratedProgram;
781
- }
782
- return this.computeCheckForCuratedProgram();
783
- }
784
- get isContentUnlocked() {
785
- if (this._cacheInitialized) {
786
- return this._cachedIsContentUnlocked;
787
- }
788
- return this.computeIsContentUnlocked();
789
- }
790
- get isParentMilestoneLocked() {
791
- if (this._cacheInitialized) {
792
- return this._cachedIsParentMilestoneLocked;
793
- }
794
- return this.computeIsParentMilestoneLocked();
795
- }
796
- get isMilestoneLocked() {
797
- if (this._cacheInitialized) {
798
- return this._cachedIsMilestoneLocked;
799
- }
800
- return this.computeIsMilestoneLocked();
801
- }
802
- get isMilestoneAssessment() {
803
- if (this._cacheInitialized) {
804
- return this._cachedIsMilestoneAssessment;
805
- }
806
- return this.computeIsMilestoneAssessment();
807
- }
808
- get isMilestoneAssessmentLocked() {
809
- if (this._cacheInitialized) {
810
- return this._cachedIsMilestoneAssessmentLocked;
811
- }
812
- return this.computeIsMilestoneAssessmentLocked();
813
- }
814
- /**
815
- * Check if a milestone's mandatory courses and assessment are completed.
816
- * Looks at the content hierarchy to find children of the milestone.
817
- */
818
- checkMilestoneContentCompletion(milestoneId) {
819
- if (!this.baseContentReadData || !this.baseContentReadData.children || !this.hierarchyMapData) {
820
- // Fallback: Try to find assessment completion in hashmap for this milestone
821
- return this.checkMilestoneAssessmentCompletion(milestoneId);
822
- }
823
- // Find the milestone in the content hierarchy
824
- const milestoneContent = this.findContentInHierarchy(this.baseContentReadData, milestoneId);
825
- if (!milestoneContent || !milestoneContent.children) {
826
- return this.checkMilestoneAssessmentCompletion(milestoneId);
827
- }
828
- // Check all mandatory courses and assessments
829
- let allMandatoryComplete = true;
830
- let hasAssessment = false;
831
- let assessmentComplete = false;
832
- milestoneContent.children.forEach((child) => {
833
- const childData = this.hierarchyMapData[child.identifier];
834
- const isAssessment = child.primaryCategory === 'Course Assessment' ||
835
- child.courseCategory === 'Course Assessment' ||
836
- child.primaryCategory === 'Final Assessment';
837
- const isMandatory = child.mandatory === true || child.optionalReading !== true;
838
- if (isAssessment) {
839
- hasAssessment = true;
840
- if (childData && (childData.completionStatus === 2 || childData.completionPercentage >= 100)) {
841
- assessmentComplete = true;
842
- }
843
- }
844
- else if (isMandatory) {
845
- // Check if mandatory content is completed
846
- if (!childData || (childData.completionStatus !== 2 && childData.completionPercentage < 100)) {
847
- allMandatoryComplete = false;
848
- }
849
- }
850
- });
851
- console.log('Milestone content check:', { allMandatoryComplete, hasAssessment, assessmentComplete });
852
- // Milestone is complete if assessment is complete (mandatory courses optional based on requirements)
853
- return hasAssessment ? assessmentComplete : allMandatoryComplete;
854
- }
855
- /**
856
- * Fallback: Check if enough assessments are completed to unlock this milestone.
857
- * For milestone at index N, we need at least N completed assessments.
858
- * E.g., For M2 (index 1), we need 1 completed assessment (M1's assessment)
859
- * For M3 (index 2), we need 2 completed assessments (M1's and M2's)
860
- */
861
- checkMilestoneAssessmentCompletion(milestoneId) {
862
- if (!this.hierarchyMapData) {
863
- return false;
864
- }
865
- // Extract milestone number from ID (M1 -> 1, M2 -> 2, etc.)
866
- const milestoneNum = parseInt(milestoneId.replace(/\D/g, '')) || 0;
867
- const requiredCompletedAssessments = milestoneNum - 1; // For M2, need 1; for M3, need 2
868
- console.log(`Milestone ${milestoneId} (num: ${milestoneNum}) requires ${requiredCompletedAssessments} completed assessments`);
869
- if (requiredCompletedAssessments <= 0) {
870
- return true; // First milestone, no requirements
871
- }
872
- // Count completed Course Assessments that are INSIDE milestones (have a parent)
873
- // Exclude pre-enrollment assessments at the root level (no parent or parent is Learning Pathway)
874
- let completedMilestoneAssessmentCount = 0;
875
- const learningPathwayId = this.baseContentReadData?.identifier;
876
- for (const key of Object.keys(this.hierarchyMapData)) {
877
- const item = this.hierarchyMapData[key];
878
- // Check if it's a completed Course Assessment
879
- if ((item.primaryCategory === 'Course Assessment' || item.courseCategory === 'Course Assessment') &&
880
- (item.completionStatus === 2 || item.completionPercentage >= 100)) {
881
- // Check if this assessment has a parent (meaning it's inside a course/milestone, not at root level)
882
- // Also exclude if parent is the Learning Pathway itself (pre-enrollment assessment)
883
- const hasParent = item.parent && item.parent !== learningPathwayId;
884
- if (hasParent) {
885
- completedMilestoneAssessmentCount++;
886
- console.log(`Found completed MILESTONE assessment: ${key}`, item);
887
- }
888
- else {
889
- console.log(`Skipping root-level/pre-enrollment assessment: ${key}`);
890
- }
891
- }
892
- }
893
- console.log(`Total completed MILESTONE assessments: ${completedMilestoneAssessmentCount}, Required: ${requiredCompletedAssessments}`);
894
- // If we have enough completed milestone assessments, unlock this milestone
895
- return completedMilestoneAssessmentCount >= requiredCompletedAssessments;
896
- }
897
- findContentInHierarchy(content, identifier) {
898
- if (!content)
899
- return null;
900
- if (content.identifier === identifier)
901
- return content;
902
- if (content.children) {
903
- for (const child of content.children) {
904
- const found = this.findContentInHierarchy(child, identifier);
905
- if (found)
906
- return found;
907
- }
908
- }
909
- return null;
910
- }
911
- get computedQueryParams() {
912
- if (this.isAllowed && !this.forPreview && this.isEnabled) {
913
- return {
914
- ...this.resourceLink.queryParams,
915
- preAssessment: 'true'
916
- };
917
- }
918
- return null;
919
- }
920
- get isMilestone() {
921
- if (this._cacheInitialized) {
922
- return this._cachedIsMilestone;
923
- }
924
- return this.computeIsMilestone();
925
- }
926
- getMilestoneCompletedCount() {
927
- if (!this.content || !this.hierarchyMapData) {
928
- return 0;
929
- }
930
- const milestoneData = this.hierarchyMapData[this.content.identifier];
931
- if (!milestoneData || !milestoneData.leafNodes) {
932
- return 0;
933
- }
934
- let completedCount = 0;
935
- milestoneData.leafNodes.forEach((leafId) => {
936
- const leafData = this.hierarchyMapData[leafId];
937
- if (leafData && leafData.completionStatus === 2) {
938
- completedCount++;
939
- }
940
- });
941
- return completedCount;
942
- }
943
- /**
944
- * Get unlock criteria message for locked milestones
945
- */
946
- getMilestoneUnlockMessage() {
947
- if (!this.content || !this.hierarchyMapData) {
948
- return '';
949
- }
950
- const milestoneData = this.hierarchyMapData[this.content.identifier];
951
- if (!milestoneData) {
952
- return '';
953
- }
954
- // Check if hashmap has pre-computed unlock message
955
- if (milestoneData.unlockMessage) {
956
- return milestoneData.unlockMessage;
957
- }
958
- const milestoneIndex = milestoneData.milestoneIndex;
959
- // Milestone 1 requires pre-assessment completion
960
- if (milestoneIndex === 0) {
961
- return 'Complete the preliminary assessment to unlock this milestone';
962
- }
963
- // Other milestones require previous milestone completion
964
- return `Complete all mandatory content and assessment in Milestone ${milestoneIndex} to unlock this milestone`;
965
- }
966
- /**
967
- * Get lock message for content inside locked milestones
968
- */
969
- getParentMilestoneLockMessage() {
970
- if (!this.isParentMilestoneLocked) {
971
- return '';
972
- }
973
- return 'This content is locked. Complete previous milestone to view this content.';
974
- }
975
- /**
976
- * Get lock message for milestone assessments
977
- */
978
- getAssessmentLockMessage() {
979
- if (!this.content || !this.hierarchyMapData) {
980
- return '';
981
- }
982
- const hashData = this.hierarchyMapData[this.content.identifier];
983
- // Check if hashmap has pre-computed assessment lock message
984
- if (hashData && hashData.assessmentLockMessage) {
985
- return hashData.assessmentLockMessage;
986
- }
987
- if (this.isMilestoneAssessmentLocked) {
988
- return 'This content is locked. Complete all mandatory items to unlock the assessment.';
989
- }
990
- return '';
991
- }
992
- shouldShowDownloadButton(content) {
993
- if (!content) {
994
- return false;
995
- }
996
- // Check if content has an artifact URL (downloadable resource)
997
- if (!content.artifactUrl) {
998
- return false;
999
- }
1000
- // Check if base content resource category includes "Case Study"
1001
- if (!this.baseContentReadData?.courseCategory ||
1002
- this.baseContentReadData.courseCategory !== NsContent.ECourseCategory.CASE_STUDY) {
1003
- return false;
1004
- }
1005
- //for public scenario check if its player plage then only enable download
1006
- if (this.forPreview && !window.location.href.includes('/viewer/')) {
1007
- return false;
1008
- }
1009
- // for logged in user check if user enrolled then only allow download
1010
- if (!this.forPreview && !this.isEnrolled) {
1011
- return false;
1012
- }
1013
- // Define downloadable MIME types
1014
- const downloadableMimeTypes = [
1015
- NsContent.EMimeTypes.PDF
1016
- ];
1017
- return downloadableMimeTypes.includes(content.mimeType);
1018
- }
1019
- downloadContent(content, event) {
1020
- if (event) {
1021
- event.preventDefault();
1022
- event.stopPropagation();
1023
- }
1024
- const pageId = `app/toc/pageId/${content.identifier}`;
1025
- this.resourceDownloadHelperSvc.downloadPDF(content, pageId);
1026
- console.log('content', content);
1027
- console.log('baseContent', this.baseContentReadData);
1028
- }
1029
- /**
1030
- * View milestone achievement - calls the achievement API and shows the result
1031
- */
1032
- viewMilestoneAchievement(event) {
1033
- if (event) {
1034
- event.preventDefault();
1035
- event.stopPropagation();
1036
- }
1037
- if (!this.content || !this.batchId || this.achievementLoading) {
1038
- return;
1039
- }
1040
- // Get user ID from ConfigurationsService
1041
- const userId = this.configSvc?.userProfile?.userId;
1042
- if (!userId) {
1043
- console.error('User ID not found');
1044
- return;
1045
- }
1046
- // Extract milestone ID (e.g., "m1", "m2") from the content name or index
1047
- // Try to get milestone number from the index or extract from content
1048
- let milestoneId = 'm' + (this.index - 1); // index is typically 1-based, milestones are 0-based
1049
- // If content name contains milestone number, extract it
1050
- if (this.content.name) {
1051
- const match = this.content.name.match(/milestone\s*(\d+)/i);
1052
- if (match) {
1053
- milestoneId = 'm' + match[1];
1054
- }
1055
- }
1056
- const courseId = this.baseContentReadData?.identifier || this.rootId;
1057
- this.achievementLoading = true;
1058
- this.appTocSvc.generateMilestoneAchievement(userId, courseId, this.batchId, milestoneId).subscribe({
1059
- next: (response) => {
1060
- this.achievementLoading = false;
1061
- console.log('Achievement generated successfully:', response);
1062
- // Show achievement dialog or handle response
1063
- if (response && response.result) {
1064
- // Open a dialog to show the achievement
1065
- this.dialog.open(CertificateDialogComponent, {
1066
- width: '1300px',
1067
- data: {
1068
- cet: response.result.printUri || response.result.svgData,
1069
- certId: response.result.identifier,
1070
- isAchievement: true
1071
- },
1072
- });
1073
- }
1074
- },
1075
- error: (error) => {
1076
- this.achievementLoading = false;
1077
- // Show error message in snackbar
1078
- const errorMessage = error?.error?.result?.message || error?.message || 'Failed to generate achievement';
1079
- this.snackBar.open(errorMessage, 'Close', {
1080
- duration: 5000,
1081
- horizontalPosition: 'center',
1082
- verticalPosition: 'bottom',
1083
- panelClass: ['error-snackbar']
1084
- });
1085
- console.error('Error generating achievement:', error);
1086
- }
1087
- });
1088
- }
1089
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AppTocContentCardV2Component, deps: [{ token: i1.EventService }, { token: i2.MatLegacyDialog }, { token: i0.Renderer2 }, { token: i3.CertificateService }, { token: i4.AppTocService }, { token: i5.ContentLanguageService }, { token: i6.ResourceDownloadHelperService }, { token: i1.ConfigurationsService }, { token: i7.MatLegacySnackBar }], target: i0.ɵɵFactoryTarget.Component }); }
1090
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AppTocContentCardV2Component, selector: "ws-widget-app-toc-content-card-v2", inputs: { content: "content", expandAll: "expandAll", rootId: "rootId", rootContentType: "rootContentType", forPreview: "forPreview", batchId: "batchId", componentName: "componentName", index: "index", pathSet: "pathSet", expandActive: "expandActive", hierarchyMapData: "hierarchyMapData", batchData: "batchData", isPreAssessment: "isPreAssessment", baseContentReadData: "baseContentReadData", mlCourse: "mlCourse", parentMilestoneLocked: "parentMilestoneLocked" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"content && !isPreAssessment\">\r\n <ng-container *ngIf=\"isCollection && !isModule\">\r\n <ng-container [ngTemplateOutlet]=\"collectionTemplate\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"isCollection && isModule\">\r\n <ng-container *ngIf=\"content?.moduleResourseCount\">\r\n <ng-container [ngTemplateOutlet]=\"collectionTemplate\">\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <div *ngIf=\"isResource\" class=\"resource-container\"\r\n [ngClass]=\"pathSet?.has(content?.identifier) && isEnrolled ? 'content-active-resource': 'content-not-active-resource'\">\r\n <div class=\"resource flex sm:flex-row flex-start width-expand w-100 sm:pr-4 sm:w-auto\"\r\n [ngClass]=\"{'activeResource': pathSet?.has(content?.identifier) && isEnrolled}\">\r\n <!-- Lock message for curated programs only (shown above content) -->\r\n <ng-container *ngIf=\"content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT && checkForCuratedProgram &&\r\n !isContentUnlocked\">\r\n <div class=\"content-locking flex w-full flex-middle mb-2 gap-3\">\r\n <mat-icon class=\"lock-icon\">lock</mat-icon>\r\n <span class=\"lock-message mat-body-2\">\r\n The content is locked. Complete program or all courses to view this module\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT && checkForCuratedProgram &&\r\n isContentUnlocked\">\r\n <div class=\"content-locking flex w-full flex-middle mb-2 gap-3\">\r\n <mat-icon class=\"unlock-icon\">lock_open_right</mat-icon>\r\n <span class=\"unlock-message mat-body-2\">\r\n This content is unlocked.\r\n </span>\r\n </div>\r\n </ng-container>\r\n <div class=\"flex flex-wrap items-start justify-start sm:justify-end\">\r\n <!-- <button *ngIf=\"!forPreview && content?.artifactUrl && !isXSmall && isAllowed && isEnabled\" type=\"button\"\r\n mat-icon-button class=\"\" [matMenuTriggerFor]=\"buttonMenu\">\r\n <mat-icon>more_vertical</mat-icon>\r\n </button> -->\r\n <ng-container *ngIf=\"isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\r\n\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\r\n <div class=\"completed\">\r\n <div>\r\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n <circle-progress class=\"flex items-center progress\"\r\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\r\n [outerStrokeColor]=\"progressColor2()\" [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\"\r\n [animation]=\"true\" [animationDuration]=\"250\" [showTitle]=\"false\" [showUnits]=\"false\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\r\n matTooltip=\"In progress\" [showZeroOuterStroke]=false [backgroundPadding]=\"-9\"\r\n [startFromZero]=\"false\" [backgroundPadding]=\"0\" [imageHeight]=\"22\" [imageWidth]=\"22\"\r\n [showBackground]=\"false\" [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress>\r\n <!-- <ws-widget-content-progress *ngIf=\"content?.identifier\" [forPreview]=\"forPreview\"\r\n [contentId]=\"content?.identifier\" class=\"progress-bar-thin\" [progress]=\"content?.completionPercentage\"\r\n [progressType]=\"'percentage'\">\r\n </ws-widget-content-progress> -->\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #elseBlock>\r\n <circle-progress class=\"flex items-center progress\" [percent]=\"0\" [radius]=\"11\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\r\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\" [showUnits]=\"false\"\r\n [animationDuration]=\"250\" [showTitle]=\"false\" [backgroundPadding]=\"0\"\r\n [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\" matTooltip=\"Not started\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\" [imageHeight]=\"22\"\r\n [imageWidth]=\"22\" [showBackground]=\"false\"></circle-progress>\r\n <!-- <p>no data</p> -->\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n <!-- deactivated as per NIC CEO requirement to access course wthout login -->\r\n <!-- For locked assessments: show content but make it non-clickable -->\r\n <div class=\"width-expand\" *ngIf=\"isMilestoneAssessmentLocked && isEnrolled; else clickableContent\"\r\n [ngClass]=\"{'ml-3': isEnrolled}\">\r\n <div class=\"text-truncate opacity-60\">\r\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\r\n <div class=\"flex items-center gap-2 w-full\">\r\n <mat-icon class=\"text-gray-500\">lock</mat-icon>\r\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate text-gray-600\">\r\n {{ content?.name | truncate:50 }}\r\n </p>\r\n </div>\r\n <span class=\"content-type optional-span nodtranslate\" *ngIf=\"content?.optionalReading\">{{\r\n 'playerbrief.optional' | translate | titlecase}} </span>\r\n </div>\r\n <!-- for default grey icons -->\r\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier) || !isEnrolled\">\r\n <div class=\"resicons ws-mat-black60-text\">\r\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/grey/module.svg\" class=\"float-left margin-right-xs\"\r\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\r\n\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\r\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </div>\r\n \r\n <!-- Lock message displayed BELOW assessment details when locked -->\r\n <div class=\"content-locking flex w-full flex-middle mt-2 gap-2 px-2 py-1 bg-orange-50 border-l-4 border-orange-400\">\r\n <mat-icon class=\"lock-icon text-orange-600\" style=\"font-size: 18px; width: 18px; height: 18px;\">lock</mat-icon>\r\n <span class=\"lock-message mat-body-2 text-orange-800\" style=\"font-size: 13px;\">\r\n This content is locked. Complete all mandatory items to unlock the assessment.\r\n </span>\r\n </div>\r\n </div>\r\n \r\n <!-- Clickable content template (when NOT locked) -->\r\n <ng-template #clickableContent>\r\n <a class=\"width-expand\"\r\n [class.disabled]=\"(forPreview || !isEnabled || !isEnrolled || !isBatchInProgess || !isContentUnlocked || isParentMilestoneLocked) ? true : null\"\r\n [ngClass]=\"{'ml-3': isEnrolled}\"\r\n [routerLink]=\"(isAllowed && !forPreview && isEnabled && !isParentMilestoneLocked) ? resourceLink.url : null\"\r\n [queryParams]=\"(isAllowed && !forPreview && isEnabled && !isParentMilestoneLocked) ? resourceLink.queryParams : null\"\r\n [matTooltip]=\"isParentMilestoneLocked ? 'This content is locked. Complete previous milestone to view this content.' : ''\"\r\n matTooltipPosition=\"above\">\r\n <div [ngClass]=\"{'resource-active': pathSet?.has(content?.identifier) && isEnrolled}\"></div>\r\n <div class=\"text-truncate \" [ngClass]=\"{'cursor-pointer': !isEnabled && isEnrolled}\"\r\n (click)=\"content.viewChildren = !content.viewChildren; raiseTelemetry(); changeResource()\">\r\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\r\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate\"\r\n [ngClass]=\"{'text-active': pathSet?.has(content?.identifier) && isEnrolled}\">\r\n {{ content?.name | truncate:50 }}\r\n </p>\r\n <span class=\"content-type optional-span nodtranslate\" *ngIf=\"content?.optionalReading\">{{\r\n 'playerbrief.optional' | translate | titlecase}} </span>\r\n </div>\r\n <!-- for default grey icons -->\r\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier) || !isEnrolled\">\r\n <div class=\"resicons ws-mat-black60-text\">\r\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/grey/module.svg\" class=\"float-left margin-right-xs\"\r\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\r\n\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\r\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- for white icons when content highlighted -->\r\n <ng-container *ngIf=\"pathSet?.has(content?.identifier) && isEnrolled\">\r\n <div class=\"resicons ws-mat-white-text\">\r\n <img src=\"/assets/icons/content/white/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/white/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/white/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <img src=\"/assets/icons/content/white/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/white/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/white/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/white/module.svg\" class=\"float-left margin-right-xs\"\r\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\r\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Download button for pdf resources -->\r\n <ng-container *ngIf=\"shouldShowDownloadButton(content)\">\r\n <div class=\"download-btn mat-body-2 mt-2 sm:mt-1\" (click)=\"downloadContent(content, $event)\"\r\n [ngClass]=\"{'active': pathSet?.has(content?.identifier)}\">\r\n <a class=\"download-link flex items-center\">\r\n <span class=\"\">Download</span>\r\n </a>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </a>\r\n </ng-template>\r\n </div>\r\n </div>\r\n</ng-container>\r\n\r\n<mat-menu #buttonMenu=\"matMenu\">\r\n <a mat-menu-item [routerLink]=\"'../' + content?.identifier + '/overview'\" [queryParams]=\"contextPath\"\r\n class=\"flex flex-middle\">\r\n <mat-icon>toc</mat-icon>\r\n <h3 class=\"margin-remove nodtranslate\">\r\n View Details\r\n </h3>\r\n </a>\r\n</mat-menu>\r\n\r\n<ng-template #collectionTemplate>\r\n <ng-container *ngIf=\"isCollection\">\r\n <div class=\"collection-wrapper p-4 flex flex-col position-relative\" [ngClass]=\"{'open': check(content),\r\n 'close': !content.viewChildren,\r\n 'course':!isModule, 'module': isModule,\r\n 'content-active': pathSet?.has(content.identifier) && isEnrolled}\">\r\n <div class=\"card-collection w-auto sm:w-100 padding-right-xl\">\r\n <!-- <img class=\"card-thumbnail ws-mat-primary-lite-background\" [src]=\"content?.appIcon\" alt=\"Thumbnail\"\r\n (click)=\"content.viewChildren = !content.viewChildren\" [wsUtilsDefaultThumbnail]=\"defaultThumbnail\" /> -->\r\n <div class=\"flex flex-col flex-wrap flex-between width-expand pr-0 w-100 \">\r\n <div class=\"text-truncate\" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\r\n (click)=\"content.viewChildren = !content.viewChildren\">\r\n <div class=\"flex items-center justify-center mb-1 sm:flex-row\">\r\n <ng-container\r\n *ngIf=\"isModule && isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\r\n\r\n <ng-container *ngIf=\"getCompletionStatus(content.identifier) == 2\">\r\n <div class=\"completed mr-2\">\r\n <div>\r\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n <circle-progress class=\"flex items-center progress mr-1\"\r\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\r\n [outerStrokeColor]=\"progressColor2()\"\r\n [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\" [animation]=\"true\"\r\n [animationDuration]=\"250\" [showTitle]=\"false\" [showUnits]=\"false\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\"\r\n [backgroundStrokeWidth]=\"3\" matTooltip=\"In progress\"\r\n [showZeroOuterStroke]=false [backgroundPadding]=\"-7\" [startFromZero]=\"false\"\r\n [backgroundPadding]=\"0\" [imageHeight]=\"18\" [imageWidth]=\"18\"\r\n [showBackground]=\"false\" [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress>\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #elseBlock>\r\n <circle-progress class=\"flex items-center progress mr-1\" [percent]=\"0\" [radius]=\"11\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\r\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\"\r\n [showUnits]=\"false\" [animationDuration]=\"250\" [showTitle]=\"false\"\r\n [backgroundPadding]=\"0\" [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\"\r\n matTooltip=\"Not started\" [showSubtitle]=\"false\" [showInnerStroke]=\"true\"\r\n [clockwise]=\"true\" [imageHeight]=\"22\" [imageWidth]=\"22\"\r\n [showBackground]=\"false\"></circle-progress>\r\n </ng-template>\r\n </ng-container>\r\n <div\r\n [ngClass]=\"{'collection-active-class': pathSet?.has(content?.identifier) && isEnrolled}\">\r\n </div>\r\n <img *ngIf=\"isMilestoneLocked\" src=\"assets/icons/hubs/lock.svg\" alt=\"Locked\"\r\n class=\"lock-icon mr-2 margin-bottom-xxs\">\r\n <p class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\r\n [ngClass]=\"{'text-active': pathSet?.has(content.identifier) && isEnrolled}\">\r\n <span>{{isMilestone ? index -1 : index}}. </span>{{ content?.name | truncate:50 }}\r\n <ng-container *ngIf=\"isMilestone\">\r\n <span *ngIf=\"isMilestoneLocked\" class=\"locked-text ml-2\">Locked</span>\r\n </ng-container>\r\n <span *ngIf=\"content?.isMandatory\"\r\n class=\"mandatory-text mat-caption ml-2\">Mandatory</span>\r\n </p>\r\n \r\n <div class=\"type-container resource mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Resource'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Resource</span>\r\n </div>\r\n <div class=\"type-container module mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Collection'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Module</span>\r\n </div>\r\n <div class=\"type-container course mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Course'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Course</span>\r\n </div>\r\n </div>\r\n <!-- Milestone Badge -->\r\n <div *ngIf=\"isMilestone\" class=\"milestone-badge mt-2 mb-2\">\r\n <span class=\"milestone-badge-text nodtranslate\">Milestone {{index - 1}}</span>\r\n </div>\r\n <!-- Milestone Description (3 lines with ellipsis) -->\r\n <p *ngIf=\"isMilestone && content?.description\" class=\"milestone-description mt-2 nodtranslate\">\r\n {{ content?.description }}\r\n </p>\r\n <div class=\"flex flex-row gap-3 items-center content-key-values mt-2\">\r\n <mat-icon *ngIf=\"!isModule\" alt=\"course\"\r\n class=\"time-icon icon-color\">video_library</mat-icon>\r\n <img *ngIf=\"isModule\" alt=\"Module\" class=\"time-icon\"\r\n src=\"/assets/icons/content/grey/module.svg\">\r\n <div class=\"text-xs nodtranslate\">{{ (hierarchyMapData[content?.identifier]?.duration ||\r\n 120)|\r\n pipeDurationTransform: 'hms' }}</div>\r\n\r\n <ng-container *ngIf=\"content?.moduleCount\">\r\n <div class=\"flex items-center\">\r\n <span class=\"period\"></span>\r\n </div>\r\n <div class=\"text-xs nodtranslate\">{{content?.moduleCount}} {{content?.moduleCount > 1?\r\n 'modules' :\r\n 'module'}}</div>\r\n </ng-container>\r\n <ng-container *ngIf=\"content?.leafNodesCount\">\r\n <div class=\"flex items-center\">\r\n <span class=\"period\"></span>\r\n </div>\r\n <div class=\"text-xs nodtranslate\">{{content?.leafNodesCount}} {{content?.leafNodesCount\r\n >1 ? 'items':\r\n 'item'}}</div>\r\n </ng-container>\r\n </div>\r\n <!-- Milestone Completion Progress -->\r\n <div *ngIf=\"isMilestone && isEnrolled && !isMilestoneLocked\" class=\"milestone-progress mt-2 flex items-center justify-between\">\r\n <div>\r\n <span class=\"milestone-progress-text nodtranslate\">{{getMilestoneCompletedCount()}} of\r\n {{content?.leafNodesCount || 0}} completed</span>\r\n </div>\r\n <!-- View Achievement Button for completed milestones - Outside clickable area -->\r\n <div *ngIf=\"isMilestone && isEnrolled && (getCompletionPercentage(content?.identifier) >= 100 || getCompletionStatus(content?.identifier) === 2)\"\r\n class=\"view-achievement-container mt-2\">\r\n <button type=\"button\" class=\"view-achievement-btn\" [disabled]=\"achievementLoading\"\r\n (click)=\"viewMilestoneAchievement($event)\">\r\n <span *ngIf=\"!achievementLoading\">View Achievement</span>\r\n <mat-spinner *ngIf=\"achievementLoading\" [diameter]=\"16\" \r\n [strokeWidth]=\"2\" color=\"primary\" class=\"inline-spinner\"></mat-spinner>\r\n </button>\r\n </div>\r\n </div>\r\n <!-- Unlock Criteria Message for Locked Milestones -->\r\n <div *ngIf=\"isMilestone && isEnrolled && isMilestoneLocked\" class=\"milestone-locked-message mt-2\">\r\n <span class=\"locked-criteria-text mat-caption\">\r\n {{ getMilestoneUnlockMessage() }}\r\n </span>\r\n </div>\r\n \r\n </div>\r\n <!-- For course progress to be shown -->\r\n <ng-container *ngIf=\"isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) && content.primaryCategory === 'Course'\">\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\r\n <div class=\"flex flex-1\">\r\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\r\n <div class=\"flex flex-row justify-end w-full \">\r\n <span class=\"mat-body-2 nodtranslate \">\r\n {{getCompletionPercentage(content?.identifier)}}%</span>\r\n </div>\r\n\r\n <ws-widget-content-progress [contentId]=\"content?.progress\"\r\n [progress]=\"getCompletionPercentage(content?.identifier)\"\r\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\r\n </ws-widget-content-progress>\r\n </div>\r\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\r\n <a class=\"ml-5 certificate-btn\"\r\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\r\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\r\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\r\n <span class=\"nodtranslate\">Certificate</span>\r\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\r\n class=\"ml-2\">arrow_downward</mat-icon>\r\n <div class=\"center flex flex-middle certificate-loader\"\r\n *ngIf=\"downloadCertificateLoading\">\r\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\r\n [diameter]=\"16\"></mat-spinner>\r\n </div>\r\n </a>\r\n </ng-container>\r\n </div>\r\n <!-- <circle-progress class=\"flex items-center progress\" [percent]=\"100\" [radius]=\"12\"\r\n [outerStrokeWidth]=\"3\" [innerStrokeWidth]=\"3\" [space]=\"-3\"\r\n [outerStrokeColor]=\"progressColor()\" [innerStrokeColor]=\"'rgba(0,0,0,.16)'\"\r\n [animation]=\"true\" [animationDuration]=\"300\" [showTitle]=\"false\" [showUnits]=\"false\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\r\n [showZeroOuterStroke]=false [backgroundPadding]=\"-9\" [startFromZero]=\"false\"\r\n [backgroundPadding]=\"0\" [imageHeight]=\"24\" [imageWidth]=\"24\" [showBackground]=\"false\"\r\n [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress> -->\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n <div class=\"flex flex-1\">\r\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\r\n <div class=\"flex flex-row justify-end w-full ws-mat-black-text\">\r\n <span class=\"mat-body-2 ws-mat-black-text nodtranslate\">\r\n {{getCompletionPercentage(content?.identifier)}}%</span>\r\n </div>\r\n\r\n <ws-widget-content-progress [contentId]=\"content?.progress\"\r\n [progress]=\"getCompletionPercentage(content?.identifier)\"\r\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\r\n </ws-widget-content-progress>\r\n </div>\r\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\r\n <a class=\"ml-5 certificate-btn\"\r\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\r\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\r\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\r\n <span class=\"nodtranslate\">Certificate</span>\r\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\r\n class=\"ml-2\">arrow_downward</mat-icon>\r\n <div class=\"center flex flex-middle certificate-loader\"\r\n *ngIf=\"downloadCertificateLoading\">\r\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\r\n [diameter]=\"16\"></mat-spinner>\r\n </div>\r\n </a>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <div class=\"see-all-container\">\r\n <a href=\"javascript:void(0)\" role=\"button\"\r\n (click)=\"content.viewChildren = !content.viewChildren; expandActive = false\"\r\n class=\"see-all-btn tab custom-chevron customicon\" mat-button>\r\n <mat-icon *ngIf=\"!content.viewChildren && !isModule\">keyboard_arrow_down</mat-icon>\r\n <mat-icon *ngIf=\"content.viewChildren && !isModule\">keyboard_arrow_up</mat-icon>\r\n <mat-icon *ngIf=\"!content.viewChildren && isModule\">add</mat-icon>\r\n <mat-icon *ngIf=\"content.viewChildren && isModule\">remove</mat-icon>\r\n </a>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"child-wrapper \" *ngIf=\"content.viewChildren\" [ngClass]=\"{'open': content.viewChildren,\r\n 'close': !content.viewChildren,\r\n 'course':!isModule,\r\n 'module': isModule}\" [@panelInOut]>\r\n <div class=\"children-container\" [ngClass]=\"{'module': isModule, '': !isModule}\">\r\n <ws-widget-app-toc-content-card-v2 [forPreview]=\"forPreview\" [componentName]=\"componentName\"\r\n [content]=\"child\" [expandAll]=\"expandAll\" [rootId]=\"rootId\" [batchId]=\"batchId\"\r\n [rootContentType]=\"rootContentType\" [index]=\"j+1\" [baseContentReadData]=\"baseContentReadData\"\r\n [pathSet]=\"pathSet\" [hierarchyMapData]=\"hierarchyMapData\" [batchData]=\"batchData\"\r\n [mlCourse]=\"mlCourse\" [parentMilestoneLocked]=\"isMilestoneLocked || isParentMilestoneLocked\"\r\n *ngFor=\"let child of content?.children; trackBy: contentTrackBy; let j= index;let isFirst = first\"\r\n [ngClass]=\"{'moduleCard': checkIsModule(child), 'resourceCard': !checkIsModule(child), 'first': isFirst}\">\r\n </ws-widget-app-toc-content-card-v2>\r\n </div>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n\r\n<ng-container *ngIf=\"isPreAssessment\">\r\n <div class=\"collection-wrapper p-4 flex flex-col position-relative\" [ngClass]=\"{'open': check(content),\r\n 'course':!isModule, 'module': isModule,\r\n 'content-active': pathSet?.has(content.identifier)}\">\r\n <div class=\"card-collection w-auto sm:w-100 padding-right-xl\">\r\n <!-- <img class=\"card-thumbnail ws-mat-primary-lite-background\" [src]=\"content?.appIcon\" alt=\"Thumbnail\"\r\n (click)=\"content.viewChildren = !content.viewChildren\" [wsUtilsDefaultThumbnail]=\"defaultThumbnail\" /> -->\r\n <div class=\"flex flex-col flex-wrap flex-between width-expand pr-0 w-100 \">\r\n\r\n <div class=\"text-truncate\" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\r\n (click)=\"content.viewChildren = !content.viewChildren\">\r\n <div class=\"flex sm:flex-row flex-wrap\">\r\n <ng-container>\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\r\n\r\n <ng-container *ngIf=\"getCompletionStatus(content.identifier) == 2\">\r\n <div class=\"completed mr-2\">\r\n <div>\r\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n\r\n <circle-progress class=\"flex items-center progress mr-1\"\r\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\r\n [outerStrokeColor]=\"progressColor2()\" [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\"\r\n [animation]=\"true\" [animationDuration]=\"250\" [showTitle]=\"false\"\r\n [showUnits]=\"false\" [showSubtitle]=\"false\" [showInnerStroke]=\"true\"\r\n [clockwise]=\"true\" [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\"\r\n [backgroundStrokeWidth]=\"3\" matTooltip=\"In progress\" [showZeroOuterStroke]=false\r\n [backgroundPadding]=\"-7\" [startFromZero]=\"false\" [backgroundPadding]=\"0\"\r\n [imageHeight]=\"18\" [imageWidth]=\"18\" [showBackground]=\"false\"\r\n [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress>\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #elseBlock>\r\n <circle-progress class=\"flex items-center progress mr-1\" [percent]=\"0\" [radius]=\"11\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\r\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\" [showUnits]=\"false\"\r\n [animationDuration]=\"250\" [showTitle]=\"false\" [backgroundPadding]=\"0\"\r\n [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\" matTooltip=\"Not started\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [imageHeight]=\"22\" [imageWidth]=\"22\" [showBackground]=\"false\"></circle-progress>\r\n </ng-template>\r\n </ng-container>\r\n <div [ngClass]=\"{'collection-active-class': pathSet?.has(content?.identifier)}\"></div>\r\n <!-- <p class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\r\n [ngClass]=\"{'text-active': pathSet?.has(content.identifier)}\">\r\n {{index}}. {{ content?.name | truncate:50 }}\r\n </p> -->\r\n <a class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\r\n [class.disabled]=\"null\" [ngClass]=\"{'ml-3': isEnrolled}\"\r\n [routerLink]=\"(isAllowed && !forPreview && isEnabled) ? resourceLink.url : null\"\r\n [queryParams]=\"computedQueryParams\">\r\n <!-- {{content?.courseCategory}} -->\r\n <div [ngClass]=\"{'resource-active': pathSet?.has(content?.identifier)}\"></div>\r\n <div class=\"text-truncate \" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\r\n (click)=\"raiseTelemetry(); changeResource()\">\r\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\r\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate\"\r\n [ngClass]=\"{'text-active': pathSet?.has(content?.identifier)}\">\r\n <!-- <mat-icon class=\"margin-right-xs radiobtn time-icon\">radio_button_unchecked </mat-icon> -->\r\n {{index}}. {{ content?.name | truncate:50 }}\r\n\r\n </p>\r\n <span class=\"content-type optional-span nodtranslate\"\r\n *ngIf=\"content?.optionalReading\">{{ 'playerbrief.optional' | translate |\r\n titlecase}} </span>\r\n </div>\r\n <!-- for default grey icons -->\r\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier)\">\r\n <div class=\"resicons ws-mat-black60-text\">\r\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <!-- <img src=\"/assets/icons/content/grey/resource.svg\" alt=\"Survey\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/survey'\"> -->\r\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\"\r\n alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/grey/module.svg\"\r\n class=\"float-left margin-right-xs\" alt=\"offline sessions\"\r\n *ngIf=\"content.mimeType === 'application/offline'\">\r\n\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{\r\n content?.maxQuestions }} {{ 'playerbrief.questions' | translate |\r\n titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{\r\n (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- for white icons when content highlighted -->\r\n <ng-container *ngIf=\"pathSet?.has(content?.identifier)\">\r\n <div class=\"resicons ws-mat-white-text\">\r\n <img src=\"/assets/icons/content/white/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/white/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/white/pdf.svg\" alt=\"PDF\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <!-- <img src=\"/assets/icons/content/white/resource.svg\" alt=\"Survey\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/survey'\"> -->\r\n <img src=\"/assets/icons/content/white/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/white/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/white/content_copy.svg\" class=\"contenticon\"\r\n alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/white/module.svg\"\r\n class=\"float-left margin-right-xs\" alt=\"offline sessions\"\r\n *ngIf=\"content.mimeType === 'application/offline'\">\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n <span class=\"resourceDuration ws-mat-white-text nodtranslate\">{{\r\n content?.maxQuestions }} {{ 'playerbrief.questions' | translate |\r\n titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-white-text nodtranslate\">{{\r\n (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </a>\r\n <!-- <div class=\"type-container resource mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Resource'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Resource</span>\r\n </div>\r\n <div class=\"type-container module mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Collection'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Module</span>\r\n </div>\r\n <div class=\"type-container course mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Course'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Course</span>\r\n </div> -->\r\n </div>\r\n\r\n </div>\r\n <!-- For course progress to be shown -->\r\n <ng-container>\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier)\">\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\r\n <div class=\"flex flex-1\">\r\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\r\n <div class=\"flex flex-row justify-end w-full \">\r\n <span class=\"mat-body-2 nodtranslate \">\r\n {{getCompletionPercentage(content?.identifier)}}%</span>\r\n </div>\r\n\r\n <ws-widget-content-progress [contentId]=\"content?.progress\"\r\n [progress]=\"getCompletionPercentage(content?.identifier)\"\r\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\r\n </ws-widget-content-progress>\r\n </div>\r\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\r\n <a class=\"ml-5 certificate-btn\"\r\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\r\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\r\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\r\n <span class=\"nodtranslate\">Certificate</span>\r\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\r\n class=\"ml-2\">arrow_downward</mat-icon>\r\n <div class=\"center flex flex-middle certificate-loader\"\r\n *ngIf=\"downloadCertificateLoading\">\r\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\r\n [diameter]=\"16\"></mat-spinner>\r\n </div>\r\n </a>\r\n </ng-container>\r\n </div>\r\n <!-- <circle-progress class=\"flex items-center progress\" [percent]=\"100\" [radius]=\"12\"\r\n [outerStrokeWidth]=\"3\" [innerStrokeWidth]=\"3\" [space]=\"-3\"\r\n [outerStrokeColor]=\"progressColor()\" [innerStrokeColor]=\"'rgba(0,0,0,.16)'\"\r\n [animation]=\"true\" [animationDuration]=\"300\" [showTitle]=\"false\" [showUnits]=\"false\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\r\n [showZeroOuterStroke]=false [backgroundPadding]=\"-9\" [startFromZero]=\"false\"\r\n [backgroundPadding]=\"0\" [imageHeight]=\"24\" [imageWidth]=\"24\" [showBackground]=\"false\"\r\n [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress> -->\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n <div class=\"flex flex-1\">\r\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\r\n <div class=\"flex flex-row justify-end w-full ws-mat-black-text\">\r\n <span class=\"mat-body-2 ws-mat-black-text nodtranslate\">\r\n {{getCompletionPercentage(content?.identifier)}}%</span>\r\n </div>\r\n\r\n <ws-widget-content-progress [contentId]=\"content?.progress\"\r\n [progress]=\"getCompletionPercentage(content?.identifier)\"\r\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\r\n </ws-widget-content-progress>\r\n </div>\r\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\r\n <a class=\"ml-5 certificate-btn\"\r\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\r\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\r\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\r\n <span class=\"nodtranslate\">Certificate</span>\r\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\r\n class=\"ml-2\">arrow_downward</mat-icon>\r\n <div class=\"center flex flex-middle certificate-loader\"\r\n *ngIf=\"downloadCertificateLoading\">\r\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\r\n [diameter]=\"16\"></mat-spinner>\r\n </div>\r\n </a>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- <div class=\"see-all-container\">\r\n <a href=\"javascript:void(0)\" role=\"button\"\r\n (click)=\"content.viewChildren = !content.viewChildren; expandActive = false\"\r\n class=\"see-all-btn tab custom-chevron customicon\" mat-button>\r\n <mat-icon *ngIf=\"!content.viewChildren && !isModule\">keyboard_arrow_down</mat-icon>\r\n <mat-icon *ngIf=\"content.viewChildren && !isModule\">keyboard_arrow_up</mat-icon>\r\n <mat-icon *ngIf=\"!content.viewChildren && isModule\">add</mat-icon>\r\n <mat-icon *ngIf=\"content.viewChildren && isModule\">remove</mat-icon>\r\n </a>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n\r\n</ng-container>", styles: [".customicon{position:absolute;top:-.5em;right:0}.customicon .mat-icon{color:#1a4ca1}a.disabled{pointer-events:none;cursor:default}span.optional-span{margin-left:8px;padding:0 6px;border-radius:2px;display:inline-block;background-color:#0074b6;color:#fff;font-size:12px}.card-collection{display:flex;align-items:center;border-radius:8px}.card-collection .card-thumbnail{height:100%;margin-right:12px;cursor:pointer;border-radius:8px 0 0}@media only screen and (max-width: 469px){.card-collection{flex-direction:column;align-items:flex-start!important}.card-collection .card-thumbnail{height:100%!important;width:100%!important}.card-collection .text-truncate{white-space:unset!important}}.tab:focus{outline:1px solid!important}.custom-chevron:focus{outline:0px solid!important}.resource-container{display:flex;align-items:flex-start;flex-direction:column}.resource-container .resource{padding:16px 16px 16px 0;width:100%}.resource-container .card-thumbnail{height:100%;cursor:pointer}.resource-container .img-container{position:relative;margin-right:12px}.resource-container .img-container ws-widget-content-progress{position:absolute;left:0;right:0;bottom:5px}@media only screen and (max-width: 469px){.resource-container{flex-direction:column;align-items:flex-start!important}.resource-container .card-thumbnail{height:100%!important;width:100%!important}.resource-container .text-truncate{white-space:unset!important}}.child-meta-container{margin-top:8px;display:flex}.child-meta-container .child-structure{display:flex;align-items:center;flex-wrap:wrap}.child-meta-container .child-structure span{margin-right:12px;text-align:center;margin-bottom:8px}.child-meta-container .child-structure .structure-icon{margin-right:12px}@media only screen and (max-width: 469px){.child-meta-container{margin-left:.5rem;justify-content:space-between}}.resource-container{display:flex;align-items:center}.resource-container ws-display-content-type-icon{display:flex;align-items:center}.resource-container .resource-meta{margin-left:12px;display:flex;justify-content:space-between;align-items:center}.completed-icon{color:#1a4ca1}.collection-wrapper{padding:1rem}.collection-wrapper.course.content-active{background-color:#1a4ca1;color:#fff}.collection-wrapper.course.content-active .period{background:#fff}.collection-wrapper.course.content-active .text-active,.collection-wrapper.course.content-active .icon-color,.collection-wrapper.course.content-active .customicon .mat-icon{color:#fff}.collection-wrapper.course.content-active .progress-container span{color:#fff!important}.text-active{color:#1a4ca1}.text-active.font-bold{font-weight:600}.activeResource{background-color:#1a4ca1;color:#fff;padding-top:1rem!important;padding-bottom:1rem!important}.activeResource .text-active{color:#fff}.activeResource .text-active.font-bold{font-weight:600}.activeResource .resourceDuration,.activeResource .completed-icon{color:#fff}.collection-wrapper.open{border-bottom:1px solid rgba(0,0,0,.16)}.collection-wrapper.close{border:none}.child-wrapper.open{border-radius:0 0 8px 8px}.children-container .mat-subheading-1{font:500 16px/24px Lato!important}.children-container .resource-container{margin-bottom:16px}.children-container .resource-container .resource{padding:0}.children-container .resource-container .card-thumbnail{height:65px;align-self:center}.first.resourceCard:nth-child(1) .resource{margin-top:16px!important}.first.resourceCard:nth-child(1) .activeResource{margin-top:0!important}.children-container .resourceCard:last-child .resource-container:has(.activeResource){margin-bottom:0!important}.moduleCard:not(:last-child)>.collection-wrapper.close.module{border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.moduleCard:not(:last-child)>.collection-wrapper.open.module+.child-wrapper.open{border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.collection-wrapper.open.course+.child-wrapper.open .collection-wrapper.open.module+.child-wrapper.open{background-color:#eff3f9;border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.collection-wrapper.open.module+.child-wrapper.open{background-color:#eff3f9;border-radius:0;padding-bottom:8px}.content-heading{letter-spacing:0px;color:#222}.content-type{letter-spacing:0px}.time-icon{height:16px;width:16px;font-size:16px;vertical-align:middle}.time-icon.icon-color{color:#0009}.period{width:3px;height:3px;background:#0009;border-radius:4px}.time-value{letter-spacing:0px;color:#222;text-transform:lowercase}.see-all-container{position:absolute;right:16px;top:24px}.oval-white{background:#fff 0% 0% no-repeat padding-box;border-radius:8px;padding:2px 8px}.type-container{letter-spacing:0px;display:flex;align-items:center}.type-container .rotate-90{transform:rotate(-90deg)}.type-container .custom-icon{width:18px;height:18px;font-size:18px;margin-right:8px}.type-container.resource{color:#00a9f4}.type-container.module{color:#34d6a4}.type-container.course{color:#f58634}.no-mb{margin-bottom:0!important}.w-100{width:100%}.w-auto{width:auto}.progress-bar-thin{height:5px!important}.progress-bar-thin ::ng-deep .mat-progress-bar{height:5px}.progress-bar-thin ::ng-deep .theme-igot.day-mode .mat-progress-bar-buffer{background-color:transparent!important}.progress-bar-thin ::ng-deep .theme-igot.day-mode .mat-progress-bar-background{fill:transparent}.radiobtn{color:#00000029}.resicons img{width:22px;opacity:.5;margin-top:2px;vertical-align:sub}.certificate-btn{height:24px;background:#1a4ca1;display:flex;justify-content:center;align-items:center;padding:4px 11px;color:#fff;border-radius:20px;border:1px solid white;font:400 12px/16px Lato;cursor:pointer}.certificate-btn .mat-icon{fill:#fff;color:#fff;font-size:16px;height:auto;width:auto}.view-certificate-wrapper{display:flex;border-radius:4px;border:1.5px solid rgb(0,116,182);opacity:1;padding:8px}.collection-wrapper.course,.collection-wrapper.module,.resource-container .resource{padding-left:16px;box-sizing:border-box;width:100%;overflow:hidden}.children-container.module .resource-container .resource,.course .collection-wrapper.module{padding-left:24px;box-sizing:border-box;width:100%}.course .children-container.module .resource-container .resource{padding-left:32px;box-sizing:border-box;width:100%}.course .resource-container .resource{padding-left:24px}::ng-deep .white-spinner{stroke:#fff!important}.certificate-loader ::ng-deep .mat-progress-spinner circle,.mat-spinner circle{stroke:#fff}.lock-message{background:#fff4ec;color:#d13924;padding:10px;border-radius:4px;display:block!important;width:100%}.content-locking{padding:8px 12px;margin-top:8px;margin-left:0;margin-right:0;border-radius:4px;background:#fff4ec;display:flex!important;align-items:center;gap:8px;width:100%;box-sizing:border-box}.lock-icon{color:#f3962f;font-size:20px;flex-shrink:0}.unlock-message{background:#efffec;color:#0c9600;padding:10px}.unlock-icon{color:#0c9600}.download-btn{padding:4px 12px;text-underline-position:from-font;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none;cursor:pointer;border-radius:40px;color:#1b4ca1;font-weight:700;border:1px solid #1B4CA1;display:inline-block;pointer-events:auto;position:relative;z-index:1}.activeResource .download-btn.active{color:#fff;border:1px solid #fff}.milestone-badge{display:inline-block;background-color:#fefaf4;border:1px solid #EF951E;border-radius:16px;padding:2px 12px}.milestone-badge-text{font-size:12px;font-weight:500;color:#212121}.milestone-description{font-size:14px;line-height:1.5;color:#000000b3;margin:0;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.milestone-progress{display:flex;align-items:center}.milestone-progress-text{font-size:14px;font-weight:500;color:#0009}.milestone-locked-message{display:flex;align-items:center;padding:8px 12px;background-color:#f3962f1a;border-left:3px solid #F3962F;border-radius:4px}.locked-criteria-text{font-size:13px;font-weight:400;color:#000000b3;line-height:1.4}.locked-text{font-size:14px;font-weight:500;color:#f3962f}.mandatory-text{color:#d13924!important}.view-achievement-container{display:flex;align-items:center}.view-achievement-btn{background-color:transparent;border:1.5px solid #1a4ca1;color:#1a4ca1;border-radius:20px;padding:6px 16px;font-size:14px;font-weight:500;cursor:pointer;display:flex;align-items:center;gap:8px;transition:all .2s ease;min-width:150px}.view-achievement-btn:hover:not(:disabled){background-color:#1a4ca1;color:#fff}.view-achievement-btn:disabled{opacity:.6;cursor:not-allowed}.view-achievement-btn .inline-spinner{display:inline-block}\n"], dependencies: [{ kind: "directive", type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i9.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i10.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i11.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i11.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "component", type: i12.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i13.ContentProgressComponent, selector: "ws-widget-content-progress", inputs: ["contentId", "progress", "progressType", "forPreview", "className", "customClassName"] }, { kind: "component", type: i14.CircleProgressComponent, selector: "circle-progress", inputs: ["name", "class", "backgroundGradient", "backgroundColor", "backgroundGradientStopColor", "backgroundOpacity", "backgroundStroke", "backgroundStrokeWidth", "backgroundPadding", "radius", "space", "percent", "toFixed", "maxPercent", "renderOnClick", "units", "unitsFontSize", "unitsFontWeight", "unitsColor", "outerStrokeGradient", "outerStrokeWidth", "outerStrokeColor", "outerStrokeGradientStopColor", "outerStrokeLinecap", "innerStrokeColor", "innerStrokeWidth", "titleFormat", "title", "titleColor", "titleFontSize", "titleFontWeight", "subtitleFormat", "subtitle", "subtitleColor", "subtitleFontSize", "subtitleFontWeight", "imageSrc", "imageHeight", "imageWidth", "animation", "animateTitle", "animateSubtitle", "animationDuration", "showTitle", "showSubtitle", "showUnits", "showImage", "showBackground", "showInnerStroke", "clockwise", "responsive", "startFromZero", "showZeroOuterStroke", "lazy", "options"], outputs: ["onClick"] }, { kind: "directive", type: i15.MatLegacyTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: AppTocContentCardV2Component, selector: "ws-widget-app-toc-content-card-v2", inputs: ["content", "expandAll", "rootId", "rootContentType", "forPreview", "batchId", "componentName", "index", "pathSet", "expandActive", "hierarchyMapData", "batchData", "isPreAssessment", "baseContentReadData", "mlCourse", "parentMilestoneLocked"] }, { kind: "pipe", type: i8.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i1.PipeDurationTransformPipe, name: "pipeDurationTransform" }, { kind: "pipe", type: i16.TranslatePipe, name: "translate" }, { kind: "pipe", type: i17.TruncatePipe, name: "truncate" }], animations: [
1091
- trigger('panelInOut', [
1092
- transition('void => *', [
1093
- style({ transform: 'translateY(-10%)', opacity: '0' }),
1094
- animate(250)
1095
- ]),
1096
- transition('* => void', [
1097
- animate(200, style({ transform: 'translateY(-10%)', opacity: '0' }))
1098
- ])
1099
- ])
1100
- ] }); }
1101
- }
1102
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AppTocContentCardV2Component, decorators: [{
1103
- type: Component,
1104
- args: [{ selector: 'ws-widget-app-toc-content-card-v2', animations: [
1105
- trigger('panelInOut', [
1106
- transition('void => *', [
1107
- style({ transform: 'translateY(-10%)', opacity: '0' }),
1108
- animate(250)
1109
- ]),
1110
- transition('* => void', [
1111
- animate(200, style({ transform: 'translateY(-10%)', opacity: '0' }))
1112
- ])
1113
- ])
1114
- ], template: "<ng-container *ngIf=\"content && !isPreAssessment\">\r\n <ng-container *ngIf=\"isCollection && !isModule\">\r\n <ng-container [ngTemplateOutlet]=\"collectionTemplate\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"isCollection && isModule\">\r\n <ng-container *ngIf=\"content?.moduleResourseCount\">\r\n <ng-container [ngTemplateOutlet]=\"collectionTemplate\">\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <div *ngIf=\"isResource\" class=\"resource-container\"\r\n [ngClass]=\"pathSet?.has(content?.identifier) && isEnrolled ? 'content-active-resource': 'content-not-active-resource'\">\r\n <div class=\"resource flex sm:flex-row flex-start width-expand w-100 sm:pr-4 sm:w-auto\"\r\n [ngClass]=\"{'activeResource': pathSet?.has(content?.identifier) && isEnrolled}\">\r\n <!-- Lock message for curated programs only (shown above content) -->\r\n <ng-container *ngIf=\"content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT && checkForCuratedProgram &&\r\n !isContentUnlocked\">\r\n <div class=\"content-locking flex w-full flex-middle mb-2 gap-3\">\r\n <mat-icon class=\"lock-icon\">lock</mat-icon>\r\n <span class=\"lock-message mat-body-2\">\r\n The content is locked. Complete program or all courses to view this module\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT && checkForCuratedProgram &&\r\n isContentUnlocked\">\r\n <div class=\"content-locking flex w-full flex-middle mb-2 gap-3\">\r\n <mat-icon class=\"unlock-icon\">lock_open_right</mat-icon>\r\n <span class=\"unlock-message mat-body-2\">\r\n This content is unlocked.\r\n </span>\r\n </div>\r\n </ng-container>\r\n <div class=\"flex flex-wrap items-start justify-start sm:justify-end\">\r\n <!-- <button *ngIf=\"!forPreview && content?.artifactUrl && !isXSmall && isAllowed && isEnabled\" type=\"button\"\r\n mat-icon-button class=\"\" [matMenuTriggerFor]=\"buttonMenu\">\r\n <mat-icon>more_vertical</mat-icon>\r\n </button> -->\r\n <ng-container *ngIf=\"isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\r\n\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\r\n <div class=\"completed\">\r\n <div>\r\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n <circle-progress class=\"flex items-center progress\"\r\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\r\n [outerStrokeColor]=\"progressColor2()\" [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\"\r\n [animation]=\"true\" [animationDuration]=\"250\" [showTitle]=\"false\" [showUnits]=\"false\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\r\n matTooltip=\"In progress\" [showZeroOuterStroke]=false [backgroundPadding]=\"-9\"\r\n [startFromZero]=\"false\" [backgroundPadding]=\"0\" [imageHeight]=\"22\" [imageWidth]=\"22\"\r\n [showBackground]=\"false\" [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress>\r\n <!-- <ws-widget-content-progress *ngIf=\"content?.identifier\" [forPreview]=\"forPreview\"\r\n [contentId]=\"content?.identifier\" class=\"progress-bar-thin\" [progress]=\"content?.completionPercentage\"\r\n [progressType]=\"'percentage'\">\r\n </ws-widget-content-progress> -->\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #elseBlock>\r\n <circle-progress class=\"flex items-center progress\" [percent]=\"0\" [radius]=\"11\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\r\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\" [showUnits]=\"false\"\r\n [animationDuration]=\"250\" [showTitle]=\"false\" [backgroundPadding]=\"0\"\r\n [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\" matTooltip=\"Not started\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\" [imageHeight]=\"22\"\r\n [imageWidth]=\"22\" [showBackground]=\"false\"></circle-progress>\r\n <!-- <p>no data</p> -->\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n <!-- deactivated as per NIC CEO requirement to access course wthout login -->\r\n <!-- For locked assessments: show content but make it non-clickable -->\r\n <div class=\"width-expand\" *ngIf=\"isMilestoneAssessmentLocked && isEnrolled; else clickableContent\"\r\n [ngClass]=\"{'ml-3': isEnrolled}\">\r\n <div class=\"text-truncate opacity-60\">\r\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\r\n <div class=\"flex items-center gap-2 w-full\">\r\n <mat-icon class=\"text-gray-500\">lock</mat-icon>\r\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate text-gray-600\">\r\n {{ content?.name | truncate:50 }}\r\n </p>\r\n </div>\r\n <span class=\"content-type optional-span nodtranslate\" *ngIf=\"content?.optionalReading\">{{\r\n 'playerbrief.optional' | translate | titlecase}} </span>\r\n </div>\r\n <!-- for default grey icons -->\r\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier) || !isEnrolled\">\r\n <div class=\"resicons ws-mat-black60-text\">\r\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/grey/module.svg\" class=\"float-left margin-right-xs\"\r\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\r\n\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\r\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </div>\r\n \r\n <!-- Lock message displayed BELOW assessment details when locked -->\r\n <div class=\"content-locking flex w-full flex-middle mt-2 gap-2 px-2 py-1 bg-orange-50 border-l-4 border-orange-400\">\r\n <mat-icon class=\"lock-icon text-orange-600\" style=\"font-size: 18px; width: 18px; height: 18px;\">lock</mat-icon>\r\n <span class=\"lock-message mat-body-2 text-orange-800\" style=\"font-size: 13px;\">\r\n This content is locked. Complete all mandatory items to unlock the assessment.\r\n </span>\r\n </div>\r\n </div>\r\n \r\n <!-- Clickable content template (when NOT locked) -->\r\n <ng-template #clickableContent>\r\n <a class=\"width-expand\"\r\n [class.disabled]=\"(forPreview || !isEnabled || !isEnrolled || !isBatchInProgess || !isContentUnlocked || isParentMilestoneLocked) ? true : null\"\r\n [ngClass]=\"{'ml-3': isEnrolled}\"\r\n [routerLink]=\"(isAllowed && !forPreview && isEnabled && !isParentMilestoneLocked) ? resourceLink.url : null\"\r\n [queryParams]=\"(isAllowed && !forPreview && isEnabled && !isParentMilestoneLocked) ? resourceLink.queryParams : null\"\r\n [matTooltip]=\"isParentMilestoneLocked ? 'This content is locked. Complete previous milestone to view this content.' : ''\"\r\n matTooltipPosition=\"above\">\r\n <div [ngClass]=\"{'resource-active': pathSet?.has(content?.identifier) && isEnrolled}\"></div>\r\n <div class=\"text-truncate \" [ngClass]=\"{'cursor-pointer': !isEnabled && isEnrolled}\"\r\n (click)=\"content.viewChildren = !content.viewChildren; raiseTelemetry(); changeResource()\">\r\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\r\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate\"\r\n [ngClass]=\"{'text-active': pathSet?.has(content?.identifier) && isEnrolled}\">\r\n {{ content?.name | truncate:50 }}\r\n </p>\r\n <span class=\"content-type optional-span nodtranslate\" *ngIf=\"content?.optionalReading\">{{\r\n 'playerbrief.optional' | translate | titlecase}} </span>\r\n </div>\r\n <!-- for default grey icons -->\r\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier) || !isEnrolled\">\r\n <div class=\"resicons ws-mat-black60-text\">\r\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/grey/module.svg\" class=\"float-left margin-right-xs\"\r\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\r\n\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\r\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- for white icons when content highlighted -->\r\n <ng-container *ngIf=\"pathSet?.has(content?.identifier) && isEnrolled\">\r\n <div class=\"resicons ws-mat-white-text\">\r\n <img src=\"/assets/icons/content/white/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/white/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/white/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <img src=\"/assets/icons/content/white/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/white/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/white/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/white/module.svg\" class=\"float-left margin-right-xs\"\r\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\r\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Download button for pdf resources -->\r\n <ng-container *ngIf=\"shouldShowDownloadButton(content)\">\r\n <div class=\"download-btn mat-body-2 mt-2 sm:mt-1\" (click)=\"downloadContent(content, $event)\"\r\n [ngClass]=\"{'active': pathSet?.has(content?.identifier)}\">\r\n <a class=\"download-link flex items-center\">\r\n <span class=\"\">Download</span>\r\n </a>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </a>\r\n </ng-template>\r\n </div>\r\n </div>\r\n</ng-container>\r\n\r\n<mat-menu #buttonMenu=\"matMenu\">\r\n <a mat-menu-item [routerLink]=\"'../' + content?.identifier + '/overview'\" [queryParams]=\"contextPath\"\r\n class=\"flex flex-middle\">\r\n <mat-icon>toc</mat-icon>\r\n <h3 class=\"margin-remove nodtranslate\">\r\n View Details\r\n </h3>\r\n </a>\r\n</mat-menu>\r\n\r\n<ng-template #collectionTemplate>\r\n <ng-container *ngIf=\"isCollection\">\r\n <div class=\"collection-wrapper p-4 flex flex-col position-relative\" [ngClass]=\"{'open': check(content),\r\n 'close': !content.viewChildren,\r\n 'course':!isModule, 'module': isModule,\r\n 'content-active': pathSet?.has(content.identifier) && isEnrolled}\">\r\n <div class=\"card-collection w-auto sm:w-100 padding-right-xl\">\r\n <!-- <img class=\"card-thumbnail ws-mat-primary-lite-background\" [src]=\"content?.appIcon\" alt=\"Thumbnail\"\r\n (click)=\"content.viewChildren = !content.viewChildren\" [wsUtilsDefaultThumbnail]=\"defaultThumbnail\" /> -->\r\n <div class=\"flex flex-col flex-wrap flex-between width-expand pr-0 w-100 \">\r\n <div class=\"text-truncate\" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\r\n (click)=\"content.viewChildren = !content.viewChildren\">\r\n <div class=\"flex items-center justify-center mb-1 sm:flex-row\">\r\n <ng-container\r\n *ngIf=\"isModule && isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\r\n\r\n <ng-container *ngIf=\"getCompletionStatus(content.identifier) == 2\">\r\n <div class=\"completed mr-2\">\r\n <div>\r\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n <circle-progress class=\"flex items-center progress mr-1\"\r\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\r\n [outerStrokeColor]=\"progressColor2()\"\r\n [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\" [animation]=\"true\"\r\n [animationDuration]=\"250\" [showTitle]=\"false\" [showUnits]=\"false\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\"\r\n [backgroundStrokeWidth]=\"3\" matTooltip=\"In progress\"\r\n [showZeroOuterStroke]=false [backgroundPadding]=\"-7\" [startFromZero]=\"false\"\r\n [backgroundPadding]=\"0\" [imageHeight]=\"18\" [imageWidth]=\"18\"\r\n [showBackground]=\"false\" [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress>\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #elseBlock>\r\n <circle-progress class=\"flex items-center progress mr-1\" [percent]=\"0\" [radius]=\"11\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\r\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\"\r\n [showUnits]=\"false\" [animationDuration]=\"250\" [showTitle]=\"false\"\r\n [backgroundPadding]=\"0\" [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\"\r\n matTooltip=\"Not started\" [showSubtitle]=\"false\" [showInnerStroke]=\"true\"\r\n [clockwise]=\"true\" [imageHeight]=\"22\" [imageWidth]=\"22\"\r\n [showBackground]=\"false\"></circle-progress>\r\n </ng-template>\r\n </ng-container>\r\n <div\r\n [ngClass]=\"{'collection-active-class': pathSet?.has(content?.identifier) && isEnrolled}\">\r\n </div>\r\n <img *ngIf=\"isMilestoneLocked\" src=\"assets/icons/hubs/lock.svg\" alt=\"Locked\"\r\n class=\"lock-icon mr-2 margin-bottom-xxs\">\r\n <p class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\r\n [ngClass]=\"{'text-active': pathSet?.has(content.identifier) && isEnrolled}\">\r\n <span>{{isMilestone ? index -1 : index}}. </span>{{ content?.name | truncate:50 }}\r\n <ng-container *ngIf=\"isMilestone\">\r\n <span *ngIf=\"isMilestoneLocked\" class=\"locked-text ml-2\">Locked</span>\r\n </ng-container>\r\n <span *ngIf=\"content?.isMandatory\"\r\n class=\"mandatory-text mat-caption ml-2\">Mandatory</span>\r\n </p>\r\n \r\n <div class=\"type-container resource mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Resource'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Resource</span>\r\n </div>\r\n <div class=\"type-container module mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Collection'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Module</span>\r\n </div>\r\n <div class=\"type-container course mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Course'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Course</span>\r\n </div>\r\n </div>\r\n <!-- Milestone Badge -->\r\n <div *ngIf=\"isMilestone\" class=\"milestone-badge mt-2 mb-2\">\r\n <span class=\"milestone-badge-text nodtranslate\">Milestone {{index - 1}}</span>\r\n </div>\r\n <!-- Milestone Description (3 lines with ellipsis) -->\r\n <p *ngIf=\"isMilestone && content?.description\" class=\"milestone-description mt-2 nodtranslate\">\r\n {{ content?.description }}\r\n </p>\r\n <div class=\"flex flex-row gap-3 items-center content-key-values mt-2\">\r\n <mat-icon *ngIf=\"!isModule\" alt=\"course\"\r\n class=\"time-icon icon-color\">video_library</mat-icon>\r\n <img *ngIf=\"isModule\" alt=\"Module\" class=\"time-icon\"\r\n src=\"/assets/icons/content/grey/module.svg\">\r\n <div class=\"text-xs nodtranslate\">{{ (hierarchyMapData[content?.identifier]?.duration ||\r\n 120)|\r\n pipeDurationTransform: 'hms' }}</div>\r\n\r\n <ng-container *ngIf=\"content?.moduleCount\">\r\n <div class=\"flex items-center\">\r\n <span class=\"period\"></span>\r\n </div>\r\n <div class=\"text-xs nodtranslate\">{{content?.moduleCount}} {{content?.moduleCount > 1?\r\n 'modules' :\r\n 'module'}}</div>\r\n </ng-container>\r\n <ng-container *ngIf=\"content?.leafNodesCount\">\r\n <div class=\"flex items-center\">\r\n <span class=\"period\"></span>\r\n </div>\r\n <div class=\"text-xs nodtranslate\">{{content?.leafNodesCount}} {{content?.leafNodesCount\r\n >1 ? 'items':\r\n 'item'}}</div>\r\n </ng-container>\r\n </div>\r\n <!-- Milestone Completion Progress -->\r\n <div *ngIf=\"isMilestone && isEnrolled && !isMilestoneLocked\" class=\"milestone-progress mt-2 flex items-center justify-between\">\r\n <div>\r\n <span class=\"milestone-progress-text nodtranslate\">{{getMilestoneCompletedCount()}} of\r\n {{content?.leafNodesCount || 0}} completed</span>\r\n </div>\r\n <!-- View Achievement Button for completed milestones - Outside clickable area -->\r\n <div *ngIf=\"isMilestone && isEnrolled && (getCompletionPercentage(content?.identifier) >= 100 || getCompletionStatus(content?.identifier) === 2)\"\r\n class=\"view-achievement-container mt-2\">\r\n <button type=\"button\" class=\"view-achievement-btn\" [disabled]=\"achievementLoading\"\r\n (click)=\"viewMilestoneAchievement($event)\">\r\n <span *ngIf=\"!achievementLoading\">View Achievement</span>\r\n <mat-spinner *ngIf=\"achievementLoading\" [diameter]=\"16\" \r\n [strokeWidth]=\"2\" color=\"primary\" class=\"inline-spinner\"></mat-spinner>\r\n </button>\r\n </div>\r\n </div>\r\n <!-- Unlock Criteria Message for Locked Milestones -->\r\n <div *ngIf=\"isMilestone && isEnrolled && isMilestoneLocked\" class=\"milestone-locked-message mt-2\">\r\n <span class=\"locked-criteria-text mat-caption\">\r\n {{ getMilestoneUnlockMessage() }}\r\n </span>\r\n </div>\r\n \r\n </div>\r\n <!-- For course progress to be shown -->\r\n <ng-container *ngIf=\"isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) && content.primaryCategory === 'Course'\">\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\r\n <div class=\"flex flex-1\">\r\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\r\n <div class=\"flex flex-row justify-end w-full \">\r\n <span class=\"mat-body-2 nodtranslate \">\r\n {{getCompletionPercentage(content?.identifier)}}%</span>\r\n </div>\r\n\r\n <ws-widget-content-progress [contentId]=\"content?.progress\"\r\n [progress]=\"getCompletionPercentage(content?.identifier)\"\r\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\r\n </ws-widget-content-progress>\r\n </div>\r\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\r\n <a class=\"ml-5 certificate-btn\"\r\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\r\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\r\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\r\n <span class=\"nodtranslate\">Certificate</span>\r\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\r\n class=\"ml-2\">arrow_downward</mat-icon>\r\n <div class=\"center flex flex-middle certificate-loader\"\r\n *ngIf=\"downloadCertificateLoading\">\r\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\r\n [diameter]=\"16\"></mat-spinner>\r\n </div>\r\n </a>\r\n </ng-container>\r\n </div>\r\n <!-- <circle-progress class=\"flex items-center progress\" [percent]=\"100\" [radius]=\"12\"\r\n [outerStrokeWidth]=\"3\" [innerStrokeWidth]=\"3\" [space]=\"-3\"\r\n [outerStrokeColor]=\"progressColor()\" [innerStrokeColor]=\"'rgba(0,0,0,.16)'\"\r\n [animation]=\"true\" [animationDuration]=\"300\" [showTitle]=\"false\" [showUnits]=\"false\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\r\n [showZeroOuterStroke]=false [backgroundPadding]=\"-9\" [startFromZero]=\"false\"\r\n [backgroundPadding]=\"0\" [imageHeight]=\"24\" [imageWidth]=\"24\" [showBackground]=\"false\"\r\n [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress> -->\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n <div class=\"flex flex-1\">\r\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\r\n <div class=\"flex flex-row justify-end w-full ws-mat-black-text\">\r\n <span class=\"mat-body-2 ws-mat-black-text nodtranslate\">\r\n {{getCompletionPercentage(content?.identifier)}}%</span>\r\n </div>\r\n\r\n <ws-widget-content-progress [contentId]=\"content?.progress\"\r\n [progress]=\"getCompletionPercentage(content?.identifier)\"\r\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\r\n </ws-widget-content-progress>\r\n </div>\r\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\r\n <a class=\"ml-5 certificate-btn\"\r\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\r\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\r\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\r\n <span class=\"nodtranslate\">Certificate</span>\r\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\r\n class=\"ml-2\">arrow_downward</mat-icon>\r\n <div class=\"center flex flex-middle certificate-loader\"\r\n *ngIf=\"downloadCertificateLoading\">\r\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\r\n [diameter]=\"16\"></mat-spinner>\r\n </div>\r\n </a>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <div class=\"see-all-container\">\r\n <a href=\"javascript:void(0)\" role=\"button\"\r\n (click)=\"content.viewChildren = !content.viewChildren; expandActive = false\"\r\n class=\"see-all-btn tab custom-chevron customicon\" mat-button>\r\n <mat-icon *ngIf=\"!content.viewChildren && !isModule\">keyboard_arrow_down</mat-icon>\r\n <mat-icon *ngIf=\"content.viewChildren && !isModule\">keyboard_arrow_up</mat-icon>\r\n <mat-icon *ngIf=\"!content.viewChildren && isModule\">add</mat-icon>\r\n <mat-icon *ngIf=\"content.viewChildren && isModule\">remove</mat-icon>\r\n </a>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"child-wrapper \" *ngIf=\"content.viewChildren\" [ngClass]=\"{'open': content.viewChildren,\r\n 'close': !content.viewChildren,\r\n 'course':!isModule,\r\n 'module': isModule}\" [@panelInOut]>\r\n <div class=\"children-container\" [ngClass]=\"{'module': isModule, '': !isModule}\">\r\n <ws-widget-app-toc-content-card-v2 [forPreview]=\"forPreview\" [componentName]=\"componentName\"\r\n [content]=\"child\" [expandAll]=\"expandAll\" [rootId]=\"rootId\" [batchId]=\"batchId\"\r\n [rootContentType]=\"rootContentType\" [index]=\"j+1\" [baseContentReadData]=\"baseContentReadData\"\r\n [pathSet]=\"pathSet\" [hierarchyMapData]=\"hierarchyMapData\" [batchData]=\"batchData\"\r\n [mlCourse]=\"mlCourse\" [parentMilestoneLocked]=\"isMilestoneLocked || isParentMilestoneLocked\"\r\n *ngFor=\"let child of content?.children; trackBy: contentTrackBy; let j= index;let isFirst = first\"\r\n [ngClass]=\"{'moduleCard': checkIsModule(child), 'resourceCard': !checkIsModule(child), 'first': isFirst}\">\r\n </ws-widget-app-toc-content-card-v2>\r\n </div>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n\r\n<ng-container *ngIf=\"isPreAssessment\">\r\n <div class=\"collection-wrapper p-4 flex flex-col position-relative\" [ngClass]=\"{'open': check(content),\r\n 'course':!isModule, 'module': isModule,\r\n 'content-active': pathSet?.has(content.identifier)}\">\r\n <div class=\"card-collection w-auto sm:w-100 padding-right-xl\">\r\n <!-- <img class=\"card-thumbnail ws-mat-primary-lite-background\" [src]=\"content?.appIcon\" alt=\"Thumbnail\"\r\n (click)=\"content.viewChildren = !content.viewChildren\" [wsUtilsDefaultThumbnail]=\"defaultThumbnail\" /> -->\r\n <div class=\"flex flex-col flex-wrap flex-between width-expand pr-0 w-100 \">\r\n\r\n <div class=\"text-truncate\" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\r\n (click)=\"content.viewChildren = !content.viewChildren\">\r\n <div class=\"flex sm:flex-row flex-wrap\">\r\n <ng-container>\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\r\n\r\n <ng-container *ngIf=\"getCompletionStatus(content.identifier) == 2\">\r\n <div class=\"completed mr-2\">\r\n <div>\r\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n\r\n <circle-progress class=\"flex items-center progress mr-1\"\r\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\r\n [outerStrokeColor]=\"progressColor2()\" [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\"\r\n [animation]=\"true\" [animationDuration]=\"250\" [showTitle]=\"false\"\r\n [showUnits]=\"false\" [showSubtitle]=\"false\" [showInnerStroke]=\"true\"\r\n [clockwise]=\"true\" [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\"\r\n [backgroundStrokeWidth]=\"3\" matTooltip=\"In progress\" [showZeroOuterStroke]=false\r\n [backgroundPadding]=\"-7\" [startFromZero]=\"false\" [backgroundPadding]=\"0\"\r\n [imageHeight]=\"18\" [imageWidth]=\"18\" [showBackground]=\"false\"\r\n [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress>\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #elseBlock>\r\n <circle-progress class=\"flex items-center progress mr-1\" [percent]=\"0\" [radius]=\"11\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\r\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\" [showUnits]=\"false\"\r\n [animationDuration]=\"250\" [showTitle]=\"false\" [backgroundPadding]=\"0\"\r\n [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\" matTooltip=\"Not started\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [imageHeight]=\"22\" [imageWidth]=\"22\" [showBackground]=\"false\"></circle-progress>\r\n </ng-template>\r\n </ng-container>\r\n <div [ngClass]=\"{'collection-active-class': pathSet?.has(content?.identifier)}\"></div>\r\n <!-- <p class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\r\n [ngClass]=\"{'text-active': pathSet?.has(content.identifier)}\">\r\n {{index}}. {{ content?.name | truncate:50 }}\r\n </p> -->\r\n <a class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\r\n [class.disabled]=\"null\" [ngClass]=\"{'ml-3': isEnrolled}\"\r\n [routerLink]=\"(isAllowed && !forPreview && isEnabled) ? resourceLink.url : null\"\r\n [queryParams]=\"computedQueryParams\">\r\n <!-- {{content?.courseCategory}} -->\r\n <div [ngClass]=\"{'resource-active': pathSet?.has(content?.identifier)}\"></div>\r\n <div class=\"text-truncate \" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\r\n (click)=\"raiseTelemetry(); changeResource()\">\r\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\r\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate\"\r\n [ngClass]=\"{'text-active': pathSet?.has(content?.identifier)}\">\r\n <!-- <mat-icon class=\"margin-right-xs radiobtn time-icon\">radio_button_unchecked </mat-icon> -->\r\n {{index}}. {{ content?.name | truncate:50 }}\r\n\r\n </p>\r\n <span class=\"content-type optional-span nodtranslate\"\r\n *ngIf=\"content?.optionalReading\">{{ 'playerbrief.optional' | translate |\r\n titlecase}} </span>\r\n </div>\r\n <!-- for default grey icons -->\r\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier)\">\r\n <div class=\"resicons ws-mat-black60-text\">\r\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <!-- <img src=\"/assets/icons/content/grey/resource.svg\" alt=\"Survey\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/survey'\"> -->\r\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\"\r\n alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/grey/module.svg\"\r\n class=\"float-left margin-right-xs\" alt=\"offline sessions\"\r\n *ngIf=\"content.mimeType === 'application/offline'\">\r\n\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{\r\n content?.maxQuestions }} {{ 'playerbrief.questions' | translate |\r\n titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{\r\n (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- for white icons when content highlighted -->\r\n <ng-container *ngIf=\"pathSet?.has(content?.identifier)\">\r\n <div class=\"resicons ws-mat-white-text\">\r\n <img src=\"/assets/icons/content/white/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/white/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/white/pdf.svg\" alt=\"PDF\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <!-- <img src=\"/assets/icons/content/white/resource.svg\" alt=\"Survey\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/survey'\"> -->\r\n <img src=\"/assets/icons/content/white/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/white/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/white/content_copy.svg\" class=\"contenticon\"\r\n alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/white/module.svg\"\r\n class=\"float-left margin-right-xs\" alt=\"offline sessions\"\r\n *ngIf=\"content.mimeType === 'application/offline'\">\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n <span class=\"resourceDuration ws-mat-white-text nodtranslate\">{{\r\n content?.maxQuestions }} {{ 'playerbrief.questions' | translate |\r\n titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-white-text nodtranslate\">{{\r\n (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </a>\r\n <!-- <div class=\"type-container resource mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Resource'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Resource</span>\r\n </div>\r\n <div class=\"type-container module mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Collection'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Module</span>\r\n </div>\r\n <div class=\"type-container course mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Course'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Course</span>\r\n </div> -->\r\n </div>\r\n\r\n </div>\r\n <!-- For course progress to be shown -->\r\n <ng-container>\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier)\">\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\r\n <div class=\"flex flex-1\">\r\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\r\n <div class=\"flex flex-row justify-end w-full \">\r\n <span class=\"mat-body-2 nodtranslate \">\r\n {{getCompletionPercentage(content?.identifier)}}%</span>\r\n </div>\r\n\r\n <ws-widget-content-progress [contentId]=\"content?.progress\"\r\n [progress]=\"getCompletionPercentage(content?.identifier)\"\r\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\r\n </ws-widget-content-progress>\r\n </div>\r\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\r\n <a class=\"ml-5 certificate-btn\"\r\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\r\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\r\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\r\n <span class=\"nodtranslate\">Certificate</span>\r\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\r\n class=\"ml-2\">arrow_downward</mat-icon>\r\n <div class=\"center flex flex-middle certificate-loader\"\r\n *ngIf=\"downloadCertificateLoading\">\r\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\r\n [diameter]=\"16\"></mat-spinner>\r\n </div>\r\n </a>\r\n </ng-container>\r\n </div>\r\n <!-- <circle-progress class=\"flex items-center progress\" [percent]=\"100\" [radius]=\"12\"\r\n [outerStrokeWidth]=\"3\" [innerStrokeWidth]=\"3\" [space]=\"-3\"\r\n [outerStrokeColor]=\"progressColor()\" [innerStrokeColor]=\"'rgba(0,0,0,.16)'\"\r\n [animation]=\"true\" [animationDuration]=\"300\" [showTitle]=\"false\" [showUnits]=\"false\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\r\n [showZeroOuterStroke]=false [backgroundPadding]=\"-9\" [startFromZero]=\"false\"\r\n [backgroundPadding]=\"0\" [imageHeight]=\"24\" [imageWidth]=\"24\" [showBackground]=\"false\"\r\n [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress> -->\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n <div class=\"flex flex-1\">\r\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\r\n <div class=\"flex flex-row justify-end w-full ws-mat-black-text\">\r\n <span class=\"mat-body-2 ws-mat-black-text nodtranslate\">\r\n {{getCompletionPercentage(content?.identifier)}}%</span>\r\n </div>\r\n\r\n <ws-widget-content-progress [contentId]=\"content?.progress\"\r\n [progress]=\"getCompletionPercentage(content?.identifier)\"\r\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\r\n </ws-widget-content-progress>\r\n </div>\r\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\r\n <a class=\"ml-5 certificate-btn\"\r\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\r\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\r\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\r\n <span class=\"nodtranslate\">Certificate</span>\r\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\r\n class=\"ml-2\">arrow_downward</mat-icon>\r\n <div class=\"center flex flex-middle certificate-loader\"\r\n *ngIf=\"downloadCertificateLoading\">\r\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\r\n [diameter]=\"16\"></mat-spinner>\r\n </div>\r\n </a>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- <div class=\"see-all-container\">\r\n <a href=\"javascript:void(0)\" role=\"button\"\r\n (click)=\"content.viewChildren = !content.viewChildren; expandActive = false\"\r\n class=\"see-all-btn tab custom-chevron customicon\" mat-button>\r\n <mat-icon *ngIf=\"!content.viewChildren && !isModule\">keyboard_arrow_down</mat-icon>\r\n <mat-icon *ngIf=\"content.viewChildren && !isModule\">keyboard_arrow_up</mat-icon>\r\n <mat-icon *ngIf=\"!content.viewChildren && isModule\">add</mat-icon>\r\n <mat-icon *ngIf=\"content.viewChildren && isModule\">remove</mat-icon>\r\n </a>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n\r\n</ng-container>", styles: [".customicon{position:absolute;top:-.5em;right:0}.customicon .mat-icon{color:#1a4ca1}a.disabled{pointer-events:none;cursor:default}span.optional-span{margin-left:8px;padding:0 6px;border-radius:2px;display:inline-block;background-color:#0074b6;color:#fff;font-size:12px}.card-collection{display:flex;align-items:center;border-radius:8px}.card-collection .card-thumbnail{height:100%;margin-right:12px;cursor:pointer;border-radius:8px 0 0}@media only screen and (max-width: 469px){.card-collection{flex-direction:column;align-items:flex-start!important}.card-collection .card-thumbnail{height:100%!important;width:100%!important}.card-collection .text-truncate{white-space:unset!important}}.tab:focus{outline:1px solid!important}.custom-chevron:focus{outline:0px solid!important}.resource-container{display:flex;align-items:flex-start;flex-direction:column}.resource-container .resource{padding:16px 16px 16px 0;width:100%}.resource-container .card-thumbnail{height:100%;cursor:pointer}.resource-container .img-container{position:relative;margin-right:12px}.resource-container .img-container ws-widget-content-progress{position:absolute;left:0;right:0;bottom:5px}@media only screen and (max-width: 469px){.resource-container{flex-direction:column;align-items:flex-start!important}.resource-container .card-thumbnail{height:100%!important;width:100%!important}.resource-container .text-truncate{white-space:unset!important}}.child-meta-container{margin-top:8px;display:flex}.child-meta-container .child-structure{display:flex;align-items:center;flex-wrap:wrap}.child-meta-container .child-structure span{margin-right:12px;text-align:center;margin-bottom:8px}.child-meta-container .child-structure .structure-icon{margin-right:12px}@media only screen and (max-width: 469px){.child-meta-container{margin-left:.5rem;justify-content:space-between}}.resource-container{display:flex;align-items:center}.resource-container ws-display-content-type-icon{display:flex;align-items:center}.resource-container .resource-meta{margin-left:12px;display:flex;justify-content:space-between;align-items:center}.completed-icon{color:#1a4ca1}.collection-wrapper{padding:1rem}.collection-wrapper.course.content-active{background-color:#1a4ca1;color:#fff}.collection-wrapper.course.content-active .period{background:#fff}.collection-wrapper.course.content-active .text-active,.collection-wrapper.course.content-active .icon-color,.collection-wrapper.course.content-active .customicon .mat-icon{color:#fff}.collection-wrapper.course.content-active .progress-container span{color:#fff!important}.text-active{color:#1a4ca1}.text-active.font-bold{font-weight:600}.activeResource{background-color:#1a4ca1;color:#fff;padding-top:1rem!important;padding-bottom:1rem!important}.activeResource .text-active{color:#fff}.activeResource .text-active.font-bold{font-weight:600}.activeResource .resourceDuration,.activeResource .completed-icon{color:#fff}.collection-wrapper.open{border-bottom:1px solid rgba(0,0,0,.16)}.collection-wrapper.close{border:none}.child-wrapper.open{border-radius:0 0 8px 8px}.children-container .mat-subheading-1{font:500 16px/24px Lato!important}.children-container .resource-container{margin-bottom:16px}.children-container .resource-container .resource{padding:0}.children-container .resource-container .card-thumbnail{height:65px;align-self:center}.first.resourceCard:nth-child(1) .resource{margin-top:16px!important}.first.resourceCard:nth-child(1) .activeResource{margin-top:0!important}.children-container .resourceCard:last-child .resource-container:has(.activeResource){margin-bottom:0!important}.moduleCard:not(:last-child)>.collection-wrapper.close.module{border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.moduleCard:not(:last-child)>.collection-wrapper.open.module+.child-wrapper.open{border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.collection-wrapper.open.course+.child-wrapper.open .collection-wrapper.open.module+.child-wrapper.open{background-color:#eff3f9;border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.collection-wrapper.open.module+.child-wrapper.open{background-color:#eff3f9;border-radius:0;padding-bottom:8px}.content-heading{letter-spacing:0px;color:#222}.content-type{letter-spacing:0px}.time-icon{height:16px;width:16px;font-size:16px;vertical-align:middle}.time-icon.icon-color{color:#0009}.period{width:3px;height:3px;background:#0009;border-radius:4px}.time-value{letter-spacing:0px;color:#222;text-transform:lowercase}.see-all-container{position:absolute;right:16px;top:24px}.oval-white{background:#fff 0% 0% no-repeat padding-box;border-radius:8px;padding:2px 8px}.type-container{letter-spacing:0px;display:flex;align-items:center}.type-container .rotate-90{transform:rotate(-90deg)}.type-container .custom-icon{width:18px;height:18px;font-size:18px;margin-right:8px}.type-container.resource{color:#00a9f4}.type-container.module{color:#34d6a4}.type-container.course{color:#f58634}.no-mb{margin-bottom:0!important}.w-100{width:100%}.w-auto{width:auto}.progress-bar-thin{height:5px!important}.progress-bar-thin ::ng-deep .mat-progress-bar{height:5px}.progress-bar-thin ::ng-deep .theme-igot.day-mode .mat-progress-bar-buffer{background-color:transparent!important}.progress-bar-thin ::ng-deep .theme-igot.day-mode .mat-progress-bar-background{fill:transparent}.radiobtn{color:#00000029}.resicons img{width:22px;opacity:.5;margin-top:2px;vertical-align:sub}.certificate-btn{height:24px;background:#1a4ca1;display:flex;justify-content:center;align-items:center;padding:4px 11px;color:#fff;border-radius:20px;border:1px solid white;font:400 12px/16px Lato;cursor:pointer}.certificate-btn .mat-icon{fill:#fff;color:#fff;font-size:16px;height:auto;width:auto}.view-certificate-wrapper{display:flex;border-radius:4px;border:1.5px solid rgb(0,116,182);opacity:1;padding:8px}.collection-wrapper.course,.collection-wrapper.module,.resource-container .resource{padding-left:16px;box-sizing:border-box;width:100%;overflow:hidden}.children-container.module .resource-container .resource,.course .collection-wrapper.module{padding-left:24px;box-sizing:border-box;width:100%}.course .children-container.module .resource-container .resource{padding-left:32px;box-sizing:border-box;width:100%}.course .resource-container .resource{padding-left:24px}::ng-deep .white-spinner{stroke:#fff!important}.certificate-loader ::ng-deep .mat-progress-spinner circle,.mat-spinner circle{stroke:#fff}.lock-message{background:#fff4ec;color:#d13924;padding:10px;border-radius:4px;display:block!important;width:100%}.content-locking{padding:8px 12px;margin-top:8px;margin-left:0;margin-right:0;border-radius:4px;background:#fff4ec;display:flex!important;align-items:center;gap:8px;width:100%;box-sizing:border-box}.lock-icon{color:#f3962f;font-size:20px;flex-shrink:0}.unlock-message{background:#efffec;color:#0c9600;padding:10px}.unlock-icon{color:#0c9600}.download-btn{padding:4px 12px;text-underline-position:from-font;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none;cursor:pointer;border-radius:40px;color:#1b4ca1;font-weight:700;border:1px solid #1B4CA1;display:inline-block;pointer-events:auto;position:relative;z-index:1}.activeResource .download-btn.active{color:#fff;border:1px solid #fff}.milestone-badge{display:inline-block;background-color:#fefaf4;border:1px solid #EF951E;border-radius:16px;padding:2px 12px}.milestone-badge-text{font-size:12px;font-weight:500;color:#212121}.milestone-description{font-size:14px;line-height:1.5;color:#000000b3;margin:0;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.milestone-progress{display:flex;align-items:center}.milestone-progress-text{font-size:14px;font-weight:500;color:#0009}.milestone-locked-message{display:flex;align-items:center;padding:8px 12px;background-color:#f3962f1a;border-left:3px solid #F3962F;border-radius:4px}.locked-criteria-text{font-size:13px;font-weight:400;color:#000000b3;line-height:1.4}.locked-text{font-size:14px;font-weight:500;color:#f3962f}.mandatory-text{color:#d13924!important}.view-achievement-container{display:flex;align-items:center}.view-achievement-btn{background-color:transparent;border:1.5px solid #1a4ca1;color:#1a4ca1;border-radius:20px;padding:6px 16px;font-size:14px;font-weight:500;cursor:pointer;display:flex;align-items:center;gap:8px;transition:all .2s ease;min-width:150px}.view-achievement-btn:hover:not(:disabled){background-color:#1a4ca1;color:#fff}.view-achievement-btn:disabled{opacity:.6;cursor:not-allowed}.view-achievement-btn .inline-spinner{display:inline-block}\n"] }]
1115
- }], ctorParameters: function () { return [{ type: i1.EventService }, { type: i2.MatLegacyDialog }, { type: i0.Renderer2 }, { type: i3.CertificateService }, { type: i4.AppTocService }, { type: i5.ContentLanguageService }, { type: i6.ResourceDownloadHelperService }, { type: i1.ConfigurationsService }, { type: i7.MatLegacySnackBar }]; }, propDecorators: { content: [{
1116
- type: Input
1117
- }], expandAll: [{
1118
- type: Input
1119
- }], rootId: [{
1120
- type: Input
1121
- }], rootContentType: [{
1122
- type: Input
1123
- }], forPreview: [{
1124
- type: Input
1125
- }], batchId: [{
1126
- type: Input
1127
- }], componentName: [{
1128
- type: Input
1129
- }], index: [{
1130
- type: Input
1131
- }], pathSet: [{
1132
- type: Input
1133
- }], expandActive: [{
1134
- type: Input
1135
- }], hierarchyMapData: [{
1136
- type: Input
1137
- }], batchData: [{
1138
- type: Input
1139
- }], isPreAssessment: [{
1140
- type: Input
1141
- }], baseContentReadData: [{
1142
- type: Input
1143
- }], mlCourse: [{
1144
- type: Input
1145
- }], parentMilestoneLocked: [{
1146
- type: Input
1147
- }] } });
1148
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicmFyeS9zdW5iaXJkLWNiL3RvYy9zcmMvbGliL19jb2xsZWN0aW9uL19jb21tb24vY29udGVudC10b2MvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicmFyeS9zdW5iaXJkLWNiL3RvYy9zcmMvbGliL19jb2xsZWN0aW9uL19jb21tb24vY29udGVudC10b2MvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQW9DLE1BQU0sZUFBZSxDQUFBO0FBQ2xGLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQTtBQUN0RSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQTtBQUU5RSxPQUFPLEVBQWdCLFFBQVEsRUFBeUIsTUFBTSxzQkFBc0IsQ0FBQTtBQUNwRixPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSx1REFBdUQsQ0FBQTtBQUVsRyxPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFDekUsbUJBQW1CO0FBQ25CLE9BQU8sQ0FBQyxNQUFNLFFBQVEsQ0FBQTtBQUN0QixPQUFPLE1BQU0sTUFBTSxRQUFRLENBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF3QjNCLE1BQU0sT0FBTyw0QkFBNEI7SUEyRHZDLFlBQ1UsTUFBb0IsRUFDcEIsTUFBaUIsRUFDakIsUUFBbUIsRUFDbkIsa0JBQXNDLEVBQ3RDLFNB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QkFDSDsyV0FHUSxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLG1CQUFtQjtzQkFBM0IsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLHFCQUFxQjtzQkFBN0IsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE9uSW5pdCwgUmVuZGVyZXIyLCBTaW1wbGVDaGFuZ2VzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSdcclxuaW1wb3J0IHsgTnNDb250ZW50IH0gZnJvbSAnLi4vLi4vLi4vLi4vX3NlcnZpY2VzL3dpZGdldC1jb250ZW50Lm1vZGVsJ1xyXG5pbXBvcnQgeyB2aWV3ZXJSb3V0ZUdlbmVyYXRvciB9IGZyb20gJy4uLy4uLy4uLy4uL19zZXJ2aWNlcy92aWV3ZXItcm91dGUtdXRpbCdcclxuaW1wb3J0IHsgTnNBcHBUb2MgfSBmcm9tICcuLi8uLi8uLi8uLi9tb2RlbHMvYXBwLXRvYy5tb2RlbCdcclxuaW1wb3J0IHsgRXZlbnRTZXJ2aWNlLCBXc0V2ZW50cywgQ29uZmlndXJhdGlvbnNTZXJ2aWNlIH0gZnJvbSAnQHN1bmJpcmQtY2IvdXRpbHMtdjInXHJcbmltcG9ydCB7IENlcnRpZmljYXRlRGlhbG9nQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vY2VydGlmaWNhdGUtZGlhbG9nL2NlcnRpZmljYXRlLWRpYWxvZy5jb21wb25lbnQnXHJcbmltcG9ydCB7IE1hdExlZ2FjeURpYWxvZyBhcyBNYXREaWFsb2cgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9sZWdhY3ktZGlhbG9nJ1xyXG5pbXBvcnQgeyBhbmltYXRlLCBzdHlsZSwgdHJhbnNpdGlvbiwgdHJpZ2dlciB9IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnXHJcbi8qIHRzbGludDpkaXNhYmxlKi9cclxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJ1xyXG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCdcclxuaW1wb3J0IHsgQ2VydGlmaWNhdGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vLi4vc2VydmljZXMvY2VydGlmaWNhdGUuc2VydmljZSdcclxuaW1wb3J0IHsgQXBwVG9jU2VydmljZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NlcnZpY2VzL2FwcC10b2Muc2VydmljZSdcclxuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcydcclxuaW1wb3J0IHsgQ29udGVudExhbmd1YWdlU2VydmljZSB9IGZyb20gJ0BzdW5iaXJkLWNiL2NvbnN1bXB0aW9uJ1xyXG5pbXBvcnQgeyBSZXNvdXJjZURvd25sb2FkSGVscGVyU2VydmljZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NlcnZpY2VzL3Jlc291cmNlLWRvd25sb2FkLWhlbHBlci5zZXJ2aWNlJ1xyXG5pbXBvcnQgeyBNYXRMZWdhY3lTbmFja0JhciBhcyBNYXRTbmFja0JhciB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2xlZ2FjeS1zbmFjay1iYXInXHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ3dzLXdpZGdldC1hcHAtdG9jLWNvbnRlbnQtY2FyZC12MicsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2FwcC10b2MtY29udGVudC1jYXJkLXYyLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9hcHAtdG9jLWNvbnRlbnQtY2FyZC12Mi5jb21wb25lbnQuc2NzcyddLFxyXG4gIGFuaW1hdGlvbnM6IFtcclxuICAgIHRyaWdnZXIoJ3BhbmVsSW5PdXQnLCBbXHJcbiAgICAgIHRyYW5zaXRpb24oJ3ZvaWQgPT4gKicsIFtcclxuICAgICAgICBzdHlsZSh7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVkoLTEwJSknLCBvcGFjaXR5OiAnMCcgfSksXHJcbiAgICAgICAgYW5pbWF0ZSgyNTApXHJcbiAgICAgIF0pLFxyXG4gICAgICB0cmFuc2l0aW9uKCcqID0+IHZvaWQnLCBbXHJcbiAgICAgICAgYW5pbWF0ZSgyMDAsIHN0eWxlKHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlWSgtMTAlKScsIG9wYWNpdHk6ICcwJyB9KSlcclxuICAgICAgXSlcclxuICAgIF0pXHJcbiAgXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgQXBwVG9jQ29udGVudENhcmRWMkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcbiAgQElucHV0KCkgY29udGVudDogTnNDb250ZW50LklDb250ZW50IHwgbnVsbCA9IG51bGxcclxuICBASW5wdXQoKSBleHBhbmRBbGwgPSBmYWxzZVxyXG4gIEBJbnB1dCgpIHJvb3RJZCE6IHN0cmluZ1xyXG4gIEBJbnB1dCgpIHJvb3RDb250ZW50VHlwZSE6IHN0cmluZ1xyXG4gIEBJbnB1dCgpIGZvclByZXZpZXcgPSBmYWxzZVxyXG4gIEBJbnB1dCgpIGJhdGNoSWQhOiBzdHJpbmdcclxuICBASW5wdXQoKSBjb21wb25lbnROYW1lOiBzdHJpbmcgPSAndG9jJ1xyXG4gIEBJbnB1dCgpIGluZGV4ITogbnVtYmVyXHJcbiAgQElucHV0KCkgcGF0aFNldCE6IGFueVxyXG4gIEBJbnB1dCgpIGV4cGFuZEFjdGl2ZSA9IHRydWVcclxuICBASW5wdXQoKSBoaWVyYXJjaHlNYXBEYXRhOiBhbnkgPSB7fVxyXG4gIEBJbnB1dCgpIGJhdGNoRGF0YTogLyoqTnNDb250ZW50LklCYXRjaExpc3RSZXNwb25zZSAqLyBhbnkgfCBudWxsID0gbnVsbFxyXG4gIEBJbnB1dCgpIGlzUHJlQXNzZXNzbWVudCA9IGZhbHNlXHJcbiAgQElucHV0KCkgYmFzZUNvbnRlbnRSZWFkRGF0YTogTnNDb250ZW50LklDb250ZW50IHwgbnVsbCA9IG51bGxcclxuICBASW5wdXQoKSBtbENvdXJzZTogTnNDb250ZW50LklDb250ZW50IHwgbnVsbCA9IG51bGxcclxuICBASW5wdXQoKSBwYXJlbnRNaWxlc3RvbmVMb2NrZWQgPSBmYWxzZSAvLyBQYXNzZWQgZnJvbSBwYXJlbnQgd2hlbiBpbnNpZGUgYSBsb2NrZWQgbWlsZXN0b25lXHJcbiAgaGFzQ29udGVudFN0cnVjdHVyZSA9IGZhbHNlXHJcbiAgZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgPSBmYWxzZVxyXG4gIGVudW1Db250ZW50VHlwZXMgPSBOc0NvbnRlbnQuRURpc3BsYXlDb250ZW50VHlwZXNcclxuICBjb250ZW50U3RydWN0dXJlOiBOc0FwcFRvYy5JVG9jU3RydWN0dXJlID0ge1xyXG4gICAgYXNzZXNzbWVudDogMCxcclxuICAgIGZpbmFsVGVzdDogMCxcclxuICAgIGNvdXJzZTogMCxcclxuICAgIGhhbmRzT246IDAsXHJcbiAgICBpbnRlcmFjdGl2ZVZpZGVvOiAwLFxyXG4gICAgbGVhcm5pbmdNb2R1bGU6IDAsXHJcbiAgICBvdGhlcjogMCxcclxuICAgIHBkZjogMCxcclxuICAgIHN1cnZleTogMCxcclxuICAgIHBvZGNhc3Q6IDAsXHJcbiAgICBwcmFjdGljZVRlc3Q6IDAsXHJcbiAgICBxdWl6OiAwLFxyXG4gICAgdmlkZW86IDAsXHJcbiAgICB3ZWJNb2R1bGU6IDAsXHJcbiAgICB3ZWJQYWdlOiAwLFxyXG4gICAgeW91dHViZTogMCxcclxuICAgIGludGVyYWN0aXZlY29udGVudDogMCxcclxuICAgIG9mZmxpbmVTZXNzaW9uOiAwLFxyXG4gIH1cclxuICBkZWZhdWx0VGh1bWJuYWlsID0gJydcclxuICB2aWV3Q2hpbGRyZW4gPSBmYWxzZVxyXG4gIHByaW1hcnlDYXRlZ29yeSA9IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5XHJcbiAgcGFnZVNjcm9sbFN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uIHwgbnVsbCA9IG51bGxcclxuICBhY2hpZXZlbWVudExvYWRpbmc6IGJvb2xlYW4gPSBmYWxzZVxyXG4gIC8vIENhY2hlZCBjb21wdXRlZCBwcm9wZXJ0aWVzIGZvciBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb25cclxuICBwcml2YXRlIF9jYWNoZWRJc0NvbGxlY3Rpb246IGJvb2xlYW4gPSBmYWxzZVxyXG4gIHByaXZhdGUgX2NhY2hlZElzTW9kdWxlOiBib29sZWFuID0gZmFsc2VcclxuICBwcml2YXRlIF9jYWNoZWRJc1Jlc291cmNlOiBib29sZWFuID0gZmFsc2VcclxuICBwcml2YXRlIF9jYWNoZWRJc01pbGVzdG9uZTogYm9vbGVhbiA9IGZhbHNlXHJcbiAgcHJpdmF0ZSBfY2FjaGVkSXNNaWxlc3RvbmVMb2NrZWQ6IGJvb2xlYW4gPSBmYWxzZVxyXG4gIHByaXZhdGUgX2NhY2hlZElzUGFyZW50TWlsZXN0b25lTG9ja2VkOiBib29sZWFuID0gZmFsc2VcclxuICBwcml2YXRlIF9jYWNoZWRJc0NvbnRlbnRVbmxvY2tlZDogYm9vbGVhbiA9IHRydWVcclxuICBwcml2YXRlIF9jYWNoZWRDaGVja0ZvckN1cmF0ZWRQcm9ncmFtOiBib29sZWFuID0gZmFsc2VcclxuICBwcml2YXRlIF9jYWNoZWRJc01pbGVzdG9uZUFzc2Vzc21lbnQ6IGJvb2xlYW4gPSBmYWxzZVxyXG4gIHByaXZhdGUgX2NhY2hlZElzTWlsZXN0b25lQXNzZXNzbWVudExvY2tlZDogYm9vbGVhbiA9IGZhbHNlXHJcbiAgcHJpdmF0ZSBfY2FjaGVkUmVzb3VyY2VMaW5rOiB7IHVybDogc3RyaW5nOyBxdWVyeVBhcmFtczogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB9ID0geyB1cmw6ICcnLCBxdWVyeVBhcmFtczoge30gfVxyXG4gIHByaXZhdGUgX2NhY2hlSW5pdGlhbGl6ZWQ6IGJvb2xlYW4gPSBmYWxzZVxyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgZXZlbnRzOiBFdmVudFNlcnZpY2UsXHJcbiAgICBwcml2YXRlIGRpYWxvZzogTWF0RGlhbG9nLFxyXG4gICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyLFxyXG4gICAgcHJpdmF0ZSBjZXJ0aWZpY2F0ZVNlcnZpY2U6IENlcnRpZmljYXRlU2VydmljZSxcclxuICAgIHByaXZhdGUgYXBwVG9jU3ZjOiBBcHBUb2NTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBjb250ZW50TGFuZ1N2YzogQ29udGVudExhbmd1YWdlU2VydmljZSxcclxuICAgIHByaXZhdGUgcmVzb3VyY2VEb3dubG9hZEhlbHBlclN2YzogUmVzb3VyY2VEb3dubG9hZEhlbHBlclNlcnZpY2UsICAgIFxyXG4gICAgcHJpdmF0ZSBjb25maWdTdmM6IENvbmZpZ3VyYXRpb25zU2VydmljZSxcclxuICAgIHByaXZhdGUgc25hY2tCYXI6IE1hdFNuYWNrQmFyXHJcbiAgKSB7IH1cclxuXHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICB0aGlzLmV2YWx1YXRlSW1tZWRpYXRlQ2hpbGRyZW5TdHJ1Y3R1cmUoKVxyXG4gICAgdGhpcy5pbml0aWFsaXplQ29tcHV0ZWRQcm9wZXJ0aWVzKClcclxuICAgIC8vIHRoaXMucm91dGUuZGF0YS5zdWJzY3JpYmUoZGF0YSA9PiB7XHJcbiAgICAvLyAgICAgdGhpcy5kZWZhdWx0VGh1bWJuYWlsID0gZGF0YS5jb25maWdEYXRhLmRhdGEubG9nb3MuZGVmYXVsdENvbnRlbnRcclxuICAgIC8vICAgfVxyXG4gICAgLy8gKVxyXG4gICAgdGhpcy5yZXNvdXJjZVNjcm9sbCgpXHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbml0aWFsaXplIGFsbCBjb21wdXRlZCBwcm9wZXJ0aWVzIG9uY2UgdG8gYXZvaWQgZXhwZW5zaXZlIGdldHRlciBjYWxjdWxhdGlvbnNcclxuICAgKiBvbiBldmVyeSBjaGFuZ2UgZGV0ZWN0aW9uIGN5Y2xlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBpbml0aWFsaXplQ29tcHV0ZWRQcm9wZXJ0aWVzKCkge1xyXG4gICAgdGhpcy5jb21wdXRlQWxsQ2FjaGVkUHJvcGVydGllcygpXHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDb21wdXRlIGFsbCBjYWNoZWQgcHJvcGVydGllcyBhdCBvbmNlIGZvciBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb25cclxuICAgKi9cclxuICBwcml2YXRlIGNvbXB1dGVBbGxDYWNoZWRQcm9wZXJ0aWVzKCkge1xyXG4gICAgaWYgKCF0aGlzLmNvbnRlbnQpIHtcclxuICAgICAgdGhpcy5fY2FjaGVJbml0aWFsaXplZCA9IGZhbHNlXHJcbiAgICAgIHJldHVyblxyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGNvbnRlbnRJZCA9IHRoaXMuY29udGVudC5pZGVudGlmaWVyXHJcbiAgICBjb25zdCBoYXNoRGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbY29udGVudElkXVxyXG5cclxuICAgIC8vIFVzZSBoYXNobWFwIGRhdGEgaWYgYXZhaWxhYmxlIGZvciBwcmUtY29tcHV0ZWQgdmFsdWVzXHJcbiAgICBpZiAoaGFzaERhdGEpIHtcclxuICAgICAgdGhpcy5fY2FjaGVkSXNDb2xsZWN0aW9uID0gaGFzaERhdGEuaXNDb2xsZWN0aW9uICE9PSB1bmRlZmluZWQgPyBcclxuICAgICAgICBoYXNoRGF0YS5pc0NvbGxlY3Rpb24gOiB0aGlzLmNvbnRlbnQubWltZVR5cGUgPT09IE5zQ29udGVudC5FTWltZVR5cGVzLkNPTExFQ1RJT05cclxuICAgICAgdGhpcy5fY2FjaGVkSXNNb2R1bGUgPSBoYXNoRGF0YS5pc01vZHVsZSAhPT0gdW5kZWZpbmVkID8gXHJcbiAgICAgICAgaGFzaERhdGEuaXNNb2R1bGUgOiB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEVcclxuICAgICAgdGhpcy5fY2FjaGVkSXNSZXNvdXJjZSA9IGhhc2hEYXRhLmlzUmVzb3VyY2UgIT09IHVuZGVmaW5lZCA/IFxyXG4gICAgICAgIGhhc2hEYXRhLmlzUmVzb3VyY2UgOiB0aGlzLmNvbXB1dGVJc1Jlc291cmNlKClcclxuICAgICAgdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmUgPSBoYXNoRGF0YS5pc01pbGVzdG9uZSAhPT0gdW5kZWZpbmVkID8gXHJcbiAgICAgICAgaGFzaERhdGEuaXNNaWxlc3RvbmUgOiB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZSgpXHJcbiAgICAgIHRoaXMuX2NhY2hlZElzTWlsZXN0b25lTG9ja2VkID0gaGFzaERhdGEuY29tcHV0ZWRJc0xvY2tlZCAhPT0gdW5kZWZpbmVkID8gXHJcbiAgICAgICAgaGFzaERhdGEuY29tcHV0ZWRJc0xvY2tlZCA6IHRoaXMuY29tcHV0ZUlzTWlsZXN0b25lTG9ja2VkKClcclxuICAgICAgdGhpcy5fY2FjaGVkSXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQgPSBoYXNoRGF0YS5pc1BhcmVudE1pbGVzdG9uZUxvY2tlZCAhPT0gdW5kZWZpbmVkID8gXHJcbiAgICAgICAgaGFzaERhdGEuaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQgOiB0aGlzLmNvbXB1dGVJc1BhcmVudE1pbGVzdG9uZUxvY2tlZCgpXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyBGYWxsYmFjayB0byBkaXJlY3QgY29tcHV0YXRpb24gaWYgaGFzaG1hcCBub3QgYXZhaWxhYmxlXHJcbiAgICAgIHRoaXMuX2NhY2hlZElzQ29sbGVjdGlvbiA9IHRoaXMuY29udGVudC5taW1lVHlwZSA9PT0gTnNDb250ZW50LkVNaW1lVHlwZXMuQ09MTEVDVElPTlxyXG4gICAgICB0aGlzLl9jYWNoZWRJc01vZHVsZSA9IHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRVxyXG4gICAgICB0aGlzLl9jYWNoZWRJc1Jlc291cmNlID0gdGhpcy5jb21wdXRlSXNSZXNvdXJjZSgpXHJcbiAgICAgIHRoaXMuX2NhY2hlZElzTWlsZXN0b25lID0gdGhpcy5jb21wdXRlSXNNaWxlc3RvbmUoKVxyXG4gICAgICB0aGlzLl9jYWNoZWRJc01pbGVzdG9uZUxvY2tlZCA9IHRoaXMuY29tcHV0ZUlzTWlsZXN0b25lTG9ja2VkKClcclxuICAgICAgdGhpcy5fY2FjaGVkSXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQgPSB0aGlzLmNvbXB1dGVJc1BhcmVudE1pbGVzdG9uZUxvY2tlZCgpXHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5fY2FjaGVkQ2hlY2tGb3JDdXJhdGVkUHJvZ3JhbSA9IHRoaXMuY29tcHV0ZUNoZWNrRm9yQ3VyYXRlZFByb2dyYW0oKVxyXG4gICAgdGhpcy5fY2FjaGVkSXNDb250ZW50VW5sb2NrZWQgPSB0aGlzLmNvbXB1dGVJc0NvbnRlbnRVbmxvY2tlZCgpXHJcbiAgICB0aGlzLl9jYWNoZWRJc01pbGVzdG9uZUFzc2Vzc21lbnQgPSB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZUFzc2Vzc21lbnQoKVxyXG4gICAgdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmVBc3Nlc3NtZW50TG9ja2VkID0gdGhpcy5jb21wdXRlSXNNaWxlc3RvbmVBc3Nlc3NtZW50TG9ja2VkKClcclxuICAgIHRoaXMuX2NhY2hlZFJlc291cmNlTGluayA9IHRoaXMuY29tcHV0ZVJlc291cmNlTGluaygpXHJcbiAgICB0aGlzLl9jYWNoZUluaXRpYWxpemVkID0gdHJ1ZVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjb21wdXRlSXNSZXNvdXJjZSgpOiBib29sZWFuIHtcclxuICAgIGlmICghdGhpcy5jb250ZW50KSByZXR1cm4gZmFsc2VcclxuICAgIHJldHVybiAoXHJcbiAgICAgIHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LlJFU09VUkNFIHx8XHJcbiAgICAgIHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFIHx8XHJcbiAgICAgIHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcclxuICAgICAgdGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UXHJcbiAgICApXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNvbXB1dGVJc01pbGVzdG9uZSgpOiBib29sZWFuIHtcclxuICAgIGlmICghdGhpcy5jb250ZW50KSByZXR1cm4gZmFsc2VcclxuICAgIGNvbnN0IHByaW1hcnlDYXQgPSB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5IGFzIHN0cmluZ1xyXG4gICAgY29uc3QgY291cnNlQ2F0ID0gdGhpcy5jb250ZW50LmNvdXJzZUNhdGVnb3J5IGFzIHN0cmluZ1xyXG4gICAgcmV0dXJuIHByaW1hcnlDYXQgPT09ICdNaWxlc3RvbmUnIHx8IGNvdXJzZUNhdCA9PT0gJ01pbGVzdG9uZSdcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY29tcHV0ZUNoZWNrRm9yQ3VyYXRlZFByb2dyYW0oKTogYm9vbGVhbiB7XHJcbiAgICBpZiAodGhpcy5jb250ZW50ICYmIHRoaXMuY29udGVudC5wYXJlbnQgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVt0aGlzLmNvbnRlbnQucGFyZW50XSkge1xyXG4gICAgICBjb25zdCBwYXJlbnREYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudC5wYXJlbnRdXHJcbiAgICAgIHJldHVybiBwYXJlbnREYXRhICYmIHBhcmVudERhdGEucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5DVVJBVEVEX1BST0dSQU0gJiZcclxuICAgICAgICBwYXJlbnREYXRhLmNvbXBhdGliaWxpdHlMZXZlbCA+PSA1ICYmXHJcbiAgICAgICAgcGFyZW50RGF0YS5jb250ZXh0TG9ja2luZ1R5cGUgPT09IE5zQ29udGVudC5FQ29udGV4dExvY2tpbmdUeXBlLkNPVVJTRV9BU1NFU1NNRU5UX09OTFlcclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjb21wdXRlSXNDb250ZW50VW5sb2NrZWQoKTogYm9vbGVhbiB7XHJcbiAgICBpZiAodGhpcy5fY2FjaGVkQ2hlY2tGb3JDdXJhdGVkUHJvZ3JhbSkge1xyXG4gICAgICBpZiAodGhpcy5jb250ZW50ICYmIHRoaXMuY29udGVudC5wYXJlbnQgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVt0aGlzLmNvbnRlbnQucGFyZW50XSkge1xyXG4gICAgICAgIGNvbnN0IHBhcmVudERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LnBhcmVudF1cclxuICAgICAgICBsZXQgY29tcGxldGVkTGVhZk5vZGVzOiBhbnlbXSA9IFtdXHJcbiAgICAgICAgcGFyZW50RGF0YS5sZWFmTm9kZXMuZm9yRWFjaCgoX2VsZTogYW55KSA9PiB7XHJcbiAgICAgICAgICBpZiAodGhpcy5oaWVyYXJjaHlNYXBEYXRhICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtfZWxlXSkge1xyXG4gICAgICAgICAgICBjb25zdCBjaGlsZERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbX2VsZV1cclxuICAgICAgICAgICAgaWYgKGNoaWxkRGF0YSAmJiBjaGlsZERhdGEuY29tcGxldGlvblN0YXR1cyA9PT0gMikge1xyXG4gICAgICAgICAgICAgIGNvbXBsZXRlZExlYWZOb2Rlcy5wdXNoKGNoaWxkRGF0YSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgcmV0dXJuIGNvbXBsZXRlZExlYWZOb2Rlcy5sZW5ndGggPj0gcGFyZW50RGF0YS5sZWFmTm9kZXNDb3VudCAtIDFcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuICAgIHJldHVybiB0cnVlXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNvbXB1dGVSZXNvdXJjZUxpbmsoKTogeyB1cmw6IHN0cmluZzsgcXVlcnlQYXJhbXM6IHsgW2tleTogc3RyaW5nXTogYW55IH0gfSB7XHJcbiAgICBpZiAodGhpcy5jb250ZW50KSB7XHJcbiAgICAgIGxldCBtaW1lVHlwZTogYW55ID0gJydcclxuICAgICAgaWYgKHRoaXMuY29udGVudCAmJiB0aGlzLmNvbnRlbnQuY291cnNlQ2F0ZWdvcnkgPT09ICdQcmUgRW5yb2xtZW50IEFzc2Vzc21lbnQnICYmXHJcbiAgICAgICAgdGhpcy5jb250ZW50Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLmVrc3RlcC5jb250ZW50LWNvbGxlY3Rpb24nXHJcbiAgICAgICkge1xyXG4gICAgICAgIG1pbWVUeXBlID0gJ2FwcGxpY2F0aW9uL3ZuZC5zdW5iaXJkLnF1ZXN0aW9uc2V0J1xyXG4gICAgICAgIHRoaXMuY29udGVudC5taW1lVHlwZSA9IE5zQ29udGVudC5FTWltZVR5cGVzLkZJTkFMX0FTU0VTU01FTlRcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBtaW1lVHlwZSA9IHRoaXMuY29udGVudC5taW1lVHlwZVxyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IHNlbGVjdGVkTGFuZ3VhZ2UgPSB0aGlzLm1sQ291cnNlID8gdGhpcy5jb250ZW50TGFuZ1N2Yy5nZXRTZWxlY3RlZExhbmd1YWdlKHRoaXMubWxDb3Vyc2UpIDogdW5kZWZpbmVkXHJcbiAgICAgIHJldHVybiB2aWV3ZXJSb3V0ZUdlbmVyYXRvcihcclxuICAgICAgICB0aGlzLmNvbnRlbnQuaWRlbnRpZmllcixcclxuICAgICAgICBtaW1lVHlwZSxcclxuICAgICAgICB0aGlzLmJhc2VDb250ZW50UmVhZERhdGE/LmlkZW50aWZpZXIgfHwgdGhpcy5yb290SWQsXHJcbiAgICAgICAgdGhpcy5iYXNlQ29udGVudFJlYWREYXRhPy5jb250ZW50VHlwZSB8fCB0aGlzLnJvb3RDb250ZW50VHlwZSxcclxuICAgICAgICB0aGlzLmZvclByZXZpZXcsXHJcbiAgICAgICAgdGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSxcclxuICAgICAgICB0aGlzLmJhdGNoSWQsXHJcbiAgICAgICAgdGhpcy5jb250ZW50Py5uYW1lIHx8IHRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YT8ubmFtZSxcclxuICAgICAgICAoc2VsZWN0ZWRMYW5ndWFnZSA/IHNlbGVjdGVkTGFuZ3VhZ2UubGFuZ0lkIDogbnVsbCksXHJcbiAgICAgICAgKHNlbGVjdGVkTGFuZ3VhZ2UgPyBzZWxlY3RlZExhbmd1YWdlLmlkZW50aWZpZXIgOiBudWxsKSxcclxuICAgICAgKVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHsgdXJsOiAnJywgcXVlcnlQYXJhbXM6IHt9IH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgY29tcHV0ZUlzTWlsZXN0b25lTG9ja2VkKCk6IGJvb2xlYW4ge1xyXG4gICAgLy8gT25seSBhcHBseSBtaWxlc3RvbmUgbG9ja2luZyBmb3IgTGVhcm5pbmcgUGF0aHdheSBjb250ZW50XHJcbiAgICBpZiAoIXRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YSB8fCB0aGlzLmJhc2VDb250ZW50UmVhZERhdGEuY291cnNlQ2F0ZWdvcnkgIT09ICdMZWFybmluZyBQYXRod2F5Jykge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXRoaXMuY29udGVudCkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICAvLyBDaGVjayBpZiBjdXJyZW50IGNvbnRlbnQgaXMgYSBNaWxlc3RvbmVcclxuICAgIGlmICghdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmUgJiYgIXRoaXMuY29tcHV0ZUlzTWlsZXN0b25lKCkpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlXHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ2hlY2sgaWYgaGFzaG1hcCBoYXMgcHJlLWNvbXB1dGVkIGxvY2tpbmcgc3RhdHVzIChwcmVmZXJyZWQgLSBjb21wdXRlZCBieSBzZXJ2aWNlKVxyXG4gICAgY29uc3QgaGFzaERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGEgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudC5pZGVudGlmaWVyXVxyXG4gICAgY29uc29sZS5sb2coYGNvbXB1dGVJc01pbGVzdG9uZUxvY2tlZCBmb3IgJHt0aGlzLmNvbnRlbnQuaWRlbnRpZmllcn0gKCR7dGhpcy5jb250ZW50Lm5hbWV9KTpgLCB7XHJcbiAgICAgIGhhc2hEYXRhLFxyXG4gICAgICBjb21wdXRlZElzTG9ja2VkOiBoYXNoRGF0YT8uY29tcHV0ZWRJc0xvY2tlZCxcclxuICAgICAgY29udGVudElzTG9ja2VkOiB0aGlzLmNvbnRlbnQuaXNMb2NrZWRcclxuICAgIH0pXHJcbiAgICBcclxuICAgIGlmIChoYXNoRGF0YSAmJiBoYXNoRGF0YS5jb21wdXRlZElzTG9ja2VkICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgcmV0dXJuIGhhc2hEYXRhLmNvbXB1dGVkSXNMb2NrZWRcclxuICAgIH1cclxuXHJcbiAgICAvLyBJZiBtaWxlc3RvbmUgaGFzIGlzTG9ja2VkIGZsYWcgZXhwbGljaXRseSBzZXQgdG8gZmFsc2UsIGl0J3MgdW5sb2NrZWRcclxuICAgIGlmICh0aGlzLmNvbnRlbnQuaXNMb2NrZWQgPT09IGZhbHNlKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZVxyXG4gICAgfVxyXG5cclxuICAgIC8vIEZhbGxiYWNrOiBBbGwgbWlsZXN0b25lcyBhcmUgbG9ja2VkIGJ5IGRlZmF1bHQgdW50aWwgY29tcHV0ZWQgb3RoZXJ3aXNlXHJcbiAgICAvLyBUaGlzIGVuc3VyZXMgcHJvcGVyIGxvY2tpbmcgdW50aWwgdGhlIGhhc2htYXAgaXMgdXBkYXRlZCB3aXRoIHByb2dyZXNzXHJcbiAgICByZXR1cm4gdHJ1ZVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjb21wdXRlSXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQoKTogYm9vbGVhbiB7XHJcbiAgICBpZiAodGhpcy5wYXJlbnRNaWxlc3RvbmVMb2NrZWQpIHtcclxuICAgICAgcmV0dXJuIHRydWVcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YSB8fCB0aGlzLmJhc2VDb250ZW50UmVhZERhdGEuY291cnNlQ2F0ZWdvcnkgIT09ICdMZWFybmluZyBQYXRod2F5Jykge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXRoaXMuY29udGVudCB8fCAhdGhpcy5oaWVyYXJjaHlNYXBEYXRhKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZVxyXG4gICAgfVxyXG5cclxuICAgIC8vIENoZWNrIGhhc2htYXAgZm9yIHByZS1jb21wdXRlZCB2YWx1ZVxyXG4gICAgY29uc3QgaGFzaERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LmlkZW50aWZpZXJdXHJcbiAgICBpZiAoaGFzaERhdGEgJiYgaGFzaERhdGEuaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICByZXR1cm4gaGFzaERhdGEuaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWRcclxuICAgIH1cclxuXHJcbiAgICAvLyBUcmF2ZXJzZSB1cCB0aGUgaGllcmFyY2h5IHRvIGZpbmQgaWYgYW55IGFuY2VzdG9yIGlzIGEgbG9ja2VkIE1pbGVzdG9uZVxyXG4gICAgbGV0IGN1cnJlbnRQYXJlbnRJZCA9IHRoaXMuY29udGVudC5wYXJlbnRcclxuICAgIGNvbnN0IG1heERlcHRoID0gNVxyXG4gICAgbGV0IGRlcHRoID0gMFxyXG5cclxuICAgIHdoaWxlIChjdXJyZW50UGFyZW50SWQgJiYgZGVwdGggPCBtYXhEZXB0aCkge1xyXG4gICAgICBjb25zdCBwYXJlbnREYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2N1cnJlbnRQYXJlbnRJZF1cclxuICAgICAgaWYgKHBhcmVudERhdGEpIHtcclxuICAgICAgICBpZiAoKHBhcmVudERhdGEuaXNNaWxlc3RvbmUgfHwgcGFyZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdNaWxlc3RvbmUnIHx8IHBhcmVudERhdGEuY291cnNlQ2F0ZWdvcnkgPT09ICdNaWxlc3RvbmUnKSAmJiBcclxuICAgICAgICAgICAgKHBhcmVudERhdGEuY29tcHV0ZWRJc0xvY2tlZCB8fCBwYXJlbnREYXRhLmlzTG9ja2VkKSkge1xyXG4gICAgICAgICAgcmV0dXJuIHRydWVcclxuICAgICAgICB9XHJcbiAgICAgICAgY3VycmVudFBhcmVudElkID0gcGFyZW50RGF0YS5wYXJlbnRcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBicmVha1xyXG4gICAgICB9XHJcbiAgICAgIGRlcHRoKytcclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgaWYgY3VycmVudCBjb250ZW50IGlzIGEgbWlsZXN0b25lIGFzc2Vzc21lbnQgKENvdXJzZSBBc3Nlc3NtZW50IG9yIEZpbmFsIEFzc2Vzc21lbnQgaW5zaWRlIGEgTWlsZXN0b25lKVxyXG4gICAqL1xyXG4gIHByaXZhdGUgY29tcHV0ZUlzTWlsZXN0b25lQXNzZXNzbWVudCgpOiBib29sZWFuIHtcclxuICAgIGlmICghdGhpcy5iYXNlQ29udGVudFJlYWREYXRhIHx8IHRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YS5jb3Vyc2VDYXRlZ29yeSAhPT0gJ0xlYXJuaW5nIFBhdGh3YXknKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZVxyXG4gICAgfVxyXG5cclxuICAgIGlmICghdGhpcy5jb250ZW50IHx8ICF0aGlzLmhpZXJhcmNoeU1hcERhdGEpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlXHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhbiBhc3Nlc3NtZW50XHJcbiAgICBjb25zdCBpc0Fzc2Vzc21lbnQgPSBcclxuICAgICAgdGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gJ0NvdXJzZSBBc3Nlc3NtZW50JyB8fFxyXG4gICAgICB0aGlzLmNvbnRlbnQuY291cnNlQ2F0ZWdvcnkgPT09ICdDb3Vyc2UgQXNzZXNzbWVudCcgfHxcclxuICAgICAgKHRoaXMuY29udGVudC5uYW1lICYmIHRoaXMuY29udGVudC5uYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ2Fzc2Vzc21lbnQnKSlcclxuXHJcbiAgICBpZiAoIWlzQXNzZXNzbWVudCkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICAvLyBDaGVjayBpZiB0aGUgcGFyZW50IG9yIGdyYW5kcGFyZW50IGlzIGEgbWlsZXN0b25lIChzaW5jZSBhc3Nlc3NtZW50cyBjYW4gYmUgaW5zaWRlIGNvdXJzZXMgaW5zaWRlIG1pbGVzdG9uZXMpXHJcbiAgICBpZiAodGhpcy5jb250ZW50LnBhcmVudCAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LnBhcmVudF0pIHtcclxuICAgICAgY29uc3QgcGFyZW50RGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVt0aGlzLmNvbnRlbnQucGFyZW50XVxyXG4gICAgICBcclxuICAgICAgLy8gQ2hlY2sgaWYgZGlyZWN0IHBhcmVudCBpcyBhIG1pbGVzdG9uZVxyXG4gICAgICBpZiAocGFyZW50RGF0YS5pc01pbGVzdG9uZSB8fCBwYXJlbnREYXRhLnByaW1hcnlDYXRlZ29yeSA9PT0gJ01pbGVzdG9uZScgfHwgcGFyZW50RGF0YS5jb3Vyc2VDYXRlZ29yeSA9PT0gJ01pbGVzdG9uZScpIHtcclxuICAgICAgICByZXR1cm4gdHJ1ZVxyXG4gICAgICB9XHJcbiAgICAgIFxyXG4gICAgICAvLyBDaGVjayBpZiBncmFuZHBhcmVudCBpcyBhIG1pbGVzdG9uZSAoZm9yIGFzc2Vzc21lbnRzIGluc2lkZSBjb3Vyc2VzIGluc2lkZSBtaWxlc3RvbmVzKVxyXG4gICAgICBpZiAocGFyZW50RGF0YS5wYXJlbnQgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3BhcmVudERhdGEucGFyZW50XSkge1xyXG4gICAgICAgIGNvbnN0IGdyYW5kcGFyZW50RGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVtwYXJlbnREYXRhLnBhcmVudF1cclxuICAgICAgICByZXR1cm4gZ3JhbmRwYXJlbnREYXRhLmlzTWlsZXN0b25lIHx8IGdyYW5kcGFyZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdNaWxlc3RvbmUnIHx8IGdyYW5kcGFyZW50RGF0YS5jb3Vyc2VDYXRlZ29yeSA9PT0gJ01pbGVzdG9uZSdcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBmYWxzZVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgaWYgbWlsZXN0b25lIGFzc2Vzc21lbnQgc2hvdWxkIGJlIGxvY2tlZFxyXG4gICAqIEFzc2Vzc21lbnQgaXMgbG9ja2VkIGlmOlxyXG4gICAqIDEuIEl0J3MgYW4gYXNzZXNzbWVudCB3aXRoaW4gYSBtaWxlc3RvbmVcclxuICAgKiAyLiBUaGUgcGFyZW50IG1pbGVzdG9uZSBpcyB1bmxvY2tlZCAob3RoZXJ3aXNlIGhhbmRsZWQgYnkgcGFyZW50IG1pbGVzdG9uZSBsb2NrKVxyXG4gICAqIDMuIE5PVCBhbGwgbWFuZGF0b3J5IGNvbnRlbnQgaW4gdGhlIHNhbWUgbWlsZXN0b25lIGlzIGNvbXBsZXRlZFxyXG4gICAqL1xyXG4gIHByaXZhdGUgY29tcHV0ZUlzTWlsZXN0b25lQXNzZXNzbWVudExvY2tlZCgpOiBib29sZWFuIHtcclxuICAgIC8vIE9ubHkgYXBwbHkgdG8gYXNzZXNzbWVudHMgd2l0aGluIG1pbGVzdG9uZXNcclxuICAgIGlmICghdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmVBc3Nlc3NtZW50ICYmICF0aGlzLmNvbXB1dGVJc01pbGVzdG9uZUFzc2Vzc21lbnQoKSkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICAvLyBDaGVjayBpZiBoYXNobWFwIGhhcyBwcmUtY29tcHV0ZWQgYXNzZXNzbWVudCBsb2NraW5nIHN0YXR1c1xyXG4gICAgY29uc3QgaGFzaERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGEgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudD8uaWRlbnRpZmllciB8fCAnJ11cclxuICAgIGlmIChoYXNoRGF0YSAmJiBoYXNoRGF0YS5pc0Fzc2Vzc21lbnRMb2NrZWQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICByZXR1cm4gaGFzaERhdGEuaXNBc3Nlc3NtZW50TG9ja2VkXHJcbiAgICB9XHJcblxyXG4gICAgLy8gSWYgYWxyZWFkeSBjb21wbGV0ZWQsIGRvbid0IGxvY2tcclxuICAgIGlmICh0aGlzLmNvbnRlbnQgJiYgKHRoaXMuY29udGVudC5jb21wbGV0aW9uU3RhdHVzID09PSAyIHx8IFxyXG4gICAgICAgICh0aGlzLmNvbnRlbnQuY29tcGxldGlvblBlcmNlbnRhZ2UgJiYgdGhpcy5jb250ZW50LmNvbXBsZXRpb25QZXJjZW50YWdlID49IDEwMCkpKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZVxyXG4gICAgfVxyXG5cclxuICAgIC8vIEZpbmQgdGhlIG1pbGVzdG9uZSBJRCAoY291bGQgYmUgcGFyZW50IG9yIGdyYW5kcGFyZW50KVxyXG4gICAgbGV0IG1pbGVzdG9uZUlkOiBzdHJpbmcgfCB1bmRlZmluZWRcclxuICAgIGxldCBtaWxlc3RvbmU6IGFueVxyXG5cclxuICAgIC8vIENoZWNrIGlmIGRpcmVjdCBwYXJlbnQgaXMgbWlsZXN0b25lXHJcbiAgICBpZiAodGhpcy5jb250ZW50Py5wYXJlbnQgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVt0aGlzLmNvbnRlbnQucGFyZW50XSkge1xyXG4gICAgICBjb25zdCBwYXJlbnREYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudC5wYXJlbnRdXHJcbiAgICAgIGlmIChwYXJlbnREYXRhLmlzTWlsZXN0b25lIHx8IHBhcmVudERhdGEucHJpbWFyeUNhdGVnb3J5ID09PSAnTWlsZXN0b25lJyB8fCBwYXJlbnREYXRhLmNvdXJzZUNhdGVnb3J5ID09PSAnTWlsZXN0b25lJykge1xyXG4gICAgICAgIG1pbGVzdG9uZUlkID0gdGhpcy5jb250ZW50LnBhcmVudFxyXG4gICAgICAgIG1pbGVzdG9uZSA9IHBhcmVudERhdGFcclxuICAgICAgfSBlbHNlIGlmIChwYXJlbnREYXRhLnBhcmVudCAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbcGFyZW50RGF0YS5wYXJlbnRdKSB7XHJcbiAgICAgICAgLy8gQ2hlY2sgaWYgZ3JhbmRwYXJlbnQgaXMgbWlsZXN0b25lXHJcbiAgICAgICAgY29uc3QgZ3JhbmRwYXJlbnREYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3BhcmVudERhdGEucGFyZW50XVxyXG4gICAgICAgIGlmIChncmFuZHBhcmVudERhdGEuaXNNaWxlc3RvbmUgfHwgZ3JhbmRwYXJlbnREYXRhLnByaW1hcnlDYXRlZ29yeSA9PT0gJ01pbGVzdG9uZScgfHwgZ3JhbmRwYXJlbnREYXRhLmNvdXJzZUNhdGVnb3J5ID09PSAnTWlsZXN0b25lJykge1xyXG4gICAgICAgICAgbWlsZXN0b25lSWQgPSBwYXJlbnREYXRhLnBhcmVudFxyXG4gICAgICAgICAgbWlsZXN0b25lID0gZ3JhbmRwYXJlbnREYXRhXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFtaWxlc3RvbmVJZCB8fCAhbWlsZXN0b25lKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZVxyXG4gICAgfVxyXG4gICAgXHJcbiAgICAvLyBJZiB0aGUgcGFyZW50IG1pbGVzdG9uZSBpdHNlbGYgaXMgbG9ja2VkLCBkb24ndCBhZGQgYWRkaXRpb25hbCBsb2NraW5nXHJcbiAgICAvLyAodGhlIHBhcmVudCBsb2NrIHdpbGwgaGFuZGxlIGl0KVxyXG4gICAgaWYgKG1pbGVzdG9uZS5jb21wdXRlZElzTG9ja2VkIHx8IG1pbGVzdG9uZS5pc0xvY2tlZCkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICAvLyBDaGVjayBpZiBhbGwgbWFuZGF0b3J5IGNvbnRlbnQgaW4gdGhlIG1pbGVzdG9uZSBpcyBjb21wbGV0ZWRcclxuICAgIGxldCBtYW5kYXRvcnlDb3VudCA9IDBcclxuICAgIGxldCBjb21wbGV0ZWRNYW5kYXRvcnlDb3VudCA9IDBcclxuXHJcbiAgICAvLyBDaGVjayBhbGwgaXRlbXMgaW4gaGFzaG1hcCB0aGF0IGJlbG9uZyB0byB0aGlzIG1pbGVzdG9uZVxyXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXModGhpcy5oaWVyYXJjaHlNYXBEYXRhKSkge1xyXG4gICAgICBjb25zdCBpdGVtID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2tleV1cclxuXHJcbiAgICAgIC8vIENoZWNrIGlmIHRoaXMgaXRlbSBiZWxvbmdzIHRvIHRoZSBtaWxlc3RvbmUgKGRpcmVjdCBjaGlsZCBvciBuZXN0ZWQpXHJcbiAgICAgIC8vIE1vc3QgY29udGVudCB3aWxsIGJlIHVuZGVyIGNvdXJzZXMgdGhhdCBhcmUgdW5kZXIgbWlsZXN0b25lXHJcbiAgICAgIGxldCBpdGVtQmVsb25nc1RvTWlsZXN0b25lID0gZmFsc2VcclxuICAgICAgaWYgKGl0ZW0ucGFyZW50ID09PSBtaWxlc3RvbmVJZCkge1xyXG4gICAgICAgIGl0ZW1CZWxvbmdzVG9NaWxlc3RvbmUgPSB0cnVlXHJcbiAgICAgIH0gZWxzZSBpZiAoaXRlbS5wYXJlbnQgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2l0ZW0ucGFyZW50XSkge1xyXG4gICAgICAgIC8vIENoZWNrIGlmIHBhcmVudCBpcyBhIGNvdXJzZSB1bmRlciB0aGlzIG1pbGVzdG9uZVxyXG4gICAgICAgIGNvbnN0IHBhcmVudEl0ZW0gPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaXRlbS5wYXJlbnRdXHJcbiAgICAgICAgaWYgKHBhcmVudEl0ZW0ucGFyZW50ID09PSBtaWxlc3RvbmVJZCAmJiBwYXJlbnRJdGVtLnByaW1hcnlDYXRlZ29yeSA9PT0gJ0NvdXJzZScpIHtcclxuICAgICAgICAgIGl0ZW1CZWxvbmdzVG9NaWxlc3RvbmUgPSB0cnVlXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoIWl0ZW1CZWxvbmdzVG9NaWxlc3RvbmUpIGNvbnRpbnVlXHJcblxyXG4gICAgICAvLyBTa2lwIGFzc2Vzc21lbnRzIC0gd2UncmUgY2hlY2tpbmcgaWYgbGVhcm5pbmcgY29udGVudCBpcyBjb21wbGV0ZVxyXG4gICAgICBjb25zdCBpc0l0ZW1Bc3Nlc3NtZW50ID1cclxuICAgICAgICBpdGVtLnByaW1hcnlDYXRlZ29yeSA9PT0gJ0NvdXJzZSBBc3Nlc3NtZW50JyB8fFxyXG4gICAgICAgIGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnRmluYWwgQXNzZXNzbWVudCcgfHxcclxuICAgICAgICBpdGVtLnByaW1hcnlDYXRlZ29yeSA9PT0gJ1N0YW5kYWxvbmUgQXNzZXNzbWVudCcgfHxcclxuICAgICAgICBpdGVtLmNvdXJzZUNhdGVnb3J5ID09PSAnQ291cnNlIEFzc2Vzc21lbnQnIHx8XHJcbiAgICAgICAgaXRlbS5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5zdW5iaXJkLnF1ZXN0aW9uc2V0JyB8fFxyXG4gICAgICAgIGl0ZW0ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9xdWl6JyB8fFxyXG4gICAgICAgIChpdGVtLm5hbWUgJiYgaXRlbS5uYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ2Fzc2Vzc21lbnQnKSlcclxuICAgICAgaWYgKGlzSXRlbUFzc2Vzc21lbnQpIGNvbnRpbnVlXHJcblxyXG4gICAgICAvLyBDaGVjayBpZiB0aGlzIGNvbnRlbnQgaXMgbWFuZGF0b3J5IChjb3Vyc2VzIGFuZCBub24tb3B0aW9uYWwgY29udGVudClcclxuICAgICAgLy8gQnkgZGVmYXVsdCwgY291cnNlcyBhcmUgbWFuZGF0b3J5IHVubGVzcyBleHBsaWNpdGx5IG1hcmtlZCBvdGhlcndpc2VcclxuICAgICAgaWYgKGl0ZW0uaXNNYW5kYXRvcnkgIT09IGZhbHNlICYmIChpdGVtLnByaW1hcnlDYXRlZ29yeSA9PT0gJ0NvdXJzZScgfHwgaXRlbS5pc01hbmRhdG9yeSA9PT0gdHJ1ZSkpIHtcclxuICAgICAgICAvLyBDb3VudCBhbGwgY291cnNlcyBhbmQgbWFuZGF0b3J5IGl0ZW1zIGFzIHRoZXkgbmVlZCB0byBiZSBjb21wbGV0ZWRcclxuICAgICAgICBtYW5kYXRvcnlDb3VudCsrXHJcbiAgICAgICAgY29uc3QgaXNDb21wbGV0ZWQgPSBpdGVtLmNvbXBsZXRpb25TdGF0dXMgPT09IDIgfHwgaXRlbS5zdGF0dXMgPT09IDIgfHwgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0uY29tcGxldGlvblBlcmNlbnRhZ2UgPj0gMTAwIHx8IGl0ZW0ucHJvZ3Jlc3MgPj0gMTAwXHJcbiAgICAgICAgaWYgKGlzQ29tcGxldGVkKSB7XHJcbiAgICAgICAgICBjb21wbGV0ZWRNYW5kYXRvcnlDb3VudCsrXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gSWYgdGhlcmUgYXJlIG5vIG1hbmRhdG9yeSBpdGVtcywgYXNzZXNzbWVudCBpcyB1bmxvY2tlZFxyXG4gICAgaWYgKG1hbmRhdG9yeUNvdW50ID09PSAwKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZVxyXG4gICAgfVxyXG5cclxuICAgIC8vIExvY2sgYXNzZXNzbWVudCBpZiBub3QgYWxsIG1hbmRhdG9yeSBpdGVtcyBhcmUgY29tcGxldGVkXHJcbiAgICBjb25zdCBhbGxNYW5kYXRvcnlDb21wbGV0ZSA9IGNvbXBsZXRlZE1hbmRhdG9yeUNvdW50ID49IG1hbmRhdG9yeUNvdW50XHJcbiAgICByZXR1cm4gIWFsbE1hbmRhdG9yeUNvbXBsZXRlXHJcbiAgfVxyXG5cclxuICAvLyBGT1IgUklHSFQgU0lERSBSRVNPVVJDRSBTQ1JPTEwgT04gVE9DIFBBR0VcclxuICByZXNvdXJjZVNjcm9sbCgpIHtcclxuICAgIHRoaXMucGFnZVNjcm9sbFN1YnNjcmlwdGlvbiA9IHRoaXMuYXBwVG9jU3ZjLnVwZGF0ZVBhZ2VTY3JvbGwuc3Vic2NyaWJlKCh2YWx1ZTogYm9vbGVhbikgPT4ge1xyXG4gICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgIHRoaXMuc2Nyb2xsVmlldygpXHJcbiAgICAgICAgfSwgNzAwKVxyXG4gICAgICB9XHJcbiAgICB9KVxyXG4gIH1cclxuICAvLyBUTyBVUERBVEUgUkVTT1VSQ0UgQkVIQVZPVVIgU1VCSkVDVCBGT1IgUkVTT1VSQ0UgU0NST0xMXHJcbiAgY2hhbmdlUmVzb3VyY2UoKSB7XHJcbiAgICB0aGlzLmFwcFRvY1N2Yy5nZXRQYWdlU2Nyb2xsLm5leHQodHJ1ZSlcclxuICB9XHJcblxyXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcclxuICAgIGxldCBzaG91bGRSZWNvbXB1dGVDYWNoZSA9IGZhbHNlXHJcblxyXG4gICAgZm9yIChjb25zdCBwcm9wZXJ0eSBpbiBjaGFuZ2VzKSB7XHJcbiAgICAgIGlmIChwcm9wZXJ0eSA9PT0gJ2V4cGFuZEFsbCcpIHtcclxuICAgICAgICB0aGlzLnZpZXdDaGlsZHJlbiA9IHRoaXMuZXhwYW5kQWxsXHJcbiAgICAgIH1cclxuICAgICAgaWYgKHByb3BlcnR5ID09PSAncGF0aFNldCcgJiYgY2hhbmdlc1sncGF0aFNldCddKSB7XHJcbiAgICAgICAgbGV0IGN1cnJlbnRWYWx1ZSA9IGNoYW5nZXNbJ3BhdGhTZXQnXS5jdXJyZW50VmFsdWVcclxuICAgICAgICBsZXQgcHJldmlvdXNWYWx1ZSA9IGNoYW5nZXNbJ3BhdGhTZXQnXS5wcmV2aW91c1ZhbHVlXHJcbiAgICAgICAgaWYgKGN1cnJlbnRWYWx1ZSAmJiBwcmV2aW91c1ZhbHVlKSB7XHJcbiAgICAgICAgICBjb25zdCBlcVNldCA9ICh4czogYW55LCB5czogYW55KSA9PlxyXG4gICAgICAgICAgICB4cy5zaXplID09PSB5cy5zaXplICYmXHJcbiAgICAgICAgICAgIFsuLi54c10uZXZlcnkoKHgpID0+IHlzLmhhcyh4KSlcclxuICAgICAgICAgIGlmICghZXFTZXQocHJldmlvdXNWYWx1ZSwgY3VycmVudFZhbHVlKSkgeyB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGlmKHByZXZpb3VzVmFsdWUgPT09IHVuZGVmaW5lZCl7XHJcbiAgICAgICAgLy8gICBzZXRUaW1lb3V0KCgpPT57XHJcbiAgICAgICAgLy8gICB9LDcwMClcclxuICAgICAgICAvLyB9XHJcbiAgICAgIH1cclxuICAgICAgLy8gdGhpcy5hcHBUb2NTdmMuZ2V0UGFnZVNjcm9sbC5uZXh0KHRydWUpXHJcblxyXG4gICAgICBpZiAocHJvcGVydHkgPT09ICdoaWVyYXJjaHlNYXBEYXRhJykge1xyXG4gICAgICAgIGlmIChfLmlzRW1wdHkoY2hhbmdlc1snaGllcmFyY2h5TWFwRGF0YSddLmN1cnJlbnRWYWx1ZSkpIHtcclxuICAgICAgICAgIC8vIHRoaXMubG9hZGluZ092ZXJhbGxQUm9ncmVzcyA9IHRydWVcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgaWYgKHRoaXMuY29udGVudCkge1xyXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUNoaWxkUGFyZW50TWFwKHRoaXMuY29udGVudC5pZGVudGlmaWVyKVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgc2hvdWxkUmVjb21wdXRlQ2FjaGUgPSB0cnVlXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBSZWNvbXB1dGUgY2FjaGUgd2hlbiBjcml0aWNhbCBpbnB1dHMgY2hhbmdlXHJcbiAgICAgIGlmIChwcm9wZXJ0eSA9PT0gJ2NvbnRlbnQnIHx8IHByb3BlcnR5ID09PSAnYmFzZUNvbnRlbnRSZWFkRGF0YScgfHwgXHJcbiAgICAgICAgICBwcm9wZXJ0eSA9PT0gJ2JhdGNoSWQnIHx8IHByb3BlcnR5ID09PSAnZm9yUHJldmlldycgfHwgXHJcbiAgICAgICAgICBwcm9wZXJ0eSA9PT0gJ3BhcmVudE1pbGVzdG9uZUxvY2tlZCcgfHwgcHJvcGVydHkgPT09ICdtbENvdXJzZScpIHtcclxuICAgICAgICBzaG91bGRSZWNvbXB1dGVDYWNoZSA9IHRydWVcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIFJlY29tcHV0ZSBhbGwgY2FjaGVkIHByb3BlcnRpZXMgaWYgbmVlZGVkXHJcbiAgICBpZiAoc2hvdWxkUmVjb21wdXRlQ2FjaGUpIHtcclxuICAgICAgdGhpcy5jb21wdXRlQWxsQ2FjaGVkUHJvcGVydGllcygpXHJcbiAgICB9XHJcbiAgICAvLyBjb25zb2xlLmxvZygncHJlIGFzc2Vzc21lbnQgY29udGVudC0tLScsIHRoaXMuY29udGVudClcclxuICAgIC8vIGNvbnNvbGUubG9nKCd0aGlzLmhpZXJhcmNoeU1hcERhdGEtLS0nLCB0aGlzLmhpZXJhcmNoeU1hcERhdGEpXHJcbiAgfVxyXG5cclxuICBjaGVjayhjb250ZW50OiBhbnkpIHtcclxuICAgIGlmICh0aGlzLmV4cGFuZEFjdGl2ZSkge1xyXG4gICAgICBjb250ZW50LnZpZXdDaGlsZHJlbiA9IHRoaXMucGF0aFNldCAmJiB0aGlzLnBhdGhTZXQuaGFzKGNvbnRlbnQuaWRlbnRpZmllcikgfHwgY29udGVudC52aWV3Q2hpbGRyZW5cclxuICAgIH1cclxuICAgIHJldHVybiBjb250ZW50LnZpZXdDaGlsZHJlblxyXG4gIH1cclxuXHJcbiAgZ2V0IGlzQ29sbGVjdGlvbigpOiBib29sZWFuIHtcclxuICAgIGlmICh0aGlzLl9jYWNoZUluaXRpYWxpemVkKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRJc0NvbGxlY3Rpb25cclxuICAgIH1cclxuICAgIGlmICh0aGlzLmNvbnRlbnQpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuY29udGVudC5taW1lVHlwZSA9PT0gTnNDb250ZW50LkVNaW1lVHlwZXMuQ09MTEVDVElPTlxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZhbHNlXHJcbiAgfVxyXG5cclxuICBnZXQgaXNNb2R1bGUoKTogYm9vbGVhbiB7XHJcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVkSXNNb2R1bGVcclxuICAgIH1cclxuICAgIGlmICh0aGlzLmNvbnRlbnQpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZhbHNlXHJcbiAgfVxyXG5cclxuICBwdWJsaWMgY2hlY2tNb2R1bGUoY29udGVudDogTnNDb250ZW50LklDb250ZW50IHwgbnVsbCk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKGNvbnRlbnQpIHtcclxuICAgICAgcmV0dXJuIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEVcclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZVxyXG4gIH1cclxuXHJcbiAgY2hlY2tJc01vZHVsZShjb250ZW50OiBhbnkpOiBib29sZWFuIHtcclxuICAgIGlmIChjb250ZW50KSB7XHJcbiAgICAgIHJldHVybiBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuTU9EVUxFXHJcbiAgICB9XHJcbiAgICByZXR1cm4gZmFsc2VcclxuICB9XHJcblxyXG4gIGdldCBpc0JhdGNoSW5Qcm9nZXNzKCkge1xyXG4gICAgaWYgKHRoaXMuYmF0Y2hEYXRhICYmICh0aGlzLmJhdGNoRGF0YS5jb250ZW50ICYmIHRoaXMuYmF0Y2hEYXRhLmNvbnRlbnQubGVuZ3RoKSAmJiB0aGlzLmJhdGNoRGF0YS5lbnJvbGxlZCkge1xyXG4gICAgICBjb25zdCBiYXRjaERhdGEgPSB0aGlzLmJhdGNoRGF0YS5jb250ZW50WzBdXHJcbiAgICAgIGlmIChiYXRjaERhdGEgJiYgYmF0Y2hEYXRhLmVuZERhdGUpIHtcclxuICAgICAgICBjb25zdCBub3cgPSBtb21lbnQoKS5mb3JtYXQoJ1lZWVktTU0tREQnKVxyXG4gICAgICAgIGNvbnN0IHN0YXJ0RGF0ZSA9IG1vbWVudChiYXRjaERhdGEuc3RhcnREYXRlKS5mb3JtYXQoJ1lZWVktTU0tREQnKVxyXG4gICAgICAgIGNvbnN0IGVuZERhdGUgPSBiYXRjaERhdGEuZW5kRGF0ZSA/IG1vbWVudChiYXRjaERhdGEuZW5kRGF0ZSkuZm9ybWF0KCdZWVlZLU1NLUREJykgOiBub3dcclxuICAgICAgICByZXR1cm4gKFxyXG4gICAgICAgICAgLy8gYmF0Y2guc3RhdHVzICYmXHJcbiAgICAgICAgICBtb21lbnQoc3RhcnREYXRlKS5pc1NhbWVPckJlZm9yZShub3cpXHJcbiAgICAgICAgICAmJiBtb21lbnQoZW5kRGF0ZSkuaXNTYW1lT3JBZnRlcihub3cpXHJcbiAgICAgICAgKVxyXG4gICAgICB9IHJldHVybiB0cnVlXHJcbiAgICB9XHJcbiAgICByZXR1cm4gZmFsc2VcclxuICB9XHJcblxyXG4gIGdldCBpc1Jlc291cmNlKCk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKHRoaXMuX2NhY2hlSW5pdGlhbGl6ZWQpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZElzUmVzb3VyY2VcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLmNvbXB1dGVJc1Jlc291cmNlKClcclxuICB9XHJcblxyXG4gIGdldCByZXNvdXJjZUxpbmsoKTogeyB1cmw6IHN0cmluZzsgcXVlcnlQYXJhbXM6IHsgW2tleTogc3RyaW5nXTogYW55IH0gfSB7XHJcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVkUmVzb3VyY2VMaW5rXHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5jb21wdXRlUmVzb3VyY2VMaW5rKClcclxuICB9XHJcblxyXG4gIHB1YmxpYyBwcm9ncmVzc0NvbG9yKCk6IHN0cmluZyB7XHJcbiAgICAvLyBpZiAodGhpcy5jdXJyZW50UHJvZ3Jlc3MgPD0gMzApIHtcclxuICAgIC8vICAgcmV0dXJuICcjRDEzOTI0J1xyXG4gICAgLy8gfSBpZiAodGhpcy5jdXJyZW50UHJvZ3Jlc3MgPiAzMCAmJiB0aGlzLmN1cnJlbnRQcm9ncmVzcyA8PSA3MCkge1xyXG4gICAgLy8gICByZXR1cm4gJyNFOTlFMzgnXHJcbiAgICAvLyB9XHJcbiAgICAvLyBpZiAodGhpcy5jdXJyZW50UHJvZ3Jlc3MgPiA3MCAmJiB0aGlzLmN1cnJlbnRQcm9ncmVzcyA8PSAxMDApIHtcclxuICAgIC8vICAgcmV0dXJuICcjMUQ4OTIzJ1xyXG4gICAgLy8gfVxyXG5cclxuICAgIHJldHVybiAnIzFEODkyMydcclxuICB9XHJcbiAgcHVibGljIHByb2dyZXNzQ29sb3IyKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gJyNmMjdkMDAnXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGV2YWx1YXRlSW1tZWRpYXRlQ2hpbGRyZW5TdHJ1Y3R1cmUoKSB7XHJcbiAgICBpZiAodGhpcy5jb250ZW50ICYmIHRoaXMuY29udGVudC5jaGlsZHJlbiAmJiB0aGlzLmNvbnRlbnQuY2hpbGRyZW4ubGVuZ3RoKSB7XHJcbiAgICAgIHRoaXMuY29udGVudC5jaGlsZHJlbi5mb3JFYWNoKChjaGlsZDogTnNDb250ZW50LklDb250ZW50KSA9PiB7XHJcbiAgICAgICAgaWYgKGNoaWxkLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuQ09VUlNFKSB7XHJcbiAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUuY291cnNlICs9IDFcclxuICAgICAgICB9IGVsc2UgaWYgKGNoaWxkLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuS05PV0xFREdFX0FSVElGQUNUKSB7XHJcbiAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUub3RoZXIgKz0gMVxyXG4gICAgICAgIH0gZWxzZSBpZiAoY2hpbGQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEUpIHtcclxuICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS5sZWFybmluZ01vZHVsZSArPSAxXHJcbiAgICAgICAgfSBlbHNlIGlmIChjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk9GRkxJTkVfU0VTU0lPTikge1xyXG4gICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLm9mZmxpbmVTZXNzaW9uICs9IDFcclxuICAgICAgICB9IGVsc2UgaWYgKGNoaWxkLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuUkVTT1VSQ0UpIHtcclxuICAgICAgICAgIHN3aXRjaCAoY2hpbGQubWltZVR5cGUpIHtcclxuICAgICAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5IQU5EU19PTjpcclxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUuaGFuZHNPbiArPSAxXHJcbiAgICAgICAgICAgICAgYnJlYWtcclxuICAgICAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5NUDM6XHJcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLnBvZGNhc3QgKz0gMVxyXG4gICAgICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuTVA0OlxyXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLk0zVTg6XHJcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLnZpZGVvICs9IDFcclxuICAgICAgICAgICAgICBicmVha1xyXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLklOVEVSQUNUSU9OOlxyXG4gICAgICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS5pbnRlcmFjdGl2ZVZpZGVvICs9IDFcclxuICAgICAgICAgICAgICBicmVha1xyXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLlBERjpcclxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUucGRmICs9IDFcclxuICAgICAgICAgICAgICBicmVha1xyXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLk9GRkxJTkVfU0VTU0lPTjpcclxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUub2ZmbGluZVNlc3Npb24gKz0gMVxyXG4gICAgICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuU1VSVkVZOlxyXG4gICAgICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS5zdXJ2ZXkgKz0gMVxyXG4gICAgICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuSFRNTDpcclxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUud2ViUGFnZSArPSAxXHJcbiAgICAgICAgICAgICAgYnJlYWtcclxuICAgICAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5RVUlaOlxyXG4gICAgICAgICAgICAgIGlmIChjaGlsZC5yZXNvdXJjZVR5cGUgPT09ICdBc3Nlc3NtZW50Jykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLmFzc2Vzc21lbnQgKz0gMVxyXG4gICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUucXVpeiArPSAxXHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuUFJBQ1RJQ0VfUkVTT1VSQ0U6XHJcbiAgICAgICAgICAgICAgLy8gY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5GSU5BTF9BU1NFU1NNRU5UOlxyXG4gICAgICAgICAgICAgIC8vIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuUFJBQ1RJQ0VfUkVTT1VSQ0U6XHJcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLnByYWN0aWNlVGVzdCArPSAxXHJcbiAgICAgICAgICAgICAgYnJlYWtcclxuICAgICAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5XRUJfTU9EVUxFOlxyXG4gICAgICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS53ZWJNb2R1bGUgKz0gMVxyXG4gICAgICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuWU9VVFVCRTpcclxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUueW91dHViZSArPSAxXHJcbiAgICAgICAgICAgICAgYnJlYWtcclxuICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUub3RoZXIgKz0gMVxyXG4gICAgICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgfVxyXG4gICAgZm9yIChjb25zdCBrZXkgaW4gdGhpcy5jb250ZW50U3RydWN0dXJlKSB7XHJcbiAgICAgIGlmICh0aGlzLmNvbnRlbnRTdHJ1Y3R1cmVba2V5XSA+IDApIHtcclxuICAgICAgICB0aGlzLmhhc0NvbnRlbnRTdHJ1Y3R1cmUgPSB0cnVlXHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldCBjb250ZXh0UGF0aCgpIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIGNvbnRleHRJZDogdGhpcy5yb290SWQsXHJcbiAgICAgIGNvbnRleHRQYXRoOiB0aGlzLnJvb3RDb250ZW50VHlwZSxcclxuICAgICAgYmF0Y2hJZDogdGhpcy5iYXRjaElkLFxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIGNvbnRlbnRUcmFja0J5KF9pbmRleDogbnVtYmVyLCBjb250ZW50OiBOc0NvbnRlbnQuSUNvbnRlbnQpIHtcclxuICAgIGlmICghY29udGVudCkge1xyXG4gICAgICByZXR1cm4gbnVsbFxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGNvbnRlbnQuaWRlbnRpZmllclxyXG4gIH1cclxuXHJcbiAgcHVibGljIHJhaXNlVGVsZW1ldHJ5KCkge1xyXG4gICAgLy8gaWYgKHRoaXMuZm9yUHJldmlldykgeyByZXR1cm4gfVxyXG4gICAgaWYgKHRoaXMuY29udGVudCkge1xyXG4gICAgICB0aGlzLmV2ZW50cy5yYWlzZUludGVyYWN0VGVsZW1ldHJ5KFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHR5cGU6ICdjbGljaycsXHJcbiAgICAgICAgICBzdWJUeXBlOiBgY2FyZC10b2NDb250ZW50Q2FyZGAsXHJcbiAgICAgICAgICAvLyBpZDogdGhpcy5jb250ZW50LmlkZW50aWZpZXIgfHwgJycsXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICAvLyBjb250ZW50SWQ6IHRoaXMuY29udGVudC5pZGVudGlmaWVyIHx8ICcnLFxyXG4gICAgICAgICAgLy8gY29udGVudFR5cGU6IHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnksXHJcbiAgICAgICAgICBpZDogdGhpcy5jb250ZW50LmlkZW50aWZpZXIgfHwgJycsXHJcbiAgICAgICAgICB0eXBlOiB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5LFxyXG4gICAgICAgICAgcm9sbHVwOiB7XHJcbiAgICAgICAgICAgIGwxOiB0aGlzLnJvb3RJZCB8fCAnJyxcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICB2ZXI6IGAke3RoaXMuY29udGVudC52ZXJzaW9ufSR7Jyd9YCxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHBhZ2VJZEV4dDogYCR7Xy5jYW1lbENhc2UodGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSl9LWNhcmRgLFxyXG4gICAgICAgICAgbW9kdWxlOiBfLmNhbWVsQ2FzZSh0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5KSxcclxuICAgICAgICB9KVxyXG4gICAgfVxyXG4gIH1cclxuICBnZXQgaXNBbGxvd2VkKCk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKHRoaXMuY29udGVudCkge1xyXG4gICAgICByZXR1cm4gIShOc0NvbnRlbnQuVU5fU1VQUE9SVEVEX0RBVEFfVFlQRVNfRk9SX05PTl9CQVRDSF9VU0VSUy5pbmRleE9mKHRoaXMuY29udGVudC5taW1lVHlwZSkgPj0gMClcclxuICAgIH0gcmV0dXJuIGZhbHNlXHJcbiAgfVxyXG5cclxuICBnZXQgaXNFbmFibGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRydWVcclxuICB9XHJcblxyXG4gIGdldCBpc0Vucm9sbGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuYmF0Y2hJZCA/IHRydWUgOiBmYWxzZVxyXG4gIH1cclxuXHJcbiAgdXBkYXRlQ2hpbGRQYXJlbnRNYXAoaWRlbnRpZmllcjogc3RyaW5nKSB7XHJcbiAgICBpZiAodGhpcy5oaWVyYXJjaHlNYXBEYXRhICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXSkge1xyXG4gICAgICBsZXQgbG9jYWxDb250ZW50RGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXVxyXG4gICAgICBpZiAoXHJcbiAgICAgICAgIShsb2NhbENvbnRlbnREYXRhLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuUkVTT1VSQ0VcclxuICAgICAgICAgIHx8IGxvY2FsQ29udGVudERhdGEucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRVxyXG4gICAgICAgICAgfHwgbG9jYWxDb250ZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlRcclxuICAgICAgICAgIHx8IGxvY2FsQ29udGVudERhdGEucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQpXHJcbiAgICAgICkge1xyXG4gICAgICAgIC8vIHJlYWwgcGVyY2VudCBsb2dpY1xyXG4gICAgICAgIC8vIGNvbnN0IHRvdGFsID0gbG9jYWxDb250ZW50RGF0YS5sZWFmTm9kZXMucmVkdWNlKChzdW06IG51bWJlciwgY2hpbGRJZDogc3RyaW5nKSA9PiB7XHJcbiAgICAgICAgLy8gICByZXR1cm4gc3VtICsgTnVtYmVyKHRoaXMuaGllcmFyY2h5TWFwRGF0YVtjaGlsZElkXS5jb21wbGV0aW9uUGVyY2VudGFnZSB8fCAwKVxyXG4gICAgICAgIC8vIH0sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKVxyXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKCd0b3RhbCAnLCB0b3RhbClcclxuICAgICAgICAvLyBpZih0b3RhbCA+IDApIHtcclxuICAgICAgICAvLyAgIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXVsnY29tcGxldGlvblBlcmNlbnRhZ2UnXSA9IHRvdGFsIC8gXy50b0ludGVnZXIoXy5nZXQodGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdLCAnbGVhZk5vZGVzQ291bnQnKSlcclxuICAgICAgICAvLyB9XHJcbiAgICAgICAgaWYgKGxvY2FsQ29udGVudERhdGEucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEUpIHtcclxuICAgICAgICAgIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXVsnZHVyYXRpb24nXSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXS5sZWFmTm9kZXMucmVkdWNlKFxyXG4gICAgICAgICAgICAoc3VtOiBhbnksIGNoaWxkSUQ6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgIGlmICh0aGlzLmhpZXJhcmNoeU1hcERhdGEgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2NoaWxkSURdKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gc3VtICsgTnVtYmVyKHRoaXMuaGllcmFyY2h5TWFwRGF0YVtjaGlsZElEXS5kdXJhdGlvbiB8fCB0aGlzLmhpZXJhcmNoeU1hcERhdGFbY2hpbGRJRF0uZXhwZWN0ZWREdXJhdGlvbiB8fCAwKVxyXG4gICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIH0sIDApXHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlXHJcbiAgICAgICAgY29uc3QgY29tcGxldGVkSXRlbXMgPSBfLmZpbHRlcih0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0ubGVhZk5vZGVzLCByID0+ICh0aGlzLmhpZXJhcmNoeU1hcERhdGFbcl0gJiYgKHRoaXMuaGllcmFyY2h5TWFwRGF0YVtyXS5jb21wbGV0aW9uU3RhdHVzID09PSAyIHx8IHRoaXMuaGllcmFyY2h5TWFwRGF0YVtyXS5jb21wbGV0aW9uUGVyY2VudGFnZSA9PT0gMTAwKSkpXHJcbiAgICAgICAgY29uc3QgdG90YWxDb3VudCA9IF8udG9JbnRlZ2VyKF8uZ2V0KHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXSwgJ2xlYWZOb2Rlc0NvdW50JykpIHx8IDFcclxuICAgICAgICB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl1bJ2NvbXBsZXRpb25QZXJjZW50YWdlJ10gPSBOdW1iZXIoKChjb21wbGV0ZWRJdGVtcy5sZW5ndGggLyB0b3RhbENvdW50KSAqIDEwMCkudG9GaXhlZCgpKVxyXG4gICAgICAgIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXVsnY29tcGxldGlvblN0YXR1cyddID0gKHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXS5jb21wbGV0aW9uUGVyY2VudGFnZSA+PSAxMDApID8gMiA6IDFcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdXHJcbiAgICB9XHJcbiAgICByZXR1cm4gJydcclxuICB9XHJcblxyXG4gIGdldENvbXBsZXRpb25QZXJjZW50YWdlKGlkZW50aWZpZXI6IHN0cmluZykge1xyXG4gICAgLy8gY29uc29sZS5sb2coJ2dldENvbXBsZXRpb25QZXJjZW50YWdlJywgaWRlbnRpZmllcilcclxuICAgIC8vIGNvbnNvbGUubG9nKCd0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0gOiAnLCB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0pXHJcbiAgICAvLyBjb25zdCBpdGVtID0gdGhpcy51cGRhdGVDaGlsZFBhcmVudE1hcChpZGVudGlmaWVyKVxyXG4gICAgbGV0IHBlcmNlbnQgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGEgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXS5jb21wbGV0aW9uUGVyY2VudGFnZSB8fCAwXHJcbiAgICByZXR1cm4gdGhpcy5yb3VuZElmRGVjaW1hbChwZXJjZW50KVxyXG4gIH1cclxuXHJcbiAgcm91bmRJZkRlY2ltYWwodmFsdWU6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICBpZiAoIU51bWJlci5pc0ludGVnZXIodmFsdWUpKSB7XHJcbiAgICAgIHJldHVybiBwYXJzZUZsb2F0KHZhbHVlLnRvRml4ZWQoMikpXHJcbiAgICB9XHJcbiAgICByZXR1cm4gdmFsdWVcclxuICB9XHJcblxyXG5cclxuICBnZXRDb21wbGV0aW9uU3RhdHVzKGlkZW50aWZpZXI6IHN0cmluZykge1xyXG4gICAgLy8gY29uc29sZS5sb2coJ2dldENvbXBsZXRpb25TdGF0dXMnKVxyXG4gICAgLy8gY29uc3QgaXRlbSA9IHRoaXMudXBkYXRlQ2hpbGRQYXJlbnRNYXAoaWRlbnRpZmllcilcclxuICAgIHJldHVybiB0aGlzLmhpZXJhcmNoeU1hcERhdGEgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXS5jb21wbGV0aW9uU3RhdHVzXHJcbiAgfVxyXG5cclxuICBvcGVuQ2VydGlmaWNhdGVEaWFsb2coY2VydERhdGE6IGFueSkge1xyXG4gICAgY29uc3QgY2V0ID0gY2VydERhdGFcclxuICAgIHRoaXMuZGlhbG9nLm9wZW4oQ2VydGlmaWNhdGVEaWFsb2dDb21wb25lbnQsIHtcclxuICAgICAgLy8gaGVpZ2h0OiAnNDAwcHgnLFxyXG4gICAgICB3aWR0aDogJzEzMDBweCcsXHJcbiAgICAgIGRhdGE6IHsgY2V0IH0sXHJcbiAgICAgIC8vIHBhbmVsQ2xhc3M6ICdjdXN0b20tZGlhbG9nLWNvbnRhaW5lcicsXHJcbiAgICB9KVxyXG4gIH1cclxuICBzY3JvbGxWaWV3KCkge1xyXG4gICAgdHJ5IHtcclxuICAgICAgbGV0IGVycm9yRmllbGQ6IGFueSA9IHRoaXMucmVuZGVyZXIuc2VsZWN0Um9vdEVsZW1lbnQoJy5yZXNvdXJjZS1jb250YWluZXIgLnJlc291cmNlLWFjdGl2ZScpXHJcbiAgICAgIGlmIChlcnJvckZpZWxkKSB7XHJcbiAgICAgICAgZXJyb3JGaWVsZC5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiBcInNtb290aFwiLCBibG9jazogXCJzdGFydFwiLCBpbmxpbmU6IFwibmVhcmVzdFwiIH0pXHJcbiAgICAgIH1cclxuICAgICAgaWYgKHRoaXMuY29tcG9uZW50TmFtZSA9PT0gJ3RvYycpIHtcclxuICAgICAgICBpZiAoZXJyb3JGaWVsZCkge1xyXG4gICAgICAgICAgY29uc3QgcmVjdCA9IGVycm9yRmllbGQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcclxuICAgICAgICAgIGlmIChyZWN0LnRvcCAtIDQyMCA+IDApIHtcclxuICAgICAgICAgICAgd2luZG93LnNjcm9sbCg0MjAsIHJlY3QudG9wIC0gMTQ4KVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICB0aGlzLmFwcFRvY1N2Yy5nZXRQYWdlU2Nyb2xsLm5leHQoZmFsc2UpXHJcbiAgICAgIH0sIDcwMClcclxuXHJcbiAgICAgIC8vIGVsc2Uge1xyXG4gICAgICAvLyAgIGVycm9yRmllbGQuc2Nyb2xsSW50b1ZpZXcoeyBiZWhhdmlvcjogXCJzbW9vdGhcIiwgYmxvY2s6IFwic3RhcnRcIiwgaW5saW5lOiBcIm5lYXJlc3RcIiB9KTtcclxuICAgICAgLy8gICBjb25zdCByZWN0ID0gZXJyb3JGaWVsZC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgLy8gICBlcnJvckZpZWxkLnNjcm9sbCgwLHJlY3QudG9wLTU2KVxyXG4gICAgICAvLyB9XHJcbiAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGRvd25sb2FkQ2VydGlmaWNhdGUoY2VydGlmaWNhdGVEYXRhOiBhbnkpIHtcclxuICAgIHRoaXMuZXZlbnRzLnJhaXNlSW50ZXJhY3RUZWxlbWV0cnkoXHJcbiAgICAgIHtcclxuICAgICAgICB0eXBlOiBXc0V2ZW50cy5FbnVtSW50ZXJhY3RUeXBlcy5DTElDSyxcclxuICAgICAgICBpZDogJ3ZpZXctY2VydGlmaWNhdGUnLFxyXG4gICAgICAgIHN1YlR5cGU6IFdzRXZlbnRzLkVudW1JbnRlcmFjdFN1YlR5cGVzLkNFUlRJRklDQVRFLFxyXG4gICAgICB9LFxyXG4gICAgICB7XHJcbiAgICAgICAgaWQ6IGNlcnRpZmljYXRlRGF0YSwgICAvLyBpZCBvZiB0aGUgY2VydGlmaWNhdGVcclxuICAgICAgICB0eXBlOiBXc0V2ZW50cy5FbnVtSW50ZXJhY3RTdWJUeXBlcy5DRVJUSUZJQ0FURSxcclxuICAgICAgfSlcclxuICAgIGlmIChjZXJ0aWZpY2F0ZURhdGEpIHtcclxuICAgICAgdGhpcy5kb3dubG9hZENlcnRpZmljYXRlTG9hZGluZyA9IHRydWVcclxuICAgICAgbGV0IGNlcnREYXRhOiBhbnkgPSBjZXJ0aWZpY2F0ZURhdGFcclxuICAgICAgdGhpcy5jZXJ0aWZpY2F0ZVNlcnZpY2UuZG93bmxvYWRDZXJ0aWZpY2F0ZV92MihjZXJ0RGF0YSkuc3Vic2NyaWJlKChyZXM6IGFueSkgPT4ge1xyXG4gICAgICAgIHRoaXMuZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgPSBmYWxzZVxyXG4gICAgICAgIGNvbnN0IGNldCA9IHJlcy5yZXN1bHQucHJpbnRVcmlcclxuICAgICAgICB0aGlzLmRpYWxvZy5vcGVuKENlcnRpZmljYXRlRGlhbG9nQ29tcG9uZW50LCB7XHJcbiAgICAgICAgICB3aWR0aDogJzEzMDBweCcsXHJcbiAgICAgICAgICBkYXRhOiB7IGNldCwgY2VydElkOiBjZXJ0RGF0YS5pZGVudGlmaWVyIH0sXHJcbiAgICAgICAgfSlcclxuICAgICAgfSlcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgPSBmYWxzZVxyXG4gICAgfVxyXG4gIH1cclxuICBuZ09uRGVzdHJveSgpIHtcclxuICAgIGlmICh0aGlzLnBhZ2VTY3JvbGxTdWJzY3JpcHRpb24pIHtcclxuICAgICAgdGhpcy5wYWdlU2Nyb2xsU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKClcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldCBjaGVja0ZvckN1cmF0ZWRQcm9ncmFtKCkge1xyXG4gICAgaWYgKHRoaXMuX2NhY2hlSW5pdGlhbGl6ZWQpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZENoZWNrRm9yQ3VyYXRlZFByb2dyYW1cclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLmNvbXB1dGVDaGVja0ZvckN1cmF0ZWRQcm9ncmFtKClcclxuICB9XHJcblxyXG4gIGdldCBpc0NvbnRlbnRVbmxvY2tlZCgpIHtcclxuICAgIGlmICh0aGlzLl9jYWNoZUluaXRpYWxpemVkKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRJc0NvbnRlbnRVbmxvY2tlZFxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuY29tcHV0ZUlzQ29udGVudFVubG9ja2VkKClcclxuICB9XHJcblxyXG4gIGdldCBpc1BhcmVudE1pbGVzdG9uZUxvY2tlZCgpOiBib29sZWFuIHtcclxuICAgIGlmICh0aGlzLl9jYWNoZUluaXRpYWxpemVkKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRJc1BhcmVudE1pbGVzdG9uZUxvY2tlZFxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuY29tcHV0ZUlzUGFyZW50TWlsZXN0b25lTG9ja2VkKClcclxuICB9XHJcblxyXG4gIGdldCBpc01pbGVzdG9uZUxvY2tlZCgpOiBib29sZWFuIHtcclxuICAgIGlmICh0aGlzLl9jYWNoZUluaXRpYWxpemVkKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRJc01pbGVzdG9uZUxvY2tlZFxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuY29tcHV0ZUlzTWlsZXN0b25lTG9ja2VkKClcclxuICB9XHJcblxyXG4gIGdldCBpc01pbGVzdG9uZUFzc2Vzc21lbnQoKTogYm9vbGVhbiB7XHJcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmVBc3Nlc3NtZW50XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5jb21wdXRlSXNNaWxlc3RvbmVBc3Nlc3NtZW50KClcclxuICB9XHJcblxyXG4gIGdldCBpc01pbGVzdG9uZUFzc2Vzc21lbnRMb2NrZWQoKTogYm9vbGVhbiB7XHJcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmVBc3Nlc3NtZW50TG9ja2VkXHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5jb21wdXRlSXNNaWxlc3RvbmVBc3Nlc3NtZW50TG9ja2VkKClcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrIGlmIGEgbWlsZXN0b25lJ3MgbWFuZGF0b3J5IGNvdXJzZXMgYW5kIGFzc2Vzc21lbnQgYXJlIGNvbXBsZXRlZC5cclxuICAgKiBMb29rcyBhdCB0aGUgY29udGVudCBoaWVyYXJjaHkgdG8gZmluZCBjaGlsZHJlbiBvZiB0aGUgbWlsZXN0b25lLlxyXG4gICAqL1xyXG4gIHByaXZhdGUgY2hlY2tNaWxlc3RvbmVDb250ZW50Q29tcGxldGlvbihtaWxlc3RvbmVJZDogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICBpZiAoIXRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YSB8fCAhdGhpcy5iYXNlQ29udGVudFJlYWREYXRhLmNoaWxkcmVuIHx8ICF0aGlzLmhpZXJhcmNoeU1hcERhdGEpIHtcclxuICAgICAgLy8gRmFsbGJhY2s6IFRyeSB0byBmaW5kIGFzc2Vzc21lbnQgY29tcGxldGlvbiBpbiBoYXNobWFwIGZvciB0aGlzIG1pbGVzdG9uZVxyXG4gICAgICByZXR1cm4gdGhpcy5jaGVja01pbGVzdG9uZUFzc2Vzc21lbnRDb21wbGV0aW9uKG1pbGVzdG9uZUlkKVxyXG4gICAgfVxyXG5cclxuICAgIC8vIEZpbmQgdGhlIG1pbGVzdG9uZSBpbiB0aGUgY29udGVudCBoaWVyYXJjaHlcclxuICAgIGNvbnN0IG1pbGVzdG9uZUNvbnRlbnQgPSB0aGlzLmZpbmRDb250ZW50SW5IaWVyYXJjaHkodGhpcy5iYXNlQ29udGVudFJlYWREYXRhLCBtaWxlc3RvbmVJZClcclxuICAgIGlmICghbWlsZXN0b25lQ29udGVudCB8fCAhbWlsZXN0b25lQ29udGVudC5jaGlsZHJlbikge1xyXG4gICAgICByZXR1cm4gdGhpcy5jaGVja01pbGVzdG9uZUFzc2Vzc21lbnRDb21wbGV0aW9uKG1pbGVzdG9uZUlkKVxyXG4gICAgfVxyXG5cclxuICAgIC8vIENoZWNrIGFsbCBtYW5kYXRvcnkgY291cnNlcyBhbmQgYXNzZXNzbWVudHNcclxuICAgIGxldCBhbGxNYW5kYXRvcnlDb21wbGV0ZSA9IHRydWVcclxuICAgIGxldCBoYXNBc3Nlc3NtZW50ID0gZmFsc2VcclxuICAgIGxldCBhc3Nlc3NtZW50Q29tcGxldGUgPSBmYWxzZVxyXG5cclxuICAgIG1pbGVzdG9uZUNvbnRlbnQuY2hpbGRyZW4uZm9yRWFjaCgoY2hpbGQ6IGFueSkgPT4ge1xyXG4gICAgICBjb25zdCBjaGlsZERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbY2hpbGQuaWRlbnRpZmllcl1cclxuICAgICAgY29uc3QgaXNBc3Nlc3NtZW50ID0gY2hpbGQucHJpbWFyeUNhdGVnb3J5ID09PSAnQ291cnNlIEFzc2Vzc21lbnQnIHx8XHJcbiAgICAgICAgY2hpbGQuY291cnNlQ2F0ZWdvcnkgPT09ICdDb3Vyc2UgQXNzZXNzbWVudCcgfHxcclxuICAgICAgICBjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdGaW5hbCBBc3Nlc3NtZW50J1xyXG4gICAgICBjb25zdCBpc01hbmRhdG9yeSA9IGNoaWxkLm1hbmRhdG9yeSA9PT0gdHJ1ZSB8fCBjaGlsZC5vcHRpb25hbFJlYWRpbmcgIT09IHRydWVcclxuXHJcbiAgICAgIGlmIChpc0Fzc2Vzc21lbnQpIHtcclxuICAgICAgICBoYXNBc3Nlc3NtZW50ID0gdHJ1ZVxyXG4gICAgICAgIGlmIChjaGlsZERhdGEgJiYgKGNoaWxkRGF0YS5jb21wbGV0aW9uU3RhdHVzID09PSAyIHx8IGNoaWxkRGF0YS5jb21wbGV0aW9uUGVyY2VudGFnZSA+PSAxMDApKSB7XHJcbiAgICAgICAgICBhc3Nlc3NtZW50Q29tcGxldGUgPSB0cnVlXHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2UgaWYgKGlzTWFuZGF0b3J5KSB7XHJcbiAgICAgICAgLy8gQ2hlY2sgaWYgbWFuZGF0b3J5IGNvbnRlbnQgaXMgY29tcGxldGVkXHJcbiAgICAgICAgaWYgKCFjaGlsZERhdGEgfHwgKGNoaWxkRGF0YS5jb21wbGV0aW9uU3RhdHVzICE9PSAyICYmIGNoaWxkRGF0YS5jb21wbGV0aW9uUGVyY2VudGFnZSA8IDEwMCkpIHtcclxuICAgICAgICAgIGFsbE1hbmRhdG9yeUNvbXBsZXRlID0gZmFsc2VcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pXHJcblxyXG4gICAgY29uc29sZS5sb2coJ01pbGVzdG9uZSBjb250ZW50IGNoZWNrOicsIHsgYWxsTWFuZGF0b3J5Q29tcGxldGUsIGhhc0Fzc2Vzc21lbnQsIGFzc2Vzc21lbnRDb21wbGV0ZSB9KVxyXG5cclxuICAgIC8vIE1pbGVzdG9uZSBpcyBjb21wbGV0ZSBpZiBhc3Nlc3NtZW50IGlzIGNvbXBsZXRlIChtYW5kYXRvcnkgY291cnNlcyBvcHRpb25hbCBiYXNlZCBvbiByZXF1aXJlbWVudHMpXHJcbiAgICByZXR1cm4gaGFzQXNzZXNzbWVudCA/IGFzc2Vzc21lbnRDb21wbGV0ZSA6IGFsbE1hbmRhdG9yeUNvbXBsZXRlXHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBGYWxsYmFjazogQ2hlY2sgaWYgZW5vdWdoIGFzc2Vzc21lbnRzIGFyZSBjb21wbGV0ZWQgdG8gdW5sb2NrIHRoaXMgbWlsZXN0b25lLlxyXG4gICAqIEZvciBtaWxlc3RvbmUgYXQgaW5kZXggTiwgd2UgbmVlZCBhdCBsZWFzdCBOIGNvbXBsZXRlZCBhc3Nlc3NtZW50cy5cclxuICAgKiBFLmcuLCBGb3IgTTIgKGluZGV4IDEpLCB3ZSBuZWVkIDEgY29tcGxldGVkIGFzc2Vzc21lbnQgKE0xJ3MgYXNzZXNzbWVudClcclxuICAgKiAgICAgICBGb3IgTTMgKGluZGV4IDIpLCB3ZSBuZWVkIDIgY29tcGxldGVkIGFzc2Vzc21lbnRzIChNMSdzIGFuZCBNMidzKVxyXG4gICAqL1xyXG4gIHByaXZhdGUgY2hlY2tNaWxlc3RvbmVBc3Nlc3NtZW50Q29tcGxldGlvbihtaWxlc3RvbmVJZDogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICBpZiAoIXRoaXMuaGllcmFyY2h5TWFwRGF0YSkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICAvLyBFeHRyYWN0IG1pbGVzdG9uZSBudW1iZXIgZnJvbSBJRCAoTTEgLT4gMSwgTTIgLT4gMiwgZXRjLilcclxuICAgIGNvbnN0IG1pbGVzdG9uZU51bSA9IHBhcnNlSW50KG1pbGVzdG9uZUlkLnJlcGxhY2UoL1xcRC9nLCAnJykpIHx8IDBcclxuICAgIGNvbnN0IHJlcXVpcmVkQ29tcGxldGVkQXNzZXNzbWVudHMgPSBtaWxlc3RvbmVOdW0gLSAxIC8vIEZvciBNMiwgbmVlZCAxOyBmb3IgTTMsIG5lZWQgMlxyXG5cclxuICAgIGNvbnNvbGUubG9nKGBNaWxlc3RvbmUgJHttaWxlc3RvbmVJZH0gKG51bTogJHttaWxlc3RvbmVOdW19KSByZXF1aXJlcyAke3JlcXVpcmVkQ29tcGxldGVkQXNzZXNzbWVudHN9IGNvbXBsZXRlZCBhc3Nlc3NtZW50c2ApXHJcblxyXG4gICAgaWYgKHJlcXVpcmVkQ29tcGxldGVkQXNzZXNzbWVudHMgPD0gMCkge1xyXG4gICAgICByZXR1cm4gdHJ1ZSAvLyBGaXJzdCBtaWxlc3RvbmUsIG5vIHJlcXVpcmVtZW50c1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENvdW50IGNvbXBsZXRlZCBDb3Vyc2UgQXNzZXNzbWVudHMgdGhhdCBhcmUgSU5TSURFIG1pbGVzdG9uZXMgKGhhdmUgYSBwYXJlbnQpXHJcbiAgICAvLyBFeGNsdWRlIHByZS1lbnJvbGxtZW50IGFzc2Vzc21lbnRzIGF0IHRoZSByb290IGxldmVsIChubyBwYXJlbnQgb3IgcGFyZW50IGlzIExlYXJuaW5nIFBhdGh3YXkpXHJcbiAgICBsZXQgY29tcGxldGVkTWlsZXN0b25lQXNzZXNzbWVudENvdW50ID0gMFxyXG4gICAgY29uc3QgbGVhcm5pbmdQYXRod2F5SWQgPSB0aGlzLmJhc2VDb250ZW50UmVhZERhdGE/LmlkZW50aWZpZXJcclxuXHJcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzLmhpZXJhcmNoeU1hcERhdGEpKSB7XHJcbiAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFba2V5XVxyXG5cclxuICAgICAgLy8gQ2hlY2sgaWYgaXQncyBhIGNvbXBsZXRlZCBDb3Vyc2UgQXNzZXNzbWVudFxyXG4gICAgICBpZiAoKGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnQ291cnNlIEFzc2Vzc21lbnQnIHx8IGl0ZW0uY291cnNlQ2F0ZWdvcnkgPT09ICdDb3Vyc2UgQXNzZXNzbWVudCcpICYmXHJcbiAgICAgICAgKGl0ZW0uY29tcGxldGlvblN0YXR1cyA9PT0gMiB8fCBpdGVtLmNvbXBsZXRpb25QZXJjZW50YWdlID49IDEwMCkpIHtcclxuXHJcbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBhc3Nlc3NtZW50IGhhcyBhIHBhcmVudCAobWVhbmluZyBpdCdzIGluc2lkZSBhIGNvdXJzZS9taWxlc3RvbmUsIG5vdCBhdCByb290IGxldmVsKVxyXG4gICAgICAgIC8vIEFsc28gZXhjbHVkZSBpZiBwYXJlbnQgaXMgdGhlIExlYXJuaW5nIFBhdGh3YXkgaXRzZWxmIChwcmUtZW5yb2xsbWVudCBhc3Nlc3NtZW50KVxyXG4gICAgICAgIGNvbnN0IGhhc1BhcmVudCA9IGl0ZW0ucGFyZW50ICYmIGl0ZW0ucGFyZW50ICE9PSBsZWFybmluZ1BhdGh3YXlJZFxyXG5cclxuICAgICAgICBpZiAoaGFzUGFyZW50KSB7XHJcbiAgICAgICAgICBjb21wbGV0ZWRNaWxlc3RvbmVBc3Nlc3NtZW50Q291bnQrK1xyXG4gICAgICAgICAgY29uc29sZS5sb2coYEZvdW5kIGNvbXBsZXRlZCBNSUxFU1RPTkUgYXNzZXNzbWVudDogJHtrZXl9YCwgaXRlbSlcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgY29uc29sZS5sb2coYFNraXBwaW5nIHJvb3QtbGV2ZWwvcHJlLWVucm9sbG1lbnQgYXNzZXNzbWVudDogJHtrZXl9YClcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBjb25zb2xlLmxvZyhgVG90YWwgY29tcGxldGVkIE1JTEVTVE9ORSBhc3Nlc3NtZW50czogJHtjb21wbGV0ZWRNaWxlc3RvbmVBc3Nlc3NtZW50Q291bnR9LCBSZXF1aXJlZDogJHtyZXF1aXJlZENvbXBsZXRlZEFzc2Vzc21lbnRzfWApXHJcblxyXG4gICAgLy8gSWYgd2UgaGF2ZSBlbm91Z2ggY29tcGxldGVkIG1pbGVzdG9uZSBhc3Nlc3NtZW50cywgdW5sb2NrIHRoaXMgbWlsZXN0b25lXHJcbiAgICByZXR1cm4gY29tcGxldGVkTWlsZXN0b25lQXNzZXNzbWVudENvdW50ID49IHJlcXVpcmVkQ29tcGxldGVkQXNzZXNzbWVudHNcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZmluZENvbnRlbnRJbkhpZXJhcmNoeShjb250ZW50OiBhbnksIGlkZW50aWZpZXI6IHN0cmluZyk6IGFueSB7XHJcbiAgICBpZiAoIWNvbnRlbnQpIHJldHVybiBudWxsXHJcbiAgICBpZiAoY29udGVudC5pZGVudGlmaWVyID09PSBpZGVudGlmaWVyKSByZXR1cm4gY29udGVudFxyXG4gICAgaWYgKGNvbnRlbnQuY2hpbGRyZW4pIHtcclxuICAgICAgZm9yIChjb25zdCBjaGlsZCBvZiBjb250ZW50LmNoaWxkcmVuKSB7XHJcbiAgICAgICAgY29uc3QgZm91bmQgPSB0aGlzLmZpbmRDb250ZW50SW5IaWVyYXJjaHkoY2hpbGQsIGlkZW50aWZpZXIpXHJcbiAgICAgICAgaWYgKGZvdW5kKSByZXR1cm4gZm91bmRcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG51bGxcclxuICB9XHJcblxyXG4gIGdldCBjb21wdXRlZFF1ZXJ5UGFyYW1zKCkge1xyXG4gICAgaWYgKHRoaXMuaXNBbGxvd2VkICYmICF0aGlzLmZvclByZXZpZXcgJiYgdGhpcy5pc0VuYWJsZWQpIHtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICAuLi50aGlzLnJlc291cmNlTGluay5xdWVyeVBhcmFtcyxcclxuICAgICAgICBwcmVBc3Nlc3NtZW50OiAndHJ1ZSdcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG51bGxcclxuICB9XHJcblxyXG4gIGdldCBpc01pbGVzdG9uZSgpOiBib29sZWFuIHtcclxuICAgIGlmICh0aGlzLl9jYWNoZUluaXRpYWxpemVkKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRJc01pbGVzdG9uZVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuY29tcHV0ZUlzTWlsZXN0b25lKClcclxuICB9XHJcblxyXG4gIGdldE1pbGVzdG9uZUNvbXBsZXRlZENvdW50KCk6IG51bWJlciB7XHJcbiAgICBpZiAoIXRoaXMuY29udGVudCB8fCAhdGhpcy5oaWVyYXJjaHlNYXBEYXRhKSB7XHJcbiAgICAgIHJldHVybiAwXHJcbiAgICB9XHJcbiAgICBjb25zdCBtaWxlc3RvbmVEYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudC5pZGVudGlmaWVyXVxyXG4gICAgaWYgKCFtaWxlc3RvbmVEYXRhIHx8ICFtaWxlc3RvbmVEYXRhLmxlYWZOb2Rlcykge1xyXG4gICAgICByZXR1cm4gMFxyXG4gICAgfVxyXG4gICAgbGV0IGNvbXBsZXRlZENvdW50ID0gMFxyXG4gICAgbWlsZXN0b25lRGF0YS5sZWFmTm9kZXMuZm9yRWFjaCgobGVhZklkOiBzdHJpbmcpID0+IHtcclxuICAgICAgY29uc3QgbGVhZkRhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbbGVhZklkXVxyXG4gICAgICBpZiAobGVhZkRhdGEgJiYgbGVhZkRhdGEuY29tcGxldGlvblN0YXR1cyA9PT0gMikge1xyXG4gICAgICAgIGNvbXBsZXRlZENvdW50KytcclxuICAgICAgfVxyXG4gICAgfSlcclxuICAgIHJldHVybiBjb21wbGV0ZWRDb3VudFxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHVubG9jayBjcml0ZXJpYSBtZXNzYWdlIGZvciBsb2NrZWQgbWlsZXN0b25lc1xyXG4gICAqL1xyXG4gIGdldE1pbGVzdG9uZVVubG9ja01lc3NhZ2UoKTogc3RyaW5nIHtcclxuICAgIGlmICghdGhpcy5jb250ZW50IHx8ICF0aGlzLmhpZXJhcmNoeU1hcERhdGEpIHtcclxuICAgICAgcmV0dXJuICcnXHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgbWlsZXN0b25lRGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVt0aGlzLmNvbnRlbnQuaWRlbnRpZmllcl1cclxuICAgIGlmICghbWlsZXN0b25lRGF0YSkge1xyXG4gICAgICByZXR1cm4gJydcclxuICAgIH1cclxuXHJcbiAgICAvLyBDaGVjayBpZiBoYXNobWFwIGhhcyBwcmUtY29tcHV0ZWQgdW5sb2NrIG1lc3NhZ2VcclxuICAgIGlmIChtaWxlc3RvbmVEYXRhLnVubG9ja01lc3NhZ2UpIHtcclxuICAgICAgcmV0dXJuIG1pbGVzdG9uZURhdGEudW5sb2NrTWVzc2FnZVxyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IG1pbGVzdG9uZUluZGV4ID0gbWlsZXN0b25lRGF0YS5taWxlc3RvbmVJbmRleFxyXG5cclxuICAgIC8vIE1pbGVzdG9uZSAxIHJlcXVpcmVzIHByZS1hc3Nlc3NtZW50IGNvbXBsZXRpb25cclxuICAgIGlmIChtaWxlc3RvbmVJbmRleCA9PT0gMCkge1xyXG4gICAgICByZXR1cm4gJ0NvbXBsZXRlIHRoZSBwcmVsaW1pbmFyeSBhc3Nlc3NtZW50IHRvIHVubG9jayB0aGlzIG1pbGVzdG9uZSdcclxuICAgIH1cclxuXHJcbiAgICAvLyBPdGhlciBtaWxlc3RvbmVzIHJlcXVpcmUgcHJldmlvdXMgbWlsZXN0b25lIGNvbXBsZXRpb25cclxuICAgIHJldHVybiBgQ29tcGxldGUgYWxsIG1hbmRhdG9yeSBjb250ZW50IGFuZCBhc3Nlc3NtZW50IGluIE1pbGVzdG9uZSAke21pbGVzdG9uZUluZGV4fSB0byB1bmxvY2sgdGhpcyBtaWxlc3RvbmVgXHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgbG9jayBtZXNzYWdlIGZvciBjb250ZW50IGluc2lkZSBsb2NrZWQgbWlsZXN0b25lc1xyXG4gICAqL1xyXG4gIGdldFBhcmVudE1pbGVzdG9uZUxvY2tNZXNzYWdlKCk6IHN0cmluZyB7XHJcbiAgICBpZiAoIXRoaXMuaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQpIHtcclxuICAgICAgcmV0dXJuICcnXHJcbiAgICB9XHJcbiAgICByZXR1cm4gJ1RoaXMgY29udGVudCBpcyBsb2NrZWQuIENvbXBsZXRlIHByZXZpb3VzIG1pbGVzdG9uZSB0byB2aWV3IHRoaXMgY29udGVudC4nXHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgbG9jayBtZXNzYWdlIGZvciBtaWxlc3RvbmUgYXNzZXNzbWVudHNcclxuICAgKi9cclxuICBnZXRBc3Nlc3NtZW50TG9ja01lc3NhZ2UoKTogc3RyaW5nIHtcclxuICAgIGlmICghdGhpcy5jb250ZW50IHx8ICF0aGlzLmhpZXJhcmNoeU1hcERhdGEpIHtcclxuICAgICAgcmV0dXJuICcnXHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgaGFzaERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LmlkZW50aWZpZXJdXHJcbiAgICBcclxuICAgIC8vIENoZWNrIGlmIGhhc2htYXAgaGFzIHByZS1jb21wdXRlZCBhc3Nlc3NtZW50IGxvY2sgbWVzc2FnZVxyXG4gICAgaWYgKGhhc2hEYXRhICYmIGhhc2hEYXRhLmFzc2Vzc21lbnRMb2NrTWVzc2FnZSkge1xyXG4gICAgICByZXR1cm4gaGFzaERhdGEuYXNzZXNzbWVudExvY2tNZXNzYWdlXHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuaXNNaWxlc3RvbmVBc3Nlc3NtZW50TG9ja2VkKSB7XHJcbiAgICAgIHJldHVybiAnVGhpcyBjb250ZW50IGlzIGxvY2tlZC4gQ29tcGxldGUgYWxsIG1hbmRhdG9yeSBpdGVtcyB0byB1bmxvY2sgdGhlIGFzc2Vzc21lbnQuJ1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiAnJ1xyXG4gIH1cclxuXHJcbiAgc2hvdWxkU2hvd0Rvd25sb2FkQnV0dG9uKGNvbnRlbnQ6IE5zQ29udGVudC5JQ29udGVudCB8IG51bGwpOiBib29sZWFuIHtcclxuICAgIGlmICghY29udGVudCkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICAvLyBDaGVjayBpZiBjb250ZW50IGhhcyBhbiBhcnRpZmFjdCBVUkwgKGRvd25sb2FkYWJsZSByZXNvdXJjZSlcclxuICAgIGlmICghY29udGVudC5hcnRpZmFjdFVybCkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICAvLyBDaGVjayBpZiBiYXNlIGNvbnRlbnQgcmVzb3VyY2UgY2F0ZWdvcnkgaW5jbHVkZXMgXCJDYXNlIFN0dWR5XCJcclxuICAgIGlmICghdGhpcy5iYXNlQ29udGVudFJlYWREYXRhPy5jb3Vyc2VDYXRlZ29yeSB8fFxyXG4gICAgICB0aGlzLmJhc2VDb250ZW50UmVhZERhdGEuY291cnNlQ2F0ZWdvcnkgIT09IE5zQ29udGVudC5FQ291cnNlQ2F0ZWdvcnkuQ0FTRV9TVFVEWSkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICAvL2ZvciBwdWJsaWMgc2NlbmFyaW8gY2hlY2sgaWYgaXRzIHBsYXllciBwbGFnZSB0aGVuIG9ubHkgZW5hYmxlIGRvd25sb2FkXHJcbiAgICBpZiAodGhpcy5mb3JQcmV2aWV3ICYmICF3aW5kb3cubG9jYXRpb24uaHJlZi5pbmNsdWRlcygnL3ZpZXdlci8nKSkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICAvLyBmb3IgbG9nZ2VkIGluIHVzZXIgY2hlY2sgaWYgdXNlciBlbnJvbGxlZCB0aGVuIG9ubHkgYWxsb3cgZG93bmxvYWRcclxuICAgIGlmICghdGhpcy5mb3JQcmV2aWV3ICYmICF0aGlzLmlzRW5yb2xsZWQpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlXHJcbiAgICB9XHJcblxyXG4gICAgLy8gRGVmaW5lIGRvd25sb2FkYWJsZSBNSU1FIHR5cGVzXHJcbiAgICBjb25zdCBkb3dubG9hZGFibGVNaW1lVHlwZXMgPSBbXHJcbiAgICAgIE5zQ29udGVudC5FTWltZVR5cGVzLlBERlxyXG4gICAgXVxyXG5cclxuICAgIHJldHVybiBkb3dubG9hZGFibGVNaW1lVHlwZXMuaW5jbHVkZXMoY29udGVudC5taW1lVHlwZSlcclxuICB9XHJcblxyXG4gIGRvd25sb2FkQ29udGVudChjb250ZW50OiBOc0NvbnRlbnQuSUNvbnRlbnQsIGV2ZW50PzogTW91c2VFdmVudCkge1xyXG4gICAgaWYgKGV2ZW50KSB7XHJcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcclxuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcclxuICAgIH1cclxuICAgIGNvbnN0IHBhZ2VJZCA9IGBhcHAvdG9jL3BhZ2VJZC8ke2NvbnRlbnQuaWRlbnRpZmllcn1gXHJcbiAgICB0aGlzLnJlc291cmNlRG93bmxvYWRIZWxwZXJTdmMuZG93bmxvYWRQREYoY29udGVudCwgcGFnZUlkKVxyXG4gICAgY29uc29sZS5sb2coJ2NvbnRlbnQnLCBjb250ZW50KVxyXG4gICAgY29uc29sZS5sb2coJ2Jhc2VDb250ZW50JywgdGhpcy5iYXNlQ29udGVudFJlYWREYXRhKVxyXG4gIH1cclxuXHJcblxyXG5cclxuICAvKipcclxuICAgKiBWaWV3IG1pbGVzdG9uZSBhY2hpZXZlbWVudCAtIGNhbGxzIHRoZSBhY2hpZXZlbWVudCBBUEkgYW5kIHNob3dzIHRoZSByZXN1bHRcclxuICAgKi9cclxuICB2aWV3TWlsZXN0b25lQWNoaWV2ZW1lbnQoZXZlbnQ/OiBNb3VzZUV2ZW50KSB7XHJcbiAgICBpZiAoZXZlbnQpIHtcclxuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxyXG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKVxyXG4gICAgfVxyXG5cclxuICAgIGlmICghdGhpcy5jb250ZW50IHx8ICF0aGlzLmJhdGNoSWQgfHwgdGhpcy5hY2hpZXZlbWVudExvYWRpbmcpIHtcclxuICAgICAgcmV0dXJuXHJcbiAgICB9XHJcblxyXG4gICAgLy8gR2V0IHVzZXIgSUQgZnJvbSBDb25maWd1cmF0aW9uc1NlcnZpY2VcclxuICAgIGNvbnN0IHVzZXJJZCA9IHRoaXMuY29uZmlnU3ZjPy51c2VyUHJvZmlsZT8udXNlcklkXHJcbiAgICBpZiAoIXVzZXJJZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdVc2VyIElEIG5vdCBmb3VuZCcpXHJcbiAgICAgIHJldHVyblxyXG4gICAgfVxyXG5cclxuICAgIC8vIEV4dHJhY3QgbWlsZXN0b25lIElEIChlLmcuLCBcIm0xXCIsIFwibTJcIikgZnJvbSB0aGUgY29udGVudCBuYW1lIG9yIGluZGV4XHJcbiAgICAvLyBUcnkgdG8gZ2V0IG1pbGVzdG9uZSBudW1iZXIgZnJvbSB0aGUgaW5kZXggb3IgZXh0cmFjdCBmcm9tIGNvbnRlbnRcclxuICAgIGxldCBtaWxlc3RvbmVJZCA9ICdtJyArICh0aGlzLmluZGV4IC0gMSkgLy8gaW5kZXggaXMgdHlwaWNhbGx5IDEtYmFzZWQsIG1pbGVzdG9uZXMgYXJlIDAtYmFzZWRcclxuXHJcbiAgICAvLyBJZiBjb250ZW50IG5hbWUgY29udGFpbnMgbWlsZXN0b25lIG51bWJlciwgZXh0cmFjdCBpdFxyXG4gICAgaWYgKHRoaXMuY29udGVudC5uYW1lKSB7XHJcbiAgICAgIGNvbnN0IG1hdGNoID0gdGhpcy5jb250ZW50Lm5hbWUubWF0Y2goL21pbGVzdG9uZVxccyooXFxkKykvaSlcclxuICAgICAgaWYgKG1hdGNoKSB7XHJcbiAgICAgICAgbWlsZXN0b25lSWQgPSAnbScgKyBtYXRjaFsxXVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgY291cnNlSWQgPSB0aGlzLmJhc2VDb250ZW50UmVhZERhdGE/LmlkZW50aWZpZXIgfHwgdGhpcy5yb290SWRcclxuXHJcbiAgICB0aGlzLmFjaGlldmVtZW50TG9hZGluZyA9IHRydWVcclxuXHJcbiAgICB0aGlzLmFwcFRvY1N2Yy5nZW5lcmF0ZU1pbGVzdG9uZUFjaGlldmVtZW50KHVzZXJJZCwgY291cnNlSWQsIHRoaXMuYmF0Y2hJZCwgbWlsZXN0b25lSWQpLnN1YnNjcmliZSh7XHJcbiAgICAgIG5leHQ6IChyZXNwb25zZTogYW55KSA9PiB7XHJcbiAgICAgICAgdGhpcy5hY2hpZXZlbWVudExvYWRpbmcgPSBmYWxzZVxyXG4gICAgICAgIGNvbnNvbGUubG9nKCdBY2hpZXZlbWVudCBnZW5lcmF0ZWQgc3VjY2Vzc2Z1bGx5OicsIHJlc3BvbnNlKVxyXG4gICAgICAgIC8vIFNob3cgYWNoaWV2ZW1lbnQgZGlhbG9nIG9yIGhhbmRsZSByZXNwb25zZVxyXG4gICAgICAgIGlmIChyZXNwb25zZSAmJiByZXNwb25zZS5yZXN1bHQpIHtcclxuICAgICAgICAgIC8vIE9wZW4gYSBkaWFsb2cgdG8gc2hvdyB0aGUgYWNoaWV2ZW1lbnRcclxuICAgICAgICAgIHRoaXMuZGlhbG9nLm9wZW4oQ2VydGlmaWNhdGVEaWFsb2dDb21wb25lbnQsIHtcclxuICAgICAgICAgICAgd2lkdGg6ICcxMzAwcHgnLFxyXG4gICAgICAgICAgICBkYXRhOiB7XHJcbiAgICAgICAgICAgICAgY2V0OiByZXNwb25zZS5yZXN1bHQucHJpbnRVcmkgfHwgcmVzcG9uc2UucmVzdWx0LnN2Z0RhdGEsXHJcbiAgICAgICAgICAgICAgY2VydElkOiByZXNwb25zZS5yZXN1bHQuaWRlbnRpZmllcixcclxuICAgICAgICAgICAgICBpc0FjaGlldmVtZW50OiB0cnVlXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICB9KVxyXG4gICAgICAgIH1cclxuICAgICAgfSxcclxuICAgICAgZXJyb3I6IChlcnJvcjogYW55KSA9PiB7XHJcbiAgICAgICAgdGhpcy5hY2hpZXZlbWVudExvYWRpbmcgPSBmYWxzZVxyXG4gICAgICAgIC8vIFNob3cgZXJyb3IgbWVzc2FnZSBpbiBzbmFja2JhclxyXG4gICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGVycm9yPy5lcnJvcj8ucmVzdWx0Py5tZXNzYWdlIHx8IGVycm9yPy5tZXNzYWdlIHx8ICdGYWlsZWQgdG8gZ2VuZXJhdGUgYWNoaWV2ZW1lbnQnXHJcbiAgICAgICAgdGhpcy5zbmFja0Jhci5vcGVuKGVycm9yTWVzc2FnZSwgJ0Nsb3NlJywge1xyXG4gICAgICAgICAgZHVyYXRpb246IDUwMDAsXHJcbiAgICAgICAgICBob3Jpem9udGFsUG9zaXRpb246ICdjZW50ZXInLFxyXG4gICAgICAgICAgdmVydGljYWxQb3NpdGlvbjogJ2JvdHRvbScsXHJcbiAgICAgICAgICBwYW5lbENsYXNzOiBbJ2Vycm9yLXNuYWNrYmFyJ11cclxuICAgICAgICB9KVxyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGdlbmVyYXRpbmcgYWNoaWV2ZW1lbnQ6JywgZXJyb3IpXHJcbiAgICAgIH1cclxuICAgIH0pXHJcbiAgfVxyXG5cclxufVxyXG4iLCI8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudCAmJiAhaXNQcmVBc3Nlc3NtZW50XCI+XHJcbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNDb2xsZWN0aW9uICYmICFpc01vZHVsZVwiPlxyXG4gICAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29sbGVjdGlvblRlbXBsYXRlXCI+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0NvbGxlY3Rpb24gJiYgaXNNb2R1bGVcIj5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8ubW9kdWxlUmVzb3Vyc2VDb3VudFwiPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbGxlY3Rpb25UZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgIDxkaXYgKm5nSWY9XCJpc1Jlc291cmNlXCIgY2xhc3M9XCJyZXNvdXJjZS1jb250YWluZXJcIlxyXG4gICAgICAgIFtuZ0NsYXNzXT1cInBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSAmJiBpc0Vucm9sbGVkID8gJ2NvbnRlbnQtYWN0aXZlLXJlc291cmNlJzogJ2NvbnRlbnQtbm90LWFjdGl2ZS1yZXNvdXJjZSdcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwicmVzb3VyY2UgZmxleCAgc206ZmxleC1yb3cgZmxleC1zdGFydCB3aWR0aC1leHBhbmQgdy0xMDAgc206cHItNCBzbTp3LWF1dG9cIlxyXG4gICAgICAgICAgICBbbmdDbGFzc109XCJ7J2FjdGl2ZVJlc291cmNlJzogcGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpICYmIGlzRW5yb2xsZWR9XCI+XHJcbiAgICAgICAgICAgIDwhLS0gTG9jayBtZXNzYWdlIGZvciBjdXJhdGVkIHByb2dyYW1zIG9ubHkgKHNob3duIGFib3ZlIGNvbnRlbnQpIC0tPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8ucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCAmJiBjaGVja0ZvckN1cmF0ZWRQcm9ncmFtICYmXHJcbiAgICAgICAgICAgICFpc0NvbnRlbnRVbmxvY2tlZFwiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRlbnQtbG9ja2luZyBmbGV4IHctZnVsbCBmbGV4LW1pZGRsZSBtYi0yIGdhcC0zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibG9jay1pY29uXCI+bG9jazwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsb2NrLW1lc3NhZ2UgbWF0LWJvZHktMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBUaGUgY29udGVudCBpcyBsb2NrZWQuIENvbXBsZXRlIHByb2dyYW0gb3IgYWxsIGNvdXJzZXMgdG8gdmlldyB0aGlzIG1vZHVsZVxyXG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQ/LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgJiYgY2hlY2tGb3JDdXJhdGVkUHJvZ3JhbSAmJlxyXG4gICAgICAgICAgICBpc0NvbnRlbnRVbmxvY2tlZFwiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRlbnQtbG9ja2luZyBmbGV4IHctZnVsbCBmbGV4LW1pZGRsZSBtYi0yIGdhcC0zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwidW5sb2NrLWljb25cIj5sb2NrX29wZW5fcmlnaHQ8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidW5sb2NrLW1lc3NhZ2UgbWF0LWJvZHktMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBUaGlzIGNvbnRlbnQgaXMgdW5sb2NrZWQuXHJcbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXdyYXAgaXRlbXMtc3RhcnQganVzdGlmeS1zdGFydCBzbTpqdXN0aWZ5LWVuZFwiPlxyXG4gICAgICAgICAgICAgICAgPCEtLSA8YnV0dG9uICpuZ0lmPVwiIWZvclByZXZpZXcgJiYgY29udGVudD8uYXJ0aWZhY3RVcmwgJiYgIWlzWFNtYWxsICYmIGlzQWxsb3dlZCAmJiBpc0VuYWJsZWRcIiB0eXBlPVwiYnV0dG9uXCJcclxuICAgICAgICAgICAgICAgICAgICBtYXQtaWNvbi1idXR0b24gY2xhc3M9XCJcIiBbbWF0TWVudVRyaWdnZXJGb3JdPVwiYnV0dG9uTWVudVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5tb3JlX3ZlcnRpY2FsPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPiAtLT5cclxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0Vucm9sbGVkICAmJiAhaXNNaWxlc3RvbmVMb2NrZWQgJiYgIWlzUGFyZW50TWlsZXN0b25lTG9ja2VkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFmb3JQcmV2aWV3ICYmICBjb250ZW50Py5pZGVudGlmaWVyICYmIGdldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpIDsgZWxzZSBlbHNlQmxvY2tcIj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb21wbGV0aW9uU3RhdHVzKGNvbnRlbnQ/LmlkZW50aWZpZXIpID09IDJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb21wbGV0ZWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJjb21wbGV0ZWQtaWNvblwiIFtjb2xvcl09XCJibHVlXCI+Y2hlY2tfY2lyY2xlPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENvbXBsZXRpb25TdGF0dXMoY29udGVudD8uaWRlbnRpZmllcikgPCAyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlLXByb2dyZXNzIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgcHJvZ3Jlc3NcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwZXJjZW50XT1cImdldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpXCIgW3JhZGl1c109XCIxMFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlV2lkdGhdPVwiMlwiIFtpbm5lclN0cm9rZVdpZHRoXT1cIjJcIiBbc3BhY2VdPVwiLTJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZUNvbG9yXT1cInByb2dyZXNzQ29sb3IyKClcIiBbaW5uZXJTdHJva2VDb2xvcl09XCIncmdiYSgwLCAwLCAwLCAwLjE2KSdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthbmltYXRpb25dPVwidHJ1ZVwiIFthbmltYXRpb25EdXJhdGlvbl09XCIyNTBcIiBbc2hvd1RpdGxlXT1cImZhbHNlXCIgW3Nob3dVbml0c109XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dTdWJ0aXRsZV09XCJmYWxzZVwiIFtzaG93SW5uZXJTdHJva2VdPVwidHJ1ZVwiIFtjbG9ja3dpc2VdPVwidHJ1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRPcGFjaXR5XT1cIjBcIiBbYmFja2dyb3VuZEdyYWRpZW50XT1cImZhbHNlXCIgW2JhY2tncm91bmRTdHJva2VXaWR0aF09XCIzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwPVwiSW4gcHJvZ3Jlc3NcIiBbc2hvd1plcm9PdXRlclN0cm9rZV09ZmFsc2UgW2JhY2tncm91bmRQYWRkaW5nXT1cIi05XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3RhcnRGcm9tWmVyb109XCJmYWxzZVwiIFtiYWNrZ3JvdW5kUGFkZGluZ109XCIwXCIgW2ltYWdlSGVpZ2h0XT1cIjIyXCIgW2ltYWdlV2lkdGhdPVwiMjJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93QmFja2dyb3VuZF09XCJmYWxzZVwiIFtvdXRlclN0cm9rZUxpbmVjYXBdPVwiJ2J1dHQnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2NpcmNsZS1wcm9ncmVzcz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPHdzLXdpZGdldC1jb250ZW50LXByb2dyZXNzICpuZ0lmPVwiY29udGVudD8uaWRlbnRpZmllclwiIFtmb3JQcmV2aWV3XT1cImZvclByZXZpZXdcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtjb250ZW50SWRdPVwiY29udGVudD8uaWRlbnRpZmllclwiIGNsYXNzPVwicHJvZ3Jlc3MtYmFyLXRoaW5cIiBbcHJvZ3Jlc3NdPVwiY29udGVudD8uY29tcGxldGlvblBlcmNlbnRhZ2VcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtwcm9ncmVzc1R5cGVdPVwiJ3BlcmNlbnRhZ2UnXCI+XHJcbiAgICAgICAgICAgICAgICAgIDwvd3Mtd2lkZ2V0LWNvbnRlbnQtcHJvZ3Jlc3M+IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2Vsc2VCbG9jaz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzXCIgW3BlcmNlbnRdPVwiMFwiIFtyYWRpdXNdPVwiMTFcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlV2lkdGhdPVwiMlwiIFtpbm5lclN0cm9rZVdpZHRoXT1cIjJcIiBbb3V0ZXJTdHJva2VDb2xvcl09XCInIzgwODA4MCdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lubmVyU3Ryb2tlQ29sb3JdPVwiJyM4MDgwODAnXCIgW2FuaW1hdGlvbl09XCJ0cnVlXCIgW3NwYWNlXT1cIi0yXCIgW3Nob3dVbml0c109XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYW5pbWF0aW9uRHVyYXRpb25dPVwiMjUwXCIgW3Nob3dUaXRsZV09XCJmYWxzZVwiIFtiYWNrZ3JvdW5kUGFkZGluZ109XCIwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtiYWNrZ3JvdW5kUGFkZGluZ109XCItOVwiIFtvdXRlclN0cm9rZUxpbmVjYXBdPVwiJ2J1dHQnXCIgbWF0VG9vbHRpcD1cIk5vdCBzdGFydGVkXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93U3VidGl0bGVdPVwiZmFsc2VcIiBbc2hvd0lubmVyU3Ryb2tlXT1cInRydWVcIiBbY2xvY2t3aXNlXT1cInRydWVcIiBbaW1hZ2VIZWlnaHRdPVwiMjJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2ltYWdlV2lkdGhdPVwiMjJcIiBbc2hvd0JhY2tncm91bmRdPVwiZmFsc2VcIj48L2NpcmNsZS1wcm9ncmVzcz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8cD5ubyBkYXRhPC9wPiAtLT5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8IS0tIGRlYWN0aXZhdGVkIGFzIHBlciBOSUMgQ0VPIHJlcXVpcmVtZW50IHRvIGFjY2VzcyBjb3Vyc2Ugd3Rob3V0IGxvZ2luIC0tPlxyXG4gICAgICAgICAgICA8IS0tIEZvciBsb2NrZWQgYXNzZXNzbWVudHM6IHNob3cgY29udGVudCBidXQgbWFrZSBpdCBub24tY2xpY2thYmxlIC0tPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwid2lkdGgtZXhwYW5kXCIgKm5nSWY9XCJpc01pbGVzdG9uZUFzc2Vzc21lbnRMb2NrZWQgJiYgaXNFbnJvbGxlZDsgZWxzZSBjbGlja2FibGVDb250ZW50XCJcclxuICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnbWwtMyc6IGlzRW5yb2xsZWR9XCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC10cnVuY2F0ZSBvcGFjaXR5LTYwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2wgc206ZmxleC1yb3cgZmxleC13cmFwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBnYXAtMiB3LWZ1bGxcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cInRleHQtZ3JheS01MDBcIj5sb2NrPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwibWFyZ2luLXJlbW92ZSB0ZXh0LXRydW5jYXRlIG1hdC1ib2R5LTIgZmxleC1hdXRvIGZvbnQtYm9sZCBub2R0cmFuc2xhdGUgdGV4dC1ncmF5LTYwMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGNvbnRlbnQ/Lm5hbWUgfCB0cnVuY2F0ZTo1MCB9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9wPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb250ZW50LXR5cGUgb3B0aW9uYWwtc3BhbiBub2R0cmFuc2xhdGVcIiAqbmdJZj1cImNvbnRlbnQ/Lm9wdGlvbmFsUmVhZGluZ1wiPnt7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAncGxheWVyYnJpZWYub3B0aW9uYWwnIHwgdHJhbnNsYXRlIHwgdGl0bGVjYXNlfX0gPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gZm9yIGRlZmF1bHQgZ3JleSBpY29ucyAtLT5cclxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSB8fCAhaXNFbnJvbGxlZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVzaWNvbnMgd3MtbWF0LWJsYWNrNjAtdGV4dFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS92aWRlby5zdmdcIiBhbHQ9XCJWaWRlb1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICd2aWRlby9tcDQnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndmlkZW8veC15b3V0dWJlJyB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgY29udGVudD8ubWltZVR5cGUgPT09J2FwcGxpY2F0aW9uL3gtbXBlZ1VSTCdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvYXVkaW8uc3ZnXCIgYWx0PVwiQXVkaW9cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIiAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXVkaW8vbXBlZydcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvcGRmLnN2Z1wiIGFsdD1cIlBERlwiIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9wZGYnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2xpbmsuc3ZnXCIgYWx0PVwiSW50ZXJhY3RpdmVDb250ZW50XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLmVrc3RlcC5odG1sLWFyY2hpdmUnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndGV4dC94LXVybCdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvYXNzZXNzbWVudC5zdmdcIiBhbHQ9XCJBc3Nlc3NtZW50XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vanNvbicgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9xdWl6JyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5zdW5iaXJkLnF1ZXN0aW9uc2V0J1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9pbWFnZS5zdmdcIiBhbHQ9XCJJbWFnZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL3BuZycgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdpbWFnZS9qcGVnJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9jb250ZW50X2NvcHkuc3ZnXCIgY2xhc3M9XCJjb250ZW50aWNvblwiIGFsdD1cIkNvdXJzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLmVrc3RlcC5jb250ZW50LWNvbGxlY3Rpb24nIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vc3VydmV5J1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9tb2R1bGUuc3ZnXCIgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0PVwib2ZmbGluZSBzZXNzaW9uc1wiICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL29mZmxpbmUnXCI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXNvdXJjZUR1cmF0aW9uIHdzLW1hdC1ibGFjazYwLXRleHQgbm9kdHJhbnNsYXRlXCI+e3sgY29udGVudD8ubWF4UXVlc3Rpb25zXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19IHt7ICdwbGF5ZXJicmllZi5xdWVzdGlvbnMnIHwgdHJhbnNsYXRlIHwgdGl0bGVjYXNlfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhKGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVzb3VyY2VEdXJhdGlvbiB3cy1tYXQtYmxhY2s2MC10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7IChjb250ZW50Py5kdXJhdGlvbnx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZXJhcmNoeU1hcERhdGFbY29udGVudD8uaWRlbnRpZmllcl0/LmV4cGVjdGVkRHVyYXRpb24gfHwgMCl8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpcGVEdXJhdGlvblRyYW5zZm9ybTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2htcydcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgPCEtLSBMb2NrIG1lc3NhZ2UgZGlzcGxheWVkIEJFTE9XIGFzc2Vzc21lbnQgZGV0YWlscyB3aGVuIGxvY2tlZCAtLT5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb250ZW50LWxvY2tpbmcgZmxleCB3LWZ1bGwgZmxleC1taWRkbGUgbXQtMiBnYXAtMiBweC0yIHB5LTEgYmctb3JhbmdlLTUwIGJvcmRlci1sLTQgYm9yZGVyLW9yYW5nZS00MDBcIj5cclxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJsb2NrLWljb24gdGV4dC1vcmFuZ2UtNjAwXCIgc3R5bGU9XCJmb250LXNpemU6IDE4cHg7IHdpZHRoOiAxOHB4OyBoZWlnaHQ6IDE4cHg7XCI+bG9jazwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsb2NrLW1lc3NhZ2UgbWF0LWJvZHktMiB0ZXh0LW9yYW5nZS04MDBcIiBzdHlsZT1cImZvbnQtc2l6ZTogMTNweDtcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyBjb250ZW50IGlzIGxvY2tlZC4gQ29tcGxldGUgYWxsIG1hbmRhdG9yeSBpdGVtcyB0byB1bmxvY2sgdGhlIGFzc2Vzc21lbnQuXHJcbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgPCEtLSBDbGlja2FibGUgY29udGVudCB0ZW1wbGF0ZSAod2hlbiBOT1QgbG9ja2VkKSAtLT5cclxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNjbGlja2FibGVDb250ZW50PlxyXG4gICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJ3aWR0aC1leHBhbmRcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtjbGFzcy5kaXNhYmxlZF09XCIoZm9yUHJldmlldyB8fCAhaXNFbmFibGVkIHx8ICFpc0Vucm9sbGVkIHx8ICFpc0JhdGNoSW5Qcm9nZXNzIHx8ICFpc0NvbnRlbnRVbmxvY2tlZCB8fCBpc1BhcmVudE1pbGVzdG9uZUxvY2tlZCkgPyB0cnVlIDogbnVsbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydtbC0zJzogaXNFbnJvbGxlZH1cIlxyXG4gICAgICAgICAgICAgICAgICAgIFtyb3V0ZXJMaW5rXT1cIihpc0FsbG93ZWQgJiYgIWZvclByZXZpZXcgJiYgaXNFbmFibGVkICYmICFpc1BhcmVudE1pbGVzdG9uZUxvY2tlZCkgPyByZXNvdXJjZUxpbmsudXJsIDogbnVsbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW3F1ZXJ5UGFyYW1zXT1cIihpc0FsbG93ZWQgJiYgIWZvclByZXZpZXcgJiYgaXNFbmFibGVkICYmICFpc1BhcmVudE1pbGVzdG9uZUxvY2tlZCkgID8gcmVzb3VyY2VMaW5rLnF1ZXJ5UGFyYW1zIDogbnVsbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwiaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQgPyAnVGhpcyBjb250ZW50IGlzIGxvY2tlZC4gQ29tcGxldGUgcHJldmlvdXMgbWlsZXN0b25lIHRvIHZpZXcgdGhpcyBjb250ZW50LicgOiAnJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcFBvc2l0aW9uPVwiYWJvdmVcIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cInsncmVzb3VyY2UtYWN0aXZlJzogcGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpICYmIGlzRW5yb2xsZWR9XCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtdHJ1bmNhdGUgXCIgW25nQ2xhc3NdPVwieydjdXJzb3ItcG9pbnRlcic6ICFpc0VuYWJsZWQgJiYgaXNFbnJvbGxlZH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY29udGVudC52aWV3Q2hpbGRyZW4gPSAhY29udGVudC52aWV3Q2hpbGRyZW47IHJhaXNlVGVsZW1ldHJ5KCk7IGNoYW5nZVJlc291cmNlKClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2wgc206ZmxleC1yb3cgZmxleC13cmFwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1hcmdpbi1yZW1vdmUgdGV4dC10cnVuY2F0ZSBtYXQtYm9keS0yIGZsZXgtYXV0byBmb250LWJvbGQgbm9kdHJhbnNsYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J3RleHQtYWN0aXZlJzogcGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpICYmIGlzRW5yb2xsZWR9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgY29udGVudD8ubmFtZSB8IHRydW5jYXRlOjUwIH19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3A+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbnRlbnQtdHlwZSBvcHRpb25hbC1zcGFuIG5vZHRyYW5zbGF0ZVwiICpuZ0lmPVwiY29udGVudD8ub3B0aW9uYWxSZWFkaW5nXCI+e3tcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncGxheWVyYnJpZWYub3B0aW9uYWwnIHwgdHJhbnNsYXRlIHwgdGl0bGVjYXNlfX0gPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBmb3IgZGVmYXVsdCBncmV5IGljb25zIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSB8fCAhaXNFbnJvbGxlZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlc2ljb25zIHdzLW1hdC1ibGFjazYwLXRleHRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L3ZpZGVvLnN2Z1wiIGFsdD1cIlZpZGVvXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICd2aWRlby9tcDQnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndmlkZW8veC15b3V0dWJlJyB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ/Lm1pbWVUeXBlID09PSdhcHBsaWNhdGlvbi94LW1wZWdVUkwnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9hdWRpby5zdmdcIiBhbHQ9XCJBdWRpb1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIiAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXVkaW8vbXBlZydcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L3BkZi5zdmdcIiBhbHQ9XCJQREZcIiBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3BkZidcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2xpbmsuc3ZnXCIgYWx0PVwiSW50ZXJhY3RpdmVDb250ZW50XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuZWtzdGVwLmh0bWwtYXJjaGl2ZScgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICd0ZXh0L3gtdXJsJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvYXNzZXNzbWVudC5zdmdcIiBhbHQ9XCJBc3Nlc3NtZW50XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9qc29uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3F1aXonIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLnN1bmJpcmQucXVlc3Rpb25zZXQnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9pbWFnZS5zdmdcIiBhbHQ9XCJJbWFnZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvcG5nJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL2pwZWcnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9jb250ZW50X2NvcHkuc3ZnXCIgY2xhc3M9XCJjb250ZW50aWNvblwiIGFsdD1cIkNvdXJzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuY29udGVudC1jb2xsZWN0aW9uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3N1cnZleSdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L21vZHVsZS5zdmdcIiBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0PVwib2ZmbGluZSBzZXNzaW9uc1wiICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL29mZmxpbmUnXCI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkNPTVBfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlc291cmNlRHVyYXRpb24gd3MtbWF0LWJsYWNrNjAtdGV4dCBub2R0cmFuc2xhdGVcIj57eyBjb250ZW50Py5tYXhRdWVzdGlvbnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19IHt7ICdwbGF5ZXJicmllZi5xdWVzdGlvbnMnIHwgdHJhbnNsYXRlIHwgdGl0bGVjYXNlfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiEoY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlNUQU5EQUxPTkVfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0UpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVzb3VyY2VEdXJhdGlvbiB3cy1tYXQtYmxhY2s2MC10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7IChjb250ZW50Py5kdXJhdGlvbnx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWVyYXJjaHlNYXBEYXRhW2NvbnRlbnQ/LmlkZW50aWZpZXJdPy5leHBlY3RlZER1cmF0aW9uIHx8IDApfFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGlwZUR1cmF0aW9uVHJhbnNmb3JtOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2htcydcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tIGZvciB3aGl0ZSBpY29ucyB3aGVuIGNvbnRlbnQgaGlnaGxpZ2h0ZWQgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSAmJiBpc0Vucm9sbGVkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZXNpY29ucyB3cy1tYXQtd2hpdGUtdGV4dFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvdmlkZW8uc3ZnXCIgYWx0PVwiVmlkZW9cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIiAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndmlkZW8vbXA0JyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ3ZpZGVvL3gteW91dHViZScgfHxcclxuICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ/Lm1pbWVUeXBlID09PSdhcHBsaWNhdGlvbi94LW1wZWdVUkwnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9hdWRpby5zdmdcIiBhbHQ9XCJBdWRpb1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhdWRpby9tcGVnJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvcGRmLnN2Z1wiIGFsdD1cIlBERlwiIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9wZGYnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9saW5rLnN2Z1wiIGFsdD1cIkludGVyYWN0aXZlQ29udGVudFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuaHRtbC1hcmNoaXZlJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ3RleHQveC11cmwnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9hc3Nlc3NtZW50LnN2Z1wiIGFsdD1cIkFzc2Vzc21lbnRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9qc29uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3F1aXonIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLnN1bmJpcmQucXVlc3Rpb25zZXQnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2ltYWdlLnN2Z1wiIGFsdD1cIkltYWdlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvcG5nJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL2pwZWcnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9jb250ZW50X2NvcHkuc3ZnXCIgY2xhc3M9XCJjb250ZW50aWNvblwiIGFsdD1cIkNvdXJzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLmVrc3RlcC5jb250ZW50LWNvbGxlY3Rpb24nIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vc3VydmV5J1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvbW9kdWxlLnN2Z1wiIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsdD1cIm9mZmxpbmUgc2Vzc2lvbnNcIiAqbmdJZj1cImNvbnRlbnQubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9vZmZsaW5lJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXNvdXJjZUR1cmF0aW9uIHdzLW1hdC1ibGFjazYwLXRleHQgbm9kdHJhbnNsYXRlXCI+e3sgY29udGVudD8ubWF4UXVlc3Rpb25zXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19IHt7ICdwbGF5ZXJicmllZi5xdWVzdGlvbnMnIHwgdHJhbnNsYXRlIHwgdGl0bGVjYXNlfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhKGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVzb3VyY2VEdXJhdGlvbiB3cy1tYXQtYmxhY2s2MC10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7IChjb250ZW50Py5kdXJhdGlvbnx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZXJhcmNoeU1hcERhdGFbY29udGVudD8uaWRlbnRpZmllcl0/LmV4cGVjdGVkRHVyYXRpb24gfHwgMCl8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpcGVEdXJhdGlvblRyYW5zZm9ybTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2htcydcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gRG93bmxvYWQgYnV0dG9uIGZvciBwZGYgcmVzb3VyY2VzIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzaG91bGRTaG93RG93bmxvYWRCdXR0b24oY29udGVudClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRvd25sb2FkLWJ0biBtYXQtYm9keS0yIG10LTIgc206bXQtMVwiIChjbGljayk9XCJkb3dubG9hZENvbnRlbnQoY29udGVudCwgJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2FjdGl2ZSc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKX1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwiZG93bmxvYWQtbGluayBmbGV4IGl0ZW1zLWNlbnRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiXCI+RG93bmxvYWQ8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2E+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvYT5cclxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG48L25nLWNvbnRhaW5lcj5cclxuXHJcbjxtYXQtbWVudSAjYnV0dG9uTWVudT1cIm1hdE1lbnVcIj5cclxuICAgIDxhIG1hdC1tZW51LWl0ZW0gW3JvdXRlckxpbmtdPVwiJy4uLycgKyBjb250ZW50Py5pZGVudGlmaWVyICsgJy9vdmVydmlldydcIiBbcXVlcnlQYXJhbXNdPVwiY29udGV4dFBhdGhcIlxyXG4gICAgICAgIGNsYXNzPVwiZmxleCBmbGV4LW1pZGRsZVwiPlxyXG4gICAgICAgIDxtYXQtaWNvbj50b2M8L21hdC1pY29uPlxyXG4gICAgICAgIDxoMyBjbGFzcz1cIm1hcmdpbi1yZW1vdmUgbm9kdHJhbnNsYXRlXCI+XHJcbiAgICAgICAgICAgIFZpZXcgRGV0YWlsc1xyXG4gICAgICAgIDwvaDM+XHJcbiAgICA8L2E+XHJcbjwvbWF0LW1lbnU+XHJcblxyXG48bmctdGVtcGxhdGUgI2NvbGxlY3Rpb25UZW1wbGF0ZT5cclxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0NvbGxlY3Rpb25cIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29sbGVjdGlvbi13cmFwcGVyIHAtNCBmbGV4IGZsZXgtY29sIHBvc2l0aW9uLXJlbGF0aXZlXCIgW25nQ2xhc3NdPVwieydvcGVuJzogY2hlY2soY29udGVudCksXHJcbiAgICAgICAgICAgICdjbG9zZSc6ICFjb250ZW50LnZpZXdDaGlsZHJlbixcclxuICAgICAgICAgICAgJ2NvdXJzZSc6IWlzTW9kdWxlLCAnbW9kdWxlJzogaXNNb2R1bGUsXHJcbiAgICAgICAgICAgICdjb250ZW50LWFjdGl2ZSc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50LmlkZW50aWZpZXIpICYmIGlzRW5yb2xsZWR9XCI+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWNvbGxlY3Rpb24gdy1hdXRvIHNtOnctMTAwIHBhZGRpbmctcmlnaHQteGxcIj5cclxuICAgICAgICAgICAgICAgIDwhLS0gPGltZyBjbGFzcz1cImNhcmQtdGh1bWJuYWlsIHdzLW1hdC1wcmltYXJ5LWxpdGUtYmFja2dyb3VuZFwiIFtzcmNdPVwiY29udGVudD8uYXBwSWNvblwiIGFsdD1cIlRodW1ibmFpbFwiXHJcbiAgICAgICAgICAgIChjbGljayk9XCJjb250ZW50LnZpZXdDaGlsZHJlbiA9ICFjb250ZW50LnZpZXdDaGlsZHJlblwiIFt3c1V0aWxzRGVmYXVsdFRodW1ibmFpbF09XCJkZWZhdWx0VGh1bWJuYWlsXCIgLz4gLS0+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBmbGV4LXdyYXAgZmxleC1iZXR3ZWVuIHdpZHRoLWV4cGFuZCBwci0wIHctMTAwIFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCIgW25nQ2xhc3NdPVwieydjdXJzb3ItcG9pbnRlcic6ICFpc0VuYWJsZWR9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNvbnRlbnQudmlld0NoaWxkcmVuID0gIWNvbnRlbnQudmlld0NoaWxkcmVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciBtYi0xIHNtOmZsZXgtcm93XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJpc01vZHVsZSAmJiBpc0Vucm9sbGVkICYmICFpc01pbGVzdG9uZUxvY2tlZCAmJiAhaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIWZvclByZXZpZXcgJiYgY29udGVudD8uaWRlbnRpZmllciAmJiBnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKSA7IGVsc2UgZWxzZUJsb2NrXCI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29tcGxldGlvblN0YXR1cyhjb250ZW50LmlkZW50aWZpZXIpID09IDJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb21wbGV0ZWQgbXItMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImNvbXBsZXRlZC1pY29uXCIgW2NvbG9yXT1cImJsdWVcIj5jaGVja19jaXJjbGU8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29tcGxldGlvblN0YXR1cyhjb250ZW50Py5pZGVudGlmaWVyKSA8IDJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjaXJjbGUtcHJvZ3Jlc3MgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBwcm9ncmVzcyBtci0xXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGVyY2VudF09XCJnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKVwiIFtyYWRpdXNdPVwiMTBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZVdpZHRoXT1cIjJcIiBbaW5uZXJTdHJva2VXaWR0aF09XCIyXCIgW3NwYWNlXT1cIi0yXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VDb2xvcl09XCJwcm9ncmVzc0NvbG9yMigpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW5uZXJTdHJva2VDb2xvcl09XCIncmdiYSgwLCAwLCAwLCAwLjE2KSdcIiBbYW5pbWF0aW9uXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthbmltYXRpb25EdXJhdGlvbl09XCIyNTBcIiBbc2hvd1RpdGxlXT1cImZhbHNlXCIgW3Nob3dVbml0c109XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dTdWJ0aXRsZV09XCJmYWxzZVwiIFtzaG93SW5uZXJTdHJva2VdPVwidHJ1ZVwiIFtjbG9ja3dpc2VdPVwidHJ1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRPcGFjaXR5XT1cIjBcIiBbYmFja2dyb3VuZEdyYWRpZW50XT1cImZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZFN0cm9rZVdpZHRoXT1cIjNcIiBtYXRUb29sdGlwPVwiSW4gcHJvZ3Jlc3NcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93WmVyb091dGVyU3Ryb2tlXT1mYWxzZSBbYmFja2dyb3VuZFBhZGRpbmddPVwiLTdcIiBbc3RhcnRGcm9tWmVyb109XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRQYWRkaW5nXT1cIjBcIiBbaW1hZ2VIZWlnaHRdPVwiMThcIiBbaW1hZ2VXaWR0aF09XCIxOFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dCYWNrZ3JvdW5kXT1cImZhbHNlXCIgW291dGVyU3Ryb2tlTGluZWNhcF09XCInYnV0dCdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvY2lyY2xlLXByb2dyZXNzPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2Vsc2VCbG9jaz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzIG1yLTFcIiBbcGVyY2VudF09XCIwXCIgW3JhZGl1c109XCIxMVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VXaWR0aF09XCIyXCIgW2lubmVyU3Ryb2tlV2lkdGhdPVwiMlwiIFtvdXRlclN0cm9rZUNvbG9yXT1cIicjODA4MDgwJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW5uZXJTdHJva2VDb2xvcl09XCInIzgwODA4MCdcIiBbYW5pbWF0aW9uXT1cInRydWVcIiBbc3BhY2VdPVwiLTJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dVbml0c109XCJmYWxzZVwiIFthbmltYXRpb25EdXJhdGlvbl09XCIyNTBcIiBbc2hvd1RpdGxlXT1cImZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtiYWNrZ3JvdW5kUGFkZGluZ109XCIwXCIgW2JhY2tncm91bmRQYWRkaW5nXT1cIi05XCIgW291dGVyU3Ryb2tlTGluZWNhcF09XCInYnV0dCdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcD1cIk5vdCBzdGFydGVkXCIgW3Nob3dTdWJ0aXRsZV09XCJmYWxzZVwiIFtzaG93SW5uZXJTdHJva2VdPVwidHJ1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xvY2t3aXNlXT1cInRydWVcIiBbaW1hZ2VIZWlnaHRdPVwiMjJcIiBbaW1hZ2VXaWR0aF09XCIyMlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd0JhY2tncm91bmRdPVwiZmFsc2VcIj48L2NpcmNsZS1wcm9ncmVzcz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydjb2xsZWN0aW9uLWFjdGl2ZS1jbGFzcyc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSAmJiBpc0Vucm9sbGVkfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nICpuZ0lmPVwiaXNNaWxlc3RvbmVMb2NrZWRcIiBzcmM9XCJhc3NldHMvaWNvbnMvaHVicy9sb2NrLnN2Z1wiIGFsdD1cIkxvY2tlZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJsb2NrLWljb24gbXItMiBtYXJnaW4tYm90dG9tLXh4c1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJtYXJnaW4tcmVtb3ZlIHRleHQtdHJ1bmNhdGUgbWF0LXN1YmhlYWRpbmctMSBmbGV4LWF1dG8gZm9udC1ib2xkIG5vZHRyYW5zbGF0ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyd0ZXh0LWFjdGl2ZSc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50LmlkZW50aWZpZXIpICYmIGlzRW5yb2xsZWR9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3tpc01pbGVzdG9uZSA/IGluZGV4IC0xIDogaW5kZXh9fS4gPC9zcGFuPnt7IGNvbnRlbnQ/Lm5hbWUgfCB0cnVuY2F0ZTo1MCB9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc01pbGVzdG9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cImlzTWlsZXN0b25lTG9ja2VkXCIgY2xhc3M9XCJsb2NrZWQtdGV4dCBtbC0yXCI+TG9ja2VkPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiY29udGVudD8uaXNNYW5kYXRvcnlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1hbmRhdG9yeS10ZXh0IG1hdC1jYXB0aW9uIG1sLTJcIj5NYW5kYXRvcnk8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3A+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0eXBlLWNvbnRhaW5lciByZXNvdXJjZSBtdC0yIHNtOm10LTBcIiAqbmdJZj1cImNvbnRlbnQ/LmNhdGVnb3J5ID09PSAnUmVzb3VyY2UnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibXItMSBjdXN0b20taWNvbiByb3RhdGUtOTBcIj5jYWxsX3RvX2FjdGlvbjwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJub2R0cmFuc2xhdGVcIj5SZXNvdXJjZTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInR5cGUtY29udGFpbmVyIG1vZHVsZSBtdC0yIHNtOm10LTBcIiAqbmdJZj1cImNvbnRlbnQ/LmNhdGVnb3J5ID09PSAnQ29sbGVjdGlvbidcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJtci0xIGN1c3RvbS1pY29uIHJvdGF0ZS05MFwiPmNhbGxfdG9fYWN0aW9uPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5vZHRyYW5zbGF0ZVwiPk1vZHVsZTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInR5cGUtY29udGFpbmVyIGNvdXJzZSBtdC0yIHNtOm10LTBcIiAqbmdJZj1cImNvbnRlbnQ/LmNhdGVnb3J5ID09PSAnQ291cnNlJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1yLTEgY3VzdG9tLWljb24gcm90YXRlLTkwXCI+Y2FsbF90b19hY3Rpb248L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibm9kdHJhbnNsYXRlXCI+Q291cnNlPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIE1pbGVzdG9uZSBCYWRnZSAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImlzTWlsZXN0b25lXCIgY2xhc3M9XCJtaWxlc3RvbmUtYmFkZ2UgbXQtMiBtYi0yXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1pbGVzdG9uZS1iYWRnZS10ZXh0IG5vZHRyYW5zbGF0ZVwiPk1pbGVzdG9uZSB7e2luZGV4IC0gMX19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBNaWxlc3RvbmUgRGVzY3JpcHRpb24gKDMgbGluZXMgd2l0aCBlbGxpcHNpcykgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxwICpuZ0lmPVwiaXNNaWxlc3RvbmUgJiYgY29udGVudD8uZGVzY3JpcHRpb25cIiBjbGFzcz1cIm1pbGVzdG9uZS1kZXNjcmlwdGlvbiBtdC0yICBub2R0cmFuc2xhdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGNvbnRlbnQ/LmRlc2NyaXB0aW9uIH19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvcD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3cgZ2FwLTMgaXRlbXMtY2VudGVyIGNvbnRlbnQta2V5LXZhbHVlcyBtdC0yXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCIhaXNNb2R1bGVcIiBhbHQ9XCJjb3Vyc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidGltZS1pY29uIGljb24tY29sb3JcIj52aWRlb19saWJyYXJ5PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgKm5nSWY9XCJpc01vZHVsZVwiIGFsdD1cIk1vZHVsZVwiIGNsYXNzPVwidGltZS1pY29uXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9tb2R1bGUuc3ZnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBub2R0cmFuc2xhdGVcIj57eyAoaGllcmFyY2h5TWFwRGF0YVtjb250ZW50Py5pZGVudGlmaWVyXT8uZHVyYXRpb24gfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMjApfFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpcGVEdXJhdGlvblRyYW5zZm9ybTogJ2htcycgfX08L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8ubW9kdWxlQ291bnRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwZXJpb2RcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQteHMgbm9kdHJhbnNsYXRlXCI+e3tjb250ZW50Py5tb2R1bGVDb3VudH19IHt7Y29udGVudD8ubW9kdWxlQ291bnQgPiAxP1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbW9kdWxlcycgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbW9kdWxlJ319PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50Py5sZWFmTm9kZXNDb3VudFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInBlcmlvZFwiPjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBub2R0cmFuc2xhdGVcIj57e2NvbnRlbnQ/LmxlYWZOb2Rlc0NvdW50fX0ge3tjb250ZW50Py5sZWFmTm9kZXNDb3VudFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+MSA/ICdpdGVtcyc6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdpdGVtJ319PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gTWlsZXN0b25lIENvbXBsZXRpb24gUHJvZ3Jlc3MgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc01pbGVzdG9uZSAmJiBpc0Vucm9sbGVkICYmICFpc01pbGVzdG9uZUxvY2tlZFwiIGNsYXNzPVwibWlsZXN0b25lLXByb2dyZXNzIG10LTIgIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktYmV0d2VlblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1pbGVzdG9uZS1wcm9ncmVzcy10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7Z2V0TWlsZXN0b25lQ29tcGxldGVkQ291bnQoKX19IG9mXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tjb250ZW50Py5sZWFmTm9kZXNDb3VudCB8fCAwfX0gY29tcGxldGVkPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFZpZXcgQWNoaWV2ZW1lbnQgQnV0dG9uIGZvciBjb21wbGV0ZWQgbWlsZXN0b25lcyAtIE91dHNpZGUgY2xpY2thYmxlIGFyZWEgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNNaWxlc3RvbmUgJiYgaXNFbnJvbGxlZCAmJiAoZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcikgPj0gMTAwIHx8IGdldENvbXBsZXRpb25TdGF0dXMoY29udGVudD8uaWRlbnRpZmllcikgPT09IDIpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInZpZXctYWNoaWV2ZW1lbnQtY29udGFpbmVyIG10LTJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInZpZXctYWNoaWV2ZW1lbnQtYnRuXCIgW2Rpc2FibGVkXT1cImFjaGlldmVtZW50TG9hZGluZ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJ2aWV3TWlsZXN0b25lQWNoaWV2ZW1lbnQoJGV2ZW50KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIiFhY2hpZXZlbWVudExvYWRpbmdcIj5WaWV3IEFjaGlldmVtZW50PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNwaW5uZXIgKm5nSWY9XCJhY2hpZXZlbWVudExvYWRpbmdcIiBbZGlhbWV0ZXJdPVwiMTZcIiBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHJva2VXaWR0aF09XCIyXCIgY29sb3I9XCJwcmltYXJ5XCIgY2xhc3M9XCJpbmxpbmUtc3Bpbm5lclwiPjwvbWF0LXNwaW5uZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gVW5sb2NrIENyaXRlcmlhIE1lc3NhZ2UgZm9yIExvY2tlZCBNaWxlc3RvbmVzIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNNaWxlc3RvbmUgJiYgaXNFbnJvbGxlZCAmJiBpc01pbGVzdG9uZUxvY2tlZFwiIGNsYXNzPVwibWlsZXN0b25lLWxvY2tlZC1tZXNzYWdlIG10LTJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibG9ja2VkLWNyaXRlcmlhLXRleHQgbWF0LWNhcHRpb25cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBnZXRNaWxlc3RvbmVVbmxvY2tNZXNzYWdlKCkgfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gRm9yIGNvdXJzZSBwcm9ncmVzcyB0byBiZSBzaG93biAtLT5cclxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNFbnJvbGxlZCAmJiAhaXNNaWxlc3RvbmVMb2NrZWQgJiYgIWlzUGFyZW50TWlsZXN0b25lTG9ja2VkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIWZvclByZXZpZXcgJiYgY29udGVudD8uaWRlbnRpZmllciAmJiBnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKSAmJiBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gJ0NvdXJzZSdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb21wbGV0aW9uU3RhdHVzKGNvbnRlbnQ/LmlkZW50aWZpZXIpID09IDJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LTFcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTIgbXItNCAgZmxleCBmbGV4LTEgZmxleC1jb2wgIHByb2dyZXNzLWNvbnRhaW5lclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3cganVzdGlmeS1lbmQgdy1mdWxsIFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWF0LWJvZHktMiBub2R0cmFuc2xhdGUgXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Z2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcil9fSU8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8d3Mtd2lkZ2V0LWNvbnRlbnQtcHJvZ3Jlc3MgW2NvbnRlbnRJZF09XCJjb250ZW50Py5wcm9ncmVzc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb2dyZXNzXT1cImdldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvZ3Jlc3NUeXBlXT1cIidwZXJjZW50YWdlJ1wiIFtjdXN0b21DbGFzc05hbWVdPVwiJ3ZpZXdlci1wcm9ncmVzcydcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvd3Mtd2lkZ2V0LWNvbnRlbnQtcHJvZ3Jlc3M+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwibWwtNSBjZXJ0aWZpY2F0ZS1idG5cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnZGlzYWJsZS1idG4nOiBkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZyB8fCBjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCIhZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgJiYgZG93bmxvYWRDZXJ0aWZpY2F0ZShjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZCk7JGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8aW1nIHNyYz1cImZ1c2lvbi1hc3NldHMvaW1hZ2VzL2NlcnRpZmljYXRlLWljby5zdmdcIiB3aWR0aD1cIjI0XCIgaGVpZ2h0PVwiMjRcIj4gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJub2R0cmFuc2xhdGVcIj5DZXJ0aWZpY2F0ZTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCIhZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1sLTJcIj5hcnJvd19kb3dud2FyZDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNlbnRlciBmbGV4IGZsZXgtbWlkZGxlIGNlcnRpZmljYXRlLWxvYWRlclwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zcGlubmVyIHN0cm9rZVdpZHRoPVwiMlwiIHN0cm9rZT1cIid3aGl0ZSdcIiBjbGFzcz1cIndoaXRlLXNwaW5uZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RpYW1ldGVyXT1cIjE2XCI+PC9tYXQtc3Bpbm5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8Y2lyY2xlLXByb2dyZXNzIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgcHJvZ3Jlc3NcIiBbcGVyY2VudF09XCIxMDBcIiBbcmFkaXVzXT1cIjEyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlV2lkdGhdPVwiM1wiIFtpbm5lclN0cm9rZVdpZHRoXT1cIjNcIiBbc3BhY2VdPVwiLTNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VDb2xvcl09XCJwcm9ncmVzc0NvbG9yKClcIiBbaW5uZXJTdHJva2VDb2xvcl09XCIncmdiYSgwLDAsMCwuMTYpJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthbmltYXRpb25dPVwidHJ1ZVwiIFthbmltYXRpb25EdXJhdGlvbl09XCIzMDBcIiBbc2hvd1RpdGxlXT1cImZhbHNlXCIgW3Nob3dVbml0c109XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93U3VidGl0bGVdPVwiZmFsc2VcIiBbc2hvd0lubmVyU3Ryb2tlXT1cInRydWVcIiBbY2xvY2t3aXNlXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZE9wYWNpdHldPVwiMFwiIFtiYWNrZ3JvdW5kR3JhZGllbnRdPVwiZmFsc2VcIiBbYmFja2dyb3VuZFN0cm9rZVdpZHRoXT1cIjNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1plcm9PdXRlclN0cm9rZV09ZmFsc2UgW2JhY2tncm91bmRQYWRkaW5nXT1cIi05XCIgW3N0YXJ0RnJvbVplcm9dPVwiZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZFBhZGRpbmddPVwiMFwiIFtpbWFnZUhlaWdodF09XCIyNFwiIFtpbWFnZVdpZHRoXT1cIjI0XCIgW3Nob3dCYWNrZ3JvdW5kXT1cImZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlTGluZWNhcF09XCInYnV0dCdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2NpcmNsZS1wcm9ncmVzcz4gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb21wbGV0aW9uU3RhdHVzKGNvbnRlbnQ/LmlkZW50aWZpZXIpIDwgMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtMVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMiBtci00ICBmbGV4IGZsZXgtMSBmbGV4LWNvbCAgcHJvZ3Jlc3MtY29udGFpbmVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBqdXN0aWZ5LWVuZCB3LWZ1bGwgd3MtbWF0LWJsYWNrLXRleHRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1hdC1ib2R5LTIgIHdzLW1hdC1ibGFjay10ZXh0IG5vZHRyYW5zbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2dldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpfX0lPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHdzLXdpZGdldC1jb250ZW50LXByb2dyZXNzIFtjb250ZW50SWRdPVwiY29udGVudD8ucHJvZ3Jlc3NcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9ncmVzc109XCJnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb2dyZXNzVHlwZV09XCIncGVyY2VudGFnZSdcIiBbY3VzdG9tQ2xhc3NOYW1lXT1cIid2aWV3ZXItcHJvZ3Jlc3MnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3dzLXdpZGdldC1jb250ZW50LXByb2dyZXNzPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQ/Lmlzc3VlZENlcnRpZmljYXRlc0lkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cIm1sLTUgY2VydGlmaWNhdGUtYnRuXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2Rpc2FibGUtYnRuJzogZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgfHwgY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWR9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiIWRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nICYmIGRvd25sb2FkQ2VydGlmaWNhdGUoY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWQpOyRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGltZyBzcmM9XCJmdXNpb24tYXNzZXRzL2ltYWdlcy9jZXJ0aWZpY2F0ZS1pY28uc3ZnXCIgd2lkdGg9XCIyNFwiIGhlaWdodD1cIjI0XCI+IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibm9kdHJhbnNsYXRlXCI+Q2VydGlmaWNhdGU8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiIWRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtbC0yXCI+YXJyb3dfZG93bndhcmQ8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjZW50ZXIgZmxleCBmbGV4LW1pZGRsZSBjZXJ0aWZpY2F0ZS1sb2FkZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtc3Bpbm5lciBzdHJva2VXaWR0aD1cIjJcIiBzdHJva2U9XCInd2hpdGUnXCIgY2xhc3M9XCJ3aGl0ZS1zcGlubmVyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaWFtZXRlcl09XCIxNlwiPjwvbWF0LXNwaW5uZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2E+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VlLWFsbC1jb250YWluZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGEgaHJlZj1cImphdmFzY3JpcHQ6dm9pZCgwKVwiIHJvbGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNvbnRlbnQudmlld0NoaWxkcmVuID0gIWNvbnRlbnQudmlld0NoaWxkcmVuOyBleHBhbmRBY3RpdmUgPSBmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNlZS1hbGwtYnRuIHRhYiBjdXN0b20tY2hldnJvbiBjdXN0b21pY29uXCIgbWF0LWJ1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIiFjb250ZW50LnZpZXdDaGlsZHJlbiAmJiAhaXNNb2R1bGVcIj5rZXlib2FyZF9hcnJvd19kb3duPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cImNvbnRlbnQudmlld0NoaWxkcmVuICYmICFpc01vZHVsZVwiPmtleWJvYXJkX2Fycm93X3VwPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIiFjb250ZW50LnZpZXdDaGlsZHJlbiAmJiBpc01vZHVsZVwiPmFkZDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJjb250ZW50LnZpZXdDaGlsZHJlbiAmJiBpc01vZHVsZVwiPnJlbW92ZTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiY2hpbGQtd3JhcHBlciAgXCIgKm5nSWY9XCJjb250ZW50LnZpZXdDaGlsZHJlblwiIFtuZ0NsYXNzXT1cInsnb3Blbic6IGNvbnRlbnQudmlld0NoaWxkcmVuLFxyXG4gICAgICAgICAgICAnY2xvc2UnOiAhY29udGVudC52aWV3Q2hpbGRyZW4sXHJcbiAgICAgICAgICAgICdjb3Vyc2UnOiFpc01vZHVsZSxcclxuICAgICAgICAgICAgJ21vZHVsZSc6IGlzTW9kdWxlfVwiIFtAcGFuZWxJbk91dF0+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjaGlsZHJlbi1jb250YWluZXJcIiBbbmdDbGFzc109XCJ7J21vZHVsZSc6IGlzTW9kdWxlLCAnJzogIWlzTW9kdWxlfVwiPlxyXG4gICAgICAgICAgICAgICAgPHdzLXdpZGdldC1hcHAtdG9jLWNvbnRlbnQtY2FyZC12MiBbZm9yUHJldmlld109XCJmb3JQcmV2aWV3XCIgW2NvbXBvbmVudE5hbWVdPVwiY29tcG9uZW50TmFtZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW2NvbnRlbnRdPVwiY2hpbGRcIiBbZXhwYW5kQWxsXT1cImV4cGFuZEFsbFwiIFtyb290SWRdPVwicm9vdElkXCIgW2JhdGNoSWRdPVwiYmF0Y2hJZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW3Jvb3RDb250ZW50VHlwZV09XCJyb290Q29udGVudFR5cGVcIiBbaW5kZXhdPVwiaisxXCIgW2Jhc2VDb250ZW50UmVhZERhdGFdPVwiYmFzZUNvbnRlbnRSZWFkRGF0YVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW3BhdGhTZXRdPVwicGF0aFNldFwiIFtoaWVyYXJjaHlNYXBEYXRhXT1cImhpZXJhcmNoeU1hcERhdGFcIiBbYmF0Y2hEYXRhXT1cImJhdGNoRGF0YVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW21sQ291cnNlXT1cIm1sQ291cnNlXCIgW3BhcmVudE1pbGVzdG9uZUxvY2tlZF09XCJpc01pbGVzdG9uZUxvY2tlZCB8fCBpc1BhcmVudE1pbGVzdG9uZUxvY2tlZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGNoaWxkIG9mIGNvbnRlbnQ/LmNoaWxkcmVuOyB0cmFja0J5OiBjb250ZW50VHJhY2tCeTsgbGV0IGo9IGluZGV4O2xldCBpc0ZpcnN0ID0gZmlyc3RcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnbW9kdWxlQ2FyZCc6IGNoZWNrSXNNb2R1bGUoY2hpbGQpLCAncmVzb3VyY2VDYXJkJzogIWNoZWNrSXNNb2R1bGUoY2hpbGQpLCAnZmlyc3QnOiBpc0ZpcnN0fVwiPlxyXG4gICAgICAgICAgICAgICAgPC93cy13aWRnZXQtYXBwLXRvYy1jb250ZW50LWNhcmQtdjI+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9uZy1jb250YWluZXI+XHJcbjwvbmctdGVtcGxhdGU+XHJcblxyXG5cclxuPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzUHJlQXNzZXNzbWVudFwiPlxyXG4gICAgPGRpdiBjbGFzcz1cImNvbGxlY3Rpb24td3JhcHBlciBwLTQgZmxleCBmbGV4LWNvbCBwb3NpdGlvbi1yZWxhdGl2ZVwiIFtuZ0NsYXNzXT1cInsnb3Blbic6IGNoZWNrKGNvbnRlbnQpLFxyXG4gICAgICAgICdjb3Vyc2UnOiFpc01vZHVsZSwgJ21vZHVsZSc6IGlzTW9kdWxlLFxyXG4gICAgICAgICdjb250ZW50LWFjdGl2ZSc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50LmlkZW50aWZpZXIpfVwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWNvbGxlY3Rpb24gdy1hdXRvIHNtOnctMTAwIHBhZGRpbmctcmlnaHQteGxcIj5cclxuICAgICAgICAgICAgPCEtLSA8aW1nIGNsYXNzPVwiY2FyZC10aHVtYm5haWwgd3MtbWF0LXByaW1hcnktbGl0ZS1iYWNrZ3JvdW5kXCIgW3NyY109XCJjb250ZW50Py5hcHBJY29uXCIgYWx0PVwiVGh1bWJuYWlsXCJcclxuICAgICAgICAoY2xpY2spPVwiY29udGVudC52aWV3Q2hpbGRyZW4gPSAhY29udGVudC52aWV3Q2hpbGRyZW5cIiBbd3NVdGlsc0RlZmF1bHRUaHVtYm5haWxdPVwiZGVmYXVsdFRodW1ibmFpbFwiIC8+IC0tPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBmbGV4LXdyYXAgZmxleC1iZXR3ZWVuIHdpZHRoLWV4cGFuZCBwci0wIHctMTAwIFwiPlxyXG5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCIgW25nQ2xhc3NdPVwieydjdXJzb3ItcG9pbnRlcic6ICFpc0VuYWJsZWR9XCJcclxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY29udGVudC52aWV3Q2hpbGRyZW4gPSAhY29udGVudC52aWV3Q2hpbGRyZW5cIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBzbTpmbGV4LXJvdyBmbGV4LXdyYXBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFmb3JQcmV2aWV3ICYmIGNvbnRlbnQ/LmlkZW50aWZpZXIgJiYgZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcikgOyBlbHNlIGVsc2VCbG9ja1wiPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29tcGxldGlvblN0YXR1cyhjb250ZW50LmlkZW50aWZpZXIpID09IDJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbXBsZXRlZCBtci0yXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImNvbXBsZXRlZC1pY29uXCIgW2NvbG9yXT1cImJsdWVcIj5jaGVja19jaXJjbGU8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb21wbGV0aW9uU3RhdHVzKGNvbnRlbnQ/LmlkZW50aWZpZXIpIDwgMlwiPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzIG1yLTFcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BlcmNlbnRdPVwiZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcilcIiBbcmFkaXVzXT1cIjEwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZVdpZHRoXT1cIjJcIiBbaW5uZXJTdHJva2VXaWR0aF09XCIyXCIgW3NwYWNlXT1cIi0yXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZUNvbG9yXT1cInByb2dyZXNzQ29sb3IyKClcIiBbaW5uZXJTdHJva2VDb2xvcl09XCIncmdiYSgwLCAwLCAwLCAwLjE2KSdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2FuaW1hdGlvbl09XCJ0cnVlXCIgW2FuaW1hdGlvbkR1cmF0aW9uXT1cIjI1MFwiIFtzaG93VGl0bGVdPVwiZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dVbml0c109XCJmYWxzZVwiIFtzaG93U3VidGl0bGVdPVwiZmFsc2VcIiBbc2hvd0lubmVyU3Ryb2tlXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Nsb2Nrd2lzZV09XCJ0cnVlXCIgW2JhY2tncm91bmRPcGFjaXR5XT1cIjBcIiBbYmFja2dyb3VuZEdyYWRpZW50XT1cImZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtiYWNrZ3JvdW5kU3Ryb2tlV2lkdGhdPVwiM1wiIG1hdFRvb2x0aXA9XCJJbiBwcm9ncmVzc1wiIFtzaG93WmVyb091dGVyU3Ryb2tlXT1mYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRQYWRkaW5nXT1cIi03XCIgW3N0YXJ0RnJvbVplcm9dPVwiZmFsc2VcIiBbYmFja2dyb3VuZFBhZGRpbmddPVwiMFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW1hZ2VIZWlnaHRdPVwiMThcIiBbaW1hZ2VXaWR0aF09XCIxOFwiIFtzaG93QmFja2dyb3VuZF09XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VMaW5lY2FwXT1cIididXR0J1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2NpcmNsZS1wcm9ncmVzcz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNlbHNlQmxvY2s+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzIG1yLTFcIiBbcGVyY2VudF09XCIwXCIgW3JhZGl1c109XCIxMVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZVdpZHRoXT1cIjJcIiBbaW5uZXJTdHJva2VXaWR0aF09XCIyXCIgW291dGVyU3Ryb2tlQ29sb3JdPVwiJyM4MDgwODAnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lubmVyU3Ryb2tlQ29sb3JdPVwiJyM4MDgwODAnXCIgW2FuaW1hdGlvbl09XCJ0cnVlXCIgW3NwYWNlXT1cIi0yXCIgW3Nob3dVbml0c109XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthbmltYXRpb25EdXJhdGlvbl09XCIyNTBcIiBbc2hvd1RpdGxlXT1cImZhbHNlXCIgW2JhY2tncm91bmRQYWRkaW5nXT1cIjBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZFBhZGRpbmddPVwiLTlcIiBbb3V0ZXJTdHJva2VMaW5lY2FwXT1cIididXR0J1wiIG1hdFRvb2x0aXA9XCJOb3Qgc3RhcnRlZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93U3VidGl0bGVdPVwiZmFsc2VcIiBbc2hvd0lubmVyU3Ryb2tlXT1cInRydWVcIiBbY2xvY2t3aXNlXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW1hZ2VIZWlnaHRdPVwiMjJcIiBbaW1hZ2VXaWR0aF09XCIyMlwiIFtzaG93QmFja2dyb3VuZF09XCJmYWxzZVwiPjwvY2lyY2xlLXByb2dyZXNzPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgW25nQ2xhc3NdPVwieydjb2xsZWN0aW9uLWFjdGl2ZS1jbGFzcyc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKX1cIj48L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8cCBjbGFzcz1cIm1hcmdpbi1yZW1vdmUgdGV4dC10cnVuY2F0ZSBtYXQtc3ViaGVhZGluZy0xIGZsZXgtYXV0byBmb250LWJvbGQgbm9kdHJhbnNsYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsndGV4dC1hY3RpdmUnOiBwYXRoU2V0Py5oYXMoY29udGVudC5pZGVudGlmaWVyKX1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7aW5kZXh9fS4ge3sgY29udGVudD8ubmFtZSB8IHRydW5jYXRlOjUwIH19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvcD4gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwibWFyZ2luLXJlbW92ZSB0ZXh0LXRydW5jYXRlIG1hdC1zdWJoZWFkaW5nLTEgZmxleC1hdXRvIGZvbnQtYm9sZCBub2R0cmFuc2xhdGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmRpc2FibGVkXT1cIm51bGxcIiBbbmdDbGFzc109XCJ7J21sLTMnOiBpc0Vucm9sbGVkfVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcm91dGVyTGlua109XCIoaXNBbGxvd2VkICYmICFmb3JQcmV2aWV3ICYmIGlzRW5hYmxlZCkgPyByZXNvdXJjZUxpbmsudXJsIDogbnVsbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcXVlcnlQYXJhbXNdPVwiY29tcHV0ZWRRdWVyeVBhcmFtc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSB7e2NvbnRlbnQ/LmNvdXJzZUNhdGVnb3J5fX0gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cInsncmVzb3VyY2UtYWN0aXZlJzogcGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpfVwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtdHJ1bmNhdGUgXCIgW25nQ2xhc3NdPVwieydjdXJzb3ItcG9pbnRlcic6ICFpc0VuYWJsZWR9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwicmFpc2VUZWxlbWV0cnkoKTsgY2hhbmdlUmVzb3VyY2UoKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sIHNtOmZsZXgtcm93IGZsZXgtd3JhcFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1hcmdpbi1yZW1vdmUgdGV4dC10cnVuY2F0ZSBtYXQtYm9keS0yIGZsZXgtYXV0byBmb250LWJvbGQgbm9kdHJhbnNsYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsndGV4dC1hY3RpdmUnOiBwYXRoU2V0Py5oYXMoY29udGVudD8uaWRlbnRpZmllcil9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDxtYXQtaWNvbiBjbGFzcz1cIm1hcmdpbi1yaWdodC14cyByYWRpb2J0biB0aW1lLWljb25cIj5yYWRpb19idXR0b25fdW5jaGVja2VkIDwvbWF0LWljb24+IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tpbmRleH19LiB7eyBjb250ZW50Py5uYW1lIHwgdHJ1bmNhdGU6NTAgfX1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb250ZW50LXR5cGUgb3B0aW9uYWwtc3BhbiBub2R0cmFuc2xhdGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5vcHRpb25hbFJlYWRpbmdcIj57eyAncGxheWVyYnJpZWYub3B0aW9uYWwnIHwgdHJhbnNsYXRlIHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlY2FzZX19IDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIGZvciBkZWZhdWx0IGdyZXkgaWNvbnMgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFwYXRoU2V0Py5oYXMoY29udGVudD8uaWRlbnRpZmllcilcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlc2ljb25zIHdzLW1hdC1ibGFjazYwLXRleHRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvdmlkZW8uc3ZnXCIgYWx0PVwiVmlkZW9cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIiAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndmlkZW8vbXA0JyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ3ZpZGVvL3gteW91dHViZScgfHxcclxuICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ/Lm1pbWVUeXBlID09PSdhcHBsaWNhdGlvbi94LW1wZWdVUkwnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2F1ZGlvLnN2Z1wiIGFsdD1cIkF1ZGlvXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXVkaW8vbXBlZydcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvcGRmLnN2Z1wiIGFsdD1cIlBERlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3BkZidcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9yZXNvdXJjZS5zdmdcIiBhbHQ9XCJTdXJ2ZXlcIiBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcclxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vc3VydmV5J1wiPiAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvbGluay5zdmdcIiBhbHQ9XCJJbnRlcmFjdGl2ZUNvbnRlbnRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuZWtzdGVwLmh0bWwtYXJjaGl2ZScgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICd0ZXh0L3gtdXJsJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9hc3Nlc3NtZW50LnN2Z1wiIGFsdD1cIkFzc2Vzc21lbnRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9qc29uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3F1aXonIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLnN1bmJpcmQucXVlc3Rpb25zZXQnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2ltYWdlLnN2Z1wiIGFsdD1cIkltYWdlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvcG5nJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL2pwZWcnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2NvbnRlbnRfY29weS5zdmdcIiBjbGFzcz1cImNvbnRlbnRpY29uXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHQ9XCJDb3Vyc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuY29udGVudC1jb2xsZWN0aW9uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3N1cnZleSdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvbW9kdWxlLnN2Z1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiIGFsdD1cIm9mZmxpbmUgc2Vzc2lvbnNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL29mZmxpbmUnXCI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFXCI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVzb3VyY2VEdXJhdGlvbiB3cy1tYXQtYmxhY2s2MC10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ/Lm1heFF1ZXN0aW9ucyB9fSB7eyAncGxheWVyYnJpZWYucXVlc3Rpb25zJyB8IHRyYW5zbGF0ZSB8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlY2FzZX19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIShjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlNUQU5EQUxPTkVfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRSlcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlc291cmNlRHVyYXRpb24gd3MtbWF0LWJsYWNrNjAtdGV4dCBub2R0cmFuc2xhdGVcIj57e1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29udGVudD8uZHVyYXRpb258fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWVyYXJjaHlNYXBEYXRhW2NvbnRlbnQ/LmlkZW50aWZpZXJdPy5leHBlY3RlZER1cmF0aW9uIHx8IDApfFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXBlRHVyYXRpb25UcmFuc2Zvcm06XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdobXMnXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIGZvciB3aGl0ZSBpY29ucyB3aGVuIGNvbnRlbnQgaGlnaGxpZ2h0ZWQgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVzaWNvbnMgd3MtbWF0LXdoaXRlLXRleHRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L3doaXRlL3ZpZGVvLnN2Z1wiIGFsdD1cIlZpZGVvXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCIgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ3ZpZGVvL21wNCcgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICd2aWRlby94LXlvdXR1YmUnIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICBjb250ZW50Py5taW1lVHlwZSA9PT0nYXBwbGljYXRpb24veC1tcGVnVVJMJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvYXVkaW8uc3ZnXCIgYWx0PVwiQXVkaW9cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhdWRpby9tcGVnJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvcGRmLnN2Z1wiIGFsdD1cIlBERlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3BkZidcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvcmVzb3VyY2Uuc3ZnXCIgYWx0PVwiU3VydmV5XCIgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3N1cnZleSdcIj4gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9saW5rLnN2Z1wiIGFsdD1cIkludGVyYWN0aXZlQ29udGVudFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuaHRtbC1hcmNoaXZlJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ3RleHQveC11cmwnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9hc3Nlc3NtZW50LnN2Z1wiIGFsdD1cIkFzc2Vzc21lbnRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9qc29uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3F1aXonIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLnN1bmJpcmQucXVlc3Rpb25zZXQnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2ltYWdlLnN2Z1wiIGFsdD1cIkltYWdlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvcG5nJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL2pwZWcnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9jb250ZW50X2NvcHkuc3ZnXCIgY2xhc3M9XCJjb250ZW50aWNvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0PVwiQ291cnNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuZWtzdGVwLmNvbnRlbnQtY29sbGVjdGlvbicgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9zdXJ2ZXknXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9tb2R1bGUuc3ZnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCIgYWx0PVwib2ZmbGluZSBzZXNzaW9uc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vb2ZmbGluZSdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlNUQU5EQUxPTkVfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVzb3VyY2VEdXJhdGlvbiB3cy1tYXQtd2hpdGUtdGV4dCBub2R0cmFuc2xhdGVcIj57e1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50Py5tYXhRdWVzdGlvbnMgfX0ge3sgJ3BsYXllcmJyaWVmLnF1ZXN0aW9ucycgfCB0cmFuc2xhdGUgfFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZWNhc2V9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiEoY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkNPTVBfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5TVEFOREFMT05FX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0UpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXNvdXJjZUR1cmF0aW9uIHdzLW1hdC13aGl0ZS10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjb250ZW50Py5kdXJhdGlvbnx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZXJhcmNoeU1hcERhdGFbY29udGVudD8uaWRlbnRpZmllcl0/LmV4cGVjdGVkRHVyYXRpb24gfHwgMCl8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpcGVEdXJhdGlvblRyYW5zZm9ybTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2htcydcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDxkaXYgY2xhc3M9XCJ0eXBlLWNvbnRhaW5lciByZXNvdXJjZSBtdC0yIHNtOm10LTBcIiAqbmdJZj1cImNvbnRlbnQ/LmNhdGVnb3J5ID09PSAnUmVzb3VyY2UnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJtci0xIGN1c3RvbS1pY29uIHJvdGF0ZS05MFwiPmNhbGxfdG9fYWN0aW9uPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibm9kdHJhbnNsYXRlXCI+UmVzb3VyY2U8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHlwZS1jb250YWluZXIgbW9kdWxlIG10LTIgc206bXQtMFwiICpuZ0lmPVwiY29udGVudD8uY2F0ZWdvcnkgPT09ICdDb2xsZWN0aW9uJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibXItMSBjdXN0b20taWNvbiByb3RhdGUtOTBcIj5jYWxsX3RvX2FjdGlvbjwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5vZHRyYW5zbGF0ZVwiPk1vZHVsZTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0eXBlLWNvbnRhaW5lciBjb3Vyc2UgbXQtMiBzbTptdC0wXCIgKm5nSWY9XCJjb250ZW50Py5jYXRlZ29yeSA9PT0gJ0NvdXJzZSdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1yLTEgY3VzdG9tLWljb24gcm90YXRlLTkwXCI+Y2FsbF90b19hY3Rpb248L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJub2R0cmFuc2xhdGVcIj5Db3Vyc2U8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PiAtLT5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwhLS0gRm9yIGNvdXJzZSBwcm9ncmVzcyB0byBiZSBzaG93biAtLT5cclxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFmb3JQcmV2aWV3ICYmIGNvbnRlbnQ/LmlkZW50aWZpZXIgJiYgZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcilcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENvbXBsZXRpb25TdGF0dXMoY29udGVudD8uaWRlbnRpZmllcikgPT0gMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC0xXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTIgbXItNCAgZmxleCBmbGV4LTEgZmxleC1jb2wgIHByb2dyZXNzLWNvbnRhaW5lclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBqdXN0aWZ5LWVuZCB3LWZ1bGwgXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1hdC1ib2R5LTIgbm9kdHJhbnNsYXRlIFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Z2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcil9fSU8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHdzLXdpZGdldC1jb250ZW50LXByb2dyZXNzIFtjb250ZW50SWRdPVwiY29udGVudD8ucHJvZ3Jlc3NcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb2dyZXNzXT1cImdldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9ncmVzc1R5cGVdPVwiJ3BlcmNlbnRhZ2UnXCIgW2N1c3RvbUNsYXNzTmFtZV09XCIndmlld2VyLXByb2dyZXNzJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3dzLXdpZGdldC1jb250ZW50LXByb2dyZXNzPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cIm1sLTUgY2VydGlmaWNhdGUtYnRuXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnZGlzYWJsZS1idG4nOiBkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZyB8fCBjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIiFkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZyAmJiBkb3dubG9hZENlcnRpZmljYXRlKGNvbnRlbnQ/Lmlzc3VlZENlcnRpZmljYXRlc0lkKTskZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGltZyBzcmM9XCJmdXNpb24tYXNzZXRzL2ltYWdlcy9jZXJ0aWZpY2F0ZS1pY28uc3ZnXCIgd2lkdGg9XCIyNFwiIGhlaWdodD1cIjI0XCI+IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJub2R0cmFuc2xhdGVcIj5DZXJ0aWZpY2F0ZTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIiFkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtbC0yXCI+YXJyb3dfZG93bndhcmQ8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNlbnRlciBmbGV4IGZsZXgtbWlkZGxlIGNlcnRpZmljYXRlLWxvYWRlclwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtc3Bpbm5lciBzdHJva2VXaWR0aD1cIjJcIiBzdHJva2U9XCInd2hpdGUnXCIgY2xhc3M9XCJ3aGl0ZS1zcGlubmVyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RpYW1ldGVyXT1cIjE2XCI+PC9tYXQtc3Bpbm5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2E+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzXCIgW3BlcmNlbnRdPVwiMTAwXCIgW3JhZGl1c109XCIxMlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlV2lkdGhdPVwiM1wiIFtpbm5lclN0cm9rZVdpZHRoXT1cIjNcIiBbc3BhY2VdPVwiLTNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZUNvbG9yXT1cInByb2dyZXNzQ29sb3IoKVwiIFtpbm5lclN0cm9rZUNvbG9yXT1cIidyZ2JhKDAsMCwwLC4xNiknXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYW5pbWF0aW9uXT1cInRydWVcIiBbYW5pbWF0aW9uRHVyYXRpb25dPVwiMzAwXCIgW3Nob3dUaXRsZV09XCJmYWxzZVwiIFtzaG93VW5pdHNdPVwiZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93U3VidGl0bGVdPVwiZmFsc2VcIiBbc2hvd0lubmVyU3Ryb2tlXT1cInRydWVcIiBbY2xvY2t3aXNlXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtiYWNrZ3JvdW5kT3BhY2l0eV09XCIwXCIgW2JhY2tncm91bmRHcmFkaWVudF09XCJmYWxzZVwiIFtiYWNrZ3JvdW5kU3Ryb2tlV2lkdGhdPVwiM1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3daZXJvT3V0ZXJTdHJva2VdPWZhbHNlIFtiYWNrZ3JvdW5kUGFkZGluZ109XCItOVwiIFtzdGFydEZyb21aZXJvXT1cImZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZFBhZGRpbmddPVwiMFwiIFtpbWFnZUhlaWdodF09XCIyNFwiIFtpbWFnZVdpZHRoXT1cIjI0XCIgW3Nob3dCYWNrZ3JvdW5kXT1cImZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VMaW5lY2FwXT1cIididXR0J1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9jaXJjbGUtcHJvZ3Jlc3M+IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENvbXBsZXRpb25TdGF0dXMoY29udGVudD8uaWRlbnRpZmllcikgPCAyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LTFcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMiBtci00ICBmbGV4IGZsZXgtMSBmbGV4LWNvbCAgcHJvZ3Jlc3MtY29udGFpbmVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93IGp1c3RpZnktZW5kIHctZnVsbCB3cy1tYXQtYmxhY2stdGV4dFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtYXQtYm9keS0yICB3cy1tYXQtYmxhY2stdGV4dCBub2R0cmFuc2xhdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2dldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpfX0lPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx3cy13aWRnZXQtY29udGVudC1wcm9ncmVzcyBbY29udGVudElkXT1cImNvbnRlbnQ/LnByb2dyZXNzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9ncmVzc109XCJnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvZ3Jlc3NUeXBlXT1cIidwZXJjZW50YWdlJ1wiIFtjdXN0b21DbGFzc05hbWVdPVwiJ3ZpZXdlci1wcm9ncmVzcydcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC93cy13aWRnZXQtY29udGVudC1wcm9ncmVzcz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJtbC01IGNlcnRpZmljYXRlLWJ0blwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2Rpc2FibGUtYnRuJzogZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgfHwgY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWR9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCIhZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgJiYgZG93bmxvYWRDZXJ0aWZpY2F0ZShjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZCk7JGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDxpbWcgc3JjPVwiZnVzaW9uLWFzc2V0cy9pbWFnZXMvY2VydGlmaWNhdGUtaWNvLnN2Z1wiIHdpZHRoPVwiMjRcIiBoZWlnaHQ9XCIyNFwiPiAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibm9kdHJhbnNsYXRlXCI+Q2VydGlmaWNhdGU8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCIhZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibWwtMlwiPmFycm93X2Rvd253YXJkPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjZW50ZXIgZmxleCBmbGV4LW1pZGRsZSBjZXJ0aWZpY2F0ZS1sb2FkZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNwaW5uZXIgc3Ryb2tlV2lkdGg9XCIyXCIgc3Ryb2tlPVwiJ3doaXRlJ1wiIGNsYXNzPVwid2hpdGUtc3Bpbm5lclwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaWFtZXRlcl09XCIxNlwiPjwvbWF0LXNwaW5uZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgICAgICAgPCEtLSA8ZGl2IGNsYXNzPVwic2VlLWFsbC1jb250YWluZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICA8YSBocmVmPVwiamF2YXNjcmlwdDp2b2lkKDApXCIgcm9sZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJjb250ZW50LnZpZXdDaGlsZHJlbiA9ICFjb250ZW50LnZpZXdDaGlsZHJlbjsgZXhwYW5kQWN0aXZlID0gZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNlZS1hbGwtYnRuIHRhYiBjdXN0b20tY2hldnJvbiBjdXN0b21pY29uXCIgbWF0LWJ1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiIWNvbnRlbnQudmlld0NoaWxkcmVuICYmICFpc01vZHVsZVwiPmtleWJvYXJkX2Fycm93X2Rvd248L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJjb250ZW50LnZpZXdDaGlsZHJlbiAmJiAhaXNNb2R1bGVcIj5rZXlib2FyZF9hcnJvd191cDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIiFjb250ZW50LnZpZXdDaGlsZHJlbiAmJiBpc01vZHVsZVwiPmFkZDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cImNvbnRlbnQudmlld0NoaWxkcmVuICYmIGlzTW9kdWxlXCI+cmVtb3ZlPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICA8L2E+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj4gLS0+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcblxyXG48L25nLWNvbnRhaW5lcj4iXX0=
1
+ import { Component, Input } from '@angular/core';
2
+ import { NsContent } from '../../../../_services/widget-content.model';
3
+ import { viewerRouteGenerator } from '../../../../_services/viewer-route-util';
4
+ import { WsEvents } from '@sunbird-cb/utils-v2';
5
+ import { CertificateDialogComponent } from '../../certificate-dialog/certificate-dialog.component';
6
+ import { animate, style, transition, trigger } from '@angular/animations';
7
+ /* tslint:disable*/
8
+ import _ from 'lodash';
9
+ import moment from 'moment';
10
+ import * as i0 from "@angular/core";
11
+ import * as i1 from "@sunbird-cb/utils-v2";
12
+ import * as i2 from "@angular/material/legacy-dialog";
13
+ import * as i3 from "../../../../services/certificate.service";
14
+ import * as i4 from "../../../../services/app-toc.service";
15
+ import * as i5 from "@sunbird-cb/consumption";
16
+ import * as i6 from "../../../../services/resource-download-helper.service";
17
+ import * as i7 from "@angular/material/legacy-snack-bar";
18
+ import * as i8 from "@angular/common";
19
+ import * as i9 from "@angular/router";
20
+ import * as i10 from "@angular/material/icon";
21
+ import * as i11 from "@angular/material/menu";
22
+ import * as i12 from "@angular/material/progress-spinner";
23
+ import * as i13 from "../../content-progress/content-progress.component";
24
+ import * as i14 from "ng-circle-progress";
25
+ import * as i15 from "@angular/material/legacy-tooltip";
26
+ import * as i16 from "@ngx-translate/core";
27
+ import * as i17 from "../pipes/truncate.pipe";
28
+ export class AppTocContentCardV2Component {
29
+ constructor(events, dialog, renderer, certificateService, appTocSvc, contentLangSvc, resourceDownloadHelperSvc, configSvc, snackBar) {
30
+ this.events = events;
31
+ this.dialog = dialog;
32
+ this.renderer = renderer;
33
+ this.certificateService = certificateService;
34
+ this.appTocSvc = appTocSvc;
35
+ this.contentLangSvc = contentLangSvc;
36
+ this.resourceDownloadHelperSvc = resourceDownloadHelperSvc;
37
+ this.configSvc = configSvc;
38
+ this.snackBar = snackBar;
39
+ this.content = null;
40
+ this.expandAll = false;
41
+ this.forPreview = false;
42
+ this.componentName = 'toc';
43
+ this.expandActive = true;
44
+ this.hierarchyMapData = {};
45
+ this.batchData = null;
46
+ this.isPreAssessment = false;
47
+ this.baseContentReadData = null;
48
+ this.mlCourse = null;
49
+ this.parentMilestoneLocked = false; // Passed from parent when inside a locked milestone
50
+ this.hasContentStructure = false;
51
+ this.downloadCertificateLoading = false;
52
+ this.enumContentTypes = NsContent.EDisplayContentTypes;
53
+ this.contentStructure = {
54
+ assessment: 0,
55
+ finalTest: 0,
56
+ course: 0,
57
+ handsOn: 0,
58
+ interactiveVideo: 0,
59
+ learningModule: 0,
60
+ other: 0,
61
+ pdf: 0,
62
+ survey: 0,
63
+ podcast: 0,
64
+ practiceTest: 0,
65
+ quiz: 0,
66
+ video: 0,
67
+ webModule: 0,
68
+ webPage: 0,
69
+ youtube: 0,
70
+ interactivecontent: 0,
71
+ offlineSession: 0,
72
+ };
73
+ this.defaultThumbnail = '';
74
+ this.viewChildren = false;
75
+ this.primaryCategory = NsContent.EPrimaryCategory;
76
+ this.pageScrollSubscription = null;
77
+ this.hashmapUpdatedSubscription = null;
78
+ this.achievementLoading = false;
79
+ // Cached computed properties for performance optimization
80
+ this._cachedIsCollection = false;
81
+ this._cachedIsModule = false;
82
+ this._cachedIsResource = false;
83
+ this._cachedIsMilestone = false;
84
+ this._cachedIsMilestoneLocked = false;
85
+ this._cachedIsParentMilestoneLocked = false;
86
+ this._cachedIsContentUnlocked = true;
87
+ this._cachedCheckForCuratedProgram = false;
88
+ this._cachedIsMilestoneAssessment = false;
89
+ this._cachedIsMilestoneAssessmentLocked = false;
90
+ this._cachedResourceLink = { url: '', queryParams: {} };
91
+ this._cacheInitialized = false;
92
+ }
93
+ ngOnInit() {
94
+ this.evaluateImmediateChildrenStructure();
95
+ this.initializeComputedProperties();
96
+ // this.route.data.subscribe(data => {
97
+ // this.defaultThumbnail = data.configData.data.logos.defaultContent
98
+ // }
99
+ // )
100
+ this.resourceScroll();
101
+ // Subscribe to hashmap updates to recompute cached properties when progress changes
102
+ this.hashmapUpdatedSubscription = this.appTocSvc.hashmapUpdated$.subscribe((update) => {
103
+ if (update && update.hashmap) {
104
+ console.log('🔄 Hashmap updated, recomputing cached properties for:', this.content?.identifier);
105
+ // IMPORTANT: Update hierarchyMapData with the latest hashmap from the service
106
+ // This ensures the component uses the updated data, not the stale @Input reference
107
+ this.hierarchyMapData = update.hashmap;
108
+ this.computeAllCachedProperties();
109
+ }
110
+ });
111
+ }
112
+ /**
113
+ * Initialize all computed properties once to avoid expensive getter calculations
114
+ * on every change detection cycle
115
+ */
116
+ initializeComputedProperties() {
117
+ this.computeAllCachedProperties();
118
+ }
119
+ /**
120
+ * Compute all cached properties at once for performance optimization
121
+ */
122
+ computeAllCachedProperties() {
123
+ if (!this.content) {
124
+ this._cacheInitialized = false;
125
+ return;
126
+ }
127
+ const contentId = this.content.identifier;
128
+ const hashData = this.hierarchyMapData && this.hierarchyMapData[contentId];
129
+ // Use hashmap data if available for pre-computed values
130
+ if (hashData) {
131
+ this._cachedIsCollection = hashData.isCollection !== undefined ?
132
+ hashData.isCollection : this.content.mimeType === NsContent.EMimeTypes.COLLECTION;
133
+ this._cachedIsModule = hashData.isModule !== undefined ?
134
+ hashData.isModule : this.content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
135
+ this._cachedIsResource = hashData.isResource !== undefined ?
136
+ hashData.isResource : this.computeIsResource();
137
+ this._cachedIsMilestone = hashData.isMilestone !== undefined ?
138
+ hashData.isMilestone : this.computeIsMilestone();
139
+ this._cachedIsMilestoneLocked = hashData.computedIsLocked !== undefined ?
140
+ hashData.computedIsLocked : this.computeIsMilestoneLocked();
141
+ this._cachedIsParentMilestoneLocked = hashData.isParentMilestoneLocked !== undefined ?
142
+ hashData.isParentMilestoneLocked : this.computeIsParentMilestoneLocked();
143
+ }
144
+ else {
145
+ // Fallback to direct computation if hashmap not available
146
+ this._cachedIsCollection = this.content.mimeType === NsContent.EMimeTypes.COLLECTION;
147
+ this._cachedIsModule = this.content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
148
+ this._cachedIsResource = this.computeIsResource();
149
+ this._cachedIsMilestone = this.computeIsMilestone();
150
+ this._cachedIsMilestoneLocked = this.computeIsMilestoneLocked();
151
+ this._cachedIsParentMilestoneLocked = this.computeIsParentMilestoneLocked();
152
+ }
153
+ this._cachedCheckForCuratedProgram = this.computeCheckForCuratedProgram();
154
+ this._cachedIsContentUnlocked = this.computeIsContentUnlocked();
155
+ this._cachedIsMilestoneAssessment = this.computeIsMilestoneAssessment();
156
+ this._cachedIsMilestoneAssessmentLocked = this.computeIsMilestoneAssessmentLocked();
157
+ this._cachedResourceLink = this.computeResourceLink();
158
+ this._cacheInitialized = true;
159
+ }
160
+ computeIsResource() {
161
+ if (!this.content)
162
+ return false;
163
+ return (this.content.primaryCategory === NsContent.EPrimaryCategory.RESOURCE ||
164
+ this.content.primaryCategory === NsContent.EPrimaryCategory.PRACTICE_RESOURCE ||
165
+ this.content.primaryCategory === NsContent.EPrimaryCategory.FINAL_ASSESSMENT ||
166
+ this.content.primaryCategory === NsContent.EPrimaryCategory.COMP_ASSESSMENT);
167
+ }
168
+ computeIsMilestone() {
169
+ if (!this.content)
170
+ return false;
171
+ const primaryCat = this.content.primaryCategory;
172
+ const courseCat = this.content.courseCategory;
173
+ return primaryCat === 'Milestone' || courseCat === 'Milestone';
174
+ }
175
+ computeCheckForCuratedProgram() {
176
+ if (this.content && this.content.parent && this.hierarchyMapData && this.hierarchyMapData[this.content.parent]) {
177
+ const parentData = this.hierarchyMapData[this.content.parent];
178
+ return parentData && parentData.primaryCategory === NsContent.EPrimaryCategory.CURATED_PROGRAM &&
179
+ parentData.compatibilityLevel >= 5 &&
180
+ parentData.contextLockingType === NsContent.EContextLockingType.COURSE_ASSESSMENT_ONLY;
181
+ }
182
+ return false;
183
+ }
184
+ computeIsContentUnlocked() {
185
+ if (this._cachedCheckForCuratedProgram) {
186
+ if (this.content && this.content.parent && this.hierarchyMapData && this.hierarchyMapData[this.content.parent]) {
187
+ const parentData = this.hierarchyMapData[this.content.parent];
188
+ let completedLeafNodes = [];
189
+ parentData.leafNodes.forEach((_ele) => {
190
+ if (this.hierarchyMapData && this.hierarchyMapData[_ele]) {
191
+ const childData = this.hierarchyMapData[_ele];
192
+ if (childData && childData.completionStatus === 2) {
193
+ completedLeafNodes.push(childData);
194
+ }
195
+ }
196
+ });
197
+ return completedLeafNodes.length >= parentData.leafNodesCount - 1;
198
+ }
199
+ return false;
200
+ }
201
+ return true;
202
+ }
203
+ computeResourceLink() {
204
+ if (this.content) {
205
+ let mimeType = '';
206
+ if (this.content && this.content.courseCategory === 'Pre Enrolment Assessment' &&
207
+ this.content.mimeType === 'application/vnd.ekstep.content-collection') {
208
+ mimeType = 'application/vnd.sunbird.questionset';
209
+ this.content.mimeType = NsContent.EMimeTypes.FINAL_ASSESSMENT;
210
+ }
211
+ else {
212
+ mimeType = this.content.mimeType;
213
+ }
214
+ const selectedLanguage = this.mlCourse ? this.contentLangSvc.getSelectedLanguage(this.mlCourse) : undefined;
215
+ return viewerRouteGenerator(this.content.identifier, mimeType, this.baseContentReadData?.identifier || this.rootId, this.baseContentReadData?.contentType || this.rootContentType, this.forPreview, this.content.primaryCategory, this.batchId, this.content?.name || this.baseContentReadData?.name, (selectedLanguage ? selectedLanguage.langId : null), (selectedLanguage ? selectedLanguage.identifier : null));
216
+ }
217
+ return { url: '', queryParams: {} };
218
+ }
219
+ computeIsMilestoneLocked() {
220
+ // Only apply milestone locking for Learning Pathway content
221
+ if (!this.baseContentReadData || this.baseContentReadData.courseCategory !== 'Learning Pathway') {
222
+ return false;
223
+ }
224
+ if (!this.content) {
225
+ return false;
226
+ }
227
+ // Check if current content is a Milestone
228
+ if (!this._cachedIsMilestone && !this.computeIsMilestone()) {
229
+ return false;
230
+ }
231
+ // Check if hashmap has pre-computed locking status (preferred - computed by service)
232
+ const hashData = this.hierarchyMapData && this.hierarchyMapData[this.content.identifier];
233
+ console.log(`computeIsMilestoneLocked for ${this.content.identifier} (${this.content.name}):`, {
234
+ hashData,
235
+ computedIsLocked: hashData?.computedIsLocked,
236
+ contentIsLocked: this.content.isLocked
237
+ });
238
+ if (hashData && hashData.computedIsLocked !== undefined) {
239
+ return hashData.computedIsLocked;
240
+ }
241
+ // If milestone has isLocked flag explicitly set to false, it's unlocked
242
+ if (this.content.isLocked === false) {
243
+ return false;
244
+ }
245
+ // Fallback: All milestones are locked by default until computed otherwise
246
+ // This ensures proper locking until the hashmap is updated with progress
247
+ return true;
248
+ }
249
+ computeIsParentMilestoneLocked() {
250
+ if (this.parentMilestoneLocked) {
251
+ return true;
252
+ }
253
+ if (!this.baseContentReadData || this.baseContentReadData.courseCategory !== 'Learning Pathway') {
254
+ return false;
255
+ }
256
+ if (!this.content || !this.hierarchyMapData) {
257
+ return false;
258
+ }
259
+ // Check hashmap for pre-computed value
260
+ const hashData = this.hierarchyMapData[this.content.identifier];
261
+ if (hashData && hashData.isParentMilestoneLocked !== undefined) {
262
+ return hashData.isParentMilestoneLocked;
263
+ }
264
+ // Traverse up the hierarchy to find if any ancestor is a locked Milestone
265
+ let currentParentId = this.content.parent;
266
+ const maxDepth = 5;
267
+ let depth = 0;
268
+ while (currentParentId && depth < maxDepth) {
269
+ const parentData = this.hierarchyMapData[currentParentId];
270
+ if (parentData) {
271
+ if ((parentData.isMilestone || parentData.primaryCategory === 'Milestone' || parentData.courseCategory === 'Milestone') &&
272
+ (parentData.computedIsLocked || parentData.isLocked)) {
273
+ return true;
274
+ }
275
+ currentParentId = parentData.parent;
276
+ }
277
+ else {
278
+ break;
279
+ }
280
+ depth++;
281
+ }
282
+ return false;
283
+ }
284
+ /**
285
+ * Check if current content is a MILESTONE assessment (DIRECT child of a Milestone)
286
+ * IMPORTANT: This should NOT return true for course assessments inside courses within milestones
287
+ * Only assessments that are direct children of milestones should be locked by milestone logic
288
+ */
289
+ computeIsMilestoneAssessment() {
290
+ if (!this.baseContentReadData || this.baseContentReadData.courseCategory !== 'Learning Pathway') {
291
+ return false;
292
+ }
293
+ if (!this.content || !this.hierarchyMapData) {
294
+ return false;
295
+ }
296
+ // Check if this is an assessment type
297
+ // Note: FINAL_ASSESSMENT maps to 'Course Assessment' in the enum, not 'Final Assessment'
298
+ const isAssessment = this.content.primaryCategory === 'Course Assessment' ||
299
+ this.content.primaryCategory === 'Standalone Assessment' ||
300
+ this.content.mimeType === 'application/vnd.sunbird.questionset' ||
301
+ this.content.mimeType === 'application/quiz';
302
+ if (!isAssessment) {
303
+ return false;
304
+ }
305
+ // IMPORTANT: Only return true if the DIRECT parent is a milestone
306
+ // Assessments inside courses (grandchildren of milestones) should NOT be locked by milestone logic
307
+ // They follow their own course's locking rules
308
+ // Get the parent from hashmap (which we fixed to track correct parent-child relationships)
309
+ // or fallback to content.parent if hashmap entry doesn't exist
310
+ const contentHashData = this.hierarchyMapData[this.content.identifier];
311
+ const parentId = contentHashData?.parent || this.content.parent;
312
+ console.log(`🔍 computeIsMilestoneAssessment for "${this.content.name}" (${this.content.identifier}):`, {
313
+ contentId: this.content.identifier,
314
+ primaryCategory: this.content.primaryCategory,
315
+ mimeType: this.content.mimeType,
316
+ contentParent: this.content.parent,
317
+ hashmapParent: contentHashData?.parent,
318
+ resolvedParentId: parentId,
319
+ hasParentData: !!this.hierarchyMapData[parentId]
320
+ });
321
+ if (parentId && this.hierarchyMapData[parentId]) {
322
+ const parentData = this.hierarchyMapData[parentId];
323
+ console.log(` Parent details:`, {
324
+ parentId: parentId,
325
+ parentName: parentData?.name,
326
+ parentPrimaryCategory: parentData?.primaryCategory,
327
+ parentIsMilestone: parentData?.isMilestone,
328
+ parentCourseCategory: parentData?.courseCategory,
329
+ });
330
+ // Check if DIRECT parent is a milestone - ONLY this case
331
+ const isParentMilestone = parentData.isMilestone ||
332
+ parentData.primaryCategory === 'Milestone' ||
333
+ parentData.courseCategory === 'Milestone';
334
+ if (isParentMilestone) {
335
+ console.log(` ✅ Result: IS a milestone assessment (direct child of milestone)`);
336
+ return true;
337
+ }
338
+ console.log(` ❌ Result: NOT a milestone assessment (parent is ${parentData.primaryCategory}, not a Milestone)`);
339
+ // DO NOT check grandparent - course assessments inside courses within milestones
340
+ // should NOT be treated as milestone assessments
341
+ return false;
342
+ }
343
+ else {
344
+ console.log(` ⚠️ No parent data found for ${parentId}`);
345
+ }
346
+ return false;
347
+ }
348
+ /**
349
+ * Check if milestone assessment should be locked
350
+ * Assessment is locked if:
351
+ * 1. It's an assessment that is a DIRECT child of a milestone
352
+ * 2. The parent milestone is unlocked (otherwise handled by parent milestone lock)
353
+ * 3. NOT all mandatory courses in the same milestone are completed
354
+ */
355
+ computeIsMilestoneAssessmentLocked() {
356
+ // Only apply to assessments that are DIRECT children of milestones
357
+ const isMilestoneAssessment = this._cachedIsMilestoneAssessment || this.computeIsMilestoneAssessment();
358
+ console.log(`🔒 computeIsMilestoneAssessmentLocked for "${this.content?.name}":`, {
359
+ isMilestoneAssessment,
360
+ _cachedIsMilestoneAssessment: this._cachedIsMilestoneAssessment,
361
+ });
362
+ if (!isMilestoneAssessment) {
363
+ console.log(`🔓 "${this.content?.name}" NOT locked - not a milestone assessment`);
364
+ return false;
365
+ }
366
+ // Check if hashmap has pre-computed assessment locking status
367
+ const hashData = this.hierarchyMapData && this.hierarchyMapData[this.content?.identifier || ''];
368
+ if (hashData && hashData.isAssessmentLocked !== undefined) {
369
+ return hashData.isAssessmentLocked;
370
+ }
371
+ // If already completed, don't lock
372
+ if (this.content && (this.content.completionStatus === 2 ||
373
+ (this.content.completionPercentage && this.content.completionPercentage >= 100))) {
374
+ return false;
375
+ }
376
+ // For milestone assessments, the parent IS the milestone (verified by computeIsMilestoneAssessment)
377
+ // Use hashmap's parent which has correct parent-child relationships
378
+ const contentHashData = this.hierarchyMapData && this.hierarchyMapData[this.content?.identifier || ''];
379
+ const milestoneId = contentHashData?.parent || this.content?.parent;
380
+ if (!milestoneId || !this.hierarchyMapData) {
381
+ return false;
382
+ }
383
+ const milestone = this.hierarchyMapData[milestoneId];
384
+ if (!milestone) {
385
+ return false;
386
+ }
387
+ // If the parent milestone itself is locked, don't add additional locking
388
+ // (the parent lock will handle it)
389
+ if (milestone.computedIsLocked || milestone.isLocked) {
390
+ return false;
391
+ }
392
+ // Check if all mandatory COURSES in the milestone are completed
393
+ // Note: Only checking courses that are direct children of the milestone
394
+ let mandatoryCount = 0;
395
+ let completedMandatoryCount = 0;
396
+ for (const key of Object.keys(this.hierarchyMapData)) {
397
+ const item = this.hierarchyMapData[key];
398
+ // Only check items that are direct children of this milestone
399
+ if (item.parent !== milestoneId)
400
+ continue;
401
+ // Only count courses (not assessments, not other types)
402
+ if (item.primaryCategory !== 'Course' && !item.isCollection)
403
+ continue;
404
+ // Skip if this is an assessment
405
+ const isItemAssessment = item.primaryCategory === 'Course Assessment' ||
406
+ item.primaryCategory === 'Final Assessment' ||
407
+ item.primaryCategory === 'Standalone Assessment' ||
408
+ item.mimeType === 'application/vnd.sunbird.questionset';
409
+ if (isItemAssessment)
410
+ continue;
411
+ // By default, courses are mandatory unless explicitly marked as optional
412
+ if (item.isMandatory !== false) {
413
+ mandatoryCount++;
414
+ const isCompleted = item.completionStatus === 2 || item.status === 2 ||
415
+ item.completionPercentage >= 100 || item.progress >= 100;
416
+ if (isCompleted) {
417
+ completedMandatoryCount++;
418
+ }
419
+ }
420
+ }
421
+ // If there are no mandatory courses, assessment is unlocked
422
+ if (mandatoryCount === 0) {
423
+ return false;
424
+ }
425
+ // Lock assessment if not all mandatory courses are completed
426
+ const allMandatoryComplete = completedMandatoryCount >= mandatoryCount;
427
+ return !allMandatoryComplete;
428
+ }
429
+ // FOR RIGHT SIDE RESOURCE SCROLL ON TOC PAGE
430
+ resourceScroll() {
431
+ this.pageScrollSubscription = this.appTocSvc.updatePageScroll.subscribe((value) => {
432
+ if (value) {
433
+ setTimeout(() => {
434
+ this.scrollView();
435
+ }, 700);
436
+ }
437
+ });
438
+ }
439
+ // TO UPDATE RESOURCE BEHAVOUR SUBJECT FOR RESOURCE SCROLL
440
+ changeResource() {
441
+ this.appTocSvc.getPageScroll.next(true);
442
+ }
443
+ ngOnChanges(changes) {
444
+ let shouldRecomputeCache = false;
445
+ for (const property in changes) {
446
+ if (property === 'expandAll') {
447
+ this.viewChildren = this.expandAll;
448
+ }
449
+ if (property === 'pathSet' && changes['pathSet']) {
450
+ let currentValue = changes['pathSet'].currentValue;
451
+ let previousValue = changes['pathSet'].previousValue;
452
+ if (currentValue && previousValue) {
453
+ const eqSet = (xs, ys) => xs.size === ys.size &&
454
+ [...xs].every((x) => ys.has(x));
455
+ if (!eqSet(previousValue, currentValue)) { }
456
+ }
457
+ // if(previousValue === undefined){
458
+ // setTimeout(()=>{
459
+ // },700)
460
+ // }
461
+ }
462
+ // this.appTocSvc.getPageScroll.next(true)
463
+ if (property === 'hierarchyMapData') {
464
+ if (_.isEmpty(changes['hierarchyMapData'].currentValue)) {
465
+ // this.loadingOverallPRogress = true
466
+ }
467
+ else {
468
+ if (this.content) {
469
+ this.updateChildParentMap(this.content.identifier);
470
+ }
471
+ shouldRecomputeCache = true;
472
+ }
473
+ }
474
+ // Recompute cache when critical inputs change
475
+ if (property === 'content' || property === 'baseContentReadData' ||
476
+ property === 'batchId' || property === 'forPreview' ||
477
+ property === 'parentMilestoneLocked' || property === 'mlCourse') {
478
+ shouldRecomputeCache = true;
479
+ }
480
+ }
481
+ // Recompute all cached properties if needed
482
+ if (shouldRecomputeCache) {
483
+ this.computeAllCachedProperties();
484
+ }
485
+ // console.log('pre assessment content---', this.content)
486
+ // console.log('this.hierarchyMapData---', this.hierarchyMapData)
487
+ }
488
+ check(content) {
489
+ if (this.expandActive) {
490
+ content.viewChildren = this.pathSet && this.pathSet.has(content.identifier) || content.viewChildren;
491
+ }
492
+ return content.viewChildren;
493
+ }
494
+ get isCollection() {
495
+ if (this._cacheInitialized) {
496
+ return this._cachedIsCollection;
497
+ }
498
+ if (this.content) {
499
+ return this.content.mimeType === NsContent.EMimeTypes.COLLECTION;
500
+ }
501
+ return false;
502
+ }
503
+ get isModule() {
504
+ if (this._cacheInitialized) {
505
+ return this._cachedIsModule;
506
+ }
507
+ if (this.content) {
508
+ return this.content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
509
+ }
510
+ return false;
511
+ }
512
+ checkModule(content) {
513
+ if (content) {
514
+ return content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
515
+ }
516
+ return false;
517
+ }
518
+ checkIsModule(content) {
519
+ if (content) {
520
+ return content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
521
+ }
522
+ return false;
523
+ }
524
+ get isBatchInProgess() {
525
+ if (this.batchData && (this.batchData.content && this.batchData.content.length) && this.batchData.enrolled) {
526
+ const batchData = this.batchData.content[0];
527
+ if (batchData && batchData.endDate) {
528
+ const now = moment().format('YYYY-MM-DD');
529
+ const startDate = moment(batchData.startDate).format('YYYY-MM-DD');
530
+ const endDate = batchData.endDate ? moment(batchData.endDate).format('YYYY-MM-DD') : now;
531
+ return (
532
+ // batch.status &&
533
+ moment(startDate).isSameOrBefore(now)
534
+ && moment(endDate).isSameOrAfter(now));
535
+ }
536
+ return true;
537
+ }
538
+ return false;
539
+ }
540
+ get isResource() {
541
+ if (this._cacheInitialized) {
542
+ return this._cachedIsResource;
543
+ }
544
+ return this.computeIsResource();
545
+ }
546
+ get resourceLink() {
547
+ if (this._cacheInitialized) {
548
+ return this._cachedResourceLink;
549
+ }
550
+ return this.computeResourceLink();
551
+ }
552
+ progressColor() {
553
+ // if (this.currentProgress <= 30) {
554
+ // return '#D13924'
555
+ // } if (this.currentProgress > 30 && this.currentProgress <= 70) {
556
+ // return '#E99E38'
557
+ // }
558
+ // if (this.currentProgress > 70 && this.currentProgress <= 100) {
559
+ // return '#1D8923'
560
+ // }
561
+ return '#1D8923';
562
+ }
563
+ progressColor2() {
564
+ return '#f27d00';
565
+ }
566
+ evaluateImmediateChildrenStructure() {
567
+ if (this.content && this.content.children && this.content.children.length) {
568
+ this.content.children.forEach((child) => {
569
+ if (child.primaryCategory === NsContent.EPrimaryCategory.COURSE) {
570
+ this.contentStructure.course += 1;
571
+ }
572
+ else if (child.primaryCategory === NsContent.EPrimaryCategory.KNOWLEDGE_ARTIFACT) {
573
+ this.contentStructure.other += 1;
574
+ }
575
+ else if (child.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
576
+ this.contentStructure.learningModule += 1;
577
+ }
578
+ else if (child.primaryCategory === NsContent.EPrimaryCategory.OFFLINE_SESSION) {
579
+ this.contentStructure.offlineSession += 1;
580
+ }
581
+ else if (child.primaryCategory === NsContent.EPrimaryCategory.RESOURCE) {
582
+ switch (child.mimeType) {
583
+ case NsContent.EMimeTypes.HANDS_ON:
584
+ this.contentStructure.handsOn += 1;
585
+ break;
586
+ case NsContent.EMimeTypes.MP3:
587
+ this.contentStructure.podcast += 1;
588
+ break;
589
+ case NsContent.EMimeTypes.MP4:
590
+ case NsContent.EMimeTypes.M3U8:
591
+ this.contentStructure.video += 1;
592
+ break;
593
+ case NsContent.EMimeTypes.INTERACTION:
594
+ this.contentStructure.interactiveVideo += 1;
595
+ break;
596
+ case NsContent.EMimeTypes.PDF:
597
+ this.contentStructure.pdf += 1;
598
+ break;
599
+ case NsContent.EMimeTypes.OFFLINE_SESSION:
600
+ this.contentStructure.offlineSession += 1;
601
+ break;
602
+ case NsContent.EMimeTypes.SURVEY:
603
+ this.contentStructure.survey += 1;
604
+ break;
605
+ case NsContent.EMimeTypes.HTML:
606
+ this.contentStructure.webPage += 1;
607
+ break;
608
+ case NsContent.EMimeTypes.QUIZ:
609
+ if (child.resourceType === 'Assessment') {
610
+ this.contentStructure.assessment += 1;
611
+ }
612
+ else {
613
+ this.contentStructure.quiz += 1;
614
+ }
615
+ break;
616
+ case NsContent.EMimeTypes.PRACTICE_RESOURCE:
617
+ // case NsContent.EMimeTypes.FINAL_ASSESSMENT:
618
+ // case NsContent.EMimeTypes.PRACTICE_RESOURCE:
619
+ this.contentStructure.practiceTest += 1;
620
+ break;
621
+ case NsContent.EMimeTypes.WEB_MODULE:
622
+ this.contentStructure.webModule += 1;
623
+ break;
624
+ case NsContent.EMimeTypes.YOUTUBE:
625
+ this.contentStructure.youtube += 1;
626
+ break;
627
+ default:
628
+ this.contentStructure.other += 1;
629
+ break;
630
+ }
631
+ }
632
+ });
633
+ }
634
+ for (const key in this.contentStructure) {
635
+ if (this.contentStructure[key] > 0) {
636
+ this.hasContentStructure = true;
637
+ }
638
+ }
639
+ }
640
+ get contextPath() {
641
+ return {
642
+ contextId: this.rootId,
643
+ contextPath: this.rootContentType,
644
+ batchId: this.batchId,
645
+ };
646
+ }
647
+ contentTrackBy(_index, content) {
648
+ if (!content) {
649
+ return null;
650
+ }
651
+ return content.identifier;
652
+ }
653
+ raiseTelemetry() {
654
+ // if (this.forPreview) { return }
655
+ if (this.content) {
656
+ this.events.raiseInteractTelemetry({
657
+ type: 'click',
658
+ subType: `card-tocContentCard`,
659
+ // id: this.content.identifier || '',
660
+ }, {
661
+ // contentId: this.content.identifier || '',
662
+ // contentType: this.content.primaryCategory,
663
+ id: this.content.identifier || '',
664
+ type: this.content.primaryCategory,
665
+ rollup: {
666
+ l1: this.rootId || '',
667
+ },
668
+ ver: `${this.content.version}${''}`,
669
+ }, {
670
+ pageIdExt: `${_.camelCase(this.content.primaryCategory)}-card`,
671
+ module: _.camelCase(this.content.primaryCategory),
672
+ });
673
+ }
674
+ }
675
+ get isAllowed() {
676
+ if (this.content) {
677
+ return !(NsContent.UN_SUPPORTED_DATA_TYPES_FOR_NON_BATCH_USERS.indexOf(this.content.mimeType) >= 0);
678
+ }
679
+ return false;
680
+ }
681
+ get isEnabled() {
682
+ return true;
683
+ }
684
+ get isEnrolled() {
685
+ // Check both batchId and batchData.enrolled to support Learning Pathways
686
+ // where batchId might not be directly set but user is enrolled in courses within the pathway
687
+ return this.batchId ? true : (this.batchData?.enrolled || false);
688
+ }
689
+ updateChildParentMap(identifier) {
690
+ if (this.hierarchyMapData && this.hierarchyMapData[identifier]) {
691
+ let localContentData = this.hierarchyMapData[identifier];
692
+ if (!(localContentData.primaryCategory === NsContent.EPrimaryCategory.RESOURCE
693
+ || localContentData.primaryCategory === NsContent.EPrimaryCategory.PRACTICE_RESOURCE
694
+ || localContentData.primaryCategory === NsContent.EPrimaryCategory.FINAL_ASSESSMENT
695
+ || localContentData.primaryCategory === NsContent.EPrimaryCategory.COMP_ASSESSMENT)) {
696
+ // real percent logic
697
+ // const total = localContentData.leafNodes.reduce((sum: number, childId: string) => {
698
+ // return sum + Number(this.hierarchyMapData[childId].completionPercentage || 0)
699
+ // }, 0)
700
+ // console.log('total ', total)
701
+ // if(total > 0) {
702
+ // this.hierarchyMapData[identifier]['completionPercentage'] = total / _.toInteger(_.get(this.hierarchyMapData[identifier], 'leafNodesCount'))
703
+ // }
704
+ if (localContentData.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
705
+ this.hierarchyMapData[identifier]['duration'] = this.hierarchyMapData[identifier].leafNodes.reduce((sum, childID) => {
706
+ if (this.hierarchyMapData && this.hierarchyMapData[childID]) {
707
+ return sum + Number(this.hierarchyMapData[childID].duration || this.hierarchyMapData[childID].expectedDuration || 0);
708
+ }
709
+ }, 0);
710
+ }
711
+ // tslint:disable
712
+ const completedItems = _.filter(this.hierarchyMapData[identifier].leafNodes, r => (this.hierarchyMapData[r] && (this.hierarchyMapData[r].completionStatus === 2 || this.hierarchyMapData[r].completionPercentage === 100)));
713
+ const totalCount = _.toInteger(_.get(this.hierarchyMapData[identifier], 'leafNodesCount')) || 1;
714
+ this.hierarchyMapData[identifier]['completionPercentage'] = Number(((completedItems.length / totalCount) * 100).toFixed());
715
+ this.hierarchyMapData[identifier]['completionStatus'] = (this.hierarchyMapData[identifier].completionPercentage >= 100) ? 2 : 1;
716
+ }
717
+ return this.hierarchyMapData[identifier];
718
+ }
719
+ return '';
720
+ }
721
+ getCompletionPercentage(identifier) {
722
+ // console.log('getCompletionPercentage', identifier)
723
+ // console.log('this.hierarchyMapData[identifier] : ', this.hierarchyMapData[identifier])
724
+ // const item = this.updateChildParentMap(identifier)
725
+ let percent = this.hierarchyMapData && this.hierarchyMapData[identifier] && this.hierarchyMapData[identifier].completionPercentage || 0;
726
+ return this.roundIfDecimal(percent);
727
+ }
728
+ roundIfDecimal(value) {
729
+ if (!Number.isInteger(value)) {
730
+ return parseFloat(value.toFixed(2));
731
+ }
732
+ return value;
733
+ }
734
+ getCompletionStatus(identifier) {
735
+ // console.log('getCompletionStatus')
736
+ // const item = this.updateChildParentMap(identifier)
737
+ return this.hierarchyMapData && this.hierarchyMapData[identifier] && this.hierarchyMapData[identifier].completionStatus;
738
+ }
739
+ openCertificateDialog(certData) {
740
+ const cet = certData;
741
+ this.dialog.open(CertificateDialogComponent, {
742
+ // height: '400px',
743
+ width: '1300px',
744
+ data: { cet },
745
+ // panelClass: 'custom-dialog-container',
746
+ });
747
+ }
748
+ scrollView() {
749
+ try {
750
+ let errorField = this.renderer.selectRootElement('.resource-container .resource-active');
751
+ if (errorField) {
752
+ errorField.scrollIntoView({ behavior: "smooth", block: "start", inline: "nearest" });
753
+ }
754
+ if (this.componentName === 'toc') {
755
+ if (errorField) {
756
+ const rect = errorField.getBoundingClientRect();
757
+ if (rect.top - 420 > 0) {
758
+ window.scroll(420, rect.top - 148);
759
+ }
760
+ }
761
+ }
762
+ setTimeout(() => {
763
+ this.appTocSvc.getPageScroll.next(false);
764
+ }, 700);
765
+ // else {
766
+ // errorField.scrollIntoView({ behavior: "smooth", block: "start", inline: "nearest" });
767
+ // const rect = errorField.getBoundingClientRect();
768
+ // errorField.scroll(0,rect.top-56)
769
+ // }
770
+ }
771
+ catch (err) {
772
+ }
773
+ }
774
+ downloadCertificate(certificateData) {
775
+ this.events.raiseInteractTelemetry({
776
+ type: WsEvents.EnumInteractTypes.CLICK,
777
+ id: 'view-certificate',
778
+ subType: WsEvents.EnumInteractSubTypes.CERTIFICATE,
779
+ }, {
780
+ id: certificateData,
781
+ type: WsEvents.EnumInteractSubTypes.CERTIFICATE,
782
+ });
783
+ if (certificateData) {
784
+ this.downloadCertificateLoading = true;
785
+ let certData = certificateData;
786
+ this.certificateService.downloadCertificate_v2(certData).subscribe((res) => {
787
+ this.downloadCertificateLoading = false;
788
+ const cet = res.result.printUri;
789
+ this.dialog.open(CertificateDialogComponent, {
790
+ width: '1300px',
791
+ data: { cet, certId: certData.identifier },
792
+ });
793
+ });
794
+ }
795
+ else {
796
+ this.downloadCertificateLoading = false;
797
+ }
798
+ }
799
+ ngOnDestroy() {
800
+ if (this.hashmapUpdatedSubscription) {
801
+ this.hashmapUpdatedSubscription.unsubscribe();
802
+ }
803
+ if (this.pageScrollSubscription) {
804
+ this.pageScrollSubscription.unsubscribe();
805
+ }
806
+ }
807
+ get checkForCuratedProgram() {
808
+ if (this._cacheInitialized) {
809
+ return this._cachedCheckForCuratedProgram;
810
+ }
811
+ return this.computeCheckForCuratedProgram();
812
+ }
813
+ get isContentUnlocked() {
814
+ if (this._cacheInitialized) {
815
+ return this._cachedIsContentUnlocked;
816
+ }
817
+ return this.computeIsContentUnlocked();
818
+ }
819
+ get isParentMilestoneLocked() {
820
+ if (this._cacheInitialized) {
821
+ return this._cachedIsParentMilestoneLocked;
822
+ }
823
+ return this.computeIsParentMilestoneLocked();
824
+ }
825
+ get isMilestoneLocked() {
826
+ if (this._cacheInitialized) {
827
+ return this._cachedIsMilestoneLocked;
828
+ }
829
+ return this.computeIsMilestoneLocked();
830
+ }
831
+ get isMilestoneAssessment() {
832
+ if (this._cacheInitialized) {
833
+ return this._cachedIsMilestoneAssessment;
834
+ }
835
+ return this.computeIsMilestoneAssessment();
836
+ }
837
+ get isMilestoneAssessmentLocked() {
838
+ if (this._cacheInitialized) {
839
+ return this._cachedIsMilestoneAssessmentLocked;
840
+ }
841
+ return this.computeIsMilestoneAssessmentLocked();
842
+ }
843
+ /**
844
+ * Check if a milestone's mandatory courses and assessment are completed.
845
+ * Looks at the content hierarchy to find children of the milestone.
846
+ */
847
+ checkMilestoneContentCompletion(milestoneId) {
848
+ if (!this.baseContentReadData || !this.baseContentReadData.children || !this.hierarchyMapData) {
849
+ // Fallback: Try to find assessment completion in hashmap for this milestone
850
+ return this.checkMilestoneAssessmentCompletion(milestoneId);
851
+ }
852
+ // Find the milestone in the content hierarchy
853
+ const milestoneContent = this.findContentInHierarchy(this.baseContentReadData, milestoneId);
854
+ if (!milestoneContent || !milestoneContent.children) {
855
+ return this.checkMilestoneAssessmentCompletion(milestoneId);
856
+ }
857
+ // Check all mandatory courses and assessments
858
+ let allMandatoryComplete = true;
859
+ let hasAssessment = false;
860
+ let assessmentComplete = false;
861
+ milestoneContent.children.forEach((child) => {
862
+ const childData = this.hierarchyMapData[child.identifier];
863
+ const isAssessment = child.primaryCategory === 'Course Assessment' ||
864
+ child.courseCategory === 'Course Assessment' ||
865
+ child.primaryCategory === 'Final Assessment';
866
+ const isMandatory = child.mandatory === true || child.optionalReading !== true;
867
+ if (isAssessment) {
868
+ hasAssessment = true;
869
+ if (childData && (childData.completionStatus === 2 || childData.completionPercentage >= 100)) {
870
+ assessmentComplete = true;
871
+ }
872
+ }
873
+ else if (isMandatory) {
874
+ // Check if mandatory content is completed
875
+ if (!childData || (childData.completionStatus !== 2 && childData.completionPercentage < 100)) {
876
+ allMandatoryComplete = false;
877
+ }
878
+ }
879
+ });
880
+ console.log('Milestone content check:', { allMandatoryComplete, hasAssessment, assessmentComplete });
881
+ // Milestone is complete if assessment is complete (mandatory courses optional based on requirements)
882
+ return hasAssessment ? assessmentComplete : allMandatoryComplete;
883
+ }
884
+ /**
885
+ * Fallback: Check if enough assessments are completed to unlock this milestone.
886
+ * For milestone at index N, we need at least N completed assessments.
887
+ * E.g., For M2 (index 1), we need 1 completed assessment (M1's assessment)
888
+ * For M3 (index 2), we need 2 completed assessments (M1's and M2's)
889
+ */
890
+ checkMilestoneAssessmentCompletion(milestoneId) {
891
+ if (!this.hierarchyMapData) {
892
+ return false;
893
+ }
894
+ // Extract milestone number from ID (M1 -> 1, M2 -> 2, etc.)
895
+ const milestoneNum = parseInt(milestoneId.replace(/\D/g, '')) || 0;
896
+ const requiredCompletedAssessments = milestoneNum - 1; // For M2, need 1; for M3, need 2
897
+ console.log(`Milestone ${milestoneId} (num: ${milestoneNum}) requires ${requiredCompletedAssessments} completed assessments`);
898
+ if (requiredCompletedAssessments <= 0) {
899
+ return true; // First milestone, no requirements
900
+ }
901
+ // Count completed Course Assessments that are INSIDE milestones (have a parent)
902
+ // Exclude pre-enrollment assessments at the root level (no parent or parent is Learning Pathway)
903
+ let completedMilestoneAssessmentCount = 0;
904
+ const learningPathwayId = this.baseContentReadData?.identifier;
905
+ for (const key of Object.keys(this.hierarchyMapData)) {
906
+ const item = this.hierarchyMapData[key];
907
+ // Check if it's a completed Course Assessment
908
+ if ((item.primaryCategory === 'Course Assessment' || item.courseCategory === 'Course Assessment') &&
909
+ (item.completionStatus === 2 || item.completionPercentage >= 100)) {
910
+ // Check if this assessment has a parent (meaning it's inside a course/milestone, not at root level)
911
+ // Also exclude if parent is the Learning Pathway itself (pre-enrollment assessment)
912
+ const hasParent = item.parent && item.parent !== learningPathwayId;
913
+ if (hasParent) {
914
+ completedMilestoneAssessmentCount++;
915
+ console.log(`Found completed MILESTONE assessment: ${key}`, item);
916
+ }
917
+ else {
918
+ console.log(`Skipping root-level/pre-enrollment assessment: ${key}`);
919
+ }
920
+ }
921
+ }
922
+ console.log(`Total completed MILESTONE assessments: ${completedMilestoneAssessmentCount}, Required: ${requiredCompletedAssessments}`);
923
+ // If we have enough completed milestone assessments, unlock this milestone
924
+ return completedMilestoneAssessmentCount >= requiredCompletedAssessments;
925
+ }
926
+ findContentInHierarchy(content, identifier) {
927
+ if (!content)
928
+ return null;
929
+ if (content.identifier === identifier)
930
+ return content;
931
+ if (content.children) {
932
+ for (const child of content.children) {
933
+ const found = this.findContentInHierarchy(child, identifier);
934
+ if (found)
935
+ return found;
936
+ }
937
+ }
938
+ return null;
939
+ }
940
+ get computedQueryParams() {
941
+ if (this.isAllowed && !this.forPreview && this.isEnabled) {
942
+ return {
943
+ ...this.resourceLink.queryParams,
944
+ preAssessment: 'true'
945
+ };
946
+ }
947
+ return null;
948
+ }
949
+ get isMilestone() {
950
+ if (this._cacheInitialized) {
951
+ return this._cachedIsMilestone;
952
+ }
953
+ return this.computeIsMilestone();
954
+ }
955
+ getMilestoneCompletedCount() {
956
+ if (!this.content || !this.hierarchyMapData) {
957
+ return 0;
958
+ }
959
+ const milestoneData = this.hierarchyMapData[this.content.identifier];
960
+ if (!milestoneData || !milestoneData.leafNodes) {
961
+ return 0;
962
+ }
963
+ let completedCount = 0;
964
+ milestoneData.leafNodes.forEach((leafId) => {
965
+ const leafData = this.hierarchyMapData[leafId];
966
+ if (leafData && leafData.completionStatus === 2) {
967
+ completedCount++;
968
+ }
969
+ });
970
+ return completedCount;
971
+ }
972
+ /**
973
+ * Get unlock criteria message for locked milestones
974
+ */
975
+ getMilestoneUnlockMessage() {
976
+ if (!this.content || !this.hierarchyMapData) {
977
+ return '';
978
+ }
979
+ const milestoneData = this.hierarchyMapData[this.content.identifier];
980
+ if (!milestoneData) {
981
+ return '';
982
+ }
983
+ // Check if hashmap has pre-computed unlock message
984
+ if (milestoneData.unlockMessage) {
985
+ return milestoneData.unlockMessage;
986
+ }
987
+ const milestoneIndex = milestoneData.milestoneIndex;
988
+ // Milestone 1 requires pre-assessment completion
989
+ if (milestoneIndex === 0) {
990
+ return 'Complete the preliminary assessment to unlock this milestone';
991
+ }
992
+ // Other milestones require previous milestone completion
993
+ return `Complete all mandatory content and assessment in Milestone ${milestoneIndex} to unlock this milestone`;
994
+ }
995
+ /**
996
+ * Get lock message for content inside locked milestones
997
+ */
998
+ getParentMilestoneLockMessage() {
999
+ if (!this.isParentMilestoneLocked) {
1000
+ return '';
1001
+ }
1002
+ return 'This content is locked. Complete previous milestone to view this content.';
1003
+ }
1004
+ /**
1005
+ * Get lock message for milestone assessments
1006
+ */
1007
+ getAssessmentLockMessage() {
1008
+ if (!this.content || !this.hierarchyMapData) {
1009
+ return '';
1010
+ }
1011
+ const hashData = this.hierarchyMapData[this.content.identifier];
1012
+ // Check if hashmap has pre-computed assessment lock message
1013
+ if (hashData && hashData.assessmentLockMessage) {
1014
+ return hashData.assessmentLockMessage;
1015
+ }
1016
+ if (this.isMilestoneAssessmentLocked) {
1017
+ return 'This content is locked. Complete all mandatory items to unlock the assessment.';
1018
+ }
1019
+ return '';
1020
+ }
1021
+ shouldShowDownloadButton(content) {
1022
+ if (!content) {
1023
+ return false;
1024
+ }
1025
+ // Check if content has an artifact URL (downloadable resource)
1026
+ if (!content.artifactUrl) {
1027
+ return false;
1028
+ }
1029
+ // Check if base content resource category includes "Case Study"
1030
+ if (!this.baseContentReadData?.courseCategory ||
1031
+ this.baseContentReadData.courseCategory !== NsContent.ECourseCategory.CASE_STUDY) {
1032
+ return false;
1033
+ }
1034
+ //for public scenario check if its player plage then only enable download
1035
+ if (this.forPreview && !window.location.href.includes('/viewer/')) {
1036
+ return false;
1037
+ }
1038
+ // for logged in user check if user enrolled then only allow download
1039
+ if (!this.forPreview && !this.isEnrolled) {
1040
+ return false;
1041
+ }
1042
+ // Define downloadable MIME types
1043
+ const downloadableMimeTypes = [
1044
+ NsContent.EMimeTypes.PDF
1045
+ ];
1046
+ return downloadableMimeTypes.includes(content.mimeType);
1047
+ }
1048
+ downloadContent(content, event) {
1049
+ if (event) {
1050
+ event.preventDefault();
1051
+ event.stopPropagation();
1052
+ }
1053
+ const pageId = `app/toc/pageId/${content.identifier}`;
1054
+ this.resourceDownloadHelperSvc.downloadPDF(content, pageId);
1055
+ console.log('content', content);
1056
+ console.log('baseContent', this.baseContentReadData);
1057
+ }
1058
+ /**
1059
+ * View milestone achievement - calls the achievement API and shows the result
1060
+ */
1061
+ viewMilestoneAchievement(event) {
1062
+ if (event) {
1063
+ event.preventDefault();
1064
+ event.stopPropagation();
1065
+ }
1066
+ if (!this.content || !this.batchId || this.achievementLoading) {
1067
+ return;
1068
+ }
1069
+ // Get user ID from ConfigurationsService
1070
+ const userId = this.configSvc?.userProfile?.userId;
1071
+ if (!userId) {
1072
+ console.error('User ID not found');
1073
+ return;
1074
+ }
1075
+ // Extract milestone ID (e.g., "m1", "m2") from the content name or index
1076
+ // Try to get milestone number from the index or extract from content
1077
+ let milestoneId = 'm' + (this.index - 1); // index is typically 1-based, milestones are 0-based
1078
+ // If content name contains milestone number, extract it
1079
+ if (this.content.name) {
1080
+ const match = this.content.name.match(/milestone\s*(\d+)/i);
1081
+ if (match) {
1082
+ milestoneId = 'm' + match[1];
1083
+ }
1084
+ }
1085
+ const courseId = this.baseContentReadData?.identifier || this.rootId;
1086
+ this.achievementLoading = true;
1087
+ this.appTocSvc.generateMilestoneAchievement(userId, courseId, this.batchId, milestoneId).subscribe({
1088
+ next: (response) => {
1089
+ this.achievementLoading = false;
1090
+ console.log('Achievement generated successfully:', response);
1091
+ // Show achievement dialog or handle response
1092
+ if (response && response.result) {
1093
+ // Open a dialog to show the achievement
1094
+ this.dialog.open(CertificateDialogComponent, {
1095
+ width: '1300px',
1096
+ data: {
1097
+ cet: response.result.printUri || response.result.svgData,
1098
+ certId: response.result.identifier,
1099
+ isAchievement: true
1100
+ },
1101
+ });
1102
+ }
1103
+ },
1104
+ error: (error) => {
1105
+ this.achievementLoading = false;
1106
+ // Show error message in snackbar
1107
+ const errorMessage = error?.error?.result?.message || error?.message || 'Failed to generate achievement';
1108
+ this.snackBar.open(errorMessage, 'Close', {
1109
+ duration: 5000,
1110
+ horizontalPosition: 'center',
1111
+ verticalPosition: 'bottom',
1112
+ panelClass: ['error-snackbar']
1113
+ });
1114
+ console.error('Error generating achievement:', error);
1115
+ }
1116
+ });
1117
+ }
1118
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AppTocContentCardV2Component, deps: [{ token: i1.EventService }, { token: i2.MatLegacyDialog }, { token: i0.Renderer2 }, { token: i3.CertificateService }, { token: i4.AppTocService }, { token: i5.ContentLanguageService }, { token: i6.ResourceDownloadHelperService }, { token: i1.ConfigurationsService }, { token: i7.MatLegacySnackBar }], target: i0.ɵɵFactoryTarget.Component }); }
1119
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AppTocContentCardV2Component, selector: "ws-widget-app-toc-content-card-v2", inputs: { content: "content", expandAll: "expandAll", rootId: "rootId", rootContentType: "rootContentType", forPreview: "forPreview", batchId: "batchId", componentName: "componentName", index: "index", pathSet: "pathSet", expandActive: "expandActive", hierarchyMapData: "hierarchyMapData", batchData: "batchData", isPreAssessment: "isPreAssessment", baseContentReadData: "baseContentReadData", mlCourse: "mlCourse", parentMilestoneLocked: "parentMilestoneLocked" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"content && !isPreAssessment\">\n <ng-container *ngIf=\"isCollection && !isModule\">\n <ng-container [ngTemplateOutlet]=\"collectionTemplate\">\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"isCollection && isModule\">\n <ng-container *ngIf=\"content?.moduleResourseCount\">\n <ng-container [ngTemplateOutlet]=\"collectionTemplate\">\n </ng-container>\n </ng-container>\n </ng-container>\n\n <div *ngIf=\"isResource\" class=\"resource-container\"\n [ngClass]=\"pathSet?.has(content?.identifier) && isEnrolled ? 'content-active-resource': 'content-not-active-resource'\">\n <div class=\"resource flex sm:flex-row flex-start width-expand w-100 sm:pr-4 sm:w-auto\"\n [ngClass]=\"{'activeResource': pathSet?.has(content?.identifier) && isEnrolled}\">\n <!-- Lock message for curated programs only (shown above content) -->\n <ng-container *ngIf=\"content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT && checkForCuratedProgram &&\n !isContentUnlocked\">\n <div class=\"content-locking flex w-full flex-middle mb-2 gap-3\">\n <mat-icon class=\"lock-icon\">lock</mat-icon>\n <span class=\"lock-message mat-body-2\">\n The content is locked. Complete program or all courses to view this module\n </span>\n </div>\n </ng-container>\n <ng-container *ngIf=\"content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT && checkForCuratedProgram &&\n isContentUnlocked\">\n <div class=\"content-locking flex w-full flex-middle mb-2 gap-3\">\n <mat-icon class=\"unlock-icon\">lock_open_right</mat-icon>\n <span class=\"unlock-message mat-body-2\">\n This content is unlocked.\n </span>\n </div>\n </ng-container>\n <div class=\"flex flex-wrap items-start justify-start sm:justify-end\">\n <!-- <button *ngIf=\"!forPreview && content?.artifactUrl && !isXSmall && isAllowed && isEnabled\" type=\"button\"\n mat-icon-button class=\"\" [matMenuTriggerFor]=\"buttonMenu\">\n <mat-icon>more_vertical</mat-icon>\n </button> -->\n <ng-container *ngIf=\"isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\n\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\n <div class=\"completed\">\n <div>\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n <circle-progress class=\"flex items-center progress\"\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\n [outerStrokeColor]=\"progressColor2()\" [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\"\n [animation]=\"true\" [animationDuration]=\"250\" [showTitle]=\"false\" [showUnits]=\"false\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\n matTooltip=\"In progress\" [showZeroOuterStroke]=false [backgroundPadding]=\"-9\"\n [startFromZero]=\"false\" [backgroundPadding]=\"0\" [imageHeight]=\"22\" [imageWidth]=\"22\"\n [showBackground]=\"false\" [outerStrokeLinecap]=\"'butt'\">\n </circle-progress>\n <!-- <ws-widget-content-progress *ngIf=\"content?.identifier\" [forPreview]=\"forPreview\"\n [contentId]=\"content?.identifier\" class=\"progress-bar-thin\" [progress]=\"content?.completionPercentage\"\n [progressType]=\"'percentage'\">\n </ws-widget-content-progress> -->\n </ng-container>\n </ng-container>\n <ng-template #elseBlock>\n <circle-progress class=\"flex items-center progress\" [percent]=\"0\" [radius]=\"11\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\" [showUnits]=\"false\"\n [animationDuration]=\"250\" [showTitle]=\"false\" [backgroundPadding]=\"0\"\n [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\" matTooltip=\"Not started\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\" [imageHeight]=\"22\"\n [imageWidth]=\"22\" [showBackground]=\"false\"></circle-progress>\n <!-- <p>no data</p> -->\n </ng-template>\n </ng-container>\n </div>\n <!-- deactivated as per NIC CEO requirement to access course wthout login -->\n <!-- For locked assessments: show content but make it non-clickable -->\n <div class=\"width-expand\" *ngIf=\"isMilestoneAssessmentLocked && isEnrolled; else clickableContent\"\n [ngClass]=\"{'ml-3': isEnrolled}\">\n <div class=\"text-truncate opacity-60\">\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\n <div class=\"flex items-center gap-2 w-full\">\n <mat-icon class=\"text-gray-500\">lock</mat-icon>\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate text-gray-600\">\n {{ content?.name | truncate:50 }}\n </p>\n </div>\n <span class=\"content-type optional-span nodtranslate\" *ngIf=\"content?.optionalReading\">{{\n 'playerbrief.optional' | translate | titlecase}} </span>\n </div>\n <!-- for default grey icons -->\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier) || !isEnrolled\">\n <div class=\"resicons ws-mat-black60-text\">\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/grey/module.svg\" class=\"float-left margin-right-xs\"\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\n\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n </div>\n \n <!-- Lock message displayed BELOW assessment details when locked -->\n <div class=\"content-locking flex w-full flex-middle mt-2 gap-2 px-2 py-1 bg-orange-50 border-l-4 border-orange-400\">\n <mat-icon class=\"lock-icon text-orange-600\" style=\"font-size: 18px; width: 18px; height: 18px;\">lock</mat-icon>\n <span class=\"lock-message mat-body-2 text-orange-800\" style=\"font-size: 13px;\">\n This content is locked. Complete all mandatory items to unlock the assessment.\n </span>\n </div>\n </div>\n \n <!-- Clickable content template (when NOT locked) -->\n <ng-template #clickableContent>\n <a class=\"width-expand\"\n [class.disabled]=\"(forPreview || !isEnabled || !isEnrolled || !isBatchInProgess || !isContentUnlocked || isParentMilestoneLocked) ? true : null\"\n [ngClass]=\"{'ml-3': isEnrolled}\"\n [routerLink]=\"(isAllowed && !forPreview && isEnabled && !isParentMilestoneLocked) ? resourceLink.url : null\"\n [queryParams]=\"(isAllowed && !forPreview && isEnabled && !isParentMilestoneLocked) ? resourceLink.queryParams : null\"\n [matTooltip]=\"isParentMilestoneLocked ? 'This content is locked. Complete previous milestone to view this content.' : ''\"\n matTooltipPosition=\"above\">\n <div [ngClass]=\"{'resource-active': pathSet?.has(content?.identifier) && isEnrolled}\"></div>\n <div class=\"text-truncate \" [ngClass]=\"{'cursor-pointer': !isEnabled && isEnrolled}\"\n (click)=\"content.viewChildren = !content.viewChildren; raiseTelemetry(); changeResource()\">\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate\"\n [ngClass]=\"{'text-active': pathSet?.has(content?.identifier) && isEnrolled}\">\n {{ content?.name | truncate:50 }}\n </p>\n <span class=\"content-type optional-span nodtranslate\" *ngIf=\"content?.optionalReading\">{{\n 'playerbrief.optional' | translate | titlecase}} </span>\n </div>\n <!-- for default grey icons -->\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier) || !isEnrolled\">\n <div class=\"resicons ws-mat-black60-text\">\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/grey/module.svg\" class=\"float-left margin-right-xs\"\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\n\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- for white icons when content highlighted -->\n <ng-container *ngIf=\"pathSet?.has(content?.identifier) && isEnrolled\">\n <div class=\"resicons ws-mat-white-text\">\n <img src=\"/assets/icons/content/white/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/white/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/white/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <img src=\"/assets/icons/content/white/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/white/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/white/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/white/module.svg\" class=\"float-left margin-right-xs\"\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Download button for pdf resources -->\n <ng-container *ngIf=\"shouldShowDownloadButton(content)\">\n <div class=\"download-btn mat-body-2 mt-2 sm:mt-1\" (click)=\"downloadContent(content, $event)\"\n [ngClass]=\"{'active': pathSet?.has(content?.identifier)}\">\n <a class=\"download-link flex items-center\">\n <span class=\"\">Download</span>\n </a>\n </div>\n </ng-container>\n </div>\n </a>\n </ng-template>\n </div>\n </div>\n</ng-container>\n\n<mat-menu #buttonMenu=\"matMenu\">\n <a mat-menu-item [routerLink]=\"'../' + content?.identifier + '/overview'\" [queryParams]=\"contextPath\"\n class=\"flex flex-middle\">\n <mat-icon>toc</mat-icon>\n <h3 class=\"margin-remove nodtranslate\">\n View Details\n </h3>\n </a>\n</mat-menu>\n\n<ng-template #collectionTemplate>\n <ng-container *ngIf=\"isCollection\">\n <div class=\"collection-wrapper p-4 flex flex-col position-relative\" [ngClass]=\"{'open': check(content),\n 'close': !content.viewChildren,\n 'course':!isModule, 'module': isModule,\n 'content-active': pathSet?.has(content.identifier) && isEnrolled}\">\n <div class=\"card-collection w-auto sm:w-100 padding-right-xl\">\n <!-- <img class=\"card-thumbnail ws-mat-primary-lite-background\" [src]=\"content?.appIcon\" alt=\"Thumbnail\"\n (click)=\"content.viewChildren = !content.viewChildren\" [wsUtilsDefaultThumbnail]=\"defaultThumbnail\" /> -->\n <div class=\"flex flex-col flex-wrap flex-between width-expand pr-0 w-100 \">\n <div class=\"text-truncate\" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\n (click)=\"content.viewChildren = !content.viewChildren\">\n <div class=\"flex items-center justify-center mb-1 sm:flex-row\">\n <ng-container\n *ngIf=\"isModule && isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\n\n <ng-container *ngIf=\"getCompletionStatus(content.identifier) == 2\">\n <div class=\"completed mr-2\">\n <div>\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n <circle-progress class=\"flex items-center progress mr-1\"\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\n [outerStrokeColor]=\"progressColor2()\"\n [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\" [animation]=\"true\"\n [animationDuration]=\"250\" [showTitle]=\"false\" [showUnits]=\"false\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\"\n [backgroundStrokeWidth]=\"3\" matTooltip=\"In progress\"\n [showZeroOuterStroke]=false [backgroundPadding]=\"-7\" [startFromZero]=\"false\"\n [backgroundPadding]=\"0\" [imageHeight]=\"18\" [imageWidth]=\"18\"\n [showBackground]=\"false\" [outerStrokeLinecap]=\"'butt'\">\n </circle-progress>\n </ng-container>\n </ng-container>\n <ng-template #elseBlock>\n <circle-progress class=\"flex items-center progress mr-1\" [percent]=\"0\" [radius]=\"11\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\"\n [showUnits]=\"false\" [animationDuration]=\"250\" [showTitle]=\"false\"\n [backgroundPadding]=\"0\" [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\"\n matTooltip=\"Not started\" [showSubtitle]=\"false\" [showInnerStroke]=\"true\"\n [clockwise]=\"true\" [imageHeight]=\"22\" [imageWidth]=\"22\"\n [showBackground]=\"false\"></circle-progress>\n </ng-template>\n </ng-container>\n <div\n [ngClass]=\"{'collection-active-class': pathSet?.has(content?.identifier) && isEnrolled}\">\n </div>\n <img *ngIf=\"isMilestoneLocked\" src=\"assets/icons/hubs/lock.svg\" alt=\"Locked\"\n class=\"lock-icon mr-2 margin-bottom-xxs\">\n <div class=\"flex-auto flex flex-col\" style=\"min-width: 0;\">\n <p class=\"margin-remove text-truncate mat-subheading-1 font-bold nodtranslate\"\n [ngClass]=\"{'text-active': pathSet?.has(content.identifier) && isEnrolled}\">\n <span>{{isMilestone ? index -1 : index}}. </span>{{ content?.name | truncate:50 }}\n </p>\n <div class=\"mt-1\" *ngIf=\"isMilestone && isMilestoneLocked\">\n <span class=\"locked-text\">Locked</span>\n </div>\n <div class=\"mt-1\" *ngIf=\"content?.isMandatory\">\n <span class=\"mandatory-text mat-caption\">Mandatory</span>\n </div>\n </div>\n \n <div class=\"type-container resource mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Resource'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Resource</span>\n </div>\n <div class=\"type-container module mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Collection'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Module</span>\n </div>\n <div class=\"type-container course mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Course'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Course</span>\n </div>\n </div>\n <!-- Milestone Badge -->\n <div *ngIf=\"isMilestone\" class=\"milestone-badge mt-2 mb-2\">\n <span class=\"milestone-badge-text nodtranslate\">Milestone {{index - 1}}</span>\n </div>\n <!-- Milestone Description (3 lines with ellipsis) -->\n <p *ngIf=\"isMilestone && content?.description\" class=\"milestone-description mt-2 nodtranslate\">\n {{ content?.description }}\n </p>\n <div class=\"flex flex-row gap-3 items-center content-key-values mt-2\">\n <mat-icon *ngIf=\"!isModule\" alt=\"course\"\n class=\"time-icon icon-color\">video_library</mat-icon>\n <img *ngIf=\"isModule\" alt=\"Module\" class=\"time-icon\"\n src=\"/assets/icons/content/grey/module.svg\">\n <div class=\"text-xs nodtranslate\">{{ (hierarchyMapData[content?.identifier]?.duration ||\n 120)|\n pipeDurationTransform: 'hms' }}</div>\n\n <ng-container *ngIf=\"content?.moduleCount\">\n <div class=\"flex items-center\">\n <span class=\"period\"></span>\n </div>\n <div class=\"text-xs nodtranslate\">{{content?.moduleCount}} {{content?.moduleCount > 1?\n 'modules' :\n 'module'}}</div>\n </ng-container>\n <ng-container *ngIf=\"content?.leafNodesCount\">\n <div class=\"flex items-center\">\n <span class=\"period\"></span>\n </div>\n <div class=\"text-xs nodtranslate\">{{content?.leafNodesCount}} {{content?.leafNodesCount\n >1 ? 'items':\n 'item'}}</div>\n </ng-container>\n </div>\n <!-- Milestone Completion Progress -->\n <div *ngIf=\"isMilestone && isEnrolled && !isMilestoneLocked\" class=\"milestone-progress mt-2 flex items-center justify-between\">\n <div>\n <span class=\"milestone-progress-text nodtranslate\">{{getMilestoneCompletedCount()}} of\n {{content?.leafNodesCount || 0}} completed</span>\n </div>\n <!-- View Achievement Button for completed milestones - Outside clickable area -->\n <div *ngIf=\"isMilestone && isEnrolled && (getCompletionPercentage(content?.identifier) >= 100 || getCompletionStatus(content?.identifier) === 2)\"\n class=\"view-achievement-container mt-2\">\n <button type=\"button\" class=\"view-achievement-btn\" [disabled]=\"achievementLoading\"\n (click)=\"viewMilestoneAchievement($event)\">\n <span *ngIf=\"!achievementLoading\">View Achievement</span>\n <mat-spinner *ngIf=\"achievementLoading\" [diameter]=\"16\" \n [strokeWidth]=\"2\" color=\"primary\" class=\"inline-spinner\"></mat-spinner>\n </button>\n </div>\n </div>\n <!-- Unlock Criteria Message for Locked Milestones -->\n <div *ngIf=\"isMilestone && isEnrolled && isMilestoneLocked\" class=\"milestone-locked-message mt-2\">\n <span class=\"locked-criteria-text mat-caption\">\n {{ getMilestoneUnlockMessage() }}\n </span>\n </div>\n \n </div>\n <!-- For course progress to be shown -->\n <ng-container *ngIf=\"isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) && content.primaryCategory === 'Course'\">\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\n <div class=\"flex flex-1\">\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\n <div class=\"flex flex-row justify-end w-full \">\n <span class=\"mat-body-2 nodtranslate \">\n {{getCompletionPercentage(content?.identifier)}}%</span>\n </div>\n\n <ws-widget-content-progress [contentId]=\"content?.progress\"\n [progress]=\"getCompletionPercentage(content?.identifier)\"\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\n </ws-widget-content-progress>\n </div>\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\n <a class=\"ml-5 certificate-btn\"\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\n <span class=\"nodtranslate\">Certificate</span>\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\n class=\"ml-2\">arrow_downward</mat-icon>\n <div class=\"center flex flex-middle certificate-loader\"\n *ngIf=\"downloadCertificateLoading\">\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\n [diameter]=\"16\"></mat-spinner>\n </div>\n </a>\n </ng-container>\n </div>\n <!-- <circle-progress class=\"flex items-center progress\" [percent]=\"100\" [radius]=\"12\"\n [outerStrokeWidth]=\"3\" [innerStrokeWidth]=\"3\" [space]=\"-3\"\n [outerStrokeColor]=\"progressColor()\" [innerStrokeColor]=\"'rgba(0,0,0,.16)'\"\n [animation]=\"true\" [animationDuration]=\"300\" [showTitle]=\"false\" [showUnits]=\"false\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\n [showZeroOuterStroke]=false [backgroundPadding]=\"-9\" [startFromZero]=\"false\"\n [backgroundPadding]=\"0\" [imageHeight]=\"24\" [imageWidth]=\"24\" [showBackground]=\"false\"\n [outerStrokeLinecap]=\"'butt'\">\n </circle-progress> -->\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n <div class=\"flex flex-1\">\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\n <div class=\"flex flex-row justify-end w-full ws-mat-black-text\">\n <span class=\"mat-body-2 ws-mat-black-text nodtranslate\">\n {{getCompletionPercentage(content?.identifier)}}%</span>\n </div>\n\n <ws-widget-content-progress [contentId]=\"content?.progress\"\n [progress]=\"getCompletionPercentage(content?.identifier)\"\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\n </ws-widget-content-progress>\n </div>\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\n <a class=\"ml-5 certificate-btn\"\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\n <span class=\"nodtranslate\">Certificate</span>\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\n class=\"ml-2\">arrow_downward</mat-icon>\n <div class=\"center flex flex-middle certificate-loader\"\n *ngIf=\"downloadCertificateLoading\">\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\n [diameter]=\"16\"></mat-spinner>\n </div>\n </a>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <div class=\"see-all-container\">\n <a href=\"javascript:void(0)\" role=\"button\"\n (click)=\"content.viewChildren = !content.viewChildren; expandActive = false\"\n class=\"see-all-btn tab custom-chevron customicon\" mat-button>\n <mat-icon *ngIf=\"!content.viewChildren && !isModule\">keyboard_arrow_down</mat-icon>\n <mat-icon *ngIf=\"content.viewChildren && !isModule\">keyboard_arrow_up</mat-icon>\n <mat-icon *ngIf=\"!content.viewChildren && isModule\">add</mat-icon>\n <mat-icon *ngIf=\"content.viewChildren && isModule\">remove</mat-icon>\n </a>\n </div>\n </div>\n </div>\n </div>\n <div class=\"child-wrapper \" *ngIf=\"content.viewChildren\" [ngClass]=\"{'open': content.viewChildren,\n 'close': !content.viewChildren,\n 'course':!isModule,\n 'module': isModule}\" [@panelInOut]>\n <div class=\"children-container\" [ngClass]=\"{'module': isModule, '': !isModule}\">\n <ws-widget-app-toc-content-card-v2 [forPreview]=\"forPreview\" [componentName]=\"componentName\"\n [content]=\"child\" [expandAll]=\"expandAll\" [rootId]=\"rootId\" [batchId]=\"batchId\"\n [rootContentType]=\"rootContentType\" [index]=\"j+1\" [baseContentReadData]=\"baseContentReadData\"\n [pathSet]=\"pathSet\" [hierarchyMapData]=\"hierarchyMapData\" [batchData]=\"batchData\"\n [mlCourse]=\"mlCourse\" [parentMilestoneLocked]=\"isMilestoneLocked || isParentMilestoneLocked\"\n *ngFor=\"let child of content?.children; trackBy: contentTrackBy; let j= index;let isFirst = first\"\n [ngClass]=\"{'moduleCard': checkIsModule(child), 'resourceCard': !checkIsModule(child), 'first': isFirst}\">\n </ws-widget-app-toc-content-card-v2>\n </div>\n </div>\n </ng-container>\n</ng-template>\n\n\n<ng-container *ngIf=\"isPreAssessment\">\n <div class=\"collection-wrapper p-4 flex flex-col position-relative\" [ngClass]=\"{'open': check(content),\n 'course':!isModule, 'module': isModule,\n 'content-active': pathSet?.has(content.identifier)}\">\n <div class=\"card-collection w-auto sm:w-100 padding-right-xl\">\n <!-- <img class=\"card-thumbnail ws-mat-primary-lite-background\" [src]=\"content?.appIcon\" alt=\"Thumbnail\"\n (click)=\"content.viewChildren = !content.viewChildren\" [wsUtilsDefaultThumbnail]=\"defaultThumbnail\" /> -->\n <div class=\"flex flex-col flex-wrap flex-between width-expand pr-0 w-100 \">\n\n <div class=\"text-truncate\" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\n (click)=\"content.viewChildren = !content.viewChildren\">\n <div class=\"flex sm:flex-row flex-wrap\">\n <ng-container>\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\n\n <ng-container *ngIf=\"getCompletionStatus(content.identifier) == 2\">\n <div class=\"completed mr-2\">\n <div>\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n\n <circle-progress class=\"flex items-center progress mr-1\"\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\n [outerStrokeColor]=\"progressColor2()\" [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\"\n [animation]=\"true\" [animationDuration]=\"250\" [showTitle]=\"false\"\n [showUnits]=\"false\" [showSubtitle]=\"false\" [showInnerStroke]=\"true\"\n [clockwise]=\"true\" [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\"\n [backgroundStrokeWidth]=\"3\" matTooltip=\"In progress\" [showZeroOuterStroke]=false\n [backgroundPadding]=\"-7\" [startFromZero]=\"false\" [backgroundPadding]=\"0\"\n [imageHeight]=\"18\" [imageWidth]=\"18\" [showBackground]=\"false\"\n [outerStrokeLinecap]=\"'butt'\">\n </circle-progress>\n </ng-container>\n </ng-container>\n <ng-template #elseBlock>\n <circle-progress class=\"flex items-center progress mr-1\" [percent]=\"0\" [radius]=\"11\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\" [showUnits]=\"false\"\n [animationDuration]=\"250\" [showTitle]=\"false\" [backgroundPadding]=\"0\"\n [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\" matTooltip=\"Not started\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [imageHeight]=\"22\" [imageWidth]=\"22\" [showBackground]=\"false\"></circle-progress>\n </ng-template>\n </ng-container>\n <div [ngClass]=\"{'collection-active-class': pathSet?.has(content?.identifier)}\"></div>\n <!-- <p class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\n [ngClass]=\"{'text-active': pathSet?.has(content.identifier)}\">\n {{index}}. {{ content?.name | truncate:50 }}\n </p> -->\n <a class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\n [class.disabled]=\"null\" [ngClass]=\"{'ml-3': isEnrolled}\"\n [routerLink]=\"(isAllowed && !forPreview && isEnabled) ? resourceLink.url : null\"\n [queryParams]=\"computedQueryParams\">\n <!-- {{content?.courseCategory}} -->\n <div [ngClass]=\"{'resource-active': pathSet?.has(content?.identifier)}\"></div>\n <div class=\"text-truncate \" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\n (click)=\"raiseTelemetry(); changeResource()\">\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate\"\n [ngClass]=\"{'text-active': pathSet?.has(content?.identifier)}\">\n <!-- <mat-icon class=\"margin-right-xs radiobtn time-icon\">radio_button_unchecked </mat-icon> -->\n {{index}}. {{ content?.name | truncate:50 }}\n\n </p>\n <span class=\"content-type optional-span nodtranslate\"\n *ngIf=\"content?.optionalReading\">{{ 'playerbrief.optional' | translate |\n titlecase}} </span>\n </div>\n <!-- for default grey icons -->\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier)\">\n <div class=\"resicons ws-mat-black60-text\">\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <!-- <img src=\"/assets/icons/content/grey/resource.svg\" alt=\"Survey\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/survey'\"> -->\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\"\n alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/grey/module.svg\"\n class=\"float-left margin-right-xs\" alt=\"offline sessions\"\n *ngIf=\"content.mimeType === 'application/offline'\">\n\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{\n content?.maxQuestions }} {{ 'playerbrief.questions' | translate |\n titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{\n (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- for white icons when content highlighted -->\n <ng-container *ngIf=\"pathSet?.has(content?.identifier)\">\n <div class=\"resicons ws-mat-white-text\">\n <img src=\"/assets/icons/content/white/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/white/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/white/pdf.svg\" alt=\"PDF\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <!-- <img src=\"/assets/icons/content/white/resource.svg\" alt=\"Survey\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/survey'\"> -->\n <img src=\"/assets/icons/content/white/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/white/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/white/content_copy.svg\" class=\"contenticon\"\n alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/white/module.svg\"\n class=\"float-left margin-right-xs\" alt=\"offline sessions\"\n *ngIf=\"content.mimeType === 'application/offline'\">\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n <span class=\"resourceDuration ws-mat-white-text nodtranslate\">{{\n content?.maxQuestions }} {{ 'playerbrief.questions' | translate |\n titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-white-text nodtranslate\">{{\n (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n </div>\n </a>\n <!-- <div class=\"type-container resource mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Resource'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Resource</span>\n </div>\n <div class=\"type-container module mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Collection'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Module</span>\n </div>\n <div class=\"type-container course mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Course'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Course</span>\n </div> -->\n </div>\n\n </div>\n <!-- For course progress to be shown -->\n <ng-container>\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier)\">\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\n <div class=\"flex flex-1\">\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\n <div class=\"flex flex-row justify-end w-full \">\n <span class=\"mat-body-2 nodtranslate \">\n {{getCompletionPercentage(content?.identifier)}}%</span>\n </div>\n\n <ws-widget-content-progress [contentId]=\"content?.progress\"\n [progress]=\"getCompletionPercentage(content?.identifier)\"\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\n </ws-widget-content-progress>\n </div>\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\n <a class=\"ml-5 certificate-btn\"\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\n <span class=\"nodtranslate\">Certificate</span>\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\n class=\"ml-2\">arrow_downward</mat-icon>\n <div class=\"center flex flex-middle certificate-loader\"\n *ngIf=\"downloadCertificateLoading\">\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\n [diameter]=\"16\"></mat-spinner>\n </div>\n </a>\n </ng-container>\n </div>\n <!-- <circle-progress class=\"flex items-center progress\" [percent]=\"100\" [radius]=\"12\"\n [outerStrokeWidth]=\"3\" [innerStrokeWidth]=\"3\" [space]=\"-3\"\n [outerStrokeColor]=\"progressColor()\" [innerStrokeColor]=\"'rgba(0,0,0,.16)'\"\n [animation]=\"true\" [animationDuration]=\"300\" [showTitle]=\"false\" [showUnits]=\"false\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\n [showZeroOuterStroke]=false [backgroundPadding]=\"-9\" [startFromZero]=\"false\"\n [backgroundPadding]=\"0\" [imageHeight]=\"24\" [imageWidth]=\"24\" [showBackground]=\"false\"\n [outerStrokeLinecap]=\"'butt'\">\n </circle-progress> -->\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n <div class=\"flex flex-1\">\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\n <div class=\"flex flex-row justify-end w-full ws-mat-black-text\">\n <span class=\"mat-body-2 ws-mat-black-text nodtranslate\">\n {{getCompletionPercentage(content?.identifier)}}%</span>\n </div>\n\n <ws-widget-content-progress [contentId]=\"content?.progress\"\n [progress]=\"getCompletionPercentage(content?.identifier)\"\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\n </ws-widget-content-progress>\n </div>\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\n <a class=\"ml-5 certificate-btn\"\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\n <span class=\"nodtranslate\">Certificate</span>\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\n class=\"ml-2\">arrow_downward</mat-icon>\n <div class=\"center flex flex-middle certificate-loader\"\n *ngIf=\"downloadCertificateLoading\">\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\n [diameter]=\"16\"></mat-spinner>\n </div>\n </a>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <!-- <div class=\"see-all-container\">\n <a href=\"javascript:void(0)\" role=\"button\"\n (click)=\"content.viewChildren = !content.viewChildren; expandActive = false\"\n class=\"see-all-btn tab custom-chevron customicon\" mat-button>\n <mat-icon *ngIf=\"!content.viewChildren && !isModule\">keyboard_arrow_down</mat-icon>\n <mat-icon *ngIf=\"content.viewChildren && !isModule\">keyboard_arrow_up</mat-icon>\n <mat-icon *ngIf=\"!content.viewChildren && isModule\">add</mat-icon>\n <mat-icon *ngIf=\"content.viewChildren && isModule\">remove</mat-icon>\n </a>\n </div> -->\n </div>\n </div>\n </div>\n\n</ng-container>", styles: [".customicon{position:absolute;top:-.5em;right:0}.customicon .mat-icon{color:#1a4ca1}a.disabled{pointer-events:none;cursor:default}span.optional-span{margin-left:8px;padding:0 6px;border-radius:2px;display:inline-block;background-color:#0074b6;color:#fff;font-size:12px}.card-collection{display:flex;align-items:center;border-radius:8px}.card-collection .card-thumbnail{height:100%;margin-right:12px;cursor:pointer;border-radius:8px 0 0}@media only screen and (max-width: 469px){.card-collection{flex-direction:column;align-items:flex-start!important}.card-collection .card-thumbnail{height:100%!important;width:100%!important}.card-collection .text-truncate{white-space:unset!important}}.tab:focus{outline:1px solid!important}.custom-chevron:focus{outline:0px solid!important}.resource-container{display:flex;align-items:flex-start;flex-direction:column}.resource-container .resource{padding:16px 16px 16px 0;width:100%}.resource-container .card-thumbnail{height:100%;cursor:pointer}.resource-container .img-container{position:relative;margin-right:12px}.resource-container .img-container ws-widget-content-progress{position:absolute;left:0;right:0;bottom:5px}@media only screen and (max-width: 469px){.resource-container{flex-direction:column;align-items:flex-start!important}.resource-container .card-thumbnail{height:100%!important;width:100%!important}.resource-container .text-truncate{white-space:unset!important}}.child-meta-container{margin-top:8px;display:flex}.child-meta-container .child-structure{display:flex;align-items:center;flex-wrap:wrap}.child-meta-container .child-structure span{margin-right:12px;text-align:center;margin-bottom:8px}.child-meta-container .child-structure .structure-icon{margin-right:12px}@media only screen and (max-width: 469px){.child-meta-container{margin-left:.5rem;justify-content:space-between}}.resource-container{display:flex;align-items:center}.resource-container ws-display-content-type-icon{display:flex;align-items:center}.resource-container .resource-meta{margin-left:12px;display:flex;justify-content:space-between;align-items:center}.completed-icon{color:#1a4ca1}.collection-wrapper{padding:1rem}.collection-wrapper.course.content-active{background-color:#1a4ca1;color:#fff}.collection-wrapper.course.content-active .period{background:#fff}.collection-wrapper.course.content-active .text-active,.collection-wrapper.course.content-active .icon-color,.collection-wrapper.course.content-active .customicon .mat-icon{color:#fff}.collection-wrapper.course.content-active .progress-container span{color:#fff!important}.text-active{color:#1a4ca1}.text-active.font-bold{font-weight:600}.activeResource{background-color:#1a4ca1;color:#fff;padding-top:1rem!important;padding-bottom:1rem!important}.activeResource .text-active{color:#fff}.activeResource .text-active.font-bold{font-weight:600}.activeResource .resourceDuration,.activeResource .completed-icon{color:#fff}.collection-wrapper.open{border-bottom:1px solid rgba(0,0,0,.16)}.collection-wrapper.close{border:none}.child-wrapper.open{border-radius:0 0 8px 8px}.children-container .mat-subheading-1{font:500 16px/24px Lato!important}.children-container .resource-container{margin-bottom:16px}.children-container .resource-container .resource{padding:0}.children-container .resource-container .card-thumbnail{height:65px;align-self:center}.first.resourceCard:nth-child(1) .resource{margin-top:16px!important}.first.resourceCard:nth-child(1) .activeResource{margin-top:0!important}.children-container .resourceCard:last-child .resource-container:has(.activeResource){margin-bottom:0!important}.moduleCard:not(:last-child)>.collection-wrapper.close.module{border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.moduleCard:not(:last-child)>.collection-wrapper.open.module+.child-wrapper.open{border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.collection-wrapper.open.course+.child-wrapper.open .collection-wrapper.open.module+.child-wrapper.open{background-color:#eff3f9;border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.collection-wrapper.open.module+.child-wrapper.open{background-color:#eff3f9;border-radius:0;padding-bottom:8px}.content-heading{letter-spacing:0px;color:#222}.content-type{letter-spacing:0px}.time-icon{height:16px;width:16px;font-size:16px;vertical-align:middle}.time-icon.icon-color{color:#0009}.period{width:3px;height:3px;background:#0009;border-radius:4px}.time-value{letter-spacing:0px;color:#222;text-transform:lowercase}.see-all-container{position:absolute;right:16px;top:24px}.oval-white{background:#fff 0% 0% no-repeat padding-box;border-radius:8px;padding:2px 8px}.type-container{letter-spacing:0px;display:flex;align-items:center}.type-container .rotate-90{transform:rotate(-90deg)}.type-container .custom-icon{width:18px;height:18px;font-size:18px;margin-right:8px}.type-container.resource{color:#00a9f4}.type-container.module{color:#34d6a4}.type-container.course{color:#f58634}.no-mb{margin-bottom:0!important}.w-100{width:100%}.w-auto{width:auto}.progress-bar-thin{height:5px!important}.progress-bar-thin ::ng-deep .mat-progress-bar{height:5px}.progress-bar-thin ::ng-deep .theme-igot.day-mode .mat-progress-bar-buffer{background-color:transparent!important}.progress-bar-thin ::ng-deep .theme-igot.day-mode .mat-progress-bar-background{fill:transparent}.radiobtn{color:#00000029}.resicons img{width:22px;opacity:.5;margin-top:2px;vertical-align:sub}.certificate-btn{height:24px;background:#1a4ca1;display:flex;justify-content:center;align-items:center;padding:4px 11px;color:#fff;border-radius:20px;border:1px solid white;font:400 12px/16px Lato;cursor:pointer}.certificate-btn .mat-icon{fill:#fff;color:#fff;font-size:16px;height:auto;width:auto}.view-certificate-wrapper{display:flex;border-radius:4px;border:1.5px solid rgb(0,116,182);opacity:1;padding:8px}.collection-wrapper.course,.collection-wrapper.module,.resource-container .resource{padding-left:16px;box-sizing:border-box;width:100%;overflow:hidden}.children-container.module .resource-container .resource,.course .collection-wrapper.module{padding-left:24px;box-sizing:border-box;width:100%}.course .children-container.module .resource-container .resource{padding-left:32px;box-sizing:border-box;width:100%}.course .resource-container .resource{padding-left:24px}::ng-deep .white-spinner{stroke:#fff!important}.certificate-loader ::ng-deep .mat-progress-spinner circle,.mat-spinner circle{stroke:#fff}.lock-message{background:#fff4ec;color:#d13924;padding:10px;border-radius:4px;display:block!important;width:100%}.content-locking{padding:8px 12px;margin-top:8px;margin-left:0;margin-right:0;border-radius:4px;background:#fff4ec;display:flex!important;align-items:center;gap:8px;width:100%;box-sizing:border-box}.lock-icon{color:#f3962f;font-size:20px;flex-shrink:0}.unlock-message{background:#efffec;color:#0c9600;padding:10px}.unlock-icon{color:#0c9600}.download-btn{padding:4px 12px;text-underline-position:from-font;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none;cursor:pointer;border-radius:40px;color:#1b4ca1;font-weight:700;border:1px solid #1B4CA1;display:inline-block;pointer-events:auto;position:relative;z-index:1}.activeResource .download-btn.active{color:#fff;border:1px solid #fff}.milestone-badge{display:inline-block;background-color:#fefaf4;border:1px solid #EF951E;border-radius:16px;padding:2px 12px}.milestone-badge-text{font-size:12px;font-weight:500;color:#212121}.milestone-description{font-size:14px;line-height:1.5;color:#000000b3;margin:0;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.milestone-progress{display:flex;align-items:center}.milestone-progress-text{font-size:14px;font-weight:500;color:#0009}.milestone-locked-message{display:flex;align-items:center;padding:8px 12px;background-color:#f3962f1a;border-left:3px solid #F3962F;border-radius:4px}.locked-criteria-text{font-size:13px;font-weight:400;color:#000000b3;line-height:1.4}.locked-text{font-size:14px;font-weight:500;color:#f3962f}.mandatory-text{color:#d13924!important}.view-achievement-container{display:flex;align-items:center}.view-achievement-btn{background-color:transparent;border:1.5px solid #1a4ca1;color:#1a4ca1;border-radius:20px;padding:6px 16px;font-size:14px;font-weight:500;cursor:pointer;display:flex;align-items:center;gap:8px;transition:all .2s ease;min-width:150px}.view-achievement-btn:hover:not(:disabled){background-color:#1a4ca1;color:#fff}.view-achievement-btn:disabled{opacity:.6;cursor:not-allowed}.view-achievement-btn .inline-spinner{display:inline-block}\n"], dependencies: [{ kind: "directive", type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i9.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i10.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i11.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i11.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "component", type: i12.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i13.ContentProgressComponent, selector: "ws-widget-content-progress", inputs: ["contentId", "progress", "progressType", "forPreview", "className", "customClassName"] }, { kind: "component", type: i14.CircleProgressComponent, selector: "circle-progress", inputs: ["name", "class", "backgroundGradient", "backgroundColor", "backgroundGradientStopColor", "backgroundOpacity", "backgroundStroke", "backgroundStrokeWidth", "backgroundPadding", "radius", "space", "percent", "toFixed", "maxPercent", "renderOnClick", "units", "unitsFontSize", "unitsFontWeight", "unitsColor", "outerStrokeGradient", "outerStrokeWidth", "outerStrokeColor", "outerStrokeGradientStopColor", "outerStrokeLinecap", "innerStrokeColor", "innerStrokeWidth", "titleFormat", "title", "titleColor", "titleFontSize", "titleFontWeight", "subtitleFormat", "subtitle", "subtitleColor", "subtitleFontSize", "subtitleFontWeight", "imageSrc", "imageHeight", "imageWidth", "animation", "animateTitle", "animateSubtitle", "animationDuration", "showTitle", "showSubtitle", "showUnits", "showImage", "showBackground", "showInnerStroke", "clockwise", "responsive", "startFromZero", "showZeroOuterStroke", "lazy", "options"], outputs: ["onClick"] }, { kind: "directive", type: i15.MatLegacyTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: AppTocContentCardV2Component, selector: "ws-widget-app-toc-content-card-v2", inputs: ["content", "expandAll", "rootId", "rootContentType", "forPreview", "batchId", "componentName", "index", "pathSet", "expandActive", "hierarchyMapData", "batchData", "isPreAssessment", "baseContentReadData", "mlCourse", "parentMilestoneLocked"] }, { kind: "pipe", type: i8.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i1.PipeDurationTransformPipe, name: "pipeDurationTransform" }, { kind: "pipe", type: i16.TranslatePipe, name: "translate" }, { kind: "pipe", type: i17.TruncatePipe, name: "truncate" }], animations: [
1120
+ trigger('panelInOut', [
1121
+ transition('void => *', [
1122
+ style({ transform: 'translateY(-10%)', opacity: '0' }),
1123
+ animate(250)
1124
+ ]),
1125
+ transition('* => void', [
1126
+ animate(200, style({ transform: 'translateY(-10%)', opacity: '0' }))
1127
+ ])
1128
+ ])
1129
+ ] }); }
1130
+ }
1131
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AppTocContentCardV2Component, decorators: [{
1132
+ type: Component,
1133
+ args: [{ selector: 'ws-widget-app-toc-content-card-v2', animations: [
1134
+ trigger('panelInOut', [
1135
+ transition('void => *', [
1136
+ style({ transform: 'translateY(-10%)', opacity: '0' }),
1137
+ animate(250)
1138
+ ]),
1139
+ transition('* => void', [
1140
+ animate(200, style({ transform: 'translateY(-10%)', opacity: '0' }))
1141
+ ])
1142
+ ])
1143
+ ], template: "<ng-container *ngIf=\"content && !isPreAssessment\">\n <ng-container *ngIf=\"isCollection && !isModule\">\n <ng-container [ngTemplateOutlet]=\"collectionTemplate\">\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"isCollection && isModule\">\n <ng-container *ngIf=\"content?.moduleResourseCount\">\n <ng-container [ngTemplateOutlet]=\"collectionTemplate\">\n </ng-container>\n </ng-container>\n </ng-container>\n\n <div *ngIf=\"isResource\" class=\"resource-container\"\n [ngClass]=\"pathSet?.has(content?.identifier) && isEnrolled ? 'content-active-resource': 'content-not-active-resource'\">\n <div class=\"resource flex sm:flex-row flex-start width-expand w-100 sm:pr-4 sm:w-auto\"\n [ngClass]=\"{'activeResource': pathSet?.has(content?.identifier) && isEnrolled}\">\n <!-- Lock message for curated programs only (shown above content) -->\n <ng-container *ngIf=\"content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT && checkForCuratedProgram &&\n !isContentUnlocked\">\n <div class=\"content-locking flex w-full flex-middle mb-2 gap-3\">\n <mat-icon class=\"lock-icon\">lock</mat-icon>\n <span class=\"lock-message mat-body-2\">\n The content is locked. Complete program or all courses to view this module\n </span>\n </div>\n </ng-container>\n <ng-container *ngIf=\"content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT && checkForCuratedProgram &&\n isContentUnlocked\">\n <div class=\"content-locking flex w-full flex-middle mb-2 gap-3\">\n <mat-icon class=\"unlock-icon\">lock_open_right</mat-icon>\n <span class=\"unlock-message mat-body-2\">\n This content is unlocked.\n </span>\n </div>\n </ng-container>\n <div class=\"flex flex-wrap items-start justify-start sm:justify-end\">\n <!-- <button *ngIf=\"!forPreview && content?.artifactUrl && !isXSmall && isAllowed && isEnabled\" type=\"button\"\n mat-icon-button class=\"\" [matMenuTriggerFor]=\"buttonMenu\">\n <mat-icon>more_vertical</mat-icon>\n </button> -->\n <ng-container *ngIf=\"isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\n\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\n <div class=\"completed\">\n <div>\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n <circle-progress class=\"flex items-center progress\"\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\n [outerStrokeColor]=\"progressColor2()\" [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\"\n [animation]=\"true\" [animationDuration]=\"250\" [showTitle]=\"false\" [showUnits]=\"false\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\n matTooltip=\"In progress\" [showZeroOuterStroke]=false [backgroundPadding]=\"-9\"\n [startFromZero]=\"false\" [backgroundPadding]=\"0\" [imageHeight]=\"22\" [imageWidth]=\"22\"\n [showBackground]=\"false\" [outerStrokeLinecap]=\"'butt'\">\n </circle-progress>\n <!-- <ws-widget-content-progress *ngIf=\"content?.identifier\" [forPreview]=\"forPreview\"\n [contentId]=\"content?.identifier\" class=\"progress-bar-thin\" [progress]=\"content?.completionPercentage\"\n [progressType]=\"'percentage'\">\n </ws-widget-content-progress> -->\n </ng-container>\n </ng-container>\n <ng-template #elseBlock>\n <circle-progress class=\"flex items-center progress\" [percent]=\"0\" [radius]=\"11\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\" [showUnits]=\"false\"\n [animationDuration]=\"250\" [showTitle]=\"false\" [backgroundPadding]=\"0\"\n [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\" matTooltip=\"Not started\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\" [imageHeight]=\"22\"\n [imageWidth]=\"22\" [showBackground]=\"false\"></circle-progress>\n <!-- <p>no data</p> -->\n </ng-template>\n </ng-container>\n </div>\n <!-- deactivated as per NIC CEO requirement to access course wthout login -->\n <!-- For locked assessments: show content but make it non-clickable -->\n <div class=\"width-expand\" *ngIf=\"isMilestoneAssessmentLocked && isEnrolled; else clickableContent\"\n [ngClass]=\"{'ml-3': isEnrolled}\">\n <div class=\"text-truncate opacity-60\">\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\n <div class=\"flex items-center gap-2 w-full\">\n <mat-icon class=\"text-gray-500\">lock</mat-icon>\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate text-gray-600\">\n {{ content?.name | truncate:50 }}\n </p>\n </div>\n <span class=\"content-type optional-span nodtranslate\" *ngIf=\"content?.optionalReading\">{{\n 'playerbrief.optional' | translate | titlecase}} </span>\n </div>\n <!-- for default grey icons -->\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier) || !isEnrolled\">\n <div class=\"resicons ws-mat-black60-text\">\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/grey/module.svg\" class=\"float-left margin-right-xs\"\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\n\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n </div>\n \n <!-- Lock message displayed BELOW assessment details when locked -->\n <div class=\"content-locking flex w-full flex-middle mt-2 gap-2 px-2 py-1 bg-orange-50 border-l-4 border-orange-400\">\n <mat-icon class=\"lock-icon text-orange-600\" style=\"font-size: 18px; width: 18px; height: 18px;\">lock</mat-icon>\n <span class=\"lock-message mat-body-2 text-orange-800\" style=\"font-size: 13px;\">\n This content is locked. Complete all mandatory items to unlock the assessment.\n </span>\n </div>\n </div>\n \n <!-- Clickable content template (when NOT locked) -->\n <ng-template #clickableContent>\n <a class=\"width-expand\"\n [class.disabled]=\"(forPreview || !isEnabled || !isEnrolled || !isBatchInProgess || !isContentUnlocked || isParentMilestoneLocked) ? true : null\"\n [ngClass]=\"{'ml-3': isEnrolled}\"\n [routerLink]=\"(isAllowed && !forPreview && isEnabled && !isParentMilestoneLocked) ? resourceLink.url : null\"\n [queryParams]=\"(isAllowed && !forPreview && isEnabled && !isParentMilestoneLocked) ? resourceLink.queryParams : null\"\n [matTooltip]=\"isParentMilestoneLocked ? 'This content is locked. Complete previous milestone to view this content.' : ''\"\n matTooltipPosition=\"above\">\n <div [ngClass]=\"{'resource-active': pathSet?.has(content?.identifier) && isEnrolled}\"></div>\n <div class=\"text-truncate \" [ngClass]=\"{'cursor-pointer': !isEnabled && isEnrolled}\"\n (click)=\"content.viewChildren = !content.viewChildren; raiseTelemetry(); changeResource()\">\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate\"\n [ngClass]=\"{'text-active': pathSet?.has(content?.identifier) && isEnrolled}\">\n {{ content?.name | truncate:50 }}\n </p>\n <span class=\"content-type optional-span nodtranslate\" *ngIf=\"content?.optionalReading\">{{\n 'playerbrief.optional' | translate | titlecase}} </span>\n </div>\n <!-- for default grey icons -->\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier) || !isEnrolled\">\n <div class=\"resicons ws-mat-black60-text\">\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/grey/module.svg\" class=\"float-left margin-right-xs\"\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\n\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- for white icons when content highlighted -->\n <ng-container *ngIf=\"pathSet?.has(content?.identifier) && isEnrolled\">\n <div class=\"resicons ws-mat-white-text\">\n <img src=\"/assets/icons/content/white/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/white/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/white/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <img src=\"/assets/icons/content/white/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/white/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/white/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/white/module.svg\" class=\"float-left margin-right-xs\"\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Download button for pdf resources -->\n <ng-container *ngIf=\"shouldShowDownloadButton(content)\">\n <div class=\"download-btn mat-body-2 mt-2 sm:mt-1\" (click)=\"downloadContent(content, $event)\"\n [ngClass]=\"{'active': pathSet?.has(content?.identifier)}\">\n <a class=\"download-link flex items-center\">\n <span class=\"\">Download</span>\n </a>\n </div>\n </ng-container>\n </div>\n </a>\n </ng-template>\n </div>\n </div>\n</ng-container>\n\n<mat-menu #buttonMenu=\"matMenu\">\n <a mat-menu-item [routerLink]=\"'../' + content?.identifier + '/overview'\" [queryParams]=\"contextPath\"\n class=\"flex flex-middle\">\n <mat-icon>toc</mat-icon>\n <h3 class=\"margin-remove nodtranslate\">\n View Details\n </h3>\n </a>\n</mat-menu>\n\n<ng-template #collectionTemplate>\n <ng-container *ngIf=\"isCollection\">\n <div class=\"collection-wrapper p-4 flex flex-col position-relative\" [ngClass]=\"{'open': check(content),\n 'close': !content.viewChildren,\n 'course':!isModule, 'module': isModule,\n 'content-active': pathSet?.has(content.identifier) && isEnrolled}\">\n <div class=\"card-collection w-auto sm:w-100 padding-right-xl\">\n <!-- <img class=\"card-thumbnail ws-mat-primary-lite-background\" [src]=\"content?.appIcon\" alt=\"Thumbnail\"\n (click)=\"content.viewChildren = !content.viewChildren\" [wsUtilsDefaultThumbnail]=\"defaultThumbnail\" /> -->\n <div class=\"flex flex-col flex-wrap flex-between width-expand pr-0 w-100 \">\n <div class=\"text-truncate\" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\n (click)=\"content.viewChildren = !content.viewChildren\">\n <div class=\"flex items-center justify-center mb-1 sm:flex-row\">\n <ng-container\n *ngIf=\"isModule && isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\n\n <ng-container *ngIf=\"getCompletionStatus(content.identifier) == 2\">\n <div class=\"completed mr-2\">\n <div>\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n <circle-progress class=\"flex items-center progress mr-1\"\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\n [outerStrokeColor]=\"progressColor2()\"\n [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\" [animation]=\"true\"\n [animationDuration]=\"250\" [showTitle]=\"false\" [showUnits]=\"false\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\"\n [backgroundStrokeWidth]=\"3\" matTooltip=\"In progress\"\n [showZeroOuterStroke]=false [backgroundPadding]=\"-7\" [startFromZero]=\"false\"\n [backgroundPadding]=\"0\" [imageHeight]=\"18\" [imageWidth]=\"18\"\n [showBackground]=\"false\" [outerStrokeLinecap]=\"'butt'\">\n </circle-progress>\n </ng-container>\n </ng-container>\n <ng-template #elseBlock>\n <circle-progress class=\"flex items-center progress mr-1\" [percent]=\"0\" [radius]=\"11\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\"\n [showUnits]=\"false\" [animationDuration]=\"250\" [showTitle]=\"false\"\n [backgroundPadding]=\"0\" [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\"\n matTooltip=\"Not started\" [showSubtitle]=\"false\" [showInnerStroke]=\"true\"\n [clockwise]=\"true\" [imageHeight]=\"22\" [imageWidth]=\"22\"\n [showBackground]=\"false\"></circle-progress>\n </ng-template>\n </ng-container>\n <div\n [ngClass]=\"{'collection-active-class': pathSet?.has(content?.identifier) && isEnrolled}\">\n </div>\n <img *ngIf=\"isMilestoneLocked\" src=\"assets/icons/hubs/lock.svg\" alt=\"Locked\"\n class=\"lock-icon mr-2 margin-bottom-xxs\">\n <div class=\"flex-auto flex flex-col\" style=\"min-width: 0;\">\n <p class=\"margin-remove text-truncate mat-subheading-1 font-bold nodtranslate\"\n [ngClass]=\"{'text-active': pathSet?.has(content.identifier) && isEnrolled}\">\n <span>{{isMilestone ? index -1 : index}}. </span>{{ content?.name | truncate:50 }}\n </p>\n <div class=\"mt-1\" *ngIf=\"isMilestone && isMilestoneLocked\">\n <span class=\"locked-text\">Locked</span>\n </div>\n <div class=\"mt-1\" *ngIf=\"content?.isMandatory\">\n <span class=\"mandatory-text mat-caption\">Mandatory</span>\n </div>\n </div>\n \n <div class=\"type-container resource mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Resource'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Resource</span>\n </div>\n <div class=\"type-container module mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Collection'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Module</span>\n </div>\n <div class=\"type-container course mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Course'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Course</span>\n </div>\n </div>\n <!-- Milestone Badge -->\n <div *ngIf=\"isMilestone\" class=\"milestone-badge mt-2 mb-2\">\n <span class=\"milestone-badge-text nodtranslate\">Milestone {{index - 1}}</span>\n </div>\n <!-- Milestone Description (3 lines with ellipsis) -->\n <p *ngIf=\"isMilestone && content?.description\" class=\"milestone-description mt-2 nodtranslate\">\n {{ content?.description }}\n </p>\n <div class=\"flex flex-row gap-3 items-center content-key-values mt-2\">\n <mat-icon *ngIf=\"!isModule\" alt=\"course\"\n class=\"time-icon icon-color\">video_library</mat-icon>\n <img *ngIf=\"isModule\" alt=\"Module\" class=\"time-icon\"\n src=\"/assets/icons/content/grey/module.svg\">\n <div class=\"text-xs nodtranslate\">{{ (hierarchyMapData[content?.identifier]?.duration ||\n 120)|\n pipeDurationTransform: 'hms' }}</div>\n\n <ng-container *ngIf=\"content?.moduleCount\">\n <div class=\"flex items-center\">\n <span class=\"period\"></span>\n </div>\n <div class=\"text-xs nodtranslate\">{{content?.moduleCount}} {{content?.moduleCount > 1?\n 'modules' :\n 'module'}}</div>\n </ng-container>\n <ng-container *ngIf=\"content?.leafNodesCount\">\n <div class=\"flex items-center\">\n <span class=\"period\"></span>\n </div>\n <div class=\"text-xs nodtranslate\">{{content?.leafNodesCount}} {{content?.leafNodesCount\n >1 ? 'items':\n 'item'}}</div>\n </ng-container>\n </div>\n <!-- Milestone Completion Progress -->\n <div *ngIf=\"isMilestone && isEnrolled && !isMilestoneLocked\" class=\"milestone-progress mt-2 flex items-center justify-between\">\n <div>\n <span class=\"milestone-progress-text nodtranslate\">{{getMilestoneCompletedCount()}} of\n {{content?.leafNodesCount || 0}} completed</span>\n </div>\n <!-- View Achievement Button for completed milestones - Outside clickable area -->\n <div *ngIf=\"isMilestone && isEnrolled && (getCompletionPercentage(content?.identifier) >= 100 || getCompletionStatus(content?.identifier) === 2)\"\n class=\"view-achievement-container mt-2\">\n <button type=\"button\" class=\"view-achievement-btn\" [disabled]=\"achievementLoading\"\n (click)=\"viewMilestoneAchievement($event)\">\n <span *ngIf=\"!achievementLoading\">View Achievement</span>\n <mat-spinner *ngIf=\"achievementLoading\" [diameter]=\"16\" \n [strokeWidth]=\"2\" color=\"primary\" class=\"inline-spinner\"></mat-spinner>\n </button>\n </div>\n </div>\n <!-- Unlock Criteria Message for Locked Milestones -->\n <div *ngIf=\"isMilestone && isEnrolled && isMilestoneLocked\" class=\"milestone-locked-message mt-2\">\n <span class=\"locked-criteria-text mat-caption\">\n {{ getMilestoneUnlockMessage() }}\n </span>\n </div>\n \n </div>\n <!-- For course progress to be shown -->\n <ng-container *ngIf=\"isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) && content.primaryCategory === 'Course'\">\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\n <div class=\"flex flex-1\">\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\n <div class=\"flex flex-row justify-end w-full \">\n <span class=\"mat-body-2 nodtranslate \">\n {{getCompletionPercentage(content?.identifier)}}%</span>\n </div>\n\n <ws-widget-content-progress [contentId]=\"content?.progress\"\n [progress]=\"getCompletionPercentage(content?.identifier)\"\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\n </ws-widget-content-progress>\n </div>\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\n <a class=\"ml-5 certificate-btn\"\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\n <span class=\"nodtranslate\">Certificate</span>\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\n class=\"ml-2\">arrow_downward</mat-icon>\n <div class=\"center flex flex-middle certificate-loader\"\n *ngIf=\"downloadCertificateLoading\">\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\n [diameter]=\"16\"></mat-spinner>\n </div>\n </a>\n </ng-container>\n </div>\n <!-- <circle-progress class=\"flex items-center progress\" [percent]=\"100\" [radius]=\"12\"\n [outerStrokeWidth]=\"3\" [innerStrokeWidth]=\"3\" [space]=\"-3\"\n [outerStrokeColor]=\"progressColor()\" [innerStrokeColor]=\"'rgba(0,0,0,.16)'\"\n [animation]=\"true\" [animationDuration]=\"300\" [showTitle]=\"false\" [showUnits]=\"false\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\n [showZeroOuterStroke]=false [backgroundPadding]=\"-9\" [startFromZero]=\"false\"\n [backgroundPadding]=\"0\" [imageHeight]=\"24\" [imageWidth]=\"24\" [showBackground]=\"false\"\n [outerStrokeLinecap]=\"'butt'\">\n </circle-progress> -->\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n <div class=\"flex flex-1\">\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\n <div class=\"flex flex-row justify-end w-full ws-mat-black-text\">\n <span class=\"mat-body-2 ws-mat-black-text nodtranslate\">\n {{getCompletionPercentage(content?.identifier)}}%</span>\n </div>\n\n <ws-widget-content-progress [contentId]=\"content?.progress\"\n [progress]=\"getCompletionPercentage(content?.identifier)\"\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\n </ws-widget-content-progress>\n </div>\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\n <a class=\"ml-5 certificate-btn\"\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\n <span class=\"nodtranslate\">Certificate</span>\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\n class=\"ml-2\">arrow_downward</mat-icon>\n <div class=\"center flex flex-middle certificate-loader\"\n *ngIf=\"downloadCertificateLoading\">\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\n [diameter]=\"16\"></mat-spinner>\n </div>\n </a>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <div class=\"see-all-container\">\n <a href=\"javascript:void(0)\" role=\"button\"\n (click)=\"content.viewChildren = !content.viewChildren; expandActive = false\"\n class=\"see-all-btn tab custom-chevron customicon\" mat-button>\n <mat-icon *ngIf=\"!content.viewChildren && !isModule\">keyboard_arrow_down</mat-icon>\n <mat-icon *ngIf=\"content.viewChildren && !isModule\">keyboard_arrow_up</mat-icon>\n <mat-icon *ngIf=\"!content.viewChildren && isModule\">add</mat-icon>\n <mat-icon *ngIf=\"content.viewChildren && isModule\">remove</mat-icon>\n </a>\n </div>\n </div>\n </div>\n </div>\n <div class=\"child-wrapper \" *ngIf=\"content.viewChildren\" [ngClass]=\"{'open': content.viewChildren,\n 'close': !content.viewChildren,\n 'course':!isModule,\n 'module': isModule}\" [@panelInOut]>\n <div class=\"children-container\" [ngClass]=\"{'module': isModule, '': !isModule}\">\n <ws-widget-app-toc-content-card-v2 [forPreview]=\"forPreview\" [componentName]=\"componentName\"\n [content]=\"child\" [expandAll]=\"expandAll\" [rootId]=\"rootId\" [batchId]=\"batchId\"\n [rootContentType]=\"rootContentType\" [index]=\"j+1\" [baseContentReadData]=\"baseContentReadData\"\n [pathSet]=\"pathSet\" [hierarchyMapData]=\"hierarchyMapData\" [batchData]=\"batchData\"\n [mlCourse]=\"mlCourse\" [parentMilestoneLocked]=\"isMilestoneLocked || isParentMilestoneLocked\"\n *ngFor=\"let child of content?.children; trackBy: contentTrackBy; let j= index;let isFirst = first\"\n [ngClass]=\"{'moduleCard': checkIsModule(child), 'resourceCard': !checkIsModule(child), 'first': isFirst}\">\n </ws-widget-app-toc-content-card-v2>\n </div>\n </div>\n </ng-container>\n</ng-template>\n\n\n<ng-container *ngIf=\"isPreAssessment\">\n <div class=\"collection-wrapper p-4 flex flex-col position-relative\" [ngClass]=\"{'open': check(content),\n 'course':!isModule, 'module': isModule,\n 'content-active': pathSet?.has(content.identifier)}\">\n <div class=\"card-collection w-auto sm:w-100 padding-right-xl\">\n <!-- <img class=\"card-thumbnail ws-mat-primary-lite-background\" [src]=\"content?.appIcon\" alt=\"Thumbnail\"\n (click)=\"content.viewChildren = !content.viewChildren\" [wsUtilsDefaultThumbnail]=\"defaultThumbnail\" /> -->\n <div class=\"flex flex-col flex-wrap flex-between width-expand pr-0 w-100 \">\n\n <div class=\"text-truncate\" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\n (click)=\"content.viewChildren = !content.viewChildren\">\n <div class=\"flex sm:flex-row flex-wrap\">\n <ng-container>\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\n\n <ng-container *ngIf=\"getCompletionStatus(content.identifier) == 2\">\n <div class=\"completed mr-2\">\n <div>\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n\n <circle-progress class=\"flex items-center progress mr-1\"\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\n [outerStrokeColor]=\"progressColor2()\" [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\"\n [animation]=\"true\" [animationDuration]=\"250\" [showTitle]=\"false\"\n [showUnits]=\"false\" [showSubtitle]=\"false\" [showInnerStroke]=\"true\"\n [clockwise]=\"true\" [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\"\n [backgroundStrokeWidth]=\"3\" matTooltip=\"In progress\" [showZeroOuterStroke]=false\n [backgroundPadding]=\"-7\" [startFromZero]=\"false\" [backgroundPadding]=\"0\"\n [imageHeight]=\"18\" [imageWidth]=\"18\" [showBackground]=\"false\"\n [outerStrokeLinecap]=\"'butt'\">\n </circle-progress>\n </ng-container>\n </ng-container>\n <ng-template #elseBlock>\n <circle-progress class=\"flex items-center progress mr-1\" [percent]=\"0\" [radius]=\"11\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\" [showUnits]=\"false\"\n [animationDuration]=\"250\" [showTitle]=\"false\" [backgroundPadding]=\"0\"\n [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\" matTooltip=\"Not started\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [imageHeight]=\"22\" [imageWidth]=\"22\" [showBackground]=\"false\"></circle-progress>\n </ng-template>\n </ng-container>\n <div [ngClass]=\"{'collection-active-class': pathSet?.has(content?.identifier)}\"></div>\n <!-- <p class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\n [ngClass]=\"{'text-active': pathSet?.has(content.identifier)}\">\n {{index}}. {{ content?.name | truncate:50 }}\n </p> -->\n <a class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\n [class.disabled]=\"null\" [ngClass]=\"{'ml-3': isEnrolled}\"\n [routerLink]=\"(isAllowed && !forPreview && isEnabled) ? resourceLink.url : null\"\n [queryParams]=\"computedQueryParams\">\n <!-- {{content?.courseCategory}} -->\n <div [ngClass]=\"{'resource-active': pathSet?.has(content?.identifier)}\"></div>\n <div class=\"text-truncate \" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\n (click)=\"raiseTelemetry(); changeResource()\">\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate\"\n [ngClass]=\"{'text-active': pathSet?.has(content?.identifier)}\">\n <!-- <mat-icon class=\"margin-right-xs radiobtn time-icon\">radio_button_unchecked </mat-icon> -->\n {{index}}. {{ content?.name | truncate:50 }}\n\n </p>\n <span class=\"content-type optional-span nodtranslate\"\n *ngIf=\"content?.optionalReading\">{{ 'playerbrief.optional' | translate |\n titlecase}} </span>\n </div>\n <!-- for default grey icons -->\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier)\">\n <div class=\"resicons ws-mat-black60-text\">\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <!-- <img src=\"/assets/icons/content/grey/resource.svg\" alt=\"Survey\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/survey'\"> -->\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\"\n alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/grey/module.svg\"\n class=\"float-left margin-right-xs\" alt=\"offline sessions\"\n *ngIf=\"content.mimeType === 'application/offline'\">\n\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{\n content?.maxQuestions }} {{ 'playerbrief.questions' | translate |\n titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{\n (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- for white icons when content highlighted -->\n <ng-container *ngIf=\"pathSet?.has(content?.identifier)\">\n <div class=\"resicons ws-mat-white-text\">\n <img src=\"/assets/icons/content/white/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/white/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/white/pdf.svg\" alt=\"PDF\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <!-- <img src=\"/assets/icons/content/white/resource.svg\" alt=\"Survey\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/survey'\"> -->\n <img src=\"/assets/icons/content/white/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/white/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/white/content_copy.svg\" class=\"contenticon\"\n alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/white/module.svg\"\n class=\"float-left margin-right-xs\" alt=\"offline sessions\"\n *ngIf=\"content.mimeType === 'application/offline'\">\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n <span class=\"resourceDuration ws-mat-white-text nodtranslate\">{{\n content?.maxQuestions }} {{ 'playerbrief.questions' | translate |\n titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-white-text nodtranslate\">{{\n (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n </div>\n </a>\n <!-- <div class=\"type-container resource mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Resource'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Resource</span>\n </div>\n <div class=\"type-container module mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Collection'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Module</span>\n </div>\n <div class=\"type-container course mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Course'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Course</span>\n </div> -->\n </div>\n\n </div>\n <!-- For course progress to be shown -->\n <ng-container>\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier)\">\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\n <div class=\"flex flex-1\">\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\n <div class=\"flex flex-row justify-end w-full \">\n <span class=\"mat-body-2 nodtranslate \">\n {{getCompletionPercentage(content?.identifier)}}%</span>\n </div>\n\n <ws-widget-content-progress [contentId]=\"content?.progress\"\n [progress]=\"getCompletionPercentage(content?.identifier)\"\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\n </ws-widget-content-progress>\n </div>\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\n <a class=\"ml-5 certificate-btn\"\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\n <span class=\"nodtranslate\">Certificate</span>\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\n class=\"ml-2\">arrow_downward</mat-icon>\n <div class=\"center flex flex-middle certificate-loader\"\n *ngIf=\"downloadCertificateLoading\">\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\n [diameter]=\"16\"></mat-spinner>\n </div>\n </a>\n </ng-container>\n </div>\n <!-- <circle-progress class=\"flex items-center progress\" [percent]=\"100\" [radius]=\"12\"\n [outerStrokeWidth]=\"3\" [innerStrokeWidth]=\"3\" [space]=\"-3\"\n [outerStrokeColor]=\"progressColor()\" [innerStrokeColor]=\"'rgba(0,0,0,.16)'\"\n [animation]=\"true\" [animationDuration]=\"300\" [showTitle]=\"false\" [showUnits]=\"false\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\n [showZeroOuterStroke]=false [backgroundPadding]=\"-9\" [startFromZero]=\"false\"\n [backgroundPadding]=\"0\" [imageHeight]=\"24\" [imageWidth]=\"24\" [showBackground]=\"false\"\n [outerStrokeLinecap]=\"'butt'\">\n </circle-progress> -->\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n <div class=\"flex flex-1\">\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\n <div class=\"flex flex-row justify-end w-full ws-mat-black-text\">\n <span class=\"mat-body-2 ws-mat-black-text nodtranslate\">\n {{getCompletionPercentage(content?.identifier)}}%</span>\n </div>\n\n <ws-widget-content-progress [contentId]=\"content?.progress\"\n [progress]=\"getCompletionPercentage(content?.identifier)\"\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\n </ws-widget-content-progress>\n </div>\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\n <a class=\"ml-5 certificate-btn\"\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\n <span class=\"nodtranslate\">Certificate</span>\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\n class=\"ml-2\">arrow_downward</mat-icon>\n <div class=\"center flex flex-middle certificate-loader\"\n *ngIf=\"downloadCertificateLoading\">\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\n [diameter]=\"16\"></mat-spinner>\n </div>\n </a>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <!-- <div class=\"see-all-container\">\n <a href=\"javascript:void(0)\" role=\"button\"\n (click)=\"content.viewChildren = !content.viewChildren; expandActive = false\"\n class=\"see-all-btn tab custom-chevron customicon\" mat-button>\n <mat-icon *ngIf=\"!content.viewChildren && !isModule\">keyboard_arrow_down</mat-icon>\n <mat-icon *ngIf=\"content.viewChildren && !isModule\">keyboard_arrow_up</mat-icon>\n <mat-icon *ngIf=\"!content.viewChildren && isModule\">add</mat-icon>\n <mat-icon *ngIf=\"content.viewChildren && isModule\">remove</mat-icon>\n </a>\n </div> -->\n </div>\n </div>\n </div>\n\n</ng-container>", styles: [".customicon{position:absolute;top:-.5em;right:0}.customicon .mat-icon{color:#1a4ca1}a.disabled{pointer-events:none;cursor:default}span.optional-span{margin-left:8px;padding:0 6px;border-radius:2px;display:inline-block;background-color:#0074b6;color:#fff;font-size:12px}.card-collection{display:flex;align-items:center;border-radius:8px}.card-collection .card-thumbnail{height:100%;margin-right:12px;cursor:pointer;border-radius:8px 0 0}@media only screen and (max-width: 469px){.card-collection{flex-direction:column;align-items:flex-start!important}.card-collection .card-thumbnail{height:100%!important;width:100%!important}.card-collection .text-truncate{white-space:unset!important}}.tab:focus{outline:1px solid!important}.custom-chevron:focus{outline:0px solid!important}.resource-container{display:flex;align-items:flex-start;flex-direction:column}.resource-container .resource{padding:16px 16px 16px 0;width:100%}.resource-container .card-thumbnail{height:100%;cursor:pointer}.resource-container .img-container{position:relative;margin-right:12px}.resource-container .img-container ws-widget-content-progress{position:absolute;left:0;right:0;bottom:5px}@media only screen and (max-width: 469px){.resource-container{flex-direction:column;align-items:flex-start!important}.resource-container .card-thumbnail{height:100%!important;width:100%!important}.resource-container .text-truncate{white-space:unset!important}}.child-meta-container{margin-top:8px;display:flex}.child-meta-container .child-structure{display:flex;align-items:center;flex-wrap:wrap}.child-meta-container .child-structure span{margin-right:12px;text-align:center;margin-bottom:8px}.child-meta-container .child-structure .structure-icon{margin-right:12px}@media only screen and (max-width: 469px){.child-meta-container{margin-left:.5rem;justify-content:space-between}}.resource-container{display:flex;align-items:center}.resource-container ws-display-content-type-icon{display:flex;align-items:center}.resource-container .resource-meta{margin-left:12px;display:flex;justify-content:space-between;align-items:center}.completed-icon{color:#1a4ca1}.collection-wrapper{padding:1rem}.collection-wrapper.course.content-active{background-color:#1a4ca1;color:#fff}.collection-wrapper.course.content-active .period{background:#fff}.collection-wrapper.course.content-active .text-active,.collection-wrapper.course.content-active .icon-color,.collection-wrapper.course.content-active .customicon .mat-icon{color:#fff}.collection-wrapper.course.content-active .progress-container span{color:#fff!important}.text-active{color:#1a4ca1}.text-active.font-bold{font-weight:600}.activeResource{background-color:#1a4ca1;color:#fff;padding-top:1rem!important;padding-bottom:1rem!important}.activeResource .text-active{color:#fff}.activeResource .text-active.font-bold{font-weight:600}.activeResource .resourceDuration,.activeResource .completed-icon{color:#fff}.collection-wrapper.open{border-bottom:1px solid rgba(0,0,0,.16)}.collection-wrapper.close{border:none}.child-wrapper.open{border-radius:0 0 8px 8px}.children-container .mat-subheading-1{font:500 16px/24px Lato!important}.children-container .resource-container{margin-bottom:16px}.children-container .resource-container .resource{padding:0}.children-container .resource-container .card-thumbnail{height:65px;align-self:center}.first.resourceCard:nth-child(1) .resource{margin-top:16px!important}.first.resourceCard:nth-child(1) .activeResource{margin-top:0!important}.children-container .resourceCard:last-child .resource-container:has(.activeResource){margin-bottom:0!important}.moduleCard:not(:last-child)>.collection-wrapper.close.module{border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.moduleCard:not(:last-child)>.collection-wrapper.open.module+.child-wrapper.open{border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.collection-wrapper.open.course+.child-wrapper.open .collection-wrapper.open.module+.child-wrapper.open{background-color:#eff3f9;border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.collection-wrapper.open.module+.child-wrapper.open{background-color:#eff3f9;border-radius:0;padding-bottom:8px}.content-heading{letter-spacing:0px;color:#222}.content-type{letter-spacing:0px}.time-icon{height:16px;width:16px;font-size:16px;vertical-align:middle}.time-icon.icon-color{color:#0009}.period{width:3px;height:3px;background:#0009;border-radius:4px}.time-value{letter-spacing:0px;color:#222;text-transform:lowercase}.see-all-container{position:absolute;right:16px;top:24px}.oval-white{background:#fff 0% 0% no-repeat padding-box;border-radius:8px;padding:2px 8px}.type-container{letter-spacing:0px;display:flex;align-items:center}.type-container .rotate-90{transform:rotate(-90deg)}.type-container .custom-icon{width:18px;height:18px;font-size:18px;margin-right:8px}.type-container.resource{color:#00a9f4}.type-container.module{color:#34d6a4}.type-container.course{color:#f58634}.no-mb{margin-bottom:0!important}.w-100{width:100%}.w-auto{width:auto}.progress-bar-thin{height:5px!important}.progress-bar-thin ::ng-deep .mat-progress-bar{height:5px}.progress-bar-thin ::ng-deep .theme-igot.day-mode .mat-progress-bar-buffer{background-color:transparent!important}.progress-bar-thin ::ng-deep .theme-igot.day-mode .mat-progress-bar-background{fill:transparent}.radiobtn{color:#00000029}.resicons img{width:22px;opacity:.5;margin-top:2px;vertical-align:sub}.certificate-btn{height:24px;background:#1a4ca1;display:flex;justify-content:center;align-items:center;padding:4px 11px;color:#fff;border-radius:20px;border:1px solid white;font:400 12px/16px Lato;cursor:pointer}.certificate-btn .mat-icon{fill:#fff;color:#fff;font-size:16px;height:auto;width:auto}.view-certificate-wrapper{display:flex;border-radius:4px;border:1.5px solid rgb(0,116,182);opacity:1;padding:8px}.collection-wrapper.course,.collection-wrapper.module,.resource-container .resource{padding-left:16px;box-sizing:border-box;width:100%;overflow:hidden}.children-container.module .resource-container .resource,.course .collection-wrapper.module{padding-left:24px;box-sizing:border-box;width:100%}.course .children-container.module .resource-container .resource{padding-left:32px;box-sizing:border-box;width:100%}.course .resource-container .resource{padding-left:24px}::ng-deep .white-spinner{stroke:#fff!important}.certificate-loader ::ng-deep .mat-progress-spinner circle,.mat-spinner circle{stroke:#fff}.lock-message{background:#fff4ec;color:#d13924;padding:10px;border-radius:4px;display:block!important;width:100%}.content-locking{padding:8px 12px;margin-top:8px;margin-left:0;margin-right:0;border-radius:4px;background:#fff4ec;display:flex!important;align-items:center;gap:8px;width:100%;box-sizing:border-box}.lock-icon{color:#f3962f;font-size:20px;flex-shrink:0}.unlock-message{background:#efffec;color:#0c9600;padding:10px}.unlock-icon{color:#0c9600}.download-btn{padding:4px 12px;text-underline-position:from-font;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none;cursor:pointer;border-radius:40px;color:#1b4ca1;font-weight:700;border:1px solid #1B4CA1;display:inline-block;pointer-events:auto;position:relative;z-index:1}.activeResource .download-btn.active{color:#fff;border:1px solid #fff}.milestone-badge{display:inline-block;background-color:#fefaf4;border:1px solid #EF951E;border-radius:16px;padding:2px 12px}.milestone-badge-text{font-size:12px;font-weight:500;color:#212121}.milestone-description{font-size:14px;line-height:1.5;color:#000000b3;margin:0;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.milestone-progress{display:flex;align-items:center}.milestone-progress-text{font-size:14px;font-weight:500;color:#0009}.milestone-locked-message{display:flex;align-items:center;padding:8px 12px;background-color:#f3962f1a;border-left:3px solid #F3962F;border-radius:4px}.locked-criteria-text{font-size:13px;font-weight:400;color:#000000b3;line-height:1.4}.locked-text{font-size:14px;font-weight:500;color:#f3962f}.mandatory-text{color:#d13924!important}.view-achievement-container{display:flex;align-items:center}.view-achievement-btn{background-color:transparent;border:1.5px solid #1a4ca1;color:#1a4ca1;border-radius:20px;padding:6px 16px;font-size:14px;font-weight:500;cursor:pointer;display:flex;align-items:center;gap:8px;transition:all .2s ease;min-width:150px}.view-achievement-btn:hover:not(:disabled){background-color:#1a4ca1;color:#fff}.view-achievement-btn:disabled{opacity:.6;cursor:not-allowed}.view-achievement-btn .inline-spinner{display:inline-block}\n"] }]
1144
+ }], ctorParameters: function () { return [{ type: i1.EventService }, { type: i2.MatLegacyDialog }, { type: i0.Renderer2 }, { type: i3.CertificateService }, { type: i4.AppTocService }, { type: i5.ContentLanguageService }, { type: i6.ResourceDownloadHelperService }, { type: i1.ConfigurationsService }, { type: i7.MatLegacySnackBar }]; }, propDecorators: { content: [{
1145
+ type: Input
1146
+ }], expandAll: [{
1147
+ type: Input
1148
+ }], rootId: [{
1149
+ type: Input
1150
+ }], rootContentType: [{
1151
+ type: Input
1152
+ }], forPreview: [{
1153
+ type: Input
1154
+ }], batchId: [{
1155
+ type: Input
1156
+ }], componentName: [{
1157
+ type: Input
1158
+ }], index: [{
1159
+ type: Input
1160
+ }], pathSet: [{
1161
+ type: Input
1162
+ }], expandActive: [{
1163
+ type: Input
1164
+ }], hierarchyMapData: [{
1165
+ type: Input
1166
+ }], batchData: [{
1167
+ type: Input
1168
+ }], isPreAssessment: [{
1169
+ type: Input
1170
+ }], baseContentReadData: [{
1171
+ type: Input
1172
+ }], mlCourse: [{
1173
+ type: Input
1174
+ }], parentMilestoneLocked: [{
1175
+ type: Input
1176
+ }] } });
1177
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicmFyeS9zdW5iaXJkLWNiL3RvYy9zcmMvbGliL19jb2xsZWN0aW9uL19jb21tb24vY29udGVudC10b2MvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicmFyeS9zdW5iaXJkLWNiL3RvYy9zcmMvbGliL19jb2xsZWN0aW9uL19jb21tb24vY29udGVudC10b2MvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQStDLE1BQU0sZUFBZSxDQUFBO0FBQzdGLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQTtBQUN0RSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQTtBQUU5RSxPQUFPLEVBQWdCLFFBQVEsRUFBeUIsTUFBTSxzQkFBc0IsQ0FBQTtBQUNwRixPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSx1REFBdUQsQ0FBQTtBQUVsRyxPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFDekUsbUJBQW1CO0FBQ25CLE9BQU8sQ0FBQyxNQUFNLFFBQVEsQ0FBQTtBQUN0QixPQUFPLE1BQU0sTUFBTSxRQUFRLENBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF3QjNCLE1BQU0sT0FBTyw0QkFBNEI7SUE0RHZDLFlBQ1UsTUFBb0IsRUFDcEIsTUFBaUIsRUFDakIsUUFBbUIsRUFDbkIsa0JBQXNDLEVBQ3RDLFNB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b25lbnQsIElucHV0LCBPbkluaXQsIE9uRGVzdHJveSwgUmVuZGVyZXIyLCBTaW1wbGVDaGFuZ2VzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSdcbmltcG9ydCB7IE5zQ29udGVudCB9IGZyb20gJy4uLy4uLy4uLy4uL19zZXJ2aWNlcy93aWRnZXQtY29udGVudC5tb2RlbCdcbmltcG9ydCB7IHZpZXdlclJvdXRlR2VuZXJhdG9yIH0gZnJvbSAnLi4vLi4vLi4vLi4vX3NlcnZpY2VzL3ZpZXdlci1yb3V0ZS11dGlsJ1xuaW1wb3J0IHsgTnNBcHBUb2MgfSBmcm9tICcuLi8uLi8uLi8uLi9tb2RlbHMvYXBwLXRvYy5tb2RlbCdcbmltcG9ydCB7IEV2ZW50U2VydmljZSwgV3NFdmVudHMsIENvbmZpZ3VyYXRpb25zU2VydmljZSB9IGZyb20gJ0BzdW5iaXJkLWNiL3V0aWxzLXYyJ1xuaW1wb3J0IHsgQ2VydGlmaWNhdGVEaWFsb2dDb21wb25lbnQgfSBmcm9tICcuLi8uLi9jZXJ0aWZpY2F0ZS1kaWFsb2cvY2VydGlmaWNhdGUtZGlhbG9nLmNvbXBvbmVudCdcbmltcG9ydCB7IE1hdExlZ2FjeURpYWxvZyBhcyBNYXREaWFsb2cgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9sZWdhY3ktZGlhbG9nJ1xuaW1wb3J0IHsgYW5pbWF0ZSwgc3R5bGUsIHRyYW5zaXRpb24sIHRyaWdnZXIgfSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJ1xuLyogdHNsaW50OmRpc2FibGUqL1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJ1xuaW1wb3J0IG1vbWVudCBmcm9tICdtb21lbnQnXG5pbXBvcnQgeyBDZXJ0aWZpY2F0ZVNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi8uLi9zZXJ2aWNlcy9jZXJ0aWZpY2F0ZS5zZXJ2aWNlJ1xuaW1wb3J0IHsgQXBwVG9jU2VydmljZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NlcnZpY2VzL2FwcC10b2Muc2VydmljZSdcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnXG5pbXBvcnQgeyBDb250ZW50TGFuZ3VhZ2VTZXJ2aWNlIH0gZnJvbSAnQHN1bmJpcmQtY2IvY29uc3VtcHRpb24nXG5pbXBvcnQgeyBSZXNvdXJjZURvd25sb2FkSGVscGVyU2VydmljZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NlcnZpY2VzL3Jlc291cmNlLWRvd25sb2FkLWhlbHBlci5zZXJ2aWNlJ1xuaW1wb3J0IHsgTWF0TGVnYWN5U25hY2tCYXIgYXMgTWF0U25hY2tCYXIgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9sZWdhY3ktc25hY2stYmFyJ1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd3cy13aWRnZXQtYXBwLXRvYy1jb250ZW50LWNhcmQtdjInLFxuICB0ZW1wbGF0ZVVybDogJy4vYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9hcHAtdG9jLWNvbnRlbnQtY2FyZC12Mi5jb21wb25lbnQuc2NzcyddLFxuICBhbmltYXRpb25zOiBbXG4gICAgdHJpZ2dlcigncGFuZWxJbk91dCcsIFtcbiAgICAgIHRyYW5zaXRpb24oJ3ZvaWQgPT4gKicsIFtcbiAgICAgICAgc3R5bGUoeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGVZKC0xMCUpJywgb3BhY2l0eTogJzAnIH0pLFxuICAgICAgICBhbmltYXRlKDI1MClcbiAgICAgIF0pLFxuICAgICAgdHJhbnNpdGlvbignKiA9PiB2b2lkJywgW1xuICAgICAgICBhbmltYXRlKDIwMCwgc3R5bGUoeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGVZKC0xMCUpJywgb3BhY2l0eTogJzAnIH0pKVxuICAgICAgXSlcbiAgICBdKVxuICBdXG59KVxuZXhwb3J0IGNsYXNzIEFwcFRvY0NvbnRlbnRDYXJkVjJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIEBJbnB1dCgpIGNvbnRlbnQ6IE5zQ29udGVudC5JQ29udGVudCB8IG51bGwgPSBudWxsXG4gIEBJbnB1dCgpIGV4cGFuZEFsbCA9IGZhbHNlXG4gIEBJbnB1dCgpIHJvb3RJZCE6IHN0cmluZ1xuICBASW5wdXQoKSByb290Q29udGVudFR5cGUhOiBzdHJpbmdcbiAgQElucHV0KCkgZm9yUHJldmlldyA9IGZhbHNlXG4gIEBJbnB1dCgpIGJhdGNoSWQhOiBzdHJpbmdcbiAgQElucHV0KCkgY29tcG9uZW50TmFtZTogc3RyaW5nID0gJ3RvYydcbiAgQElucHV0KCkgaW5kZXghOiBudW1iZXJcbiAgQElucHV0KCkgcGF0aFNldCE6IGFueVxuICBASW5wdXQoKSBleHBhbmRBY3RpdmUgPSB0cnVlXG4gIEBJbnB1dCgpIGhpZXJhcmNoeU1hcERhdGE6IGFueSA9IHt9XG4gIEBJbnB1dCgpIGJhdGNoRGF0YTogLyoqTnNDb250ZW50LklCYXRjaExpc3RSZXNwb25zZSAqLyBhbnkgfCBudWxsID0gbnVsbFxuICBASW5wdXQoKSBpc1ByZUFzc2Vzc21lbnQgPSBmYWxzZVxuICBASW5wdXQoKSBiYXNlQ29udGVudFJlYWREYXRhOiBOc0NvbnRlbnQuSUNvbnRlbnQgfCBudWxsID0gbnVsbFxuICBASW5wdXQoKSBtbENvdXJzZTogTnNDb250ZW50LklDb250ZW50IHwgbnVsbCA9IG51bGxcbiAgQElucHV0KCkgcGFyZW50TWlsZXN0b25lTG9ja2VkID0gZmFsc2UgLy8gUGFzc2VkIGZyb20gcGFyZW50IHdoZW4gaW5zaWRlIGEgbG9ja2VkIG1pbGVzdG9uZVxuICBoYXNDb250ZW50U3RydWN0dXJlID0gZmFsc2VcbiAgZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgPSBmYWxzZVxuICBlbnVtQ29udGVudFR5cGVzID0gTnNDb250ZW50LkVEaXNwbGF5Q29udGVudFR5cGVzXG4gIGNvbnRlbnRTdHJ1Y3R1cmU6IE5zQXBwVG9jLklUb2NTdHJ1Y3R1cmUgPSB7XG4gICAgYXNzZXNzbWVudDogMCxcbiAgICBmaW5hbFRlc3Q6IDAsXG4gICAgY291cnNlOiAwLFxuICAgIGhhbmRzT246IDAsXG4gICAgaW50ZXJhY3RpdmVWaWRlbzogMCxcbiAgICBsZWFybmluZ01vZHVsZTogMCxcbiAgICBvdGhlcjogMCxcbiAgICBwZGY6IDAsXG4gICAgc3VydmV5OiAwLFxuICAgIHBvZGNhc3Q6IDAsXG4gICAgcHJhY3RpY2VUZXN0OiAwLFxuICAgIHF1aXo6IDAsXG4gICAgdmlkZW86IDAsXG4gICAgd2ViTW9kdWxlOiAwLFxuICAgIHdlYlBhZ2U6IDAsXG4gICAgeW91dHViZTogMCxcbiAgICBpbnRlcmFjdGl2ZWNvbnRlbnQ6IDAsXG4gICAgb2ZmbGluZVNlc3Npb246IDAsXG4gIH1cbiAgZGVmYXVsdFRodW1ibmFpbCA9ICcnXG4gIHZpZXdDaGlsZHJlbiA9IGZhbHNlXG4gIHByaW1hcnlDYXRlZ29yeSA9IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5XG4gIHBhZ2VTY3JvbGxTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiB8IG51bGwgPSBudWxsXG4gIGhhc2htYXBVcGRhdGVkU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb24gfCBudWxsID0gbnVsbFxuICBhY2hpZXZlbWVudExvYWRpbmc6IGJvb2xlYW4gPSBmYWxzZVxuICAvLyBDYWNoZWQgY29tcHV0ZWQgcHJvcGVydGllcyBmb3IgcGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uXG4gIHByaXZhdGUgX2NhY2hlZElzQ29sbGVjdGlvbjogYm9vbGVhbiA9IGZhbHNlXG4gIHByaXZhdGUgX2NhY2hlZElzTW9kdWxlOiBib29sZWFuID0gZmFsc2VcbiAgcHJpdmF0ZSBfY2FjaGVkSXNSZXNvdXJjZTogYm9vbGVhbiA9IGZhbHNlXG4gIHByaXZhdGUgX2NhY2hlZElzTWlsZXN0b25lOiBib29sZWFuID0gZmFsc2VcbiAgcHJpdmF0ZSBfY2FjaGVkSXNNaWxlc3RvbmVMb2NrZWQ6IGJvb2xlYW4gPSBmYWxzZVxuICBwcml2YXRlIF9jYWNoZWRJc1BhcmVudE1pbGVzdG9uZUxvY2tlZDogYm9vbGVhbiA9IGZhbHNlXG4gIHByaXZhdGUgX2NhY2hlZElzQ29udGVudFVubG9ja2VkOiBib29sZWFuID0gdHJ1ZVxuICBwcml2YXRlIF9jYWNoZWRDaGVja0ZvckN1cmF0ZWRQcm9ncmFtOiBib29sZWFuID0gZmFsc2VcbiAgcHJpdmF0ZSBfY2FjaGVkSXNNaWxlc3RvbmVBc3Nlc3NtZW50OiBib29sZWFuID0gZmFsc2VcbiAgcHJpdmF0ZSBfY2FjaGVkSXNNaWxlc3RvbmVBc3Nlc3NtZW50TG9ja2VkOiBib29sZWFuID0gZmFsc2VcbiAgcHJpdmF0ZSBfY2FjaGVkUmVzb3VyY2VMaW5rOiB7IHVybDogc3RyaW5nOyBxdWVyeVBhcmFtczogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB9ID0geyB1cmw6ICcnLCBxdWVyeVBhcmFtczoge30gfVxuICBwcml2YXRlIF9jYWNoZUluaXRpYWxpemVkOiBib29sZWFuID0gZmFsc2VcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGV2ZW50czogRXZlbnRTZXJ2aWNlLFxuICAgIHByaXZhdGUgZGlhbG9nOiBNYXREaWFsb2csXG4gICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIHByaXZhdGUgY2VydGlmaWNhdGVTZXJ2aWNlOiBDZXJ0aWZpY2F0ZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBhcHBUb2NTdmM6IEFwcFRvY1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBjb250ZW50TGFuZ1N2YzogQ29udGVudExhbmd1YWdlU2VydmljZSxcbiAgICBwcml2YXRlIHJlc291cmNlRG93bmxvYWRIZWxwZXJTdmM6IFJlc291cmNlRG93bmxvYWRIZWxwZXJTZXJ2aWNlLCAgICBcbiAgICBwcml2YXRlIGNvbmZpZ1N2YzogQ29uZmlndXJhdGlvbnNTZXJ2aWNlLFxuICAgIHByaXZhdGUgc25hY2tCYXI6IE1hdFNuYWNrQmFyXG4gICkgeyB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5ldmFsdWF0ZUltbWVkaWF0ZUNoaWxkcmVuU3RydWN0dXJlKClcbiAgICB0aGlzLmluaXRpYWxpemVDb21wdXRlZFByb3BlcnRpZXMoKVxuICAgIC8vIHRoaXMucm91dGUuZGF0YS5zdWJzY3JpYmUoZGF0YSA9PiB7XG4gICAgLy8gICAgIHRoaXMuZGVmYXVsdFRodW1ibmFpbCA9IGRhdGEuY29uZmlnRGF0YS5kYXRhLmxvZ29zLmRlZmF1bHRDb250ZW50XG4gICAgLy8gICB9XG4gICAgLy8gKVxuICAgIHRoaXMucmVzb3VyY2VTY3JvbGwoKVxuICAgIFxuICAgIC8vIFN1YnNjcmliZSB0byBoYXNobWFwIHVwZGF0ZXMgdG8gcmVjb21wdXRlIGNhY2hlZCBwcm9wZXJ0aWVzIHdoZW4gcHJvZ3Jlc3MgY2hhbmdlc1xuICAgIHRoaXMuaGFzaG1hcFVwZGF0ZWRTdWJzY3JpcHRpb24gPSB0aGlzLmFwcFRvY1N2Yy5oYXNobWFwVXBkYXRlZCQuc3Vic2NyaWJlKCh1cGRhdGUpID0+IHtcbiAgICAgIGlmICh1cGRhdGUgJiYgdXBkYXRlLmhhc2htYXApIHtcbiAgICAgICAgY29uc29sZS5sb2coJ/CflIQgSGFzaG1hcCB1cGRhdGVkLCByZWNvbXB1dGluZyBjYWNoZWQgcHJvcGVydGllcyBmb3I6JywgdGhpcy5jb250ZW50Py5pZGVudGlmaWVyKVxuICAgICAgICAvLyBJTVBPUlRBTlQ6IFVwZGF0ZSBoaWVyYXJjaHlNYXBEYXRhIHdpdGggdGhlIGxhdGVzdCBoYXNobWFwIGZyb20gdGhlIHNlcnZpY2VcbiAgICAgICAgLy8gVGhpcyBlbnN1cmVzIHRoZSBjb21wb25lbnQgdXNlcyB0aGUgdXBkYXRlZCBkYXRhLCBub3QgdGhlIHN0YWxlIEBJbnB1dCByZWZlcmVuY2VcbiAgICAgICAgdGhpcy5oaWVyYXJjaHlNYXBEYXRhID0gdXBkYXRlLmhhc2htYXBcbiAgICAgICAgdGhpcy5jb21wdXRlQWxsQ2FjaGVkUHJvcGVydGllcygpXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIGFsbCBjb21wdXRlZCBwcm9wZXJ0aWVzIG9uY2UgdG8gYXZvaWQgZXhwZW5zaXZlIGdldHRlciBjYWxjdWxhdGlvbnNcbiAgICogb24gZXZlcnkgY2hhbmdlIGRldGVjdGlvbiBjeWNsZVxuICAgKi9cbiAgcHJpdmF0ZSBpbml0aWFsaXplQ29tcHV0ZWRQcm9wZXJ0aWVzKCkge1xuICAgIHRoaXMuY29tcHV0ZUFsbENhY2hlZFByb3BlcnRpZXMoKVxuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGUgYWxsIGNhY2hlZCBwcm9wZXJ0aWVzIGF0IG9uY2UgZm9yIHBlcmZvcm1hbmNlIG9wdGltaXphdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBjb21wdXRlQWxsQ2FjaGVkUHJvcGVydGllcygpIHtcbiAgICBpZiAoIXRoaXMuY29udGVudCkge1xuICAgICAgdGhpcy5fY2FjaGVJbml0aWFsaXplZCA9IGZhbHNlXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBjb250ZW50SWQgPSB0aGlzLmNvbnRlbnQuaWRlbnRpZmllclxuICAgIGNvbnN0IGhhc2hEYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtjb250ZW50SWRdXG5cbiAgICAvLyBVc2UgaGFzaG1hcCBkYXRhIGlmIGF2YWlsYWJsZSBmb3IgcHJlLWNvbXB1dGVkIHZhbHVlc1xuICAgIGlmIChoYXNoRGF0YSkge1xuICAgICAgdGhpcy5fY2FjaGVkSXNDb2xsZWN0aW9uID0gaGFzaERhdGEuaXNDb2xsZWN0aW9uICE9PSB1bmRlZmluZWQgPyBcbiAgICAgICAgaGFzaERhdGEuaXNDb2xsZWN0aW9uIDogdGhpcy5jb250ZW50Lm1pbWVUeXBlID09PSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5DT0xMRUNUSU9OXG4gICAgICB0aGlzLl9jYWNoZWRJc01vZHVsZSA9IGhhc2hEYXRhLmlzTW9kdWxlICE9PSB1bmRlZmluZWQgPyBcbiAgICAgICAgaGFzaERhdGEuaXNNb2R1bGUgOiB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEVcbiAgICAgIHRoaXMuX2NhY2hlZElzUmVzb3VyY2UgPSBoYXNoRGF0YS5pc1Jlc291cmNlICE9PSB1bmRlZmluZWQgPyBcbiAgICAgICAgaGFzaERhdGEuaXNSZXNvdXJjZSA6IHRoaXMuY29tcHV0ZUlzUmVzb3VyY2UoKVxuICAgICAgdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmUgPSBoYXNoRGF0YS5pc01pbGVzdG9uZSAhPT0gdW5kZWZpbmVkID8gXG4gICAgICAgIGhhc2hEYXRhLmlzTWlsZXN0b25lIDogdGhpcy5jb21wdXRlSXNNaWxlc3RvbmUoKVxuICAgICAgdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmVMb2NrZWQgPSBoYXNoRGF0YS5jb21wdXRlZElzTG9ja2VkICE9PSB1bmRlZmluZWQgPyBcbiAgICAgICAgaGFzaERhdGEuY29tcHV0ZWRJc0xvY2tlZCA6IHRoaXMuY29tcHV0ZUlzTWlsZXN0b25lTG9ja2VkKClcbiAgICAgIHRoaXMuX2NhY2hlZElzUGFyZW50TWlsZXN0b25lTG9ja2VkID0gaGFzaERhdGEuaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQgIT09IHVuZGVmaW5lZCA/IFxuICAgICAgICBoYXNoRGF0YS5pc1BhcmVudE1pbGVzdG9uZUxvY2tlZCA6IHRoaXMuY29tcHV0ZUlzUGFyZW50TWlsZXN0b25lTG9ja2VkKClcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRmFsbGJhY2sgdG8gZGlyZWN0IGNvbXB1dGF0aW9uIGlmIGhhc2htYXAgbm90IGF2YWlsYWJsZVxuICAgICAgdGhpcy5fY2FjaGVkSXNDb2xsZWN0aW9uID0gdGhpcy5jb250ZW50Lm1pbWVUeXBlID09PSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5DT0xMRUNUSU9OXG4gICAgICB0aGlzLl9jYWNoZWRJc01vZHVsZSA9IHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRVxuICAgICAgdGhpcy5fY2FjaGVkSXNSZXNvdXJjZSA9IHRoaXMuY29tcHV0ZUlzUmVzb3VyY2UoKVxuICAgICAgdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmUgPSB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZSgpXG4gICAgICB0aGlzLl9jYWNoZWRJc01pbGVzdG9uZUxvY2tlZCA9IHRoaXMuY29tcHV0ZUlzTWlsZXN0b25lTG9ja2VkKClcbiAgICAgIHRoaXMuX2NhY2hlZElzUGFyZW50TWlsZXN0b25lTG9ja2VkID0gdGhpcy5jb21wdXRlSXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQoKVxuICAgIH1cblxuICAgIHRoaXMuX2NhY2hlZENoZWNrRm9yQ3VyYXRlZFByb2dyYW0gPSB0aGlzLmNvbXB1dGVDaGVja0ZvckN1cmF0ZWRQcm9ncmFtKClcbiAgICB0aGlzLl9jYWNoZWRJc0NvbnRlbnRVbmxvY2tlZCA9IHRoaXMuY29tcHV0ZUlzQ29udGVudFVubG9ja2VkKClcbiAgICB0aGlzLl9jYWNoZWRJc01pbGVzdG9uZUFzc2Vzc21lbnQgPSB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZUFzc2Vzc21lbnQoKVxuICAgIHRoaXMuX2NhY2hlZElzTWlsZXN0b25lQXNzZXNzbWVudExvY2tlZCA9IHRoaXMuY29tcHV0ZUlzTWlsZXN0b25lQXNzZXNzbWVudExvY2tlZCgpXG4gICAgdGhpcy5fY2FjaGVkUmVzb3VyY2VMaW5rID0gdGhpcy5jb21wdXRlUmVzb3VyY2VMaW5rKClcbiAgICB0aGlzLl9jYWNoZUluaXRpYWxpemVkID0gdHJ1ZVxuICB9XG5cbiAgcHJpdmF0ZSBjb21wdXRlSXNSZXNvdXJjZSgpOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMuY29udGVudCkgcmV0dXJuIGZhbHNlXG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LlJFU09VUkNFIHx8XG4gICAgICB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRSB8fFxuICAgICAgdGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxuICAgICAgdGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UXG4gICAgKVxuICB9XG5cbiAgcHJpdmF0ZSBjb21wdXRlSXNNaWxlc3RvbmUoKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLmNvbnRlbnQpIHJldHVybiBmYWxzZVxuICAgIGNvbnN0IHByaW1hcnlDYXQgPSB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5IGFzIHN0cmluZ1xuICAgIGNvbnN0IGNvdXJzZUNhdCA9IHRoaXMuY29udGVudC5jb3Vyc2VDYXRlZ29yeSBhcyBzdHJpbmdcbiAgICByZXR1cm4gcHJpbWFyeUNhdCA9PT0gJ01pbGVzdG9uZScgfHwgY291cnNlQ2F0ID09PSAnTWlsZXN0b25lJ1xuICB9XG5cbiAgcHJpdmF0ZSBjb21wdXRlQ2hlY2tGb3JDdXJhdGVkUHJvZ3JhbSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5jb250ZW50ICYmIHRoaXMuY29udGVudC5wYXJlbnQgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVt0aGlzLmNvbnRlbnQucGFyZW50XSkge1xuICAgICAgY29uc3QgcGFyZW50RGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVt0aGlzLmNvbnRlbnQucGFyZW50XVxuICAgICAgcmV0dXJuIHBhcmVudERhdGEgJiYgcGFyZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkNVUkFURURfUFJPR1JBTSAmJlxuICAgICAgICBwYXJlbnREYXRhLmNvbXBhdGliaWxpdHlMZXZlbCA+PSA1ICYmXG4gICAgICAgIHBhcmVudERhdGEuY29udGV4dExvY2tpbmdUeXBlID09PSBOc0NvbnRlbnQuRUNvbnRleHRMb2NraW5nVHlwZS5DT1VSU0VfQVNTRVNTTUVOVF9PTkxZXG4gICAgfVxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgcHJpdmF0ZSBjb21wdXRlSXNDb250ZW50VW5sb2NrZWQoKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuX2NhY2hlZENoZWNrRm9yQ3VyYXRlZFByb2dyYW0pIHtcbiAgICAgIGlmICh0aGlzLmNvbnRlbnQgJiYgdGhpcy5jb250ZW50LnBhcmVudCAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGEgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudC5wYXJlbnRdKSB7XG4gICAgICAgIGNvbnN0IHBhcmVudERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LnBhcmVudF1cbiAgICAgICAgbGV0IGNvbXBsZXRlZExlYWZOb2RlczogYW55W10gPSBbXVxuICAgICAgICBwYXJlbnREYXRhLmxlYWZOb2Rlcy5mb3JFYWNoKChfZWxlOiBhbnkpID0+IHtcbiAgICAgICAgICBpZiAodGhpcy5oaWVyYXJjaHlNYXBEYXRhICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtfZWxlXSkge1xuICAgICAgICAgICAgY29uc3QgY2hpbGREYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW19lbGVdXG4gICAgICAgICAgICBpZiAoY2hpbGREYXRhICYmIGNoaWxkRGF0YS5jb21wbGV0aW9uU3RhdHVzID09PSAyKSB7XG4gICAgICAgICAgICAgIGNvbXBsZXRlZExlYWZOb2Rlcy5wdXNoKGNoaWxkRGF0YSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIHJldHVybiBjb21wbGV0ZWRMZWFmTm9kZXMubGVuZ3RoID49IHBhcmVudERhdGEubGVhZk5vZGVzQ291bnQgLSAxXG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIHByaXZhdGUgY29tcHV0ZVJlc291cmNlTGluaygpOiB7IHVybDogc3RyaW5nOyBxdWVyeVBhcmFtczogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB9IHtcbiAgICBpZiAodGhpcy5jb250ZW50KSB7XG4gICAgICBsZXQgbWltZVR5cGU6IGFueSA9ICcnXG4gICAgICBpZiAodGhpcy5jb250ZW50ICYmIHRoaXMuY29udGVudC5jb3Vyc2VDYXRlZ29yeSA9PT0gJ1ByZSBFbnJvbG1lbnQgQXNzZXNzbWVudCcgJiZcbiAgICAgICAgdGhpcy5jb250ZW50Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLmVrc3RlcC5jb250ZW50LWNvbGxlY3Rpb24nXG4gICAgICApIHtcbiAgICAgICAgbWltZVR5cGUgPSAnYXBwbGljYXRpb24vdm5kLnN1bmJpcmQucXVlc3Rpb25zZXQnXG4gICAgICAgIHRoaXMuY29udGVudC5taW1lVHlwZSA9IE5zQ29udGVudC5FTWltZVR5cGVzLkZJTkFMX0FTU0VTU01FTlRcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1pbWVUeXBlID0gdGhpcy5jb250ZW50Lm1pbWVUeXBlXG4gICAgICB9XG4gICAgICBjb25zdCBzZWxlY3RlZExhbmd1YWdlID0gdGhpcy5tbENvdXJzZSA/IHRoaXMuY29udGVudExhbmdTdmMuZ2V0U2VsZWN0ZWRMYW5ndWFnZSh0aGlzLm1sQ291cnNlKSA6IHVuZGVmaW5lZFxuICAgICAgcmV0dXJuIHZpZXdlclJvdXRlR2VuZXJhdG9yKFxuICAgICAgICB0aGlzLmNvbnRlbnQuaWRlbnRpZmllcixcbiAgICAgICAgbWltZVR5cGUsXG4gICAgICAgIHRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YT8uaWRlbnRpZmllciB8fCB0aGlzLnJvb3RJZCxcbiAgICAgICAgdGhpcy5iYXNlQ29udGVudFJlYWREYXRhPy5jb250ZW50VHlwZSB8fCB0aGlzLnJvb3RDb250ZW50VHlwZSxcbiAgICAgICAgdGhpcy5mb3JQcmV2aWV3LFxuICAgICAgICB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5LFxuICAgICAgICB0aGlzLmJhdGNoSWQsXG4gICAgICAgIHRoaXMuY29udGVudD8ubmFtZSB8fCB0aGlzLmJhc2VDb250ZW50UmVhZERhdGE/Lm5hbWUsXG4gICAgICAgIChzZWxlY3RlZExhbmd1YWdlID8gc2VsZWN0ZWRMYW5ndWFnZS5sYW5nSWQgOiBudWxsKSxcbiAgICAgICAgKHNlbGVjdGVkTGFuZ3VhZ2UgPyBzZWxlY3RlZExhbmd1YWdlLmlkZW50aWZpZXIgOiBudWxsKSxcbiAgICAgIClcbiAgICB9XG4gICAgcmV0dXJuIHsgdXJsOiAnJywgcXVlcnlQYXJhbXM6IHt9IH1cbiAgfVxuXG4gIHByaXZhdGUgY29tcHV0ZUlzTWlsZXN0b25lTG9ja2VkKCk6IGJvb2xlYW4ge1xuICAgIC8vIE9ubHkgYXBwbHkgbWlsZXN0b25lIGxvY2tpbmcgZm9yIExlYXJuaW5nIFBhdGh3YXkgY29udGVudFxuICAgIGlmICghdGhpcy5iYXNlQ29udGVudFJlYWREYXRhIHx8IHRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YS5jb3Vyc2VDYXRlZ29yeSAhPT0gJ0xlYXJuaW5nIFBhdGh3YXknKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuY29udGVudCkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgY3VycmVudCBjb250ZW50IGlzIGEgTWlsZXN0b25lXG4gICAgaWYgKCF0aGlzLl9jYWNoZWRJc01pbGVzdG9uZSAmJiAhdGhpcy5jb21wdXRlSXNNaWxlc3RvbmUoKSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgaGFzaG1hcCBoYXMgcHJlLWNvbXB1dGVkIGxvY2tpbmcgc3RhdHVzIChwcmVmZXJyZWQgLSBjb21wdXRlZCBieSBzZXJ2aWNlKVxuICAgIGNvbnN0IGhhc2hEYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVt0aGlzLmNvbnRlbnQuaWRlbnRpZmllcl1cbiAgICBjb25zb2xlLmxvZyhgY29tcHV0ZUlzTWlsZXN0b25lTG9ja2VkIGZvciAke3RoaXMuY29udGVudC5pZGVudGlmaWVyfSAoJHt0aGlzLmNvbnRlbnQubmFtZX0pOmAsIHtcbiAgICAgIGhhc2hEYXRhLFxuICAgICAgY29tcHV0ZWRJc0xvY2tlZDogaGFzaERhdGE/LmNvbXB1dGVkSXNMb2NrZWQsXG4gICAgICBjb250ZW50SXNMb2NrZWQ6IHRoaXMuY29udGVudC5pc0xvY2tlZFxuICAgIH0pXG4gICAgXG4gICAgaWYgKGhhc2hEYXRhICYmIGhhc2hEYXRhLmNvbXB1dGVkSXNMb2NrZWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGhhc2hEYXRhLmNvbXB1dGVkSXNMb2NrZWRcbiAgICB9XG5cbiAgICAvLyBJZiBtaWxlc3RvbmUgaGFzIGlzTG9ja2VkIGZsYWcgZXhwbGljaXRseSBzZXQgdG8gZmFsc2UsIGl0J3MgdW5sb2NrZWRcbiAgICBpZiAodGhpcy5jb250ZW50LmlzTG9ja2VkID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gRmFsbGJhY2s6IEFsbCBtaWxlc3RvbmVzIGFyZSBsb2NrZWQgYnkgZGVmYXVsdCB1bnRpbCBjb21wdXRlZCBvdGhlcndpc2VcbiAgICAvLyBUaGlzIGVuc3VyZXMgcHJvcGVyIGxvY2tpbmcgdW50aWwgdGhlIGhhc2htYXAgaXMgdXBkYXRlZCB3aXRoIHByb2dyZXNzXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIHByaXZhdGUgY29tcHV0ZUlzUGFyZW50TWlsZXN0b25lTG9ja2VkKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLnBhcmVudE1pbGVzdG9uZUxvY2tlZCkge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YSB8fCB0aGlzLmJhc2VDb250ZW50UmVhZERhdGEuY291cnNlQ2F0ZWdvcnkgIT09ICdMZWFybmluZyBQYXRod2F5Jykge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmNvbnRlbnQgfHwgIXRoaXMuaGllcmFyY2h5TWFwRGF0YSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaGFzaG1hcCBmb3IgcHJlLWNvbXB1dGVkIHZhbHVlXG4gICAgY29uc3QgaGFzaERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LmlkZW50aWZpZXJdXG4gICAgaWYgKGhhc2hEYXRhICYmIGhhc2hEYXRhLmlzUGFyZW50TWlsZXN0b25lTG9ja2VkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBoYXNoRGF0YS5pc1BhcmVudE1pbGVzdG9uZUxvY2tlZFxuICAgIH1cblxuICAgIC8vIFRyYXZlcnNlIHVwIHRoZSBoaWVyYXJjaHkgdG8gZmluZCBpZiBhbnkgYW5jZXN0b3IgaXMgYSBsb2NrZWQgTWlsZXN0b25lXG4gICAgbGV0IGN1cnJlbnRQYXJlbnRJZCA9IHRoaXMuY29udGVudC5wYXJlbnRcbiAgICBjb25zdCBtYXhEZXB0aCA9IDVcbiAgICBsZXQgZGVwdGggPSAwXG5cbiAgICB3aGlsZSAoY3VycmVudFBhcmVudElkICYmIGRlcHRoIDwgbWF4RGVwdGgpIHtcbiAgICAgIGNvbnN0IHBhcmVudERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbY3VycmVudFBhcmVudElkXVxuICAgICAgaWYgKHBhcmVudERhdGEpIHtcbiAgICAgICAgaWYgKChwYXJlbnREYXRhLmlzTWlsZXN0b25lIHx8IHBhcmVudERhdGEucHJpbWFyeUNhdGVnb3J5ID09PSAnTWlsZXN0b25lJyB8fCBwYXJlbnREYXRhLmNvdXJzZUNhdGVnb3J5ID09PSAnTWlsZXN0b25lJykgJiYgXG4gICAgICAgICAgICAocGFyZW50RGF0YS5jb21wdXRlZElzTG9ja2VkIHx8IHBhcmVudERhdGEuaXNMb2NrZWQpKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfVxuICAgICAgICBjdXJyZW50UGFyZW50SWQgPSBwYXJlbnREYXRhLnBhcmVudFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICAgIGRlcHRoKytcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgY3VycmVudCBjb250ZW50IGlzIGEgTUlMRVNUT05FIGFzc2Vzc21lbnQgKERJUkVDVCBjaGlsZCBvZiBhIE1pbGVzdG9uZSlcbiAgICogSU1QT1JUQU5UOiBUaGlzIHNob3VsZCBOT1QgcmV0dXJuIHRydWUgZm9yIGNvdXJzZSBhc3Nlc3NtZW50cyBpbnNpZGUgY291cnNlcyB3aXRoaW4gbWlsZXN0b25lc1xuICAgKiBPbmx5IGFzc2Vzc21lbnRzIHRoYXQgYXJlIGRpcmVjdCBjaGlsZHJlbiBvZiBtaWxlc3RvbmVzIHNob3VsZCBiZSBsb2NrZWQgYnkgbWlsZXN0b25lIGxvZ2ljXG4gICAqL1xuICBwcml2YXRlIGNvbXB1dGVJc01pbGVzdG9uZUFzc2Vzc21lbnQoKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLmJhc2VDb250ZW50UmVhZERhdGEgfHwgdGhpcy5iYXNlQ29udGVudFJlYWREYXRhLmNvdXJzZUNhdGVnb3J5ICE9PSAnTGVhcm5pbmcgUGF0aHdheScpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGlmICghdGhpcy5jb250ZW50IHx8ICF0aGlzLmhpZXJhcmNoeU1hcERhdGEpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIHRoaXMgaXMgYW4gYXNzZXNzbWVudCB0eXBlXG4gICAgLy8gTm90ZTogRklOQUxfQVNTRVNTTUVOVCBtYXBzIHRvICdDb3Vyc2UgQXNzZXNzbWVudCcgaW4gdGhlIGVudW0sIG5vdCAnRmluYWwgQXNzZXNzbWVudCdcbiAgICBjb25zdCBpc0Fzc2Vzc21lbnQgPSBcbiAgICAgIHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdDb3Vyc2UgQXNzZXNzbWVudCcgfHxcbiAgICAgIHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdTdGFuZGFsb25lIEFzc2Vzc21lbnQnIHx8XG4gICAgICB0aGlzLmNvbnRlbnQubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuc3VuYmlyZC5xdWVzdGlvbnNldCcgfHxcbiAgICAgIHRoaXMuY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3F1aXonXG5cbiAgICBpZiAoIWlzQXNzZXNzbWVudCkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gSU1QT1JUQU5UOiBPbmx5IHJldHVybiB0cnVlIGlmIHRoZSBESVJFQ1QgcGFyZW50IGlzIGEgbWlsZXN0b25lXG4gICAgLy8gQXNzZXNzbWVudHMgaW5zaWRlIGNvdXJzZXMgKGdyYW5kY2hpbGRyZW4gb2YgbWlsZXN0b25lcykgc2hvdWxkIE5PVCBiZSBsb2NrZWQgYnkgbWlsZXN0b25lIGxvZ2ljXG4gICAgLy8gVGhleSBmb2xsb3cgdGhlaXIgb3duIGNvdXJzZSdzIGxvY2tpbmcgcnVsZXNcbiAgICBcbiAgICAvLyBHZXQgdGhlIHBhcmVudCBmcm9tIGhhc2htYXAgKHdoaWNoIHdlIGZpeGVkIHRvIHRyYWNrIGNvcnJlY3QgcGFyZW50LWNoaWxkIHJlbGF0aW9uc2hpcHMpXG4gICAgLy8gb3IgZmFsbGJhY2sgdG8gY29udGVudC5wYXJlbnQgaWYgaGFzaG1hcCBlbnRyeSBkb2Vzbid0IGV4aXN0XG4gICAgY29uc3QgY29udGVudEhhc2hEYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudC5pZGVudGlmaWVyXVxuICAgIGNvbnN0IHBhcmVudElkID0gY29udGVudEhhc2hEYXRhPy5wYXJlbnQgfHwgdGhpcy5jb250ZW50LnBhcmVudFxuICAgIFxuICAgIGNvbnNvbGUubG9nKGDwn5SNIGNvbXB1dGVJc01pbGVzdG9uZUFzc2Vzc21lbnQgZm9yIFwiJHt0aGlzLmNvbnRlbnQubmFtZX1cIiAoJHt0aGlzLmNvbnRlbnQuaWRlbnRpZmllcn0pOmAsIHtcbiAgICAgIGNvbnRlbnRJZDogdGhpcy5jb250ZW50LmlkZW50aWZpZXIsXG4gICAgICBwcmltYXJ5Q2F0ZWdvcnk6IHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnksXG4gICAgICBtaW1lVHlwZTogdGhpcy5jb250ZW50Lm1pbWVUeXBlLFxuICAgICAgY29udGVudFBhcmVudDogdGhpcy5jb250ZW50LnBhcmVudCxcbiAgICAgIGhhc2htYXBQYXJlbnQ6IGNvbnRlbnRIYXNoRGF0YT8ucGFyZW50LFxuICAgICAgcmVzb2x2ZWRQYXJlbnRJZDogcGFyZW50SWQsXG4gICAgICBoYXNQYXJlbnREYXRhOiAhIXRoaXMuaGllcmFyY2h5TWFwRGF0YVtwYXJlbnRJZF1cbiAgICB9KVxuICAgIFxuICAgIGlmIChwYXJlbnRJZCAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbcGFyZW50SWRdKSB7XG4gICAgICBjb25zdCBwYXJlbnREYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3BhcmVudElkXVxuICAgICAgXG4gICAgICBjb25zb2xlLmxvZyhgICAgUGFyZW50IGRldGFpbHM6YCwge1xuICAgICAgICBwYXJlbnRJZDogcGFyZW50SWQsXG4gICAgICAgIHBhcmVudE5hbWU6IHBhcmVudERhdGE/Lm5hbWUsXG4gICAgICAgIHBhcmVudFByaW1hcnlDYXRlZ29yeTogcGFyZW50RGF0YT8ucHJpbWFyeUNhdGVnb3J5LFxuICAgICAgICBwYXJlbnRJc01pbGVzdG9uZTogcGFyZW50RGF0YT8uaXNNaWxlc3RvbmUsXG4gICAgICAgIHBhcmVudENvdXJzZUNhdGVnb3J5OiBwYXJlbnREYXRhPy5jb3Vyc2VDYXRlZ29yeSxcbiAgICAgIH0pXG4gICAgICBcbiAgICAgIC8vIENoZWNrIGlmIERJUkVDVCBwYXJlbnQgaXMgYSBtaWxlc3RvbmUgLSBPTkxZIHRoaXMgY2FzZVxuICAgICAgY29uc3QgaXNQYXJlbnRNaWxlc3RvbmUgPSBwYXJlbnREYXRhLmlzTWlsZXN0b25lIHx8IFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnREYXRhLnByaW1hcnlDYXRlZ29yeSA9PT0gJ01pbGVzdG9uZScgfHwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudERhdGEuY291cnNlQ2F0ZWdvcnkgPT09ICdNaWxlc3RvbmUnXG4gICAgICBcbiAgICAgIGlmIChpc1BhcmVudE1pbGVzdG9uZSkge1xuICAgICAgICBjb25zb2xlLmxvZyhgICAg4pyFIFJlc3VsdDogSVMgYSBtaWxlc3RvbmUgYXNzZXNzbWVudCAoZGlyZWN0IGNoaWxkIG9mIG1pbGVzdG9uZSlgKVxuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfVxuICAgICAgXG4gICAgICBjb25zb2xlLmxvZyhgICAg4p2MIFJlc3VsdDogTk9UIGEgbWlsZXN0b25lIGFzc2Vzc21lbnQgKHBhcmVudCBpcyAke3BhcmVudERhdGEucHJpbWFyeUNhdGVnb3J5fSwgbm90IGEgTWlsZXN0b25lKWApXG4gICAgICAvLyBETyBOT1QgY2hlY2sgZ3JhbmRwYXJlbnQgLSBjb3Vyc2UgYXNzZXNzbWVudHMgaW5zaWRlIGNvdXJzZXMgd2l0aGluIG1pbGVzdG9uZXNcbiAgICAgIC8vIHNob3VsZCBOT1QgYmUgdHJlYXRlZCBhcyBtaWxlc3RvbmUgYXNzZXNzbWVudHNcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLmxvZyhgICAg4pqg77iPICBObyBwYXJlbnQgZGF0YSBmb3VuZCBmb3IgJHtwYXJlbnRJZH1gKVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIG1pbGVzdG9uZSBhc3Nlc3NtZW50IHNob3VsZCBiZSBsb2NrZWRcbiAgICogQXNzZXNzbWVudCBpcyBsb2NrZWQgaWY6XG4gICAqIDEuIEl0J3MgYW4gYXNzZXNzbWVudCB0aGF0IGlzIGEgRElSRUNUIGNoaWxkIG9mIGEgbWlsZXN0b25lXG4gICAqIDIuIFRoZSBwYXJlbnQgbWlsZXN0b25lIGlzIHVubG9ja2VkIChvdGhlcndpc2UgaGFuZGxlZCBieSBwYXJlbnQgbWlsZXN0b25lIGxvY2spXG4gICAqIDMuIE5PVCBhbGwgbWFuZGF0b3J5IGNvdXJzZXMgaW4gdGhlIHNhbWUgbWlsZXN0b25lIGFyZSBjb21wbGV0ZWRcbiAgICovXG4gIHByaXZhdGUgY29tcHV0ZUlzTWlsZXN0b25lQXNzZXNzbWVudExvY2tlZCgpOiBib29sZWFuIHtcbiAgICAvLyBPbmx5IGFwcGx5IHRvIGFzc2Vzc21lbnRzIHRoYXQgYXJlIERJUkVDVCBjaGlsZHJlbiBvZiBtaWxlc3RvbmVzXG4gICAgY29uc3QgaXNNaWxlc3RvbmVBc3Nlc3NtZW50ID0gdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmVBc3Nlc3NtZW50IHx8IHRoaXMuY29tcHV0ZUlzTWlsZXN0b25lQXNzZXNzbWVudCgpXG4gICAgXG4gICAgY29uc29sZS5sb2coYPCflJIgY29tcHV0ZUlzTWlsZXN0b25lQXNzZXNzbWVudExvY2tlZCBmb3IgXCIke3RoaXMuY29udGVudD8ubmFtZX1cIjpgLCB7XG4gICAgICBpc01pbGVzdG9uZUFzc2Vzc21lbnQsXG4gICAgICBfY2FjaGVkSXNNaWxlc3RvbmVBc3Nlc3NtZW50OiB0aGlzLl9jYWNoZWRJc01pbGVzdG9uZUFzc2Vzc21lbnQsXG4gICAgfSlcbiAgICBcbiAgICBpZiAoIWlzTWlsZXN0b25lQXNzZXNzbWVudCkge1xuICAgICAgY29uc29sZS5sb2coYPCflJMgXCIke3RoaXMuY29udGVudD8ubmFtZX1cIiBOT1QgbG9ja2VkIC0gbm90IGEgbWlsZXN0b25lIGFzc2Vzc21lbnRgKVxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgaGFzaG1hcCBoYXMgcHJlLWNvbXB1dGVkIGFzc2Vzc21lbnQgbG9ja2luZyBzdGF0dXNcbiAgICBjb25zdCBoYXNoRGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50Py5pZGVudGlmaWVyIHx8ICcnXVxuICAgIGlmIChoYXNoRGF0YSAmJiBoYXNoRGF0YS5pc0Fzc2Vzc21lbnRMb2NrZWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGhhc2hEYXRhLmlzQXNzZXNzbWVudExvY2tlZFxuICAgIH1cblxuICAgIC8vIElmIGFscmVhZHkgY29tcGxldGVkLCBkb24ndCBsb2NrXG4gICAgaWYgKHRoaXMuY29udGVudCAmJiAodGhpcy5jb250ZW50LmNvbXBsZXRpb25TdGF0dXMgPT09IDIgfHwgXG4gICAgICAgICh0aGlzLmNvbnRlbnQuY29tcGxldGlvblBlcmNlbnRhZ2UgJiYgdGhpcy5jb250ZW50LmNvbXBsZXRpb25QZXJjZW50YWdlID49IDEwMCkpKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICAvLyBGb3IgbWlsZXN0b25lIGFzc2Vzc21lbnRzLCB0aGUgcGFyZW50IElTIHRoZSBtaWxlc3RvbmUgKHZlcmlmaWVkIGJ5IGNvbXB1dGVJc01pbGVzdG9uZUFzc2Vzc21lbnQpXG4gICAgLy8gVXNlIGhhc2htYXAncyBwYXJlbnQgd2hpY2ggaGFzIGNvcnJlY3QgcGFyZW50LWNoaWxkIHJlbGF0aW9uc2hpcHNcbiAgICBjb25zdCBjb250ZW50SGFzaERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGEgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudD8uaWRlbnRpZmllciB8fCAnJ11cbiAgICBjb25zdCBtaWxlc3RvbmVJZCA9IGNvbnRlbnRIYXNoRGF0YT8ucGFyZW50IHx8IHRoaXMuY29udGVudD8ucGFyZW50XG4gICAgXG4gICAgaWYgKCFtaWxlc3RvbmVJZCB8fCAhdGhpcy5oaWVyYXJjaHlNYXBEYXRhKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gICAgXG4gICAgY29uc3QgbWlsZXN0b25lID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW21pbGVzdG9uZUlkXVxuICAgIFxuICAgIGlmICghbWlsZXN0b25lKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gICAgXG4gICAgLy8gSWYgdGhlIHBhcmVudCBtaWxlc3RvbmUgaXRzZWxmIGlzIGxvY2tlZCwgZG9uJ3QgYWRkIGFkZGl0aW9uYWwgbG9ja2luZ1xuICAgIC8vICh0aGUgcGFyZW50IGxvY2sgd2lsbCBoYW5kbGUgaXQpXG4gICAgaWYgKG1pbGVzdG9uZS5jb21wdXRlZElzTG9ja2VkIHx8IG1pbGVzdG9uZS5pc0xvY2tlZCkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgYWxsIG1hbmRhdG9yeSBDT1VSU0VTIGluIHRoZSBtaWxlc3RvbmUgYXJlIGNvbXBsZXRlZFxuICAgIC8vIE5vdGU6IE9ubHkgY2hlY2tpbmcgY291cnNlcyB0aGF0IGFyZSBkaXJlY3QgY2hpbGRyZW4gb2YgdGhlIG1pbGVzdG9uZVxuICAgIGxldCBtYW5kYXRvcnlDb3VudCA9IDBcbiAgICBsZXQgY29tcGxldGVkTWFuZGF0b3J5Q291bnQgPSAwXG5cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzLmhpZXJhcmNoeU1hcERhdGEpKSB7XG4gICAgICBjb25zdCBpdGVtID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2tleV1cblxuICAgICAgLy8gT25seSBjaGVjayBpdGVtcyB0aGF0IGFyZSBkaXJlY3QgY2hpbGRyZW4gb2YgdGhpcyBtaWxlc3RvbmVcbiAgICAgIGlmIChpdGVtLnBhcmVudCAhPT0gbWlsZXN0b25lSWQpIGNvbnRpbnVlXG5cbiAgICAgIC8vIE9ubHkgY291bnQgY291cnNlcyAobm90IGFzc2Vzc21lbnRzLCBub3Qgb3RoZXIgdHlwZXMpXG4gICAgICBpZiAoaXRlbS5wcmltYXJ5Q2F0ZWdvcnkgIT09ICdDb3Vyc2UnICYmICFpdGVtLmlzQ29sbGVjdGlvbikgY29udGludWVcbiAgICAgIFxuICAgICAgLy8gU2tpcCBpZiB0aGlzIGlzIGFuIGFzc2Vzc21lbnRcbiAgICAgIGNvbnN0IGlzSXRlbUFzc2Vzc21lbnQgPVxuICAgICAgICBpdGVtLnByaW1hcnlDYXRlZ29yeSA9PT0gJ0NvdXJzZSBBc3Nlc3NtZW50JyB8fFxuICAgICAgICBpdGVtLnByaW1hcnlDYXRlZ29yeSA9PT0gJ0ZpbmFsIEFzc2Vzc21lbnQnIHx8XG4gICAgICAgIGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnU3RhbmRhbG9uZSBBc3Nlc3NtZW50JyB8fFxuICAgICAgICBpdGVtLm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLnN1bmJpcmQucXVlc3Rpb25zZXQnXG4gICAgICBpZiAoaXNJdGVtQXNzZXNzbWVudCkgY29udGludWVcblxuICAgICAgLy8gQnkgZGVmYXVsdCwgY291cnNlcyBhcmUgbWFuZGF0b3J5IHVubGVzcyBleHBsaWNpdGx5IG1hcmtlZCBhcyBvcHRpb25hbFxuICAgICAgaWYgKGl0ZW0uaXNNYW5kYXRvcnkgIT09IGZhbHNlKSB7XG4gICAgICAgIG1hbmRhdG9yeUNvdW50KytcbiAgICAgICAgY29uc3QgaXNDb21wbGV0ZWQgPSBpdGVtLmNvbXBsZXRpb25TdGF0dXMgPT09IDIgfHwgaXRlbS5zdGF0dXMgPT09IDIgfHwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLmNvbXBsZXRpb25QZXJjZW50YWdlID49IDEwMCB8fCBpdGVtLnByb2dyZXNzID49IDEwMFxuICAgICAgICBpZiAoaXNDb21wbGV0ZWQpIHtcbiAgICAgICAgICBjb21wbGV0ZWRNYW5kYXRvcnlDb3VudCsrXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBJZiB0aGVyZSBhcmUgbm8gbWFuZGF0b3J5IGNvdXJzZXMsIGFzc2Vzc21lbnQgaXMgdW5sb2NrZWRcbiAgICBpZiAobWFuZGF0b3J5Q291bnQgPT09IDApIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIC8vIExvY2sgYXNzZXNzbWVudCBpZiBub3QgYWxsIG1hbmRhdG9yeSBjb3Vyc2VzIGFyZSBjb21wbGV0ZWRcbiAgICBjb25zdCBhbGxNYW5kYXRvcnlDb21wbGV0ZSA9IGNvbXBsZXRlZE1hbmRhdG9yeUNvdW50ID49IG1hbmRhdG9yeUNvdW50XG4gICAgcmV0dXJuICFhbGxNYW5kYXRvcnlDb21wbGV0ZVxuICB9XG5cbiAgLy8gRk9SIFJJR0hUIFNJREUgUkVTT1VSQ0UgU0NST0xMIE9OIFRPQyBQQUdFXG4gIHJlc291cmNlU2Nyb2xsKCkge1xuICAgIHRoaXMucGFnZVNjcm9sbFN1YnNjcmlwdGlvbiA9IHRoaXMuYXBwVG9jU3ZjLnVwZGF0ZVBhZ2VTY3JvbGwuc3Vic2NyaWJlKCh2YWx1ZTogYm9vbGVhbikgPT4ge1xuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc2Nyb2xsVmlldygpXG4gICAgICAgIH0sIDcwMClcbiAgICAgIH1cbiAgICB9KVxuICB9XG4gIC8vIFRPIFVQREFURSBSRVNPVVJDRSBCRUhBVk9VUiBTVUJKRUNUIEZPUiBSRVNPVVJDRSBTQ1JPTExcbiAgY2hhbmdlUmVzb3VyY2UoKSB7XG4gICAgdGhpcy5hcHBUb2NTdmMuZ2V0UGFnZVNjcm9sbC5uZXh0KHRydWUpXG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgbGV0IHNob3VsZFJlY29tcHV0ZUNhY2hlID0gZmFsc2VcblxuICAgIGZvciAoY29uc3QgcHJvcGVydHkgaW4gY2hhbmdlcykge1xuICAgICAgaWYgKHByb3BlcnR5ID09PSAnZXhwYW5kQWxsJykge1xuICAgICAgICB0aGlzLnZpZXdDaGlsZHJlbiA9IHRoaXMuZXhwYW5kQWxsXG4gICAgICB9XG4gICAgICBpZiAocHJvcGVydHkgPT09ICdwYXRoU2V0JyAmJiBjaGFuZ2VzWydwYXRoU2V0J10pIHtcbiAgICAgICAgbGV0IGN1cnJlbnRWYWx1ZSA9IGNoYW5nZXNbJ3BhdGhTZXQnXS5jdXJyZW50VmFsdWVcbiAgICAgICAgbGV0IHByZXZpb3VzVmFsdWUgPSBjaGFuZ2VzWydwYXRoU2V0J10ucHJldmlvdXNWYWx1ZVxuICAgICAgICBpZiAoY3VycmVudFZhbHVlICYmIHByZXZpb3VzVmFsdWUpIHtcbiAgICAgICAgICBjb25zdCBlcVNldCA9ICh4czogYW55LCB5czogYW55KSA9PlxuICAgICAgICAgICAgeHMuc2l6ZSA9PT0geXMuc2l6ZSAmJlxuICAgICAgICAgICAgWy4uLnhzXS5ldmVyeSgoeCkgPT4geXMuaGFzKHgpKVxuICAgICAgICAgIGlmICghZXFTZXQocHJldmlvdXNWYWx1ZSwgY3VycmVudFZhbHVlKSkgeyB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYocHJldmlvdXNWYWx1ZSA9PT0gdW5kZWZpbmVkKXtcbiAgICAgICAgLy8gICBzZXRUaW1lb3V0KCgpPT57XG4gICAgICAgIC8vICAgfSw3MDApXG4gICAgICAgIC8vIH1cbiAgICAgIH1cbiAgICAgIC8vIHRoaXMuYXBwVG9jU3ZjLmdldFBhZ2VTY3JvbGwubmV4dCh0cnVlKVxuXG4gICAgICBpZiAocHJvcGVydHkgPT09ICdoaWVyYXJjaHlNYXBEYXRhJykge1xuICAgICAgICBpZiAoXy5pc0VtcHR5KGNoYW5nZXNbJ2hpZXJhcmNoeU1hcERhdGEnXS5jdXJyZW50VmFsdWUpKSB7XG4gICAgICAgICAgLy8gdGhpcy5sb2FkaW5nT3ZlcmFsbFBSb2dyZXNzID0gdHJ1ZVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICh0aGlzLmNvbnRlbnQpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlQ2hpbGRQYXJlbnRNYXAodGhpcy5jb250ZW50LmlkZW50aWZpZXIpXG4gICAgICAgICAgfVxuICAgICAgICAgIHNob3VsZFJlY29tcHV0ZUNhY2hlID0gdHJ1ZVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFJlY29tcHV0ZSBjYWNoZSB3aGVuIGNyaXRpY2FsIGlucHV0cyBjaGFuZ2VcbiAgICAgIGlmIChwcm9wZXJ0eSA9PT0gJ2NvbnRlbnQnIHx8IHByb3BlcnR5ID09PSAnYmFzZUNvbnRlbnRSZWFkRGF0YScgfHwgXG4gICAgICAgICAgcHJvcGVydHkgPT09ICdiYXRjaElkJyB8fCBwcm9wZXJ0eSA9PT0gJ2ZvclByZXZpZXcnIHx8IFxuICAgICAgICAgIHByb3BlcnR5ID09PSAncGFyZW50TWlsZXN0b25lTG9ja2VkJyB8fCBwcm9wZXJ0eSA9PT0gJ21sQ291cnNlJykge1xuICAgICAgICBzaG91bGRSZWNvbXB1dGVDYWNoZSA9IHRydWVcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZWNvbXB1dGUgYWxsIGNhY2hlZCBwcm9wZXJ0aWVzIGlmIG5lZWRlZFxuICAgIGlmIChzaG91bGRSZWNvbXB1dGVDYWNoZSkge1xuICAgICAgdGhpcy5jb21wdXRlQWxsQ2FjaGVkUHJvcGVydGllcygpXG4gICAgfVxuICAgIC8vIGNvbnNvbGUubG9nKCdwcmUgYXNzZXNzbWVudCBjb250ZW50LS0tJywgdGhpcy5jb250ZW50KVxuICAgIC8vIGNvbnNvbGUubG9nKCd0aGlzLmhpZXJhcmNoeU1hcERhdGEtLS0nLCB0aGlzLmhpZXJhcmNoeU1hcERhdGEpXG4gIH1cblxuICBjaGVjayhjb250ZW50OiBhbnkpIHtcbiAgICBpZiAodGhpcy5leHBhbmRBY3RpdmUpIHtcbiAgICAgIGNvbnRlbnQudmlld0NoaWxkcmVuID0gdGhpcy5wYXRoU2V0ICYmIHRoaXMucGF0aFNldC5oYXMoY29udGVudC5pZGVudGlmaWVyKSB8fCBjb250ZW50LnZpZXdDaGlsZHJlblxuICAgIH1cbiAgICByZXR1cm4gY29udGVudC52aWV3Q2hpbGRyZW5cbiAgfVxuXG4gIGdldCBpc0NvbGxlY3Rpb24oKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuX2NhY2hlSW5pdGlhbGl6ZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRJc0NvbGxlY3Rpb25cbiAgICB9XG4gICAgaWYgKHRoaXMuY29udGVudCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29udGVudC5taW1lVHlwZSA9PT0gTnNDb250ZW50LkVNaW1lVHlwZXMuQ09MTEVDVElPTlxuICAgIH1cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIGdldCBpc01vZHVsZSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZElzTW9kdWxlXG4gICAgfVxuICAgIGlmICh0aGlzLmNvbnRlbnQpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEVcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBwdWJsaWMgY2hlY2tNb2R1bGUoY29udGVudDogTnNDb250ZW50LklDb250ZW50IHwgbnVsbCk6IGJvb2xlYW4ge1xuICAgIGlmIChjb250ZW50KSB7XG4gICAgICByZXR1cm4gY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIGNoZWNrSXNNb2R1bGUoY29udGVudDogYW55KTogYm9vbGVhbiB7XG4gICAgaWYgKGNvbnRlbnQpIHtcbiAgICAgIHJldHVybiBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuTU9EVUxFXG4gICAgfVxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgZ2V0IGlzQmF0Y2hJblByb2dlc3MoKSB7XG4gICAgaWYgKHRoaXMuYmF0Y2hEYXRhICYmICh0aGlzLmJhdGNoRGF0YS5jb250ZW50ICYmIHRoaXMuYmF0Y2hEYXRhLmNvbnRlbnQubGVuZ3RoKSAmJiB0aGlzLmJhdGNoRGF0YS5lbnJvbGxlZCkge1xuICAgICAgY29uc3QgYmF0Y2hEYXRhID0gdGhpcy5iYXRjaERhdGEuY29udGVudFswXVxuICAgICAgaWYgKGJhdGNoRGF0YSAmJiBiYXRjaERhdGEuZW5kRGF0ZSkge1xuICAgICAgICBjb25zdCBub3cgPSBtb21lbnQoKS5mb3JtYXQoJ1lZWVktTU0tREQnKVxuICAgICAgICBjb25zdCBzdGFydERhdGUgPSBtb21lbnQoYmF0Y2hEYXRhLnN0YXJ0RGF0ZSkuZm9ybWF0KCdZWVlZLU1NLUREJylcbiAgICAgICAgY29uc3QgZW5kRGF0ZSA9IGJhdGNoRGF0YS5lbmREYXRlID8gbW9tZW50KGJhdGNoRGF0YS5lbmREYXRlKS5mb3JtYXQoJ1lZWVktTU0tREQnKSA6IG5vd1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIC8vIGJhdGNoLnN0YXR1cyAmJlxuICAgICAgICAgIG1vbWVudChzdGFydERhdGUpLmlzU2FtZU9yQmVmb3JlKG5vdylcbiAgICAgICAgICAmJiBtb21lbnQoZW5kRGF0ZSkuaXNTYW1lT3JBZnRlcihub3cpXG4gICAgICAgIClcbiAgICAgIH0gcmV0dXJuIHRydWVcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBnZXQgaXNSZXNvdXJjZSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZElzUmVzb3VyY2VcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY29tcHV0ZUlzUmVzb3VyY2UoKVxuICB9XG5cbiAgZ2V0IHJlc291cmNlTGluaygpOiB7IHVybDogc3RyaW5nOyBxdWVyeVBhcmFtczogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB9IHtcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZFJlc291cmNlTGlua1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb21wdXRlUmVzb3VyY2VMaW5rKClcbiAgfVxuXG4gIHB1YmxpYyBwcm9ncmVzc0NvbG9yKCk6IHN0cmluZyB7XG4gICAgLy8gaWYgKHRoaXMuY3VycmVudFByb2dyZXNzIDw9IDMwKSB7XG4gICAgLy8gICByZXR1cm4gJyNEMTM5MjQnXG4gICAgLy8gfSBpZiAodGhpcy5jdXJyZW50UHJvZ3Jlc3MgPiAzMCAmJiB0aGlzLmN1cnJlbnRQcm9ncmVzcyA8PSA3MCkge1xuICAgIC8vICAgcmV0dXJuICcjRTk5RTM4J1xuICAgIC8vIH1cbiAgICAvLyBpZiAodGhpcy5jdXJyZW50UHJvZ3Jlc3MgPiA3MCAmJiB0aGlzLmN1cnJlbnRQcm9ncmVzcyA8PSAxMDApIHtcbiAgICAvLyAgIHJldHVybiAnIzFEODkyMydcbiAgICAvLyB9XG5cbiAgICByZXR1cm4gJyMxRDg5MjMnXG4gIH1cbiAgcHVibGljIHByb2dyZXNzQ29sb3IyKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICcjZjI3ZDAwJ1xuICB9XG5cbiAgcHJpdmF0ZSBldmFsdWF0ZUltbWVkaWF0ZUNoaWxkcmVuU3RydWN0dXJlKCkge1xuICAgIGlmICh0aGlzLmNvbnRlbnQgJiYgdGhpcy5jb250ZW50LmNoaWxkcmVuICYmIHRoaXMuY29udGVudC5jaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgIHRoaXMuY29udGVudC5jaGlsZHJlbi5mb3JFYWNoKChjaGlsZDogTnNDb250ZW50LklDb250ZW50KSA9PiB7XG4gICAgICAgIGlmIChjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkNPVVJTRSkge1xuICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS5jb3Vyc2UgKz0gMVxuICAgICAgICB9IGVsc2UgaWYgKGNoaWxkLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuS05PV0xFREdFX0FSVElGQUNUKSB7XG4gICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLm90aGVyICs9IDFcbiAgICAgICAgfSBlbHNlIGlmIChjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRSkge1xuICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS5sZWFybmluZ01vZHVsZSArPSAxXG4gICAgICAgIH0gZWxzZSBpZiAoY2hpbGQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5PRkZMSU5FX1NFU1NJT04pIHtcbiAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUub2ZmbGluZVNlc3Npb24gKz0gMVxuICAgICAgICB9IGVsc2UgaWYgKGNoaWxkLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuUkVTT1VSQ0UpIHtcbiAgICAgICAgICBzd2l0Y2ggKGNoaWxkLm1pbWVUeXBlKSB7XG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLkhBTkRTX09OOlxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUuaGFuZHNPbiArPSAxXG4gICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLk1QMzpcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLnBvZGNhc3QgKz0gMVxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5NUDQ6XG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLk0zVTg6XG4gICAgICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS52aWRlbyArPSAxXG4gICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLklOVEVSQUNUSU9OOlxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUuaW50ZXJhY3RpdmVWaWRlbyArPSAxXG4gICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLlBERjpcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLnBkZiArPSAxXG4gICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLk9GRkxJTkVfU0VTU0lPTjpcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLm9mZmxpbmVTZXNzaW9uICs9IDFcbiAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuU1VSVkVZOlxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUuc3VydmV5ICs9IDFcbiAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuSFRNTDpcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLndlYlBhZ2UgKz0gMVxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5RVUlaOlxuICAgICAgICAgICAgICBpZiAoY2hpbGQucmVzb3VyY2VUeXBlID09PSAnQXNzZXNzbWVudCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUuYXNzZXNzbWVudCArPSAxXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLnF1aXogKz0gMVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLlBSQUNUSUNFX1JFU09VUkNFOlxuICAgICAgICAgICAgICAvLyBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLkZJTkFMX0FTU0VTU01FTlQ6XG4gICAgICAgICAgICAgIC8vIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuUFJBQ1RJQ0VfUkVTT1VSQ0U6XG4gICAgICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS5wcmFjdGljZVRlc3QgKz0gMVxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5XRUJfTU9EVUxFOlxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUud2ViTW9kdWxlICs9IDFcbiAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuWU9VVFVCRTpcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLnlvdXR1YmUgKz0gMVxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLm90aGVyICs9IDFcbiAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICAgIGZvciAoY29uc3Qga2V5IGluIHRoaXMuY29udGVudFN0cnVjdHVyZSkge1xuICAgICAgaWYgKHRoaXMuY29udGVudFN0cnVjdHVyZVtrZXldID4gMCkge1xuICAgICAgICB0aGlzLmhhc0NvbnRlbnRTdHJ1Y3R1cmUgPSB0cnVlXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0IGNvbnRleHRQYXRoKCkge1xuICAgIHJldHVybiB7XG4gICAgICBjb250ZXh0SWQ6IHRoaXMucm9vdElkLFxuICAgICAgY29udGV4dFBhdGg6IHRoaXMucm9vdENvbnRlbnRUeXBlLFxuICAgICAgYmF0Y2hJZDogdGhpcy5iYXRjaElkLFxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBjb250ZW50VHJhY2tCeShfaW5kZXg6IG51bWJlciwgY29udGVudDogTnNDb250ZW50LklDb250ZW50KSB7XG4gICAgaWYgKCFjb250ZW50KSB7XG4gICAgICByZXR1cm4gbnVsbFxuICAgIH1cbiAgICByZXR1cm4gY29udGVudC5pZGVudGlmaWVyXG4gIH1cblxuICBwdWJsaWMgcmFpc2VUZWxlbWV0cnkoKSB7XG4gICAgLy8gaWYgKHRoaXMuZm9yUHJldmlldykgeyByZXR1cm4gfVxuICAgIGlmICh0aGlzLmNvbnRlbnQpIHtcbiAgICAgIHRoaXMuZXZlbnRzLnJhaXNlSW50ZXJhY3RUZWxlbWV0cnkoXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnY2xpY2snLFxuICAgICAgICAgIHN1YlR5cGU6IGBjYXJkLXRvY0NvbnRlbnRDYXJkYCxcbiAgICAgICAgICAvLyBpZDogdGhpcy5jb250ZW50LmlkZW50aWZpZXIgfHwgJycsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAvLyBjb250ZW50SWQ6IHRoaXMuY29udGVudC5pZGVudGlmaWVyIHx8ICcnLFxuICAgICAgICAgIC8vIGNvbnRlbnRUeXBlOiB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5LFxuICAgICAgICAgIGlkOiB0aGlzLmNvbnRlbnQuaWRlbnRpZmllciB8fCAnJyxcbiAgICAgICAgICB0eXBlOiB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5LFxuICAgICAgICAgIHJvbGx1cDoge1xuICAgICAgICAgICAgbDE6IHRoaXMucm9vdElkIHx8ICcnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdmVyOiBgJHt0aGlzLmNvbnRlbnQudmVyc2lvbn0keycnfWAsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYWdlSWRFeHQ6IGAke18uY2FtZWxDYXNlKHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkpfS1jYXJkYCxcbiAgICAgICAgICBtb2R1bGU6IF8uY2FtZWxDYXNlKHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkpLFxuICAgICAgICB9KVxuICAgIH1cbiAgfVxuICBnZXQgaXNBbGxvd2VkKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLmNvbnRlbnQpIHtcbiAgICAgIHJldHVybiAhKE5zQ29udGVudC5VTl9TVVBQT1JURURfREFUQV9UWVBFU19GT1JfTk9OX0JBVENIX1VTRVJTLmluZGV4T2YodGhpcy5jb250ZW50Lm1pbWVUeXBlKSA+PSAwKVxuICAgIH0gcmV0dXJuIGZhbHNlXG4gIH1cblxuICBnZXQgaXNFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBnZXQgaXNFbnJvbGxlZCgpOiBib29sZWFuIHtcbiAgICAvLyBDaGVjayBib3RoIGJhdGNoSWQgYW5kIGJhdGNoRGF0YS5lbnJvbGxlZCB0byBzdXBwb3J0IExlYXJuaW5nIFBhdGh3YXlzXG4gICAgLy8gd2hlcmUgYmF0Y2hJZCBtaWdodCBub3QgYmUgZGlyZWN0bHkgc2V0IGJ1dCB1c2VyIGlzIGVucm9sbGVkIGluIGNvdXJzZXMgd2l0aGluIHRoZSBwYXRod2F5XG4gICAgcmV0dXJuIHRoaXMuYmF0Y2hJZCA/IHRydWUgOiAodGhpcy5iYXRjaERhdGE/LmVucm9sbGVkIHx8IGZhbHNlKVxuICB9XG5cbiAgdXBkYXRlQ2hpbGRQYXJlbnRNYXAoaWRlbnRpZmllcjogc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0pIHtcbiAgICAgIGxldCBsb2NhbENvbnRlbnREYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdXG4gICAgICBpZiAoXG4gICAgICAgICEobG9jYWxDb250ZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LlJFU09VUkNFXG4gICAgICAgICAgfHwgbG9jYWxDb250ZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFXG4gICAgICAgICAgfHwgbG9jYWxDb250ZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlRcbiAgICAgICAgICB8fCBsb2NhbENvbnRlbnREYXRhLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UKVxuICAgICAgKSB7XG4gICAgICAgIC8vIHJlYWwgcGVyY2VudCBsb2dpY1xuICAgICAgICAvLyBjb25zdCB0b3RhbCA9IGxvY2FsQ29udGVudERhdGEubGVhZk5vZGVzLnJlZHVjZSgoc3VtOiBudW1iZXIsIGNoaWxkSWQ6IHN0cmluZykgPT4ge1xuICAgICAgICAvLyAgIHJldHVybiBzdW0gKyBOdW1iZXIodGhpcy5oaWVyYXJjaHlNYXBEYXRhW2NoaWxkSWRdLmNvbXBsZXRpb25QZXJjZW50YWdlIHx8IDApXG4gICAgICAgIC8vIH0sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKVxuICAgICAgICAvLyBjb25zb2xlLmxvZygndG90YWwgJywgdG90YWwpXG4gICAgICAgIC8vIGlmKHRvdGFsID4gMCkge1xuICAgICAgICAvLyAgIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXVsnY29tcGxldGlvblBlcmNlbnRhZ2UnXSA9IHRvdGFsIC8gXy50b0ludGVnZXIoXy5nZXQodGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdLCAnbGVhZk5vZGVzQ291bnQnKSlcbiAgICAgICAgLy8gfVxuICAgICAgICBpZiAobG9jYWxDb250ZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRSkge1xuICAgICAgICAgIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXVsnZHVyYXRpb24nXSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXS5sZWFmTm9kZXMucmVkdWNlKFxuICAgICAgICAgICAgKHN1bTogYW55LCBjaGlsZElEOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgaWYgKHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbY2hpbGRJRF0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc3VtICsgTnVtYmVyKHRoaXMuaGllcmFyY2h5TWFwRGF0YVtjaGlsZElEXS5kdXJhdGlvbiB8fCB0aGlzLmhpZXJhcmNoeU1hcERhdGFbY2hpbGRJRF0uZXhwZWN0ZWREdXJhdGlvbiB8fCAwKVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH0sIDApXG4gICAgICAgIH1cbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGVcbiAgICAgICAgY29uc3QgY29tcGxldGVkSXRlbXMgPSBfLmZpbHRlcih0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0ubGVhZk5vZGVzLCByID0+ICh0aGlzLmhpZXJhcmNoeU1hcERhdGFbcl0gJiYgKHRoaXMuaGllcmFyY2h5TWFwRGF0YVtyXS5jb21wbGV0aW9uU3RhdHVzID09PSAyIHx8IHRoaXMuaGllcmFyY2h5TWFwRGF0YVtyXS5jb21wbGV0aW9uUGVyY2VudGFnZSA9PT0gMTAwKSkpXG4gICAgICAgIGNvbnN0IHRvdGFsQ291bnQgPSBfLnRvSW50ZWdlcihfLmdldCh0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0sICdsZWFmTm9kZXNDb3VudCcpKSB8fCAxXG4gICAgICAgIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXVsnY29tcGxldGlvblBlcmNlbnRhZ2UnXSA9IE51bWJlcigoKGNvbXBsZXRlZEl0ZW1zLmxlbmd0aCAvIHRvdGFsQ291bnQpICogMTAwKS50b0ZpeGVkKCkpXG4gICAgICAgIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXVsnY29tcGxldGlvblN0YXR1cyddID0gKHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXS5jb21wbGV0aW9uUGVyY2VudGFnZSA+PSAxMDApID8gMiA6IDFcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl1cbiAgICB9XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBnZXRDb21wbGV0aW9uUGVyY2VudGFnZShpZGVudGlmaWVyOiBzdHJpbmcpIHtcbiAgICAvLyBjb25zb2xlLmxvZygnZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UnLCBpZGVudGlmaWVyKVxuICAgIC8vIGNvbnNvbGUubG9nKCd0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0gOiAnLCB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0pXG4gICAgLy8gY29uc3QgaXRlbSA9IHRoaXMudXBkYXRlQ2hpbGRQYXJlbnRNYXAoaWRlbnRpZmllcilcbiAgICBsZXQgcGVyY2VudCA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0gJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdLmNvbXBsZXRpb25QZXJjZW50YWdlIHx8IDBcbiAgICByZXR1cm4gdGhpcy5yb3VuZElmRGVjaW1hbChwZXJjZW50KVxuICB9XG5cbiAgcm91bmRJZkRlY2ltYWwodmFsdWU6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHBhcnNlRmxvYXQodmFsdWUudG9GaXhlZCgyKSlcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlXG4gIH1cblxuXG4gIGdldENvbXBsZXRpb25TdGF0dXMoaWRlbnRpZmllcjogc3RyaW5nKSB7XG4gICAgLy8gY29uc29sZS5sb2coJ2dldENvbXBsZXRpb25TdGF0dXMnKVxuICAgIC8vIGNvbnN0IGl0ZW0gPSB0aGlzLnVwZGF0ZUNoaWxkUGFyZW50TWFwKGlkZW50aWZpZXIpXG4gICAgcmV0dXJuIHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0gJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdLmNvbXBsZXRpb25TdGF0dXNcbiAgfVxuXG4gIG9wZW5DZXJ0aWZpY2F0ZURpYWxvZyhjZXJ0RGF0YTogYW55KSB7XG4gICAgY29uc3QgY2V0ID0gY2VydERhdGFcbiAgICB0aGlzLmRpYWxvZy5vcGVuKENlcnRpZmljYXRlRGlhbG9nQ29tcG9uZW50LCB7XG4gICAgICAvLyBoZWlnaHQ6ICc0MDBweCcsXG4gICAgICB3aWR0aDogJzEzMDBweCcsXG4gICAgICBkYXRhOiB7IGNldCB9LFxuICAgICAgLy8gcGFuZWxDbGFzczogJ2N1c3RvbS1kaWFsb2ctY29udGFpbmVyJyxcbiAgICB9KVxuICB9XG4gIHNjcm9sbFZpZXcoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGxldCBlcnJvckZpZWxkOiBhbnkgPSB0aGlzLnJlbmRlcmVyLnNlbGVjdFJvb3RFbGVtZW50KCcucmVzb3VyY2UtY29udGFpbmVyIC5yZXNvdXJjZS1hY3RpdmUnKVxuICAgICAgaWYgKGVycm9yRmllbGQpIHtcbiAgICAgICAgZXJyb3JGaWVsZC5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiBcInNtb290aFwiLCBibG9jazogXCJzdGFydFwiLCBpbmxpbmU6IFwibmVhcmVzdFwiIH0pXG4gICAgICB9XG4gICAgICBpZiAodGhpcy5jb21wb25lbnROYW1lID09PSAndG9jJykge1xuICAgICAgICBpZiAoZXJyb3JGaWVsZCkge1xuICAgICAgICAgIGNvbnN0IHJlY3QgPSBlcnJvckZpZWxkLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgICAgICAgaWYgKHJlY3QudG9wIC0gNDIwID4gMCkge1xuICAgICAgICAgICAgd2luZG93LnNjcm9sbCg0MjAsIHJlY3QudG9wIC0gMTQ4KVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuYXBwVG9jU3ZjLmdldFBhZ2VTY3JvbGwubmV4dChmYWxzZSlcbiAgICAgIH0sIDcwMClcblxuICAgICAgLy8gZWxzZSB7XG4gICAgICAvLyAgIGVycm9yRmllbGQuc2Nyb2xsSW50b1ZpZXcoeyBiZWhhdmlvcjogXCJzbW9vdGhcIiwgYmxvY2s6IFwic3RhcnRcIiwgaW5saW5lOiBcIm5lYXJlc3RcIiB9KTtcbiAgICAgIC8vICAgY29uc3QgcmVjdCA9IGVycm9yRmllbGQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAvLyAgIGVycm9yRmllbGQuc2Nyb2xsKDAscmVjdC50b3AtNTYpXG4gICAgICAvLyB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgfVxuICB9XG5cbiAgZG93bmxvYWRDZXJ0aWZpY2F0ZShjZXJ0aWZpY2F0ZURhdGE6IGFueSkge1xuICAgIHRoaXMuZXZlbnRzLnJhaXNlSW50ZXJhY3RUZWxlbWV0cnkoXG4gICAgICB7XG4gICAgICAgIHR5cGU6IFdzRXZlbnRzLkVudW1JbnRlcmFjdFR5cGVzLkNMSUNLLFxuICAgICAgICBpZDogJ3ZpZXctY2VydGlmaWNhdGUnLFxuICAgICAgICBzdWJUeXBlOiBXc0V2ZW50cy5FbnVtSW50ZXJhY3RTdWJUeXBlcy5DRVJUSUZJQ0FURSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGlkOiBjZXJ0aWZpY2F0ZURhdGEsICAgLy8gaWQgb2YgdGhlIGNlcnRpZmljYXRlXG4gICAgICAgIHR5cGU6IFdzRXZlbnRzLkVudW1JbnRlcmFjdFN1YlR5cGVzLkNFUlRJRklDQVRFLFxuICAgICAgfSlcbiAgICBpZiAoY2VydGlmaWNhdGVEYXRhKSB7XG4gICAgICB0aGlzLmRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nID0gdHJ1ZVxuICAgICAgbGV0IGNlcnREYXRhOiBhbnkgPSBjZXJ0aWZpY2F0ZURhdGFcbiAgICAgIHRoaXMuY2VydGlmaWNhdGVTZXJ2aWNlLmRvd25sb2FkQ2VydGlmaWNhdGVfdjIoY2VydERhdGEpLnN1YnNjcmliZSgocmVzOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5kb3dubG9hZENlcnRpZmljYXRlTG9hZGluZyA9IGZhbHNlXG4gICAgICAgIGNvbnN0IGNldCA9IHJlcy5yZXN1bHQucHJpbnRVcmlcbiAgICAgICAgdGhpcy5kaWFsb2cub3BlbihDZXJ0aWZpY2F0ZURpYWxvZ0NvbXBvbmVudCwge1xuICAgICAgICAgIHdpZHRoOiAnMTMwMHB4JyxcbiAgICAgICAgICBkYXRhOiB7IGNldCwgY2VydElkOiBjZXJ0RGF0YS5pZGVudGlmaWVyIH0sXG4gICAgICAgIH0pXG4gICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nID0gZmFsc2VcbiAgICB9XG4gIH1cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgaWYgKHRoaXMuaGFzaG1hcFVwZGF0ZWRTdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMuaGFzaG1hcFVwZGF0ZWRTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKVxuICAgIH1cbiAgICBpZiAodGhpcy5wYWdlU2Nyb2xsU3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLnBhZ2VTY3JvbGxTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKVxuICAgIH1cbiAgfVxuXG4gIGdldCBjaGVja0ZvckN1cmF0ZWRQcm9ncmFtKCkge1xuICAgIGlmICh0aGlzLl9jYWNoZUluaXRpYWxpemVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVkQ2hlY2tGb3JDdXJhdGVkUHJvZ3JhbVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb21wdXRlQ2hlY2tGb3JDdXJhdGVkUHJvZ3JhbSgpXG4gIH1cblxuICBnZXQgaXNDb250ZW50VW5sb2NrZWQoKSB7XG4gICAgaWYgKHRoaXMuX2NhY2hlSW5pdGlhbGl6ZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRJc0NvbnRlbnRVbmxvY2tlZFxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb21wdXRlSXNDb250ZW50VW5sb2NrZWQoKVxuICB9XG5cbiAgZ2V0IGlzUGFyZW50TWlsZXN0b25lTG9ja2VkKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLl9jYWNoZUluaXRpYWxpemVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVkSXNQYXJlbnRNaWxlc3RvbmVMb2NrZWRcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY29tcHV0ZUlzUGFyZW50TWlsZXN0b25lTG9ja2VkKClcbiAgfVxuXG4gIGdldCBpc01pbGVzdG9uZUxvY2tlZCgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZElzTWlsZXN0b25lTG9ja2VkXG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZUxvY2tlZCgpXG4gIH1cblxuICBnZXQgaXNNaWxlc3RvbmVBc3Nlc3NtZW50KCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLl9jYWNoZUluaXRpYWxpemVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmVBc3Nlc3NtZW50XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZUFzc2Vzc21lbnQoKVxuICB9XG5cbiAgZ2V0IGlzTWlsZXN0b25lQXNzZXNzbWVudExvY2tlZCgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZElzTWlsZXN0b25lQXNzZXNzbWVudExvY2tlZFxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb21wdXRlSXNNaWxlc3RvbmVBc3Nlc3NtZW50TG9ja2VkKClcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIG1pbGVzdG9uZSdzIG1hbmRhdG9yeSBjb3Vyc2VzIGFuZCBhc3Nlc3NtZW50IGFyZSBjb21wbGV0ZWQuXG4gICAqIExvb2tzIGF0IHRoZSBjb250ZW50IGhpZXJhcmNoeSB0byBmaW5kIGNoaWxkcmVuIG9mIHRoZSBtaWxlc3RvbmUuXG4gICAqL1xuICBwcml2YXRlIGNoZWNrTWlsZXN0b25lQ29udGVudENvbXBsZXRpb24obWlsZXN0b25lSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5iYXNlQ29udGVudFJlYWREYXRhIHx8ICF0aGlzLmJhc2VDb250ZW50UmVhZERhdGEuY2hpbGRyZW4gfHwgIXRoaXMuaGllcmFyY2h5TWFwRGF0YSkge1xuICAgICAgLy8gRmFsbGJhY2s6IFRyeSB0byBmaW5kIGFzc2Vzc21lbnQgY29tcGxldGlvbiBpbiBoYXNobWFwIGZvciB0aGlzIG1pbGVzdG9uZVxuICAgICAgcmV0dXJuIHRoaXMuY2hlY2tNaWxlc3RvbmVBc3Nlc3NtZW50Q29tcGxldGlvbihtaWxlc3RvbmVJZClcbiAgICB9XG5cbiAgICAvLyBGaW5kIHRoZSBtaWxlc3RvbmUgaW4gdGhlIGNvbnRlbnQgaGllcmFyY2h5XG4gICAgY29uc3QgbWlsZXN0b25lQ29udGVudCA9IHRoaXMuZmluZENvbnRlbnRJbkhpZXJhcmNoeSh0aGlzLmJhc2VDb250ZW50UmVhZERhdGEsIG1pbGVzdG9uZUlkKVxuICAgIGlmICghbWlsZXN0b25lQ29udGVudCB8fCAhbWlsZXN0b25lQ29udGVudC5jaGlsZHJlbikge1xuICAgICAgcmV0dXJuIHRoaXMuY2hlY2tNaWxlc3RvbmVBc3Nlc3NtZW50Q29tcGxldGlvbihtaWxlc3RvbmVJZClcbiAgICB9XG5cbiAgICAvLyBDaGVjayBhbGwgbWFuZGF0b3J5IGNvdXJzZXMgYW5kIGFzc2Vzc21lbnRzXG4gICAgbGV0IGFsbE1hbmRhdG9yeUNvbXBsZXRlID0gdHJ1ZVxuICAgIGxldCBoYXNBc3Nlc3NtZW50ID0gZmFsc2VcbiAgICBsZXQgYXNzZXNzbWVudENvbXBsZXRlID0gZmFsc2VcblxuICAgIG1pbGVzdG9uZUNvbnRlbnQuY2hpbGRyZW4uZm9yRWFjaCgoY2hpbGQ6IGFueSkgPT4ge1xuICAgICAgY29uc3QgY2hpbGREYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2NoaWxkLmlkZW50aWZpZXJdXG4gICAgICBjb25zdCBpc0Fzc2Vzc21lbnQgPSBjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdDb3Vyc2UgQXNzZXNzbWVudCcgfHxcbiAgICAgICAgY2hpbGQuY291cnNlQ2F0ZWdvcnkgPT09ICdDb3Vyc2UgQXNzZXNzbWVudCcgfHxcbiAgICAgICAgY2hpbGQucHJpbWFyeUNhdGVnb3J5ID09PSAnRmluYWwgQXNzZXNzbWVudCdcbiAgICAgIGNvbnN0IGlzTWFuZGF0b3J5ID0gY2hpbGQubWFuZGF0b3J5ID09PSB0cnVlIHx8IGNoaWxkLm9wdGlvbmFsUmVhZGluZyAhPT0gdHJ1ZVxuXG4gICAgICBpZiAoaXNBc3Nlc3NtZW50KSB7XG4gICAgICAgIGhhc0Fzc2Vzc21lbnQgPSB0cnVlXG4gICAgICAgIGlmIChjaGlsZERhdGEgJiYgKGNoaWxkRGF0YS5jb21wbGV0aW9uU3RhdHVzID09PSAyIHx8IGNoaWxkRGF0YS5jb21wbGV0aW9uUGVyY2VudGFnZSA+PSAxMDApKSB7XG4gICAgICAgICAgYXNzZXNzbWVudENvbXBsZXRlID0gdHJ1ZVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGlzTWFuZGF0b3J5KSB7XG4gICAgICAgIC8vIENoZWNrIGlmIG1hbmRhdG9yeSBjb250ZW50IGlzIGNvbXBsZXRlZFxuICAgICAgICBpZiAoIWNoaWxkRGF0YSB8fCAoY2hpbGREYXRhLmNvbXBsZXRpb25TdGF0dXMgIT09IDIgJiYgY2hpbGREYXRhLmNvbXBsZXRpb25QZXJjZW50YWdlIDwgMTAwKSkge1xuICAgICAgICAgIGFsbE1hbmRhdG9yeUNvbXBsZXRlID0gZmFsc2VcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG5cbiAgICBjb25zb2xlLmxvZygnTWlsZXN0b25lIGNvbnRlbnQgY2hlY2s6JywgeyBhbGxNYW5kYXRvcnlDb21wbGV0ZSwgaGFzQXNzZXNzbWVudCwgYXNzZXNzbWVudENvbXBsZXRlIH0pXG5cbiAgICAvLyBNaWxlc3RvbmUgaXMgY29tcGxldGUgaWYgYXNzZXNzbWVudCBpcyBjb21wbGV0ZSAobWFuZGF0b3J5IGNvdXJzZXMgb3B0aW9uYWwgYmFzZWQgb24gcmVxdWlyZW1lbnRzKVxuICAgIHJldHVybiBoYXNBc3Nlc3NtZW50ID8gYXNzZXNzbWVudENvbXBsZXRlIDogYWxsTWFuZGF0b3J5Q29tcGxldGVcbiAgfVxuXG4gIC8qKlxuICAgKiBGYWxsYmFjazogQ2hlY2sgaWYgZW5vdWdoIGFzc2Vzc21lbnRzIGFyZSBjb21wbGV0ZWQgdG8gdW5sb2NrIHRoaXMgbWlsZXN0b25lLlxuICAgKiBGb3IgbWlsZXN0b25lIGF0IGluZGV4IE4sIHdlIG5lZWQgYXQgbGVhc3QgTiBjb21wbGV0ZWQgYXNzZXNzbWVudHMuXG4gICAqIEUuZy4sIEZvciBNMiAoaW5kZXggMSksIHdlIG5lZWQgMSBjb21wbGV0ZWQgYXNzZXNzbWVudCAoTTEncyBhc3Nlc3NtZW50KVxuICAgKiAgICAgICBGb3IgTTMgKGluZGV4IDIpLCB3ZSBuZWVkIDIgY29tcGxldGVkIGFzc2Vzc21lbnRzIChNMSdzIGFuZCBNMidzKVxuICAgKi9cbiAgcHJpdmF0ZSBjaGVja01pbGVzdG9uZUFzc2Vzc21lbnRDb21wbGV0aW9uKG1pbGVzdG9uZUlkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMuaGllcmFyY2h5TWFwRGF0YSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gRXh0cmFjdCBtaWxlc3RvbmUgbnVtYmVyIGZyb20gSUQgKE0xIC0+IDEsIE0yIC0+IDIsIGV0Yy4pXG4gICAgY29uc3QgbWlsZXN0b25lTnVtID0gcGFyc2VJbnQobWlsZXN0b25lSWQucmVwbGFjZSgvXFxEL2csICcnKSkgfHwgMFxuICAgIGNvbnN0IHJlcXVpcmVkQ29tcGxldGVkQXNzZXNzbWVudHMgPSBtaWxlc3RvbmVOdW0gLSAxIC8vIEZvciBNMiwgbmVlZCAxOyBmb3IgTTMsIG5lZWQgMlxuXG4gICAgY29uc29sZS5sb2coYE1pbGVzdG9uZSAke21pbGVzdG9uZUlkfSAobnVtOiAke21pbGVzdG9uZU51bX0pIHJlcXVpcmVzICR7cmVxdWlyZWRDb21wbGV0ZWRBc3Nlc3NtZW50c30gY29tcGxldGVkIGFzc2Vzc21lbnRzYClcblxuICAgIGlmIChyZXF1aXJlZENvbXBsZXRlZEFzc2Vzc21lbnRzIDw9IDApIHtcbiAgICAgIHJldHVybiB0cnVlIC8vIEZpcnN0IG1pbGVzdG9uZSwgbm8gcmVxdWlyZW1lbnRzXG4gICAgfVxuXG4gICAgLy8gQ291bnQgY29tcGxldGVkIENvdXJzZSBBc3Nlc3NtZW50cyB0aGF0IGFyZSBJTlNJREUgbWlsZXN0b25lcyAoaGF2ZSBhIHBhcmVudClcbiAgICAvLyBFeGNsdWRlIHByZS1lbnJvbGxtZW50IGFzc2Vzc21lbnRzIGF0IHRoZSByb290IGxldmVsIChubyBwYXJlbnQgb3IgcGFyZW50IGlzIExlYXJuaW5nIFBhdGh3YXkpXG4gICAgbGV0IGNvbXBsZXRlZE1pbGVzdG9uZUFzc2Vzc21lbnRDb3VudCA9IDBcbiAgICBjb25zdCBsZWFybmluZ1BhdGh3YXlJZCA9IHRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YT8uaWRlbnRpZmllclxuXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXModGhpcy5oaWVyYXJjaHlNYXBEYXRhKSkge1xuICAgICAgY29uc3QgaXRlbSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVtrZXldXG5cbiAgICAgIC8vIENoZWNrIGlmIGl0J3MgYSBjb21wbGV0ZWQgQ291cnNlIEFzc2Vzc21lbnRcbiAgICAgIGlmICgoaXRlbS5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdDb3Vyc2UgQXNzZXNzbWVudCcgfHwgaXRlbS5jb3Vyc2VDYXRlZ29yeSA9PT0gJ0NvdXJzZSBBc3Nlc3NtZW50JykgJiZcbiAgICAgICAgKGl0ZW0uY29tcGxldGlvblN0YXR1cyA9PT0gMiB8fCBpdGVtLmNvbXBsZXRpb25QZXJjZW50YWdlID49IDEwMCkpIHtcblxuICAgICAgICAvLyBDaGVjayBpZiB0aGlzIGFzc2Vzc21lbnQgaGFzIGEgcGFyZW50IChtZWFuaW5nIGl0J3MgaW5zaWRlIGEgY291cnNlL21pbGVzdG9uZSwgbm90IGF0IHJvb3QgbGV2ZWwpXG4gICAgICAgIC8vIEFsc28gZXhjbHVkZSBpZiBwYXJlbnQgaXMgdGhlIExlYXJuaW5nIFBhdGh3YXkgaXRzZWxmIChwcmUtZW5yb2xsbWVudCBhc3Nlc3NtZW50KVxuICAgICAgICBjb25zdCBoYXNQYXJlbnQgPSBpdGVtLnBhcmVudCAmJiBpdGVtLnBhcmVudCAhPT0gbGVhcm5pbmdQYXRod2F5SWRcblxuICAgICAgICBpZiAoaGFzUGFyZW50KSB7XG4gICAgICAgICAgY29tcGxldGVkTWlsZXN0b25lQXNzZXNzbWVudENvdW50KytcbiAgICAgICAgICBjb25zb2xlLmxvZyhgRm91bmQgY29tcGxldGVkIE1JTEVTVE9ORSBhc3Nlc3NtZW50OiAke2tleX1gLCBpdGVtKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBTa2lwcGluZyByb290LWxldmVsL3ByZS1lbnJvbGxtZW50IGFzc2Vzc21lbnQ6ICR7a2V5fWApXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZyhgVG90YWwgY29tcGxldGVkIE1JTEVTVE9ORSBhc3Nlc3NtZW50czogJHtjb21wbGV0ZWRNaWxlc3RvbmVBc3Nlc3NtZW50Q291bnR9LCBSZXF1aXJlZDogJHtyZXF1aXJlZENvbXBsZXRlZEFzc2Vzc21lbnRzfWApXG5cbiAgICAvLyBJZiB3ZSBoYXZlIGVub3VnaCBjb21wbGV0ZWQgbWlsZXN0b25lIGFzc2Vzc21lbnRzLCB1bmxvY2sgdGhpcyBtaWxlc3RvbmVcbiAgICByZXR1cm4gY29tcGxldGVkTWlsZXN0b25lQXNzZXNzbWVudENvdW50ID49IHJlcXVpcmVkQ29tcGxldGVkQXNzZXNzbWVudHNcbiAgfVxuXG4gIHByaXZhdGUgZmluZENvbnRlbnRJbkhpZXJhcmNoeShjb250ZW50OiBhbnksIGlkZW50aWZpZXI6IHN0cmluZyk6IGFueSB7XG4gICAgaWYgKCFjb250ZW50KSByZXR1cm4gbnVsbFxuICAgIGlmIChjb250ZW50LmlkZW50aWZpZXIgPT09IGlkZW50aWZpZXIpIHJldHVybiBjb250ZW50XG4gICAgaWYgKGNvbnRlbnQuY2hpbGRyZW4pIHtcbiAgICAgIGZvciAoY29uc3QgY2hpbGQgb2YgY29udGVudC5jaGlsZHJlbikge1xuICAgICAgICBjb25zdCBmb3VuZCA9IHRoaXMuZmluZENvbnRlbnRJbkhpZXJhcmNoeShjaGlsZCwgaWRlbnRpZmllcilcbiAgICAgICAgaWYgKGZvdW5kKSByZXR1cm4gZm91bmRcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIGdldCBjb21wdXRlZFF1ZXJ5UGFyYW1zKCkge1xuICAgIGlmICh0aGlzLmlzQWxsb3dlZCAmJiAhdGhpcy5mb3JQcmV2aWV3ICYmIHRoaXMuaXNFbmFibGVkKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi50aGlzLnJlc291cmNlTGluay5xdWVyeVBhcmFtcyxcbiAgICAgICAgcHJlQXNzZXNzbWVudDogJ3RydWUnXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsXG4gIH1cblxuICBnZXQgaXNNaWxlc3RvbmUoKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuX2NhY2hlSW5pdGlhbGl6ZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRJc01pbGVzdG9uZVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb21wdXRlSXNNaWxlc3RvbmUoKVxuICB9XG5cbiAgZ2V0TWlsZXN0b25lQ29tcGxldGVkQ291bnQoKTogbnVtYmVyIHtcbiAgICBpZiAoIXRoaXMuY29udGVudCB8fCAhdGhpcy5oaWVyYXJjaHlNYXBEYXRhKSB7XG4gICAgICByZXR1cm4gMFxuICAgIH1cbiAgICBjb25zdCBtaWxlc3RvbmVEYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudC5pZGVudGlmaWVyXVxuICAgIGlmICghbWlsZXN0b25lRGF0YSB8fCAhbWlsZXN0b25lRGF0YS5sZWFmTm9kZXMpIHtcbiAgICAgIHJldHVybiAwXG4gICAgfVxuICAgIGxldCBjb21wbGV0ZWRDb3VudCA9IDBcbiAgICBtaWxlc3RvbmVEYXRhLmxlYWZOb2Rlcy5mb3JFYWNoKChsZWFmSWQ6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgbGVhZkRhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbbGVhZklkXVxuICAgICAgaWYgKGxlYWZEYXRhICYmIGxlYWZEYXRhLmNvbXBsZXRpb25TdGF0dXMgPT09IDIpIHtcbiAgICAgICAgY29tcGxldGVkQ291bnQrK1xuICAgICAgfVxuICAgIH0pXG4gICAgcmV0dXJuIGNvbXBsZXRlZENvdW50XG4gIH1cblxuICAvKipcbiAgICogR2V0IHVubG9jayBjcml0ZXJpYSBtZXNzYWdlIGZvciBsb2NrZWQgbWlsZXN0b25lc1xuICAgKi9cbiAgZ2V0TWlsZXN0b25lVW5sb2NrTWVzc2FnZSgpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5jb250ZW50IHx8ICF0aGlzLmhpZXJhcmNoeU1hcERhdGEpIHtcbiAgICAgIHJldHVybiAnJ1xuICAgIH1cblxuICAgIGNvbnN0IG1pbGVzdG9uZURhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LmlkZW50aWZpZXJdXG4gICAgaWYgKCFtaWxlc3RvbmVEYXRhKSB7XG4gICAgICByZXR1cm4gJydcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiBoYXNobWFwIGhhcyBwcmUtY29tcHV0ZWQgdW5sb2NrIG1lc3NhZ2VcbiAgICBpZiAobWlsZXN0b25lRGF0YS51bmxvY2tNZXNzYWdlKSB7XG4gICAgICByZXR1cm4gbWlsZXN0b25lRGF0YS51bmxvY2tNZXNzYWdlXG4gICAgfVxuXG4gICAgY29uc3QgbWlsZXN0b25lSW5kZXggPSBtaWxlc3RvbmVEYXRhLm1pbGVzdG9uZUluZGV4XG5cbiAgICAvLyBNaWxlc3RvbmUgMSByZXF1aXJlcyBwcmUtYXNzZXNzbWVudCBjb21wbGV0aW9uXG4gICAgaWYgKG1pbGVzdG9uZUluZGV4ID09PSAwKSB7XG4gICAgICByZXR1cm4gJ0NvbXBsZXRlIHRoZSBwcmVsaW1pbmFyeSBhc3Nlc3NtZW50IHRvIHVubG9jayB0aGlzIG1pbGVzdG9uZSdcbiAgICB9XG5cbiAgICAvLyBPdGhlciBtaWxlc3RvbmVzIHJlcXVpcmUgcHJldmlvdXMgbWlsZXN0b25lIGNvbXBsZXRpb25cbiAgICByZXR1cm4gYENvbXBsZXRlIGFsbCBtYW5kYXRvcnkgY29udGVudCBhbmQgYXNzZXNzbWVudCBpbiBNaWxlc3RvbmUgJHttaWxlc3RvbmVJbmRleH0gdG8gdW5sb2NrIHRoaXMgbWlsZXN0b25lYFxuICB9XG5cbiAgLyoqXG4gICAqIEdldCBsb2NrIG1lc3NhZ2UgZm9yIGNvbnRlbnQgaW5zaWRlIGxvY2tlZCBtaWxlc3RvbmVzXG4gICAqL1xuICBnZXRQYXJlbnRNaWxlc3RvbmVMb2NrTWVzc2FnZSgpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5pc1BhcmVudE1pbGVzdG9uZUxvY2tlZCkge1xuICAgICAgcmV0dXJuICcnXG4gICAgfVxuICAgIHJldHVybiAnVGhpcyBjb250ZW50IGlzIGxvY2tlZC4gQ29tcGxldGUgcHJldmlvdXMgbWlsZXN0b25lIHRvIHZpZXcgdGhpcyBjb250ZW50LidcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgbG9jayBtZXNzYWdlIGZvciBtaWxlc3RvbmUgYXNzZXNzbWVudHNcbiAgICovXG4gIGdldEFzc2Vzc21lbnRMb2NrTWVzc2FnZSgpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5jb250ZW50IHx8ICF0aGlzLmhpZXJhcmNoeU1hcERhdGEpIHtcbiAgICAgIHJldHVybiAnJ1xuICAgIH1cblxuICAgIGNvbnN0IGhhc2hEYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudC5pZGVudGlmaWVyXVxuICAgIFxuICAgIC8vIENoZWNrIGlmIGhhc2htYXAgaGFzIHByZS1jb21wdXRlZCBhc3Nlc3NtZW50IGxvY2sgbWVzc2FnZVxuICAgIGlmIChoYXNoRGF0YSAmJiBoYXNoRGF0YS5hc3Nlc3NtZW50TG9ja01lc3NhZ2UpIHtcbiAgICAgIHJldHVybiBoYXNoRGF0YS5hc3Nlc3NtZW50TG9ja01lc3NhZ2VcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc01pbGVzdG9uZUFzc2Vzc21lbnRMb2NrZWQpIHtcbiAgICAgIHJldHVybiAnVGhpcyBjb250ZW50IGlzIGxvY2tlZC4gQ29tcGxldGUgYWxsIG1hbmRhdG9yeSBpdGVtcyB0byB1bmxvY2sgdGhlIGFzc2Vzc21lbnQuJ1xuICAgIH1cblxuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgc2hvdWxkU2hvd0Rvd25sb2FkQnV0dG9uKGNvbnRlbnQ6IE5zQ29udGVudC5JQ29udGVudCB8IG51bGwpOiBib29sZWFuIHtcbiAgICBpZiAoIWNvbnRlbnQpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIGNvbnRlbnQgaGFzIGFuIGFydGlmYWN0IFVSTCAoZG93bmxvYWRhYmxlIHJlc291cmNlKVxuICAgIGlmICghY29udGVudC5hcnRpZmFjdFVybCkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgYmFzZSBjb250ZW50IHJlc291cmNlIGNhdGVnb3J5IGluY2x1ZGVzIFwiQ2FzZSBTdHVkeVwiXG4gICAgaWYgKCF0aGlzLmJhc2VDb250ZW50UmVhZERhdGE/LmNvdXJzZUNhdGVnb3J5IHx8XG4gICAgICB0aGlzLmJhc2VDb250ZW50UmVhZERhdGEuY291cnNlQ2F0ZWdvcnkgIT09IE5zQ29udGVudC5FQ291cnNlQ2F0ZWdvcnkuQ0FTRV9TVFVEWSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy9mb3IgcHVibGljIHNjZW5hcmlvIGNoZWNrIGlmIGl0cyBwbGF5ZXIgcGxhZ2UgdGhlbiBvbmx5IGVuYWJsZSBkb3dubG9hZFxuICAgIGlmICh0aGlzLmZvclByZXZpZXcgJiYgIXdpbmRvdy5sb2NhdGlvbi5ocmVmLmluY2x1ZGVzKCcvdmlld2VyLycpKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICAvLyBmb3IgbG9nZ2VkIGluIHVzZXIgY2hlY2sgaWYgdXNlciBlbnJvbGxlZCB0aGVuIG9ubHkgYWxsb3cgZG93bmxvYWRcbiAgICBpZiAoIXRoaXMuZm9yUHJldmlldyAmJiAhdGhpcy5pc0Vucm9sbGVkKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICAvLyBEZWZpbmUgZG93bmxvYWRhYmxlIE1JTUUgdHlwZXNcbiAgICBjb25zdCBkb3dubG9hZGFibGVNaW1lVHlwZXMgPSBbXG4gICAgICBOc0NvbnRlbnQuRU1pbWVUeXBlcy5QREZcbiAgICBdXG5cbiAgICByZXR1cm4gZG93bmxvYWRhYmxlTWltZVR5cGVzLmluY2x1ZGVzKGNvbnRlbnQubWltZVR5cGUpXG4gIH1cblxuICBkb3dubG9hZENvbnRlbnQoY29udGVudDogTnNDb250ZW50LklDb250ZW50LCBldmVudD86IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAoZXZlbnQpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXG4gICAgfVxuICAgIGNvbnN0IHBhZ2VJZCA9IGBhcHAvdG9jL3BhZ2VJZC8ke2NvbnRlbnQuaWRlbnRpZmllcn1gXG4gICAgdGhpcy5yZXNvdXJjZURvd25sb2FkSGVscGVyU3ZjLmRvd25sb2FkUERGKGNvbnRlbnQsIHBhZ2VJZClcbiAgICBjb25zb2xlLmxvZygnY29udGVudCcsIGNvbnRlbnQpXG4gICAgY29uc29sZS5sb2coJ2Jhc2VDb250ZW50JywgdGhpcy5iYXNlQ29udGVudFJlYWREYXRhKVxuICB9XG5cblxuXG4gIC8qKlxuICAgKiBWaWV3IG1pbGVzdG9uZSBhY2hpZXZlbWVudCAtIGNhbGxzIHRoZSBhY2hpZXZlbWVudCBBUEkgYW5kIHNob3dzIHRoZSByZXN1bHRcbiAgICovXG4gIHZpZXdNaWxlc3RvbmVBY2hpZXZlbWVudChldmVudD86IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAoZXZlbnQpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmNvbnRlbnQgfHwgIXRoaXMuYmF0Y2hJZCB8fCB0aGlzLmFjaGlldmVtZW50TG9hZGluZykge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gR2V0IHVzZXIgSUQgZnJvbSBDb25maWd1cmF0aW9uc1NlcnZpY2VcbiAgICBjb25zdCB1c2VySWQgPSB0aGlzLmNvbmZpZ1N2Yz8udXNlclByb2ZpbGU/LnVzZXJJZFxuICAgIGlmICghdXNlcklkKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdVc2VyIElEIG5vdCBmb3VuZCcpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBFeHRyYWN0IG1pbGVzdG9uZSBJRCAoZS5nLiwgXCJtMVwiLCBcIm0yXCIpIGZyb20gdGhlIGNvbnRlbnQgbmFtZSBvciBpbmRleFxuICAgIC8vIFRyeSB0byBnZXQgbWlsZXN0b25lIG51bWJlciBmcm9tIHRoZSBpbmRleCBvciBleHRyYWN0IGZyb20gY29udGVudFxuICAgIGxldCBtaWxlc3RvbmVJZCA9ICdtJyArICh0aGlzLmluZGV4IC0gMSkgLy8gaW5kZXggaXMgdHlwaWNhbGx5IDEtYmFzZWQsIG1pbGVzdG9uZXMgYXJlIDAtYmFzZWRcblxuICAgIC8vIElmIGNvbnRlbnQgbmFtZSBjb250YWlucyBtaWxlc3RvbmUgbnVtYmVyLCBleHRyYWN0IGl0XG4gICAgaWYgKHRoaXMuY29udGVudC5uYW1lKSB7XG4gICAgICBjb25zdCBtYXRjaCA9IHRoaXMuY29udGVudC5uYW1lLm1hdGNoKC9taWxlc3RvbmVcXHMqKFxcZCspL2kpXG4gICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgbWlsZXN0b25lSWQgPSAnbScgKyBtYXRjaFsxXVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGNvdXJzZUlkID0gdGhpcy5iYXNlQ29udGVudFJlYWREYXRhPy5pZGVudGlmaWVyIHx8IHRoaXMucm9vdElkXG5cbiAgICB0aGlzLmFjaGlldmVtZW50TG9hZGluZyA9IHRydWVcblxuICAgIHRoaXMuYXBwVG9jU3ZjLmdlbmVyYXRlTWlsZXN0b25lQWNoaWV2ZW1lbnQodXNlcklkLCBjb3Vyc2VJZCwgdGhpcy5iYXRjaElkLCBtaWxlc3RvbmVJZCkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXNwb25zZTogYW55KSA9PiB7XG4gICAgICAgIHRoaXMuYWNoaWV2ZW1lbnRMb2FkaW5nID0gZmFsc2VcbiAgICAgICAgY29uc29sZS5sb2coJ0FjaGlldmVtZW50IGdlbmVyYXRlZCBzdWNjZXNzZnVsbHk6JywgcmVzcG9uc2UpXG4gICAgICAgIC8vIFNob3cgYWNoaWV2ZW1lbnQgZGlhbG9nIG9yIGhhbmRsZSByZXNwb25zZVxuICAgICAgICBpZiAocmVzcG9uc2UgJiYgcmVzcG9uc2UucmVzdWx0KSB7XG4gICAgICAgICAgLy8gT3BlbiBhIGRpYWxvZyB0byBzaG93IHRoZSBhY2hpZXZlbWVudFxuICAgICAgICAgIHRoaXMuZGlhbG9nLm9wZW4oQ2VydGlmaWNhdGVEaWFsb2dDb21wb25lbnQsIHtcbiAgICAgICAgICAgIHdpZHRoOiAnMTMwMHB4JyxcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgY2V0OiByZXNwb25zZS5yZXN1bHQucHJpbnRVcmkgfHwgcmVzcG9uc2UucmVzdWx0LnN2Z0RhdGEsXG4gICAgICAgICAgICAgIGNlcnRJZDogcmVzcG9uc2UucmVzdWx0LmlkZW50aWZpZXIsXG4gICAgICAgICAgICAgIGlzQWNoaWV2ZW1lbnQ6IHRydWVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGVycm9yOiAoZXJyb3I6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLmFjaGlldmVtZW50TG9hZGluZyA9IGZhbHNlXG4gICAgICAgIC8vIFNob3cgZXJyb3IgbWVzc2FnZSBpbiBzbmFja2JhclxuICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvcj8uZXJyb3I/LnJlc3VsdD8ubWVzc2FnZSB8fCBlcnJvcj8ubWVzc2FnZSB8fCAnRmFpbGVkIHRvIGdlbmVyYXRlIGFjaGlldmVtZW50J1xuICAgICAgICB0aGlzLnNuYWNrQmFyLm9wZW4oZXJyb3JNZXNzYWdlLCAnQ2xvc2UnLCB7XG4gICAgICAgICAgZHVyYXRpb246IDUwMDAsXG4gICAgICAgICAgaG9yaXpvbnRhbFBvc2l0aW9uOiAnY2VudGVyJyxcbiAgICAgICAgICB2ZXJ0aWNhbFBvc2l0aW9uOiAnYm90dG9tJyxcbiAgICAgICAgICBwYW5lbENsYXNzOiBbJ2Vycm9yLXNuYWNrYmFyJ11cbiAgICAgICAgfSlcbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZ2VuZXJhdGluZyBhY2hpZXZlbWVudDonLCBlcnJvcilcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbn1cbiIsIjxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50ICYmICFpc1ByZUFzc2Vzc21lbnRcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNDb2xsZWN0aW9uICYmICFpc01vZHVsZVwiPlxuICAgICAgICA8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbGxlY3Rpb25UZW1wbGF0ZVwiPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNDb2xsZWN0aW9uICYmIGlzTW9kdWxlXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50Py5tb2R1bGVSZXNvdXJzZUNvdW50XCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbGxlY3Rpb25UZW1wbGF0ZVwiPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgPGRpdiAqbmdJZj1cImlzUmVzb3VyY2VcIiBjbGFzcz1cInJlc291cmNlLWNvbnRhaW5lclwiXG4gICAgICAgIFtuZ0NsYXNzXT1cInBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSAmJiBpc0Vucm9sbGVkID8gJ2NvbnRlbnQtYWN0aXZlLXJlc291cmNlJzogJ2NvbnRlbnQtbm90LWFjdGl2ZS1yZXNvdXJjZSdcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInJlc291cmNlIGZsZXggIHNtOmZsZXgtcm93IGZsZXgtc3RhcnQgd2lkdGgtZXhwYW5kIHctMTAwIHNtOnByLTQgc206dy1hdXRvXCJcbiAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnYWN0aXZlUmVzb3VyY2UnOiBwYXRoU2V0Py5oYXMoY29udGVudD8uaWRlbnRpZmllcikgJiYgaXNFbnJvbGxlZH1cIj5cbiAgICAgICAgICAgIDwhLS0gTG9jayBtZXNzYWdlIGZvciBjdXJhdGVkIHByb2dyYW1zIG9ubHkgKHNob3duIGFib3ZlIGNvbnRlbnQpIC0tPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQ/LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgJiYgY2hlY2tGb3JDdXJhdGVkUHJvZ3JhbSAmJlxuICAgICAgICAgICAgIWlzQ29udGVudFVubG9ja2VkXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRlbnQtbG9ja2luZyBmbGV4IHctZnVsbCBmbGV4LW1pZGRsZSBtYi0yIGdhcC0zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImxvY2staWNvblwiPmxvY2s8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxvY2stbWVzc2FnZSBtYXQtYm9keS0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBUaGUgY29udGVudCBpcyBsb2NrZWQuIENvbXBsZXRlIHByb2dyYW0gb3IgYWxsIGNvdXJzZXMgdG8gdmlldyB0aGlzIG1vZHVsZVxuICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50Py5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UICYmIGNoZWNrRm9yQ3VyYXRlZFByb2dyYW0gJiZcbiAgICAgICAgICAgIGlzQ29udGVudFVubG9ja2VkXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRlbnQtbG9ja2luZyBmbGV4IHctZnVsbCBmbGV4LW1pZGRsZSBtYi0yIGdhcC0zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cInVubG9jay1pY29uXCI+bG9ja19vcGVuX3JpZ2h0PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ1bmxvY2stbWVzc2FnZSBtYXQtYm9keS0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBUaGlzIGNvbnRlbnQgaXMgdW5sb2NrZWQuXG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC13cmFwIGl0ZW1zLXN0YXJ0IGp1c3RpZnktc3RhcnQgc206anVzdGlmeS1lbmRcIj5cbiAgICAgICAgICAgICAgICA8IS0tIDxidXR0b24gKm5nSWY9XCIhZm9yUHJldmlldyAmJiBjb250ZW50Py5hcnRpZmFjdFVybCAmJiAhaXNYU21hbGwgJiYgaXNBbGxvd2VkICYmIGlzRW5hYmxlZFwiIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBtYXQtaWNvbi1idXR0b24gY2xhc3M9XCJcIiBbbWF0TWVudVRyaWdnZXJGb3JdPVwiYnV0dG9uTWVudVwiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+bW9yZV92ZXJ0aWNhbDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+IC0tPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0Vucm9sbGVkICAmJiAhaXNNaWxlc3RvbmVMb2NrZWQgJiYgIWlzUGFyZW50TWlsZXN0b25lTG9ja2VkXCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIWZvclByZXZpZXcgJiYgIGNvbnRlbnQ/LmlkZW50aWZpZXIgJiYgZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcikgOyBlbHNlIGVsc2VCbG9ja1wiPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29tcGxldGlvblN0YXR1cyhjb250ZW50Py5pZGVudGlmaWVyKSA9PSAyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbXBsZXRlZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwiY29tcGxldGVkLWljb25cIiBbY29sb3JdPVwiYmx1ZVwiPmNoZWNrX2NpcmNsZTwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29tcGxldGlvblN0YXR1cyhjb250ZW50Py5pZGVudGlmaWVyKSA8IDJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlLXByb2dyZXNzIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgcHJvZ3Jlc3NcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGVyY2VudF09XCJnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKVwiIFtyYWRpdXNdPVwiMTBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VXaWR0aF09XCIyXCIgW2lubmVyU3Ryb2tlV2lkdGhdPVwiMlwiIFtzcGFjZV09XCItMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZUNvbG9yXT1cInByb2dyZXNzQ29sb3IyKClcIiBbaW5uZXJTdHJva2VDb2xvcl09XCIncmdiYSgwLCAwLCAwLCAwLjE2KSdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYW5pbWF0aW9uXT1cInRydWVcIiBbYW5pbWF0aW9uRHVyYXRpb25dPVwiMjUwXCIgW3Nob3dUaXRsZV09XCJmYWxzZVwiIFtzaG93VW5pdHNdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1N1YnRpdGxlXT1cImZhbHNlXCIgW3Nob3dJbm5lclN0cm9rZV09XCJ0cnVlXCIgW2Nsb2Nrd2lzZV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRPcGFjaXR5XT1cIjBcIiBbYmFja2dyb3VuZEdyYWRpZW50XT1cImZhbHNlXCIgW2JhY2tncm91bmRTdHJva2VXaWR0aF09XCIzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcD1cIkluIHByb2dyZXNzXCIgW3Nob3daZXJvT3V0ZXJTdHJva2VdPWZhbHNlIFtiYWNrZ3JvdW5kUGFkZGluZ109XCItOVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdGFydEZyb21aZXJvXT1cImZhbHNlXCIgW2JhY2tncm91bmRQYWRkaW5nXT1cIjBcIiBbaW1hZ2VIZWlnaHRdPVwiMjJcIiBbaW1hZ2VXaWR0aF09XCIyMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93QmFja2dyb3VuZF09XCJmYWxzZVwiIFtvdXRlclN0cm9rZUxpbmVjYXBdPVwiJ2J1dHQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9jaXJjbGUtcHJvZ3Jlc3M+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8d3Mtd2lkZ2V0LWNvbnRlbnQtcHJvZ3Jlc3MgKm5nSWY9XCJjb250ZW50Py5pZGVudGlmaWVyXCIgW2ZvclByZXZpZXddPVwiZm9yUHJldmlld1wiXG4gICAgICAgICAgICAgICAgICAgIFtjb250ZW50SWRdPVwiY29udGVudD8uaWRlbnRpZmllclwiIGNsYXNzPVwicHJvZ3Jlc3MtYmFyLXRoaW5cIiBbcHJvZ3Jlc3NdPVwiY29udGVudD8uY29tcGxldGlvblBlcmNlbnRhZ2VcIlxuICAgICAgICAgICAgICAgICAgICBbcHJvZ3Jlc3NUeXBlXT1cIidwZXJjZW50YWdlJ1wiPlxuICAgICAgICAgICAgICAgICAgPC93cy13aWRnZXQtY29udGVudC1wcm9ncmVzcz4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZWxzZUJsb2NrPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzXCIgW3BlcmNlbnRdPVwiMFwiIFtyYWRpdXNdPVwiMTFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZVdpZHRoXT1cIjJcIiBbaW5uZXJTdHJva2VXaWR0aF09XCIyXCIgW291dGVyU3Ryb2tlQ29sb3JdPVwiJyM4MDgwODAnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW5uZXJTdHJva2VDb2xvcl09XCInIzgwODA4MCdcIiBbYW5pbWF0aW9uXT1cInRydWVcIiBbc3BhY2VdPVwiLTJcIiBbc2hvd1VuaXRzXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYW5pbWF0aW9uRHVyYXRpb25dPVwiMjUwXCIgW3Nob3dUaXRsZV09XCJmYWxzZVwiIFtiYWNrZ3JvdW5kUGFkZGluZ109XCIwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZFBhZGRpbmddPVwiLTlcIiBbb3V0ZXJTdHJva2VMaW5lY2FwXT1cIididXR0J1wiIG1hdFRvb2x0aXA9XCJOb3Qgc3RhcnRlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dTdWJ0aXRsZV09XCJmYWxzZVwiIFtzaG93SW5uZXJTdHJva2VdPVwidHJ1ZVwiIFtjbG9ja3dpc2VdPVwidHJ1ZVwiIFtpbWFnZUhlaWdodF09XCIyMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2ltYWdlV2lkdGhdPVwiMjJcIiBbc2hvd0JhY2tncm91bmRdPVwiZmFsc2VcIj48L2NpcmNsZS1wcm9ncmVzcz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPHA+bm8gZGF0YTwvcD4gLS0+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwhLS0gZGVhY3RpdmF0ZWQgYXMgcGVyIE5JQyBDRU8gcmVxdWlyZW1lbnQgdG8gYWNjZXNzIGNvdXJzZSB3dGhvdXQgbG9naW4gLS0+XG4gICAgICAgICAgICA8IS0tIEZvciBsb2NrZWQgYXNzZXNzbWVudHM6IHNob3cgY29udGVudCBidXQgbWFrZSBpdCBub24tY2xpY2thYmxlIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIndpZHRoLWV4cGFuZFwiICpuZ0lmPVwiaXNNaWxlc3RvbmVBc3Nlc3NtZW50TG9ja2VkICYmIGlzRW5yb2xsZWQ7IGVsc2UgY2xpY2thYmxlQ29udGVudFwiXG4gICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydtbC0zJzogaXNFbnJvbGxlZH1cIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC10cnVuY2F0ZSBvcGFjaXR5LTYwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sIHNtOmZsZXgtcm93IGZsZXgtd3JhcFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGdhcC0yIHctZnVsbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cInRleHQtZ3JheS01MDBcIj5sb2NrPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1hcmdpbi1yZW1vdmUgdGV4dC10cnVuY2F0ZSBtYXQtYm9keS0yIGZsZXgtYXV0byBmb250LWJvbGQgbm9kdHJhbnNsYXRlIHRleHQtZ3JheS02MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgY29udGVudD8ubmFtZSB8IHRydW5jYXRlOjUwIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbnRlbnQtdHlwZSBvcHRpb25hbC1zcGFuIG5vZHRyYW5zbGF0ZVwiICpuZ0lmPVwiY29udGVudD8ub3B0aW9uYWxSZWFkaW5nXCI+e3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAncGxheWVyYnJpZWYub3B0aW9uYWwnIHwgdHJhbnNsYXRlIHwgdGl0bGVjYXNlfX0gPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBmb3IgZGVmYXVsdCBncmV5IGljb25zIC0tPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSB8fCAhaXNFbnJvbGxlZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlc2ljb25zIHdzLW1hdC1ibGFjazYwLXRleHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L3ZpZGVvLnN2Z1wiIGFsdD1cIlZpZGVvXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICd2aWRlby9tcDQnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndmlkZW8veC15b3V0dWJlJyB8fFxuICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ/Lm1pbWVUeXBlID09PSdhcHBsaWNhdGlvbi94LW1wZWdVUkwnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9hdWRpby5zdmdcIiBhbHQ9XCJBdWRpb1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIiAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXVkaW8vbXBlZydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L3BkZi5zdmdcIiBhbHQ9XCJQREZcIiBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3BkZidcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2xpbmsuc3ZnXCIgYWx0PVwiSW50ZXJhY3RpdmVDb250ZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuZWtzdGVwLmh0bWwtYXJjaGl2ZScgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICd0ZXh0L3gtdXJsJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvYXNzZXNzbWVudC5zdmdcIiBhbHQ9XCJBc3Nlc3NtZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9qc29uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3F1aXonIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLnN1bmJpcmQucXVlc3Rpb25zZXQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9pbWFnZS5zdmdcIiBhbHQ9XCJJbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvcG5nJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL2pwZWcnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9jb250ZW50X2NvcHkuc3ZnXCIgY2xhc3M9XCJjb250ZW50aWNvblwiIGFsdD1cIkNvdXJzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuY29udGVudC1jb2xsZWN0aW9uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3N1cnZleSdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L21vZHVsZS5zdmdcIiBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0PVwib2ZmbGluZSBzZXNzaW9uc1wiICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL29mZmxpbmUnXCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlNUQU5EQUxPTkVfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXNvdXJjZUR1cmF0aW9uIHdzLW1hdC1ibGFjazYwLXRleHQgbm9kdHJhbnNsYXRlXCI+e3sgY29udGVudD8ubWF4UXVlc3Rpb25zXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9fSB7eyAncGxheWVyYnJpZWYucXVlc3Rpb25zJyB8IHRyYW5zbGF0ZSB8IHRpdGxlY2FzZX19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhKGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5TVEFOREFMT05FX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlc291cmNlRHVyYXRpb24gd3MtbWF0LWJsYWNrNjAtdGV4dCBub2R0cmFuc2xhdGVcIj57eyAoY29udGVudD8uZHVyYXRpb258fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGllcmFyY2h5TWFwRGF0YVtjb250ZW50Py5pZGVudGlmaWVyXT8uZXhwZWN0ZWREdXJhdGlvbiB8fCAwKXxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpcGVEdXJhdGlvblRyYW5zZm9ybTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdobXMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICA8IS0tIExvY2sgbWVzc2FnZSBkaXNwbGF5ZWQgQkVMT1cgYXNzZXNzbWVudCBkZXRhaWxzIHdoZW4gbG9ja2VkIC0tPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb250ZW50LWxvY2tpbmcgZmxleCB3LWZ1bGwgZmxleC1taWRkbGUgbXQtMiBnYXAtMiBweC0yIHB5LTEgYmctb3JhbmdlLTUwIGJvcmRlci1sLTQgYm9yZGVyLW9yYW5nZS00MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibG9jay1pY29uIHRleHQtb3JhbmdlLTYwMFwiIHN0eWxlPVwiZm9udC1zaXplOiAxOHB4OyB3aWR0aDogMThweDsgaGVpZ2h0OiAxOHB4O1wiPmxvY2s8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxvY2stbWVzc2FnZSBtYXQtYm9keS0yIHRleHQtb3JhbmdlLTgwMFwiIHN0eWxlPVwiZm9udC1zaXplOiAxM3B4O1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyBjb250ZW50IGlzIGxvY2tlZC4gQ29tcGxldGUgYWxsIG1hbmRhdG9yeSBpdGVtcyB0byB1bmxvY2sgdGhlIGFzc2Vzc21lbnQuXG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgXG4gICAgICAgICAgICA8IS0tIENsaWNrYWJsZSBjb250ZW50IHRlbXBsYXRlICh3aGVuIE5PVCBsb2NrZWQpIC0tPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNjbGlja2FibGVDb250ZW50PlxuICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwid2lkdGgtZXhwYW5kXCJcbiAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmRpc2FibGVkXT1cIihmb3JQcmV2aWV3IHx8ICFpc0VuYWJsZWQgfHwgIWlzRW5yb2xsZWQgfHwgIWlzQmF0Y2hJblByb2dlc3MgfHwgIWlzQ29udGVudFVubG9ja2VkIHx8IGlzUGFyZW50TWlsZXN0b25lTG9ja2VkKSA/IHRydWUgOiBudWxsXCJcbiAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydtbC0zJzogaXNFbnJvbGxlZH1cIlxuICAgICAgICAgICAgICAgICAgICBbcm91dGVyTGlua109XCIoaXNBbGxvd2VkICYmICFmb3JQcmV2aWV3ICYmIGlzRW5hYmxlZCAmJiAhaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQpID8gcmVzb3VyY2VMaW5rLnVybCA6IG51bGxcIlxuICAgICAgICAgICAgICAgICAgICBbcXVlcnlQYXJhbXNdPVwiKGlzQWxsb3dlZCAmJiAhZm9yUHJldmlldyAmJiBpc0VuYWJsZWQgJiYgIWlzUGFyZW50TWlsZXN0b25lTG9ja2VkKSAgPyByZXNvdXJjZUxpbmsucXVlcnlQYXJhbXMgOiBudWxsXCJcbiAgICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwiaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQgPyAnVGhpcyBjb250ZW50IGlzIGxvY2tlZC4gQ29tcGxldGUgcHJldmlvdXMgbWlsZXN0b25lIHRvIHZpZXcgdGhpcyBjb250ZW50LicgOiAnJ1wiXG4gICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXBQb3NpdGlvbj1cImFib3ZlXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgW25nQ2xhc3NdPVwieydyZXNvdXJjZS1hY3RpdmUnOiBwYXRoU2V0Py5oYXMoY29udGVudD8uaWRlbnRpZmllcikgJiYgaXNFbnJvbGxlZH1cIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtdHJ1bmNhdGUgXCIgW25nQ2xhc3NdPVwieydjdXJzb3ItcG9pbnRlcic6ICFpc0VuYWJsZWQgJiYgaXNFbnJvbGxlZH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNvbnRlbnQudmlld0NoaWxkcmVuID0gIWNvbnRlbnQudmlld0NoaWxkcmVuOyByYWlzZVRlbGVtZXRyeSgpOyBjaGFuZ2VSZXNvdXJjZSgpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBzbTpmbGV4LXJvdyBmbGV4LXdyYXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1hcmdpbi1yZW1vdmUgdGV4dC10cnVuY2F0ZSBtYXQtYm9keS0yIGZsZXgtYXV0byBmb250LWJvbGQgbm9kdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyd0ZXh0LWFjdGl2ZSc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSAmJiBpc0Vucm9sbGVkfVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBjb250ZW50Py5uYW1lIHwgdHJ1bmNhdGU6NTAgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb250ZW50LXR5cGUgb3B0aW9uYWwtc3BhbiBub2R0cmFuc2xhdGVcIiAqbmdJZj1cImNvbnRlbnQ/Lm9wdGlvbmFsUmVhZGluZ1wiPnt7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwbGF5ZXJicmllZi5vcHRpb25hbCcgfCB0cmFuc2xhdGUgfCB0aXRsZWNhc2V9fSA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gZm9yIGRlZmF1bHQgZ3JleSBpY29ucyAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhcGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpIHx8ICFpc0Vucm9sbGVkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlc2ljb25zIHdzLW1hdC1ibGFjazYwLXRleHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS92aWRlby5zdmdcIiBhbHQ9XCJWaWRlb1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCIgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ3ZpZGVvL21wNCcgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICd2aWRlby94LXlvdXR1YmUnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ/Lm1pbWVUeXBlID09PSdhcHBsaWNhdGlvbi94LW1wZWdVUkwnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvYXVkaW8uc3ZnXCIgYWx0PVwiQXVkaW9cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhdWRpby9tcGVnJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L3BkZi5zdmdcIiBhbHQ9XCJQREZcIiBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9wZGYnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvbGluay5zdmdcIiBhbHQ9XCJJbnRlcmFjdGl2ZUNvbnRlbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLmVrc3RlcC5odG1sLWFyY2hpdmUnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndGV4dC94LXVybCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9hc3Nlc3NtZW50LnN2Z1wiIGFsdD1cIkFzc2Vzc21lbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vanNvbicgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9xdWl6JyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5zdW5iaXJkLnF1ZXN0aW9uc2V0J1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2ltYWdlLnN2Z1wiIGFsdD1cIkltYWdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL3BuZycgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdpbWFnZS9qcGVnJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2NvbnRlbnRfY29weS5zdmdcIiBjbGFzcz1cImNvbnRlbnRpY29uXCIgYWx0PVwiQ291cnNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuY29udGVudC1jb2xsZWN0aW9uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3N1cnZleSdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9tb2R1bGUuc3ZnXCIgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHQ9XCJvZmZsaW5lIHNlc3Npb25zXCIgKm5nSWY9XCJjb250ZW50Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vb2ZmbGluZSdcIj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVzb3VyY2VEdXJhdGlvbiB3cy1tYXQtYmxhY2s2MC10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7IGNvbnRlbnQ/Lm1heFF1ZXN0aW9uc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19IHt7ICdwbGF5ZXJicmllZi5xdWVzdGlvbnMnIHwgdHJhbnNsYXRlIHwgdGl0bGVjYXNlfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIShjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5TVEFOREFMT05FX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVzb3VyY2VEdXJhdGlvbiB3cy1tYXQtYmxhY2s2MC10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7IChjb250ZW50Py5kdXJhdGlvbnx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGllcmFyY2h5TWFwRGF0YVtjb250ZW50Py5pZGVudGlmaWVyXT8uZXhwZWN0ZWREdXJhdGlvbiB8fCAwKXxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXBlRHVyYXRpb25UcmFuc2Zvcm06XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2htcydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgICAgICA8IS0tIGZvciB3aGl0ZSBpY29ucyB3aGVuIGNvbnRlbnQgaGlnaGxpZ2h0ZWQgLS0+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJwYXRoU2V0Py5oYXMoY29udGVudD8uaWRlbnRpZmllcikgJiYgaXNFbnJvbGxlZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlc2ljb25zIHdzLW1hdC13aGl0ZS10ZXh0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvdmlkZW8uc3ZnXCIgYWx0PVwiVmlkZW9cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCIgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ3ZpZGVvL21wNCcgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICd2aWRlby94LXlvdXR1YmUnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgY29udGVudD8ubWltZVR5cGUgPT09J2FwcGxpY2F0aW9uL3gtbXBlZ1VSTCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9hdWRpby5zdmdcIiBhbHQ9XCJBdWRpb1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIiAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXVkaW8vbXBlZydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9wZGYuc3ZnXCIgYWx0PVwiUERGXCIgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9wZGYnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvbGluay5zdmdcIiBhbHQ9XCJJbnRlcmFjdGl2ZUNvbnRlbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuaHRtbC1hcmNoaXZlJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ3RleHQveC11cmwnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvYXNzZXNzbWVudC5zdmdcIiBhbHQ9XCJBc3Nlc3NtZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9qc29uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3F1aXonIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLnN1bmJpcmQucXVlc3Rpb25zZXQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9pbWFnZS5zdmdcIiBhbHQ9XCJJbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvcG5nJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL2pwZWcnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvY29udGVudF9jb3B5LnN2Z1wiIGNsYXNzPVwiY29udGVudGljb25cIiBhbHQ9XCJDb3Vyc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuZWtzdGVwLmNvbnRlbnQtY29sbGVjdGlvbicgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9zdXJ2ZXknXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvbW9kdWxlLnN2Z1wiIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHQ9XCJvZmZsaW5lIHNlc3Npb25zXCIgKm5nSWY9XCJjb250ZW50Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vb2ZmbGluZSdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlNUQU5EQUxPTkVfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXNvdXJjZUR1cmF0aW9uIHdzLW1hdC1ibGFjazYwLXRleHQgbm9kdHJhbnNsYXRlXCI+e3sgY29udGVudD8ubWF4UXVlc3Rpb25zXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9fSB7eyAncGxheWVyYnJpZWYucXVlc3Rpb25zJyB8IHRyYW5zbGF0ZSB8IHRpdGxlY2FzZX19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhKGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5TVEFOREFMT05FX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlc291cmNlRHVyYXRpb24gd3MtbWF0LWJsYWNrNjAtdGV4dCBub2R0cmFuc2xhdGVcIj57eyAoY29udGVudD8uZHVyYXRpb258fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGllcmFyY2h5TWFwRGF0YVtjb250ZW50Py5pZGVudGlmaWVyXT8uZXhwZWN0ZWREdXJhdGlvbiB8fCAwKXxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpcGVEdXJhdGlvblRyYW5zZm9ybTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdobXMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgICAgICA8IS0tIERvd25sb2FkIGJ1dHRvbiBmb3IgcGRmIHJlc291cmNlcyAtLT5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNob3VsZFNob3dEb3dubG9hZEJ1dHRvbihjb250ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRvd25sb2FkLWJ0biBtYXQtYm9keS0yIG10LTIgc206bXQtMVwiIChjbGljayk9XCJkb3dubG9hZENvbnRlbnQoY29udGVudCwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydhY3RpdmUnOiBwYXRoU2V0Py5oYXMoY29udGVudD8uaWRlbnRpZmllcil9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJkb3dubG9hZC1saW5rIGZsZXggaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiXCI+RG93bmxvYWQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L25nLWNvbnRhaW5lcj5cblxuPG1hdC1tZW51ICNidXR0b25NZW51PVwibWF0TWVudVwiPlxuICAgIDxhIG1hdC1tZW51LWl0ZW0gW3JvdXRlckxpbmtdPVwiJy4uLycgKyBjb250ZW50Py5pZGVudGlmaWVyICsgJy9vdmVydmlldydcIiBbcXVlcnlQYXJhbXNdPVwiY29udGV4dFBhdGhcIlxuICAgICAgICBjbGFzcz1cImZsZXggZmxleC1taWRkbGVcIj5cbiAgICAgICAgPG1hdC1pY29uPnRvYzwvbWF0LWljb24+XG4gICAgICAgIDxoMyBjbGFzcz1cIm1hcmdpbi1yZW1vdmUgbm9kdHJhbnNsYXRlXCI+XG4gICAgICAgICAgICBWaWV3IERldGFpbHNcbiAgICAgICAgPC9oMz5cbiAgICA8L2E+XG48L21hdC1tZW51PlxuXG48bmctdGVtcGxhdGUgI2NvbGxlY3Rpb25UZW1wbGF0ZT5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNDb2xsZWN0aW9uXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2xsZWN0aW9uLXdyYXBwZXIgcC00IGZsZXggZmxleC1jb2wgcG9zaXRpb24tcmVsYXRpdmVcIiBbbmdDbGFzc109XCJ7J29wZW4nOiBjaGVjayhjb250ZW50KSxcbiAgICAgICAgICAgICdjbG9zZSc6ICFjb250ZW50LnZpZXdDaGlsZHJlbixcbiAgICAgICAgICAgICdjb3Vyc2UnOiFpc01vZHVsZSwgJ21vZHVsZSc6IGlzTW9kdWxlLFxuICAgICAgICAgICAgJ2NvbnRlbnQtYWN0aXZlJzogcGF0aFNldD8uaGFzKGNvbnRlbnQuaWRlbnRpZmllcikgJiYgaXNFbnJvbGxlZH1cIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWNvbGxlY3Rpb24gdy1hdXRvIHNtOnctMTAwIHBhZGRpbmctcmlnaHQteGxcIj5cbiAgICAgICAgICAgICAgICA8IS0tIDxpbWcgY2xhc3M9XCJjYXJkLXRodW1ibmFpbCB3cy1tYXQtcHJpbWFyeS1saXRlLWJhY2tncm91bmRcIiBbc3JjXT1cImNvbnRlbnQ/LmFwcEljb25cIiBhbHQ9XCJUaHVtYm5haWxcIlxuICAgICAgICAgICAgKGNsaWNrKT1cImNvbnRlbnQudmlld0NoaWxkcmVuID0gIWNvbnRlbnQudmlld0NoaWxkcmVuXCIgW3dzVXRpbHNEZWZhdWx0VGh1bWJuYWlsXT1cImRlZmF1bHRUaHVtYm5haWxcIiAvPiAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBmbGV4LXdyYXAgZmxleC1iZXR3ZWVuIHdpZHRoLWV4cGFuZCBwci0wIHctMTAwIFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC10cnVuY2F0ZVwiIFtuZ0NsYXNzXT1cInsnY3Vyc29yLXBvaW50ZXInOiAhaXNFbmFibGVkfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY29udGVudC52aWV3Q2hpbGRyZW4gPSAhY29udGVudC52aWV3Q2hpbGRyZW5cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciBtYi0xIHNtOmZsZXgtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImlzTW9kdWxlICYmIGlzRW5yb2xsZWQgJiYgIWlzTWlsZXN0b25lTG9ja2VkICYmICFpc1BhcmVudE1pbGVzdG9uZUxvY2tlZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFmb3JQcmV2aWV3ICYmIGNvbnRlbnQ/LmlkZW50aWZpZXIgJiYgZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcikgOyBlbHNlIGVsc2VCbG9ja1wiPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29tcGxldGlvblN0YXR1cyhjb250ZW50LmlkZW50aWZpZXIpID09IDJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29tcGxldGVkIG1yLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImNvbXBsZXRlZC1pY29uXCIgW2NvbG9yXT1cImJsdWVcIj5jaGVja19jaXJjbGU8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENvbXBsZXRpb25TdGF0dXMoY29udGVudD8uaWRlbnRpZmllcikgPCAyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzIG1yLTFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGVyY2VudF09XCJnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKVwiIFtyYWRpdXNdPVwiMTBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VXaWR0aF09XCIyXCIgW2lubmVyU3Ryb2tlV2lkdGhdPVwiMlwiIFtzcGFjZV09XCItMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZUNvbG9yXT1cInByb2dyZXNzQ29sb3IyKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW5uZXJTdHJva2VDb2xvcl09XCIncmdiYSgwLCAwLCAwLCAwLjE2KSdcIiBbYW5pbWF0aW9uXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYW5pbWF0aW9uRHVyYXRpb25dPVwiMjUwXCIgW3Nob3dUaXRsZV09XCJmYWxzZVwiIFtzaG93VW5pdHNdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1N1YnRpdGxlXT1cImZhbHNlXCIgW3Nob3dJbm5lclN0cm9rZV09XCJ0cnVlXCIgW2Nsb2Nrd2lzZV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRPcGFjaXR5XT1cIjBcIiBbYmFja2dyb3VuZEdyYWRpZW50XT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRTdHJva2VXaWR0aF09XCIzXCIgbWF0VG9vbHRpcD1cIkluIHByb2dyZXNzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3daZXJvT3V0ZXJTdHJva2VdPWZhbHNlIFtiYWNrZ3JvdW5kUGFkZGluZ109XCItN1wiIFtzdGFydEZyb21aZXJvXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRQYWRkaW5nXT1cIjBcIiBbaW1hZ2VIZWlnaHRdPVwiMThcIiBbaW1hZ2VXaWR0aF09XCIxOFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93QmFja2dyb3VuZF09XCJmYWxzZVwiIFtvdXRlclN0cm9rZUxpbmVjYXBdPVwiJ2J1dHQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9jaXJjbGUtcHJvZ3Jlc3M+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZWxzZUJsb2NrPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzIG1yLTFcIiBbcGVyY2VudF09XCIwXCIgW3JhZGl1c109XCIxMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlV2lkdGhdPVwiMlwiIFtpbm5lclN0cm9rZVdpZHRoXT1cIjJcIiBbb3V0ZXJTdHJva2VDb2xvcl09XCInIzgwODA4MCdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpbm5lclN0cm9rZUNvbG9yXT1cIicjODA4MDgwJ1wiIFthbmltYXRpb25dPVwidHJ1ZVwiIFtzcGFjZV09XCItMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dVbml0c109XCJmYWxzZVwiIFthbmltYXRpb25EdXJhdGlvbl09XCIyNTBcIiBbc2hvd1RpdGxlXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZFBhZGRpbmddPVwiMFwiIFtiYWNrZ3JvdW5kUGFkZGluZ109XCItOVwiIFtvdXRlclN0cm9rZUxpbmVjYXBdPVwiJ2J1dHQnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwPVwiTm90IHN0YXJ0ZWRcIiBbc2hvd1N1YnRpdGxlXT1cImZhbHNlXCIgW3Nob3dJbm5lclN0cm9rZV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xvY2t3aXNlXT1cInRydWVcIiBbaW1hZ2VIZWlnaHRdPVwiMjJcIiBbaW1hZ2VXaWR0aF09XCIyMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dCYWNrZ3JvdW5kXT1cImZhbHNlXCI+PC9jaXJjbGUtcHJvZ3Jlc3M+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2NvbGxlY3Rpb24tYWN0aXZlLWNsYXNzJzogcGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpICYmIGlzRW5yb2xsZWR9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyAqbmdJZj1cImlzTWlsZXN0b25lTG9ja2VkXCIgc3JjPVwiYXNzZXRzL2ljb25zL2h1YnMvbG9jay5zdmdcIiBhbHQ9XCJMb2NrZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImxvY2staWNvbiBtci0yIG1hcmdpbi1ib3R0b20teHhzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtYXV0byBmbGV4IGZsZXgtY29sXCIgc3R5bGU9XCJtaW4td2lkdGg6IDA7XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwibWFyZ2luLXJlbW92ZSB0ZXh0LXRydW5jYXRlIG1hdC1zdWJoZWFkaW5nLTEgZm9udC1ib2xkIG5vZHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J3RleHQtYWN0aXZlJzogcGF0aFNldD8uaGFzKGNvbnRlbnQuaWRlbnRpZmllcikgJiYgaXNFbnJvbGxlZH1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7aXNNaWxlc3RvbmUgPyBpbmRleCAtMSA6IGluZGV4fX0uIDwvc3Bhbj57eyBjb250ZW50Py5uYW1lIHwgdHJ1bmNhdGU6NTAgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMVwiICpuZ0lmPVwiaXNNaWxlc3RvbmUgJiYgaXNNaWxlc3RvbmVMb2NrZWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibG9ja2VkLXRleHRcIj5Mb2NrZWQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMVwiICpuZ0lmPVwiY29udGVudD8uaXNNYW5kYXRvcnlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWFuZGF0b3J5LXRleHQgbWF0LWNhcHRpb25cIj5NYW5kYXRvcnk8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0eXBlLWNvbnRhaW5lciByZXNvdXJjZSBtdC0yIHNtOm10LTBcIiAqbmdJZj1cImNvbnRlbnQ/LmNhdGVnb3J5ID09PSAnUmVzb3VyY2UnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1yLTEgY3VzdG9tLWljb24gcm90YXRlLTkwXCI+Y2FsbF90b19hY3Rpb248L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5vZHRyYW5zbGF0ZVwiPlJlc291cmNlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0eXBlLWNvbnRhaW5lciBtb2R1bGUgbXQtMiBzbTptdC0wXCIgKm5nSWY9XCJjb250ZW50Py5jYXRlZ29yeSA9PT0gJ0NvbGxlY3Rpb24nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1yLTEgY3VzdG9tLWljb24gcm90YXRlLTkwXCI+Y2FsbF90b19hY3Rpb248L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5vZHRyYW5zbGF0ZVwiPk1vZHVsZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHlwZS1jb250YWluZXIgY291cnNlIG10LTIgc206bXQtMFwiICpuZ0lmPVwiY29udGVudD8uY2F0ZWdvcnkgPT09ICdDb3Vyc2UnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1yLTEgY3VzdG9tLWljb24gcm90YXRlLTkwXCI+Y2FsbF90b19hY3Rpb248L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5vZHRyYW5zbGF0ZVwiPkNvdXJzZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBNaWxlc3RvbmUgQmFkZ2UgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNNaWxlc3RvbmVcIiBjbGFzcz1cIm1pbGVzdG9uZS1iYWRnZSBtdC0yIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1pbGVzdG9uZS1iYWRnZS10ZXh0IG5vZHRyYW5zbGF0ZVwiPk1pbGVzdG9uZSB7e2luZGV4IC0gMX19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIE1pbGVzdG9uZSBEZXNjcmlwdGlvbiAoMyBsaW5lcyB3aXRoIGVsbGlwc2lzKSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwICpuZ0lmPVwiaXNNaWxlc3RvbmUgJiYgY29udGVudD8uZGVzY3JpcHRpb25cIiBjbGFzcz1cIm1pbGVzdG9uZS1kZXNjcmlwdGlvbiBtdC0yICBub2R0cmFuc2xhdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBjb250ZW50Py5kZXNjcmlwdGlvbiB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3cgZ2FwLTMgaXRlbXMtY2VudGVyIGNvbnRlbnQta2V5LXZhbHVlcyBtdC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiIWlzTW9kdWxlXCIgYWx0PVwiY291cnNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0aW1lLWljb24gaWNvbi1jb2xvclwiPnZpZGVvX2xpYnJhcnk8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgKm5nSWY9XCJpc01vZHVsZVwiIGFsdD1cIk1vZHVsZVwiIGNsYXNzPVwidGltZS1pY29uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvbW9kdWxlLnN2Z1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXhzIG5vZHRyYW5zbGF0ZVwiPnt7IChoaWVyYXJjaHlNYXBEYXRhW2NvbnRlbnQ/LmlkZW50aWZpZXJdPy5kdXJhdGlvbiB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMjApfFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXBlRHVyYXRpb25UcmFuc2Zvcm06ICdobXMnIH19PC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8ubW9kdWxlQ291bnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInBlcmlvZFwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXhzIG5vZHRyYW5zbGF0ZVwiPnt7Y29udGVudD8ubW9kdWxlQ291bnR9fSB7e2NvbnRlbnQ/Lm1vZHVsZUNvdW50ID4gMT9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdtb2R1bGVzJyA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbW9kdWxlJ319PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQ/LmxlYWZOb2Rlc0NvdW50XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwZXJpb2RcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBub2R0cmFuc2xhdGVcIj57e2NvbnRlbnQ/LmxlYWZOb2Rlc0NvdW50fX0ge3tjb250ZW50Py5sZWFmTm9kZXNDb3VudFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPjEgPyAnaXRlbXMnOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2l0ZW0nfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBNaWxlc3RvbmUgQ29tcGxldGlvbiBQcm9ncmVzcyAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc01pbGVzdG9uZSAmJiBpc0Vucm9sbGVkICYmICFpc01pbGVzdG9uZUxvY2tlZFwiIGNsYXNzPVwibWlsZXN0b25lLXByb2dyZXNzIG10LTIgIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktYmV0d2VlblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWlsZXN0b25lLXByb2dyZXNzLXRleHQgbm9kdHJhbnNsYXRlXCI+e3tnZXRNaWxlc3RvbmVDb21wbGV0ZWRDb3VudCgpfX0gb2ZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tjb250ZW50Py5sZWFmTm9kZXNDb3VudCB8fCAwfX0gY29tcGxldGVkPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gVmlldyBBY2hpZXZlbWVudCBCdXR0b24gZm9yIGNvbXBsZXRlZCBtaWxlc3RvbmVzIC0gT3V0c2lkZSBjbGlja2FibGUgYXJlYSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNNaWxlc3RvbmUgJiYgaXNFbnJvbGxlZCAmJiAoZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcikgPj0gMTAwIHx8IGdldENvbXBsZXRpb25TdGF0dXMoY29udGVudD8uaWRlbnRpZmllcikgPT09IDIpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ2aWV3LWFjaGlldmVtZW50LWNvbnRhaW5lciBtdC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwidmlldy1hY2hpZXZlbWVudC1idG5cIiBbZGlzYWJsZWRdPVwiYWNoaWV2ZW1lbnRMb2FkaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJ2aWV3TWlsZXN0b25lQWNoaWV2ZW1lbnQoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCIhYWNoaWV2ZW1lbnRMb2FkaW5nXCI+VmlldyBBY2hpZXZlbWVudDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtc3Bpbm5lciAqbmdJZj1cImFjaGlldmVtZW50TG9hZGluZ1wiIFtkaWFtZXRlcl09XCIxNlwiIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHJva2VXaWR0aF09XCIyXCIgY29sb3I9XCJwcmltYXJ5XCIgY2xhc3M9XCJpbmxpbmUtc3Bpbm5lclwiPjwvbWF0LXNwaW5uZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFVubG9jayBDcml0ZXJpYSBNZXNzYWdlIGZvciBMb2NrZWQgTWlsZXN0b25lcyAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc01pbGVzdG9uZSAmJiBpc0Vucm9sbGVkICYmIGlzTWlsZXN0b25lTG9ja2VkXCIgY2xhc3M9XCJtaWxlc3RvbmUtbG9ja2VkLW1lc3NhZ2UgbXQtMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibG9ja2VkLWNyaXRlcmlhLXRleHQgbWF0LWNhcHRpb25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZ2V0TWlsZXN0b25lVW5sb2NrTWVzc2FnZSgpIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gRm9yIGNvdXJzZSBwcm9ncmVzcyB0byBiZSBzaG93biAtLT5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzRW5yb2xsZWQgJiYgIWlzTWlsZXN0b25lTG9ja2VkICYmICFpc1BhcmVudE1pbGVzdG9uZUxvY2tlZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIWZvclByZXZpZXcgJiYgY29udGVudD8uaWRlbnRpZmllciAmJiBnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKSAmJiBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gJ0NvdXJzZSdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29tcGxldGlvblN0YXR1cyhjb250ZW50Py5pZGVudGlmaWVyKSA9PSAyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTIgbXItNCAgZmxleCBmbGV4LTEgZmxleC1jb2wgIHByb2dyZXNzLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93IGp1c3RpZnktZW5kIHctZnVsbCBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtYXQtYm9keS0yIG5vZHRyYW5zbGF0ZSBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Z2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcil9fSU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8d3Mtd2lkZ2V0LWNvbnRlbnQtcHJvZ3Jlc3MgW2NvbnRlbnRJZF09XCJjb250ZW50Py5wcm9ncmVzc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9ncmVzc109XCJnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9ncmVzc1R5cGVdPVwiJ3BlcmNlbnRhZ2UnXCIgW2N1c3RvbUNsYXNzTmFtZV09XCIndmlld2VyLXByb2dyZXNzJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvd3Mtd2lkZ2V0LWNvbnRlbnQtcHJvZ3Jlc3M+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwibWwtNSBjZXJ0aWZpY2F0ZS1idG5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2Rpc2FibGUtYnRuJzogZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgfHwgY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWR9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIiFkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZyAmJiBkb3dubG9hZENlcnRpZmljYXRlKGNvbnRlbnQ/Lmlzc3VlZENlcnRpZmljYXRlc0lkKTskZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8aW1nIHNyYz1cImZ1c2lvbi1hc3NldHMvaW1hZ2VzL2NlcnRpZmljYXRlLWljby5zdmdcIiB3aWR0aD1cIjI0XCIgaGVpZ2h0PVwiMjRcIj4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibm9kdHJhbnNsYXRlXCI+Q2VydGlmaWNhdGU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIiFkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1sLTJcIj5hcnJvd19kb3dud2FyZDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjZW50ZXIgZmxleCBmbGV4LW1pZGRsZSBjZXJ0aWZpY2F0ZS1sb2FkZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zcGlubmVyIHN0cm9rZVdpZHRoPVwiMlwiIHN0cm9rZT1cIid3aGl0ZSdcIiBjbGFzcz1cIndoaXRlLXNwaW5uZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaWFtZXRlcl09XCIxNlwiPjwvbWF0LXNwaW5uZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8Y2lyY2xlLXByb2dyZXNzIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgcHJvZ3Jlc3NcIiBbcGVyY2VudF09XCIxMDBcIiBbcmFkaXVzXT1cIjEyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZVdpZHRoXT1cIjNcIiBbaW5uZXJTdHJva2VXaWR0aF09XCIzXCIgW3NwYWNlXT1cIi0zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZUNvbG9yXT1cInByb2dyZXNzQ29sb3IoKVwiIFtpbm5lclN0cm9rZUNvbG9yXT1cIidyZ2JhKDAsMCwwLC4xNiknXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthbmltYXRpb25dPVwidHJ1ZVwiIFthbmltYXRpb25EdXJhdGlvbl09XCIzMDBcIiBbc2hvd1RpdGxlXT1cImZhbHNlXCIgW3Nob3dVbml0c109XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1N1YnRpdGxlXT1cImZhbHNlXCIgW3Nob3dJbm5lclN0cm9rZV09XCJ0cnVlXCIgW2Nsb2Nrd2lzZV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtiYWNrZ3JvdW5kT3BhY2l0eV09XCIwXCIgW2JhY2tncm91bmRHcmFkaWVudF09XCJmYWxzZVwiIFtiYWNrZ3JvdW5kU3Ryb2tlV2lkdGhdPVwiM1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1plcm9PdXRlclN0cm9rZV09ZmFsc2UgW2JhY2tncm91bmRQYWRkaW5nXT1cIi05XCIgW3N0YXJ0RnJvbVplcm9dPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRQYWRkaW5nXT1cIjBcIiBbaW1hZ2VIZWlnaHRdPVwiMjRcIiBbaW1hZ2VXaWR0aF09XCIyNFwiIFtzaG93QmFja2dyb3VuZF09XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VMaW5lY2FwXT1cIididXR0J1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2NpcmNsZS1wcm9ncmVzcz4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENvbXBsZXRpb25TdGF0dXMoY29udGVudD8uaWRlbnRpZmllcikgPCAyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTIgbXItNCAgZmxleCBmbGV4LTEgZmxleC1jb2wgIHByb2dyZXNzLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93IGp1c3RpZnktZW5kIHctZnVsbCB3cy1tYXQtYmxhY2stdGV4dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1hdC1ib2R5LTIgIHdzLW1hdC1ibGFjay10ZXh0IG5vZHRyYW5zbGF0ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKX19JTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx3cy13aWRnZXQtY29udGVudC1wcm9ncmVzcyBbY29udGVudElkXT1cImNvbnRlbnQ/LnByb2dyZXNzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb2dyZXNzXT1cImdldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb2dyZXNzVHlwZV09XCIncGVyY2VudGFnZSdcIiBbY3VzdG9tQ2xhc3NOYW1lXT1cIid2aWV3ZXItcHJvZ3Jlc3MnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC93cy13aWRnZXQtY29udGVudC1wcm9ncmVzcz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQ/Lmlzc3VlZENlcnRpZmljYXRlc0lkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJtbC01IGNlcnRpZmljYXRlLWJ0blwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnZGlzYWJsZS1idG4nOiBkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZyB8fCBjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiIWRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nICYmIGRvd25sb2FkQ2VydGlmaWNhdGUoY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWQpOyRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDxpbWcgc3JjPVwiZnVzaW9uLWFzc2V0cy9pbWFnZXMvY2VydGlmaWNhdGUtaWNvLnN2Z1wiIHdpZHRoPVwiMjRcIiBoZWlnaHQ9XCIyNFwiPiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJub2R0cmFuc2xhdGVcIj5DZXJ0aWZpY2F0ZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiIWRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibWwtMlwiPmFycm93X2Rvd253YXJkPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNlbnRlciBmbGV4IGZsZXgtbWlkZGxlIGNlcnRpZmljYXRlLWxvYWRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNwaW5uZXIgc3Ryb2tlV2lkdGg9XCIyXCIgc3Ryb2tlPVwiJ3doaXRlJ1wiIGNsYXNzPVwid2hpdGUtc3Bpbm5lclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RpYW1ldGVyXT1cIjE2XCI+PC9tYXQtc3Bpbm5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZWUtYWxsLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGEgaHJlZj1cImphdmFzY3JpcHQ6dm9pZCgwKVwiIHJvbGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJjb250ZW50LnZpZXdDaGlsZHJlbiA9ICFjb250ZW50LnZpZXdDaGlsZHJlbjsgZXhwYW5kQWN0aXZlID0gZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwic2VlLWFsbC1idG4gdGFiIGN1c3RvbS1jaGV2cm9uIGN1c3RvbWljb25cIiBtYXQtYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIiFjb250ZW50LnZpZXdDaGlsZHJlbiAmJiAhaXNNb2R1bGVcIj5rZXlib2FyZF9hcnJvd19kb3duPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJjb250ZW50LnZpZXdDaGlsZHJlbiAmJiAhaXNNb2R1bGVcIj5rZXlib2FyZF9hcnJvd191cDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiIWNvbnRlbnQudmlld0NoaWxkcmVuICYmIGlzTW9kdWxlXCI+YWRkPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJjb250ZW50LnZpZXdDaGlsZHJlbiAmJiBpc01vZHVsZVwiPnJlbW92ZTwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY2hpbGQtd3JhcHBlciAgXCIgKm5nSWY9XCJjb250ZW50LnZpZXdDaGlsZHJlblwiIFtuZ0NsYXNzXT1cInsnb3Blbic6IGNvbnRlbnQudmlld0NoaWxkcmVuLFxuICAgICAgICAgICAgJ2Nsb3NlJzogIWNvbnRlbnQudmlld0NoaWxkcmVuLFxuICAgICAgICAgICAgJ2NvdXJzZSc6IWlzTW9kdWxlLFxuICAgICAgICAgICAgJ21vZHVsZSc6IGlzTW9kdWxlfVwiIFtAcGFuZWxJbk91dF0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2hpbGRyZW4tY29udGFpbmVyXCIgW25nQ2xhc3NdPVwieydtb2R1bGUnOiBpc01vZHVsZSwgJyc6ICFpc01vZHVsZX1cIj5cbiAgICAgICAgICAgICAgICA8d3Mtd2lkZ2V0LWFwcC10b2MtY29udGVudC1jYXJkLXYyIFtmb3JQcmV2aWV3XT1cImZvclByZXZpZXdcIiBbY29tcG9uZW50TmFtZV09XCJjb21wb25lbnROYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgW2NvbnRlbnRdPVwiY2hpbGRcIiBbZXhwYW5kQWxsXT1cImV4cGFuZEFsbFwiIFtyb290SWRdPVwicm9vdElkXCIgW2JhdGNoSWRdPVwiYmF0Y2hJZFwiXG4gICAgICAgICAgICAgICAgICAgIFtyb290Q29udGVudFR5cGVdPVwicm9vdENvbnRlbnRUeXBlXCIgW2luZGV4XT1cImorMVwiIFtiYXNlQ29udGVudFJlYWREYXRhXT1cImJhc2VDb250ZW50UmVhZERhdGFcIlxuICAgICAgICAgICAgICAgICAgICBbcGF0aFNldF09XCJwYXRoU2V0XCIgW2hpZXJhcmNoeU1hcERhdGFdPVwiaGllcmFyY2h5TWFwRGF0YVwiIFtiYXRjaERhdGFdPVwiYmF0Y2hEYXRhXCJcbiAgICAgICAgICAgICAgICAgICAgW21sQ291cnNlXT1cIm1sQ291cnNlXCIgW3BhcmVudE1pbGVzdG9uZUxvY2tlZF09XCJpc01pbGVzdG9uZUxvY2tlZCB8fCBpc1BhcmVudE1pbGVzdG9uZUxvY2tlZFwiXG4gICAgICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBjaGlsZCBvZiBjb250ZW50Py5jaGlsZHJlbjsgdHJhY2tCeTogY29udGVudFRyYWNrQnk7IGxldCBqPSBpbmRleDtsZXQgaXNGaXJzdCA9IGZpcnN0XCJcbiAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydtb2R1bGVDYXJkJzogY2hlY2tJc01vZHVsZShjaGlsZCksICdyZXNvdXJjZUNhcmQnOiAhY2hlY2tJc01vZHVsZShjaGlsZCksICdmaXJzdCc6IGlzRmlyc3R9XCI+XG4gICAgICAgICAgICAgICAgPC93cy13aWRnZXQtYXBwLXRvYy1jb250ZW50LWNhcmQtdjI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG48L25nLXRlbXBsYXRlPlxuXG5cbjxuZy1jb250YWluZXIgKm5nSWY9XCJpc1ByZUFzc2Vzc21lbnRcIj5cbiAgICA8ZGl2IGNsYXNzPVwiY29sbGVjdGlvbi13cmFwcGVyIHAtNCBmbGV4IGZsZXgtY29sIHBvc2l0aW9uLXJlbGF0aXZlXCIgW25nQ2xhc3NdPVwieydvcGVuJzogY2hlY2soY29udGVudCksXG4gICAgICAgICdjb3Vyc2UnOiFpc01vZHVsZSwgJ21vZHVsZSc6IGlzTW9kdWxlLFxuICAgICAgICAnY29udGVudC1hY3RpdmUnOiBwYXRoU2V0Py5oYXMoY29udGVudC5pZGVudGlmaWVyKX1cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtY29sbGVjdGlvbiB3LWF1dG8gc206dy0xMDAgcGFkZGluZy1yaWdodC14bFwiPlxuICAgICAgICAgICAgPCEtLSA8aW1nIGNsYXNzPVwiY2FyZC10aHVtYm5haWwgd3MtbWF0LXByaW1hcnktbGl0ZS1iYWNrZ3JvdW5kXCIgW3NyY109XCJjb250ZW50Py5hcHBJY29uXCIgYWx0PVwiVGh1bWJuYWlsXCJcbiAgICAgICAgKGNsaWNrKT1cImNvbnRlbnQudmlld0NoaWxkcmVuID0gIWNvbnRlbnQudmlld0NoaWxkcmVuXCIgW3dzVXRpbHNEZWZhdWx0VGh1bWJuYWlsXT1cImRlZmF1bHRUaHVtYm5haWxcIiAvPiAtLT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sIGZsZXgtd3JhcCBmbGV4LWJldHdlZW4gd2lkdGgtZXhwYW5kIHByLTAgdy0xMDAgXCI+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC10cnVuY2F0ZVwiIFtuZ0NsYXNzXT1cInsnY3Vyc29yLXBvaW50ZXInOiAhaXNFbmFibGVkfVwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJjb250ZW50LnZpZXdDaGlsZHJlbiA9ICFjb250ZW50LnZpZXdDaGlsZHJlblwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBzbTpmbGV4LXJvdyBmbGV4LXdyYXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFmb3JQcmV2aWV3ICYmIGNvbnRlbnQ/LmlkZW50aWZpZXIgJiYgZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcikgOyBlbHNlIGVsc2VCbG9ja1wiPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb21wbGV0aW9uU3RhdHVzKGNvbnRlbnQuaWRlbnRpZmllcikgPT0gMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbXBsZXRlZCBtci0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwiY29tcGxldGVkLWljb25cIiBbY29sb3JdPVwiYmx1ZVwiPmNoZWNrX2NpcmNsZTwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb21wbGV0aW9uU3RhdHVzKGNvbnRlbnQ/LmlkZW50aWZpZXIpIDwgMlwiPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlLXByb2dyZXNzIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgcHJvZ3Jlc3MgbXItMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BlcmNlbnRdPVwiZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcilcIiBbcmFkaXVzXT1cIjEwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VXaWR0aF09XCIyXCIgW2lubmVyU3Ryb2tlV2lkdGhdPVwiMlwiIFtzcGFjZV09XCItMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlQ29sb3JdPVwicHJvZ3Jlc3NDb2xvcjIoKVwiIFtpbm5lclN0cm9rZUNvbG9yXT1cIidyZ2JhKDAsIDAsIDAsIDAuMTYpJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2FuaW1hdGlvbl09XCJ0cnVlXCIgW2FuaW1hdGlvbkR1cmF0aW9uXT1cIjI1MFwiIFtzaG93VGl0bGVdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93VW5pdHNdPVwiZmFsc2VcIiBbc2hvd1N1YnRpdGxlXT1cImZhbHNlXCIgW3Nob3dJbm5lclN0cm9rZV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xvY2t3aXNlXT1cInRydWVcIiBbYmFja2dyb3VuZE9wYWNpdHldPVwiMFwiIFtiYWNrZ3JvdW5kR3JhZGllbnRdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtiYWNrZ3JvdW5kU3Ryb2tlV2lkdGhdPVwiM1wiIG1hdFRvb2x0aXA9XCJJbiBwcm9ncmVzc1wiIFtzaG93WmVyb091dGVyU3Ryb2tlXT1mYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtiYWNrZ3JvdW5kUGFkZGluZ109XCItN1wiIFtzdGFydEZyb21aZXJvXT1cImZhbHNlXCIgW2JhY2tncm91bmRQYWRkaW5nXT1cIjBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpbWFnZUhlaWdodF09XCIxOFwiIFtpbWFnZVdpZHRoXT1cIjE4XCIgW3Nob3dCYWNrZ3JvdW5kXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VMaW5lY2FwXT1cIididXR0J1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9jaXJjbGUtcHJvZ3Jlc3M+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZWxzZUJsb2NrPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlLXByb2dyZXNzIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgcHJvZ3Jlc3MgbXItMVwiIFtwZXJjZW50XT1cIjBcIiBbcmFkaXVzXT1cIjExXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZVdpZHRoXT1cIjJcIiBbaW5uZXJTdHJva2VXaWR0aF09XCIyXCIgW291dGVyU3Ryb2tlQ29sb3JdPVwiJyM4MDgwODAnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpbm5lclN0cm9rZUNvbG9yXT1cIicjODA4MDgwJ1wiIFthbmltYXRpb25dPVwidHJ1ZVwiIFtzcGFjZV09XCItMlwiIFtzaG93VW5pdHNdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2FuaW1hdGlvbkR1cmF0aW9uXT1cIjI1MFwiIFtzaG93VGl0bGVdPVwiZmFsc2VcIiBbYmFja2dyb3VuZFBhZGRpbmddPVwiMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZFBhZGRpbmddPVwiLTlcIiBbb3V0ZXJTdHJva2VMaW5lY2FwXT1cIididXR0J1wiIG1hdFRvb2x0aXA9XCJOb3Qgc3RhcnRlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1N1YnRpdGxlXT1cImZhbHNlXCIgW3Nob3dJbm5lclN0cm9rZV09XCJ0cnVlXCIgW2Nsb2Nrd2lzZV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpbWFnZUhlaWdodF09XCIyMlwiIFtpbWFnZVdpZHRoXT1cIjIyXCIgW3Nob3dCYWNrZ3JvdW5kXT1cImZhbHNlXCI+PC9jaXJjbGUtcHJvZ3Jlc3M+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBbbmdDbGFzc109XCJ7J2NvbGxlY3Rpb24tYWN0aXZlLWNsYXNzJzogcGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpfVwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8cCBjbGFzcz1cIm1hcmdpbi1yZW1vdmUgdGV4dC10cnVuY2F0ZSBtYXQtc3ViaGVhZGluZy0xIGZsZXgtYXV0byBmb250LWJvbGQgbm9kdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J3RleHQtYWN0aXZlJzogcGF0aFNldD8uaGFzKGNvbnRlbnQuaWRlbnRpZmllcil9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3tpbmRleH19LiB7eyBjb250ZW50Py5uYW1lIHwgdHJ1bmNhdGU6NTAgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvcD4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cIm1hcmdpbi1yZW1vdmUgdGV4dC10cnVuY2F0ZSBtYXQtc3ViaGVhZGluZy0xIGZsZXgtYXV0byBmb250LWJvbGQgbm9kdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuZGlzYWJsZWRdPVwibnVsbFwiIFtuZ0NsYXNzXT1cInsnbWwtMyc6IGlzRW5yb2xsZWR9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcm91dGVyTGlua109XCIoaXNBbGxvd2VkICYmICFmb3JQcmV2aWV3ICYmIGlzRW5hYmxlZCkgPyByZXNvdXJjZUxpbmsudXJsIDogbnVsbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3F1ZXJ5UGFyYW1zXT1cImNvbXB1dGVkUXVlcnlQYXJhbXNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIHt7Y29udGVudD8uY291cnNlQ2F0ZWdvcnl9fSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cInsncmVzb3VyY2UtYWN0aXZlJzogcGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpfVwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlIFwiIFtuZ0NsYXNzXT1cInsnY3Vyc29yLXBvaW50ZXInOiAhaXNFbmFibGVkfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJyYWlzZVRlbGVtZXRyeSgpOyBjaGFuZ2VSZXNvdXJjZSgpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sIHNtOmZsZXgtcm93IGZsZXgtd3JhcFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJtYXJnaW4tcmVtb3ZlIHRleHQtdHJ1bmNhdGUgbWF0LWJvZHktMiBmbGV4LWF1dG8gZm9udC1ib2xkIG5vZHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyd0ZXh0LWFjdGl2ZSc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKX1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDxtYXQtaWNvbiBjbGFzcz1cIm1hcmdpbi1yaWdodC14cyByYWRpb2J0biB0aW1lLWljb25cIj5yYWRpb19idXR0b25fdW5jaGVja2VkIDwvbWF0LWljb24+IC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7aW5kZXh9fS4ge3sgY29udGVudD8ubmFtZSB8IHRydW5jYXRlOjUwIH19XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY29udGVudC10eXBlIG9wdGlvbmFsLXNwYW4gbm9kdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm9wdGlvbmFsUmVhZGluZ1wiPnt7ICdwbGF5ZXJicmllZi5vcHRpb25hbCcgfCB0cmFuc2xhdGUgfFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlY2FzZX19IDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gZm9yIGRlZmF1bHQgZ3JleSBpY29ucyAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFwYXRoU2V0Py5oYXMoY29udGVudD8uaWRlbnRpZmllcilcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZXNpY29ucyB3cy1tYXQtYmxhY2s2MC10ZXh0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS92aWRlby5zdmdcIiBhbHQ9XCJWaWRlb1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIiAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndmlkZW8vbXA0JyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ3ZpZGVvL3gteW91dHViZScgfHxcbiAgICAgICAgICAgICAgICAgICAgICBjb250ZW50Py5taW1lVHlwZSA9PT0nYXBwbGljYXRpb24veC1tcGVnVVJMJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvYXVkaW8uc3ZnXCIgYWx0PVwiQXVkaW9cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2F1ZGlvL21wZWcnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9wZGYuc3ZnXCIgYWx0PVwiUERGXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9wZGYnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L3Jlc291cmNlLnN2Z1wiIGFsdD1cIlN1cnZleVwiIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vc3VydmV5J1wiPiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2xpbmsuc3ZnXCIgYWx0PVwiSW50ZXJhY3RpdmVDb250ZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuZWtzdGVwLmh0bWwtYXJjaGl2ZScgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICd0ZXh0L3gtdXJsJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvYXNzZXNzbWVudC5zdmdcIiBhbHQ9XCJBc3Nlc3NtZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9qc29uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3F1aXonIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLnN1bmJpcmQucXVlc3Rpb25zZXQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9pbWFnZS5zdmdcIiBhbHQ9XCJJbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvcG5nJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL2pwZWcnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9jb250ZW50X2NvcHkuc3ZnXCIgY2xhc3M9XCJjb250ZW50aWNvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsdD1cIkNvdXJzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuY29udGVudC1jb2xsZWN0aW9uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3N1cnZleSdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L21vZHVsZS5zdmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCIgYWx0PVwib2ZmbGluZSBzZXNzaW9uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL29mZmxpbmUnXCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlNUQU5EQUxPTkVfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0VcIj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlc291cmNlRHVyYXRpb24gd3MtbWF0LWJsYWNrNjAtdGV4dCBub2R0cmFuc2xhdGVcIj57e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudD8ubWF4UXVlc3Rpb25zIH19IHt7ICdwbGF5ZXJicmllZi5xdWVzdGlvbnMnIHwgdHJhbnNsYXRlIHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlY2FzZX19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhKGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5TVEFOREFMT05FX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlc291cmNlRHVyYXRpb24gd3MtbWF0LWJsYWNrNjAtdGV4dCBub2R0cmFuc2xhdGVcIj57e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvbnRlbnQ/LmR1cmF0aW9ufHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZXJhcmNoeU1hcERhdGFbY29udGVudD8uaWRlbnRpZmllcl0/LmV4cGVjdGVkRHVyYXRpb24gfHwgMCl8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXBlRHVyYXRpb25UcmFuc2Zvcm06XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaG1zJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBmb3Igd2hpdGUgaWNvbnMgd2hlbiBjb250ZW50IGhpZ2hsaWdodGVkIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwicGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVzaWNvbnMgd3MtbWF0LXdoaXRlLXRleHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS92aWRlby5zdmdcIiBhbHQ9XCJWaWRlb1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIiAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndmlkZW8vbXA0JyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ3ZpZGVvL3gteW91dHViZScgfHxcbiAgICAgICAgICAgICAgICAgICAgICBjb250ZW50Py5taW1lVHlwZSA9PT0nYXBwbGljYXRpb24veC1tcGVnVVJMJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L3doaXRlL2F1ZGlvLnN2Z1wiIGFsdD1cIkF1ZGlvXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhdWRpby9tcGVnJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L3doaXRlL3BkZi5zdmdcIiBhbHQ9XCJQREZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3BkZidcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L3doaXRlL3Jlc291cmNlLnN2Z1wiIGFsdD1cIlN1cnZleVwiIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vc3VydmV5J1wiPiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9saW5rLnN2Z1wiIGFsdD1cIkludGVyYWN0aXZlQ29udGVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLmVrc3RlcC5odG1sLWFyY2hpdmUnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndGV4dC94LXVybCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9hc3Nlc3NtZW50LnN2Z1wiIGFsdD1cIkFzc2Vzc21lbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL2pzb24nIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vcXVpeicgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuc3VuYmlyZC5xdWVzdGlvbnNldCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2ltYWdlLnN2Z1wiIGFsdD1cIkltYWdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdpbWFnZS9wbmcnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvanBlZydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9jb250ZW50X2NvcHkuc3ZnXCIgY2xhc3M9XCJjb250ZW50aWNvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsdD1cIkNvdXJzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuY29udGVudC1jb2xsZWN0aW9uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3N1cnZleSdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9tb2R1bGUuc3ZnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiIGFsdD1cIm9mZmxpbmUgc2Vzc2lvbnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9vZmZsaW5lJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkNPTVBfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlc291cmNlRHVyYXRpb24gd3MtbWF0LXdoaXRlLXRleHQgbm9kdHJhbnNsYXRlXCI+e3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ/Lm1heFF1ZXN0aW9ucyB9fSB7eyAncGxheWVyYnJpZWYucXVlc3Rpb25zJyB8IHRyYW5zbGF0ZSB8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZWNhc2V9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIShjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkNPTVBfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXNvdXJjZUR1cmF0aW9uIHdzLW1hdC13aGl0ZS10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29udGVudD8uZHVyYXRpb258fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGllcmFyY2h5TWFwRGF0YVtjb250ZW50Py5pZGVudGlmaWVyXT8uZXhwZWN0ZWREdXJhdGlvbiB8fCAwKXxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpcGVEdXJhdGlvblRyYW5zZm9ybTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdobXMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGRpdiBjbGFzcz1cInR5cGUtY29udGFpbmVyIHJlc291cmNlIG10LTIgc206bXQtMFwiICpuZ0lmPVwiY29udGVudD8uY2F0ZWdvcnkgPT09ICdSZXNvdXJjZSdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJtci0xIGN1c3RvbS1pY29uIHJvdGF0ZS05MFwiPmNhbGxfdG9fYWN0aW9uPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5vZHRyYW5zbGF0ZVwiPlJlc291cmNlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHlwZS1jb250YWluZXIgbW9kdWxlIG10LTIgc206bXQtMFwiICpuZ0lmPVwiY29udGVudD8uY2F0ZWdvcnkgPT09ICdDb2xsZWN0aW9uJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1yLTEgY3VzdG9tLWljb24gcm90YXRlLTkwXCI+Y2FsbF90b19hY3Rpb248L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibm9kdHJhbnNsYXRlXCI+TW9kdWxlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHlwZS1jb250YWluZXIgY291cnNlIG10LTIgc206bXQtMFwiICpuZ0lmPVwiY29udGVudD8uY2F0ZWdvcnkgPT09ICdDb3Vyc2UnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibXItMSBjdXN0b20taWNvbiByb3RhdGUtOTBcIj5jYWxsX3RvX2FjdGlvbjwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJub2R0cmFuc2xhdGVcIj5Db3Vyc2U8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4gLS0+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPCEtLSBGb3IgY291cnNlIHByb2dyZXNzIHRvIGJlIHNob3duIC0tPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIWZvclByZXZpZXcgJiYgY29udGVudD8uaWRlbnRpZmllciAmJiBnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENvbXBsZXRpb25TdGF0dXMoY29udGVudD8uaWRlbnRpZmllcikgPT0gMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMiBtci00ICBmbGV4IGZsZXgtMSBmbGV4LWNvbCAgcHJvZ3Jlc3MtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBqdXN0aWZ5LWVuZCB3LWZ1bGwgXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtYXQtYm9keS0yIG5vZHRyYW5zbGF0ZSBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKX19JTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8d3Mtd2lkZ2V0LWNvbnRlbnQtcHJvZ3Jlc3MgW2NvbnRlbnRJZF09XCJjb250ZW50Py5wcm9ncmVzc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb2dyZXNzXT1cImdldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvZ3Jlc3NUeXBlXT1cIidwZXJjZW50YWdlJ1wiIFtjdXN0b21DbGFzc05hbWVdPVwiJ3ZpZXdlci1wcm9ncmVzcydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvd3Mtd2lkZ2V0LWNvbnRlbnQtcHJvZ3Jlc3M+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwibWwtNSBjZXJ0aWZpY2F0ZS1idG5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnZGlzYWJsZS1idG4nOiBkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZyB8fCBjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCIhZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgJiYgZG93bmxvYWRDZXJ0aWZpY2F0ZShjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZCk7JGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8aW1nIHNyYz1cImZ1c2lvbi1hc3NldHMvaW1hZ2VzL2NlcnRpZmljYXRlLWljby5zdmdcIiB3aWR0aD1cIjI0XCIgaGVpZ2h0PVwiMjRcIj4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJub2R0cmFuc2xhdGVcIj5DZXJ0aWZpY2F0ZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCIhZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1sLTJcIj5hcnJvd19kb3dud2FyZDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNlbnRlciBmbGV4IGZsZXgtbWlkZGxlIGNlcnRpZmljYXRlLWxvYWRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zcGlubmVyIHN0cm9rZVdpZHRoPVwiMlwiIHN0cm9rZT1cIid3aGl0ZSdcIiBjbGFzcz1cIndoaXRlLXNwaW5uZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RpYW1ldGVyXT1cIjE2XCI+PC9tYXQtc3Bpbm5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8Y2lyY2xlLXByb2dyZXNzIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgcHJvZ3Jlc3NcIiBbcGVyY2VudF09XCIxMDBcIiBbcmFkaXVzXT1cIjEyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlV2lkdGhdPVwiM1wiIFtpbm5lclN0cm9rZVdpZHRoXT1cIjNcIiBbc3BhY2VdPVwiLTNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VDb2xvcl09XCJwcm9ncmVzc0NvbG9yKClcIiBbaW5uZXJTdHJva2VDb2xvcl09XCIncmdiYSgwLDAsMCwuMTYpJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthbmltYXRpb25dPVwidHJ1ZVwiIFthbmltYXRpb25EdXJhdGlvbl09XCIzMDBcIiBbc2hvd1RpdGxlXT1cImZhbHNlXCIgW3Nob3dVbml0c109XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93U3VidGl0bGVdPVwiZmFsc2VcIiBbc2hvd0lubmVyU3Ryb2tlXT1cInRydWVcIiBbY2xvY2t3aXNlXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZE9wYWNpdHldPVwiMFwiIFtiYWNrZ3JvdW5kR3JhZGllbnRdPVwiZmFsc2VcIiBbYmFja2dyb3VuZFN0cm9rZVdpZHRoXT1cIjNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1plcm9PdXRlclN0cm9rZV09ZmFsc2UgW2JhY2tncm91bmRQYWRkaW5nXT1cIi05XCIgW3N0YXJ0RnJvbVplcm9dPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZFBhZGRpbmddPVwiMFwiIFtpbWFnZUhlaWdodF09XCIyNFwiIFtpbWFnZVdpZHRoXT1cIjI0XCIgW3Nob3dCYWNrZ3JvdW5kXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlTGluZWNhcF09XCInYnV0dCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2NpcmNsZS1wcm9ncmVzcz4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb21wbGV0aW9uU3RhdHVzKGNvbnRlbnQ/LmlkZW50aWZpZXIpIDwgMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMiBtci00ICBmbGV4IGZsZXgtMSBmbGV4LWNvbCAgcHJvZ3Jlc3MtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBqdXN0aWZ5LWVuZCB3LWZ1bGwgd3MtbWF0LWJsYWNrLXRleHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1hdC1ib2R5LTIgIHdzLW1hdC1ibGFjay10ZXh0IG5vZHRyYW5zbGF0ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2dldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpfX0lPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx3cy13aWRnZXQtY29udGVudC1wcm9ncmVzcyBbY29udGVudElkXT1cImNvbnRlbnQ/LnByb2dyZXNzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvZ3Jlc3NdPVwiZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcilcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9ncmVzc1R5cGVdPVwiJ3BlcmNlbnRhZ2UnXCIgW2N1c3RvbUNsYXNzTmFtZV09XCIndmlld2VyLXByb2dyZXNzJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC93cy13aWRnZXQtY29udGVudC1wcm9ncmVzcz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJtbC01IGNlcnRpZmljYXRlLWJ0blwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydkaXNhYmxlLWJ0bic6IGRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nIHx8IGNvbnRlbnQ/Lmlzc3VlZENlcnRpZmljYXRlc0lkfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIiFkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZyAmJiBkb3dubG9hZENlcnRpZmljYXRlKGNvbnRlbnQ/Lmlzc3VlZENlcnRpZmljYXRlc0lkKTskZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDxpbWcgc3JjPVwiZnVzaW9uLWFzc2V0cy9pbWFnZXMvY2VydGlmaWNhdGUtaWNvLnN2Z1wiIHdpZHRoPVwiMjRcIiBoZWlnaHQ9XCIyNFwiPiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5vZHRyYW5zbGF0ZVwiPkNlcnRpZmljYXRlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIiFkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibWwtMlwiPmFycm93X2Rvd253YXJkPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2VudGVyIGZsZXggZmxleC1taWRkbGUgY2VydGlmaWNhdGUtbG9hZGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNwaW5uZXIgc3Ryb2tlV2lkdGg9XCIyXCIgc3Ryb2tlPVwiJ3doaXRlJ1wiIGNsYXNzPVwid2hpdGUtc3Bpbm5lclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlhbWV0ZXJdPVwiMTZcIj48L21hdC1zcGlubmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgIDwhLS0gPGRpdiBjbGFzcz1cInNlZS1hbGwtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxhIGhyZWY9XCJqYXZhc2NyaXB0OnZvaWQoMClcIiByb2xlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJjb250ZW50LnZpZXdDaGlsZHJlbiA9ICFjb250ZW50LnZpZXdDaGlsZHJlbjsgZXhwYW5kQWN0aXZlID0gZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzZWUtYWxsLWJ0biB0YWIgY3VzdG9tLWNoZXZyb24gY3VzdG9taWNvblwiIG1hdC1idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCIhY29udGVudC52aWV3Q2hpbGRyZW4gJiYgIWlzTW9kdWxlXCI+a2V5Ym9hcmRfYXJyb3dfZG93bjwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJjb250ZW50LnZpZXdDaGlsZHJlbiAmJiAhaXNNb2R1bGVcIj5rZXlib2FyZF9hcnJvd191cDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCIhY29udGVudC52aWV3Q2hpbGRyZW4gJiYgaXNNb2R1bGVcIj5hZGQ8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiY29udGVudC52aWV3Q2hpbGRyZW4gJiYgaXNNb2R1bGVcIj5yZW1vdmU8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgPC9kaXY+IC0tPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG48L25nLWNvbnRhaW5lcj4iXX0=