rubyfox-server 2.13.4.1 → 2.16.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (605) hide show
  1. checksums.yaml +5 -5
  2. data/lib/rubyfox/server/data/config/UploadsLock.txt +3 -0
  3. data/lib/rubyfox/server/data/config/admin/admintool.xml +2 -0
  4. data/lib/rubyfox/server/data/config/admin/descriptors/config_room.txt +97 -43
  5. data/lib/rubyfox/server/data/config/admin/descriptors/config_server.txt +307 -93
  6. data/lib/rubyfox/server/data/config/admin/descriptors/config_zone.txt +311 -95
  7. data/lib/rubyfox/server/data/config/admin/descriptors/runtime_game.txt +5 -5
  8. data/lib/rubyfox/server/data/config/admin/descriptors/runtime_mmo.txt +6 -6
  9. data/lib/rubyfox/server/data/config/admin/descriptors/runtime_room.txt +69 -44
  10. data/lib/rubyfox/server/data/config/admin/descriptors/runtime_user.txt +55 -43
  11. data/lib/rubyfox/server/data/config/admin/descriptors/runtime_zone.txt +81 -36
  12. data/lib/rubyfox/server/data/config/admin/gmc/gmc.py +55 -18
  13. data/lib/rubyfox/server/data/config/admin/icons/Analytics.png +0 -0
  14. data/lib/rubyfox/server/data/config/admin/icons/Analytics.svg +1 -0
  15. data/lib/rubyfox/server/data/config/admin/icons/BanManager.png +0 -0
  16. data/lib/rubyfox/server/data/config/admin/icons/BanManager.svg +1 -0
  17. data/lib/rubyfox/server/data/config/admin/icons/BlueBoxMonitor.png +0 -0
  18. data/lib/rubyfox/server/data/config/admin/icons/BlueBoxMonitor.svg +1 -0
  19. data/lib/rubyfox/server/data/config/admin/icons/Console.png +0 -0
  20. data/lib/rubyfox/server/data/config/admin/icons/Console.svg +9 -0
  21. data/lib/rubyfox/server/data/config/admin/icons/Dashboard.png +0 -0
  22. data/lib/rubyfox/server/data/config/admin/icons/Dashboard.svg +1 -0
  23. data/lib/rubyfox/server/data/config/admin/icons/ExtensionManager.png +0 -0
  24. data/lib/rubyfox/server/data/config/admin/icons/ExtensionManager.svg +1 -0
  25. data/lib/rubyfox/server/data/config/admin/icons/LicenseManager.png +0 -0
  26. data/lib/rubyfox/server/data/config/admin/icons/LicenseManager.svg +1 -0
  27. data/lib/rubyfox/server/data/config/admin/icons/LogViewer.png +0 -0
  28. data/lib/rubyfox/server/data/config/admin/icons/LogViewer.svg +1 -0
  29. data/lib/rubyfox/server/data/config/admin/icons/ServerConfigurator.png +0 -0
  30. data/lib/rubyfox/server/data/config/admin/icons/ServerConfigurator.svg +1 -0
  31. data/lib/rubyfox/server/data/config/admin/icons/ServletManager.png +0 -0
  32. data/lib/rubyfox/server/data/config/admin/icons/ServletManager.svg +1 -0
  33. data/lib/rubyfox/server/data/config/admin/icons/ZoneConfigurator.png +0 -0
  34. data/lib/rubyfox/server/data/config/admin/icons/ZoneConfigurator.svg +1 -0
  35. data/lib/rubyfox/server/data/config/admin/icons/ZoneMonitor.png +0 -0
  36. data/lib/rubyfox/server/data/config/admin/icons/ZoneMonitor.svg +1 -0
  37. data/lib/rubyfox/server/data/config/core.xml +2 -2
  38. data/lib/rubyfox/server/data/config/log4j.properties +7 -7
  39. data/lib/rubyfox/server/data/config/server.xml +9 -10
  40. data/lib/rubyfox/server/data/config/wordsFile.txt +0 -2
  41. data/lib/rubyfox/server/data/data/GeoLite2-Country.mmdb +0 -0
  42. data/lib/rubyfox/server/data/{config → data/buddylists/BasicExamples}/.keep +0 -0
  43. data/lib/rubyfox/server/data/data/{buddylists → uploads}/.keep +0 -0
  44. data/lib/rubyfox/server/data/lib/BlueBox.war +0 -0
  45. data/lib/rubyfox/server/data/lib/apache-tomcat/LICENSE +1061 -0
  46. data/lib/rubyfox/server/data/lib/apache-tomcat/NOTICE +68 -0
  47. data/lib/rubyfox/server/data/lib/apache-tomcat/README.md +79 -0
  48. data/lib/rubyfox/server/data/lib/apache-tomcat/RELEASE-NOTES +173 -0
  49. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/bootstrap.jar +0 -0
  50. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/catalina-tasks.xml +39 -0
  51. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/catalina.bat +372 -0
  52. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/catalina.sh +648 -0
  53. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/ciphers.bat +58 -0
  54. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/ciphers.sh +60 -0
  55. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/commons-daemon-native.tar.gz +0 -0
  56. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/commons-daemon.jar +0 -0
  57. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/configtest.bat +58 -0
  58. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/configtest.sh +60 -0
  59. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/daemon.sh +275 -0
  60. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/digest.bat +58 -0
  61. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/digest.sh +60 -0
  62. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/makebase.bat +114 -0
  63. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/makebase.sh +115 -0
  64. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/setclasspath.bat +94 -0
  65. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/setclasspath.sh +98 -0
  66. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/shutdown.bat +58 -0
  67. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/shutdown.sh +60 -0
  68. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/startup.bat +58 -0
  69. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/startup.sh +60 -0
  70. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/tomcat-juli.jar +0 -0
  71. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/tomcat-native.tar.gz +0 -0
  72. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/tool-wrapper.bat +110 -0
  73. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/tool-wrapper.sh +153 -0
  74. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/version.bat +58 -0
  75. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/version.sh +60 -0
  76. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/Catalina/localhost/rewrite.config +1 -0
  77. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/catalina.policy +260 -0
  78. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/catalina.properties +205 -0
  79. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/context.xml +31 -0
  80. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/jaspic-providers.xml +23 -0
  81. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/jaspic-providers.xsd +53 -0
  82. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/keystore.jks +0 -0
  83. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/logging.properties +79 -0
  84. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/server.xml +161 -0
  85. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/tomcat-users.xml +41 -0
  86. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/tomcat-users.xsd +59 -0
  87. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/web.xml +4737 -0
  88. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/annotations-api.jar +0 -0
  89. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/catalina-ant.jar +0 -0
  90. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/catalina-ha.jar +0 -0
  91. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/catalina-storeconfig.jar +0 -0
  92. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/catalina-tribes.jar +0 -0
  93. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/catalina.jar +0 -0
  94. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/ecj-4.12.jar +0 -0
  95. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/el-api.jar +0 -0
  96. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/jasper-el.jar +0 -0
  97. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/jasper.jar +0 -0
  98. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/jaspic-api.jar +0 -0
  99. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/jsp-api.jar +0 -0
  100. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/servlet-api.jar +0 -0
  101. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/sfs2x-ws-helper.jar +0 -0
  102. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-api.jar +0 -0
  103. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-coyote.jar +0 -0
  104. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-dbcp.jar +0 -0
  105. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-cs.jar +0 -0
  106. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-de.jar +0 -0
  107. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-es.jar +0 -0
  108. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-fr.jar +0 -0
  109. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-ja.jar +0 -0
  110. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-ko.jar +0 -0
  111. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-pt-BR.jar +0 -0
  112. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-ru.jar +0 -0
  113. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-zh-CN.jar +0 -0
  114. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-jdbc.jar +0 -0
  115. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-jni.jar +0 -0
  116. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-util-scan.jar +0 -0
  117. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-util.jar +0 -0
  118. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-websocket.jar +0 -0
  119. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/websocket-api.jar +0 -0
  120. data/lib/rubyfox/server/data/{extensions → lib/apache-tomcat/logs}/.keep +0 -0
  121. data/lib/rubyfox/server/data/lib/{jetty/lib/ext/.donotdelete → apache-tomcat/temp/safeToDelete.tmp} +0 -0
  122. data/lib/rubyfox/server/data/lib/{jetty/resources → apache-tomcat/work}/.keep +0 -0
  123. data/lib/rubyfox/server/data/lib/commons-collections-3.2.2.jar +0 -0
  124. data/lib/rubyfox/server/data/lib/commons-compress-1.19.jar +0 -0
  125. data/lib/rubyfox/server/data/lib/js/LibApi.js +48 -181
  126. data/lib/rubyfox/server/data/lib/sfs2x-admin.jar +0 -0
  127. data/lib/rubyfox/server/data/lib/sfs2x-core.jar +0 -0
  128. data/lib/rubyfox/server/data/lib/sfs2x-lib.jar +0 -0
  129. data/lib/rubyfox/server/data/lib/sfs2x-util.jar +0 -0
  130. data/lib/rubyfox/server/data/lib/sfs2x.jar +0 -0
  131. data/lib/rubyfox/server/data/sfs2x-service +6 -6
  132. data/lib/rubyfox/server/data/sfs2x-service.vmoptions +1 -1
  133. data/lib/rubyfox/server/data/sfs2x.sh +1 -1
  134. data/lib/rubyfox/server/data/www/BlueBox.war +0 -0
  135. data/lib/rubyfox/server/data/www/HelloServlet/index.jsp +1 -1
  136. data/lib/rubyfox/server/data/www/{root → ROOT}/_css_/default.css +0 -0
  137. data/lib/rubyfox/server/data/www/{root → ROOT}/_css_/reset.css +0 -0
  138. data/lib/rubyfox/server/data/www/{root → ROOT}/_images_/background_gradient.png +0 -0
  139. data/lib/rubyfox/server/data/www/{root → ROOT}/_images_/background_logo.png +0 -0
  140. data/lib/rubyfox/server/data/www/{root → ROOT}/_images_/favicon.png +0 -0
  141. data/lib/rubyfox/server/data/www/{root → ROOT}/_images_/logo_smartfoxserver.png +0 -0
  142. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/_changes-to-default-themes_.txt +15 -0
  143. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/bootstrap.min.css +7 -0
  144. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/custom-bootstrap.min.css +1 -0
  145. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/fontawesome/css/all.min.css +5 -0
  146. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/fontawesome/webfonts/fa-brands-400.eot +0 -0
  147. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/fontawesome/webfonts/fa-brands-400.svg +3459 -0
  148. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/fontawesome/webfonts/fa-brands-400.ttf +0 -0
  149. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/fontawesome/webfonts/fa-brands-400.woff +0 -0
  150. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/fontawesome/webfonts/fa-brands-400.woff2 +0 -0
  151. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/fontawesome/webfonts/fa-regular-400.eot +0 -0
  152. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/fontawesome/webfonts/fa-regular-400.svg +803 -0
  153. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/fontawesome/webfonts/fa-regular-400.ttf +0 -0
  154. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/fontawesome/webfonts/fa-regular-400.woff +0 -0
  155. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/fontawesome/webfonts/fa-regular-400.woff2 +0 -0
  156. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/fontawesome/webfonts/fa-solid-900.eot +0 -0
  157. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/fontawesome/webfonts/fa-solid-900.svg +4527 -0
  158. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/fontawesome/webfonts/fa-solid-900.ttf +0 -0
  159. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/fontawesome/webfonts/fa-solid-900.woff +0 -0
  160. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/fontawesome/webfonts/fa-solid-900.woff2 +0 -0
  161. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/fonts.css +175 -0
  162. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/jquery.scrolling-tabs.min.css +8 -0
  163. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/kendo.custom-bootstrap-v4.css +15280 -0
  164. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/reset.css +54 -0
  165. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/style.css +1428 -0
  166. data/lib/rubyfox/server/data/www/ROOT/admin/assets/data/countries.geo.json +178 -0
  167. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/FreeMono.otf +0 -0
  168. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/FreeMono.ttf +0 -0
  169. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/FreeMono.woff +0 -0
  170. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/FreeMono.woff2 +0 -0
  171. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-300.ttf +0 -0
  172. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-300.woff +0 -0
  173. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-300.woff2 +0 -0
  174. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-300italic.ttf +0 -0
  175. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-300italic.woff +0 -0
  176. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-300italic.woff2 +0 -0
  177. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-600.ttf +0 -0
  178. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-600.woff +0 -0
  179. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-600.woff2 +0 -0
  180. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-600italic.ttf +0 -0
  181. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-600italic.woff +0 -0
  182. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-600italic.woff2 +0 -0
  183. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-700.ttf +0 -0
  184. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-700.woff +0 -0
  185. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-700.woff2 +0 -0
  186. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-700italic.ttf +0 -0
  187. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-700italic.woff +0 -0
  188. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-700italic.woff2 +0 -0
  189. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-800.ttf +0 -0
  190. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-800.woff +0 -0
  191. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-800.woff2 +0 -0
  192. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-800italic.ttf +0 -0
  193. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-800italic.woff +0 -0
  194. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-800italic.woff2 +0 -0
  195. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-italic.ttf +0 -0
  196. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-italic.woff +0 -0
  197. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-italic.woff2 +0 -0
  198. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-regular.ttf +0 -0
  199. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-regular.woff +0 -0
  200. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/open-sans-v15-cyrillic_greek_cyrillic-ext_vietnamese_latin_latin-ext_greek-ext-regular.woff2 +0 -0
  201. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/roboto-condensed-v16-latin-300.ttf +0 -0
  202. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/roboto-condensed-v16-latin-300.woff +0 -0
  203. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/roboto-condensed-v16-latin-300.woff2 +0 -0
  204. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/roboto-condensed-v16-latin-700.ttf +0 -0
  205. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/roboto-condensed-v16-latin-700.woff +0 -0
  206. data/lib/rubyfox/server/data/www/ROOT/admin/assets/fonts/roboto-condensed-v16-latin-700.woff2 +0 -0
  207. data/lib/rubyfox/server/data/www/ROOT/admin/assets/images/analytics-adv/compare.png +0 -0
  208. data/lib/rubyfox/server/data/www/ROOT/admin/assets/images/analytics-adv/demographicsChart.png +0 -0
  209. data/lib/rubyfox/server/data/www/ROOT/admin/assets/images/analytics-adv/demographicsCompare.png +0 -0
  210. data/lib/rubyfox/server/data/www/ROOT/admin/assets/images/analytics-adv/demographicsFilter.png +0 -0
  211. data/lib/rubyfox/server/data/www/ROOT/admin/assets/images/analytics-adv/demographicsMap.png +0 -0
  212. data/lib/rubyfox/server/data/www/ROOT/admin/assets/images/analytics-adv/demographicsTable.png +0 -0
  213. data/lib/rubyfox/server/data/www/ROOT/admin/assets/images/analytics-adv/technologyChart.png +0 -0
  214. data/lib/rubyfox/server/data/www/ROOT/admin/assets/images/analytics-adv/technologyCompare.png +0 -0
  215. data/lib/rubyfox/server/data/www/ROOT/admin/assets/images/analytics-adv/technologyFilter.png +0 -0
  216. data/lib/rubyfox/server/data/www/ROOT/admin/assets/images/analytics-adv/technologyTable.png +0 -0
  217. data/lib/rubyfox/server/data/www/ROOT/admin/assets/images/apple-touch-icon-180x180.png +0 -0
  218. data/lib/rubyfox/server/data/www/ROOT/admin/assets/images/favicon-16x16.png +0 -0
  219. data/lib/rubyfox/server/data/www/ROOT/admin/assets/images/favicon-32x32.png +0 -0
  220. data/lib/rubyfox/server/data/www/ROOT/admin/assets/images/favicon-64x64.png +0 -0
  221. data/lib/rubyfox/server/data/www/ROOT/admin/assets/images/logo.png +0 -0
  222. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/application.bundle.js +2208 -0
  223. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-0.bundle.js +7662 -0
  224. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-1.bundle.js +929 -0
  225. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-10.bundle.js +766 -0
  226. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-11.bundle.js +71 -0
  227. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-12.bundle.js +1184 -0
  228. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-12~module-13~module-9.bundle.js +2618 -0
  229. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-13.bundle.js +3315 -0
  230. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-3.bundle.js +280 -0
  231. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-4.bundle.js +1122 -0
  232. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-5.bundle.js +2624 -0
  233. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-6.bundle.js +801 -0
  234. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-7.bundle.js +607 -0
  235. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-8.bundle.js +1221 -0
  236. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-9.bundle.js +847 -0
  237. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/vendors~module-0.bundle.js +3240 -0
  238. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/vendors~module-0~module-1~module-13~module-4~module-5~module-7~module-8.bundle.js +17357 -0
  239. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/vendors~module-9.bundle.js +807 -0
  240. data/lib/rubyfox/server/data/{lib/jetty/webapps → www/ROOT/admin/assets/js/custom-modules}/.keep +0 -0
  241. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/libs/bootstrap.min.js +7 -0
  242. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/libs/jquery-3.3.1.min.js +2 -0
  243. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/libs/jquery.scrolling-tabs.min.js +8 -0
  244. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/libs/js.cookie.min.js +8 -0
  245. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/libs/kendo.all.min.js +136 -0
  246. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/libs/popper.min.js +5 -0
  247. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/libs/sfs2x-api-1.7.15.js +8 -0
  248. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/libs/versions-readme.txt +16 -0
  249. data/lib/rubyfox/server/data/www/ROOT/admin/index.html +244 -0
  250. data/lib/rubyfox/server/data/www/ROOT/admin/manifest.json +25 -0
  251. data/lib/rubyfox/server/data/www/ROOT/admin/modules/analytics.html +328 -0
  252. data/lib/rubyfox/server/data/www/ROOT/admin/modules/ban-manager.html +160 -0
  253. data/lib/rubyfox/server/data/www/ROOT/admin/modules/blue-box-monitor.html +37 -0
  254. data/lib/rubyfox/server/data/www/ROOT/admin/modules/console.html +135 -0
  255. data/lib/rubyfox/server/data/www/ROOT/admin/modules/dashboard.html +368 -0
  256. data/lib/rubyfox/server/data/www/ROOT/admin/modules/extension-manager.html +98 -0
  257. data/lib/rubyfox/server/data/www/ROOT/admin/modules/license-manager.html +117 -0
  258. data/lib/rubyfox/server/data/www/ROOT/admin/modules/log-viewer.html +194 -0
  259. data/lib/rubyfox/server/data/www/ROOT/admin/modules/server-configurator.html +55 -0
  260. data/lib/rubyfox/server/data/www/ROOT/admin/modules/servlet-manager.html +98 -0
  261. data/lib/rubyfox/server/data/www/ROOT/admin/modules/zone-configurator.html +62 -0
  262. data/lib/rubyfox/server/data/www/ROOT/admin/modules/zone-monitor.html +346 -0
  263. data/lib/rubyfox/server/data/www/{root → ROOT}/crossdomain.xml +0 -0
  264. data/lib/rubyfox/server/data/www/{root → ROOT}/examples/index.html +0 -0
  265. data/lib/rubyfox/server/data/www/{root → ROOT}/favicon.ico +0 -0
  266. data/lib/rubyfox/server/data/www/{root → ROOT}/favicon.png +0 -0
  267. data/lib/rubyfox/server/data/www/{root → ROOT}/index.html +0 -0
  268. data/lib/rubyfox/server/data/www/host-manager/META-INF/context.xml +24 -0
  269. data/lib/rubyfox/server/data/www/host-manager/WEB-INF/jsp/401.jsp +71 -0
  270. data/lib/rubyfox/server/data/www/host-manager/WEB-INF/jsp/403.jsp +90 -0
  271. data/lib/rubyfox/server/data/www/host-manager/WEB-INF/jsp/404.jsp +62 -0
  272. data/lib/rubyfox/server/data/www/host-manager/WEB-INF/web.xml +131 -0
  273. data/lib/rubyfox/server/data/www/host-manager/images/asf-logo.svg +226 -0
  274. data/lib/rubyfox/server/data/www/host-manager/images/tomcat.gif +0 -0
  275. data/lib/rubyfox/server/data/www/host-manager/index.jsp +18 -0
  276. data/lib/rubyfox/server/data/www/host-manager/manager.xml +26 -0
  277. data/lib/rubyfox/server/data/{logs → www/logsBackup}/.keep +0 -0
  278. data/lib/rubyfox/server/data/www/manager/META-INF/context.xml +24 -0
  279. data/lib/rubyfox/server/data/www/manager/WEB-INF/jsp/401.jsp +80 -0
  280. data/lib/rubyfox/server/data/www/manager/WEB-INF/jsp/403.jsp +100 -0
  281. data/lib/rubyfox/server/data/www/manager/WEB-INF/jsp/404.jsp +63 -0
  282. data/lib/rubyfox/server/data/www/manager/WEB-INF/jsp/connectorCerts.jsp +92 -0
  283. data/lib/rubyfox/server/data/www/manager/WEB-INF/jsp/connectorCiphers.jsp +92 -0
  284. data/lib/rubyfox/server/data/www/manager/WEB-INF/jsp/connectorTrustedCerts.jsp +92 -0
  285. data/lib/rubyfox/server/data/www/manager/WEB-INF/jsp/sessionDetail.jsp +197 -0
  286. data/lib/rubyfox/server/data/www/manager/WEB-INF/jsp/sessionsList.jsp +170 -0
  287. data/lib/rubyfox/server/data/www/manager/WEB-INF/web.xml +195 -0
  288. data/lib/rubyfox/server/data/www/manager/images/asf-logo.svg +226 -0
  289. data/lib/rubyfox/server/data/www/manager/images/tomcat.gif +0 -0
  290. data/lib/rubyfox/server/data/www/manager/index.jsp +18 -0
  291. data/lib/rubyfox/server/data/www/manager/status.xsd +84 -0
  292. data/lib/rubyfox/server/data/www/manager/xform.xsl +125 -0
  293. data/lib/rubyfox/server/version.rb +1 -1
  294. metadata +257 -333
  295. data/lib/rubyfox/server/data/config/ExtensionManagerLock.txt +0 -2
  296. data/lib/rubyfox/server/data/data/bannedusers/users.bin +0 -0
  297. data/lib/rubyfox/server/data/lib/Lib/reindex$py.class +0 -0
  298. data/lib/rubyfox/server/data/lib/cachedir/packages/charsets.pkc +0 -0
  299. data/lib/rubyfox/server/data/lib/cachedir/packages/cldrdata.pkc +0 -0
  300. data/lib/rubyfox/server/data/lib/cachedir/packages/dnsns.pkc +0 -0
  301. data/lib/rubyfox/server/data/lib/cachedir/packages/jaccess.pkc +0 -0
  302. data/lib/rubyfox/server/data/lib/cachedir/packages/javax.mail.glassfish-1.4.1.v201005082020.pkc +0 -0
  303. data/lib/rubyfox/server/data/lib/cachedir/packages/javax.transaction-api-1.2.pkc +0 -0
  304. data/lib/rubyfox/server/data/lib/cachedir/packages/jce.pkc +0 -0
  305. data/lib/rubyfox/server/data/lib/cachedir/packages/jetty-annotations-9.3.11.v20160721.pkc +0 -0
  306. data/lib/rubyfox/server/data/lib/cachedir/packages/jetty-deploy-9.3.11.v20160721.pkc +0 -0
  307. data/lib/rubyfox/server/data/lib/cachedir/packages/jetty-http-9.3.11.v20160721.pkc +0 -0
  308. data/lib/rubyfox/server/data/lib/cachedir/packages/jetty-io-9.3.11.v20160721.pkc +0 -0
  309. data/lib/rubyfox/server/data/lib/cachedir/packages/jetty-jndi-9.3.11.v20160721.pkc +0 -0
  310. data/lib/rubyfox/server/data/lib/cachedir/packages/jetty-plus-9.3.11.v20160721.pkc +0 -0
  311. data/lib/rubyfox/server/data/lib/cachedir/packages/jetty-schemas-3.1.pkc +0 -0
  312. data/lib/rubyfox/server/data/lib/cachedir/packages/jetty-security-9.3.11.v20160721.pkc +0 -0
  313. data/lib/rubyfox/server/data/lib/cachedir/packages/jetty-server-9.3.11.v20160721.pkc +0 -0
  314. data/lib/rubyfox/server/data/lib/cachedir/packages/jetty-servlet-9.3.11.v20160721.pkc +0 -0
  315. data/lib/rubyfox/server/data/lib/cachedir/packages/jetty-util-9.3.11.v20160721.pkc +0 -0
  316. data/lib/rubyfox/server/data/lib/cachedir/packages/jetty-webapp-9.3.11.v20160721.pkc +0 -0
  317. data/lib/rubyfox/server/data/lib/cachedir/packages/jetty-xml-9.3.11.v20160721.pkc +0 -0
  318. data/lib/rubyfox/server/data/lib/cachedir/packages/jfr.pkc +0 -0
  319. data/lib/rubyfox/server/data/lib/cachedir/packages/jfxrt.pkc +0 -0
  320. data/lib/rubyfox/server/data/lib/cachedir/packages/jsse.pkc +0 -0
  321. data/lib/rubyfox/server/data/lib/cachedir/packages/localedata.pkc +0 -0
  322. data/lib/rubyfox/server/data/lib/cachedir/packages/nashorn.pkc +0 -0
  323. data/lib/rubyfox/server/data/lib/cachedir/packages/packages.idx +0 -0
  324. data/lib/rubyfox/server/data/lib/cachedir/packages/resources.pkc +0 -0
  325. data/lib/rubyfox/server/data/lib/cachedir/packages/rt.pkc +0 -0
  326. data/lib/rubyfox/server/data/lib/cachedir/packages/servlet-api-3.1.pkc +0 -0
  327. data/lib/rubyfox/server/data/lib/cachedir/packages/sunec.pkc +0 -0
  328. data/lib/rubyfox/server/data/lib/cachedir/packages/sunjce_provider.pkc +0 -0
  329. data/lib/rubyfox/server/data/lib/cachedir/packages/sunpkcs11.pkc +0 -0
  330. data/lib/rubyfox/server/data/lib/cachedir/packages/zipfs.pkc +0 -0
  331. data/lib/rubyfox/server/data/lib/jetty/VERSION.txt +0 -9320
  332. data/lib/rubyfox/server/data/lib/jetty/etc/README.spnego +0 -62
  333. data/lib/rubyfox/server/data/lib/jetty/etc/jamon.xml +0 -32
  334. data/lib/rubyfox/server/data/lib/jetty/etc/jdbcRealm.properties +0 -72
  335. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-alpn.xml +0 -32
  336. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-annotations.xml +0 -20
  337. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-cdi.xml +0 -19
  338. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-debug.xml +0 -36
  339. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-debuglog.xml +0 -25
  340. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-deploy.xml +0 -76
  341. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-gcloud-memcached-sessions.xml +0 -27
  342. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-gcloud-session-idmgr.xml +0 -19
  343. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-gcloud-sessions.xml +0 -27
  344. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-gzip.xml +0 -67
  345. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-http-forwarded.xml +0 -17
  346. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-http.xml +0 -47
  347. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-http2.xml +0 -26
  348. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-http2c.xml +0 -18
  349. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-https.xml +0 -29
  350. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-infinispan.xml +0 -39
  351. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-ipaccess.xml +0 -28
  352. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-jaas.xml +0 -16
  353. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-jdbc-sessions.xml +0 -34
  354. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-jmx-remote.xml +0 -40
  355. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-jmx.xml +0 -32
  356. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-logging.xml +0 -36
  357. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-lowresources.xml +0 -22
  358. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-monitor.xml +0 -30
  359. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-nosql.xml +0 -19
  360. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-plus.xml +0 -26
  361. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-proxy-protocol-ssl.xml +0 -10
  362. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-proxy-protocol.xml +0 -10
  363. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-proxy.xml +0 -35
  364. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-requestlog.xml +0 -30
  365. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-rewrite-customizer.xml +0 -17
  366. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-rewrite.xml +0 -31
  367. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-setuid.xml +0 -30
  368. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-spring.xml +0 -61
  369. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-ssl-context.xml +0 -29
  370. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-ssl.xml +0 -58
  371. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-started.xml +0 -15
  372. data/lib/rubyfox/server/data/lib/jetty/etc/jetty-stats.xml +0 -18
  373. data/lib/rubyfox/server/data/lib/jetty/etc/jetty.conf +0 -12
  374. data/lib/rubyfox/server/data/lib/jetty/etc/jetty.xml +0 -195
  375. data/lib/rubyfox/server/data/lib/jetty/etc/jminix.xml +0 -12
  376. data/lib/rubyfox/server/data/lib/jetty/etc/jolokia.xml +0 -16
  377. data/lib/rubyfox/server/data/lib/jetty/etc/keystore +0 -0
  378. data/lib/rubyfox/server/data/lib/jetty/etc/krb5.ini +0 -23
  379. data/lib/rubyfox/server/data/lib/jetty/etc/rewrite-compactpath.xml +0 -10
  380. data/lib/rubyfox/server/data/lib/jetty/etc/spnego.conf +0 -19
  381. data/lib/rubyfox/server/data/lib/jetty/etc/spnego.properties +0 -1
  382. data/lib/rubyfox/server/data/lib/jetty/etc/webdefault.xml +0 -539
  383. data/lib/rubyfox/server/data/lib/jetty/lib/asm-5.0.1.jar +0 -0
  384. data/lib/rubyfox/server/data/lib/jetty/lib/asm-commons-5.0.1.jar +0 -0
  385. data/lib/rubyfox/server/data/lib/jetty/lib/fcgi/fcgi-client-9.3.11.v20160721.jar +0 -0
  386. data/lib/rubyfox/server/data/lib/jetty/lib/fcgi/fcgi-server-9.3.11.v20160721.jar +0 -0
  387. data/lib/rubyfox/server/data/lib/jetty/lib/http2-common-9.3.11.v20160721.jar +0 -0
  388. data/lib/rubyfox/server/data/lib/jetty/lib/http2-hpack-9.3.11.v20160721.jar +0 -0
  389. data/lib/rubyfox/server/data/lib/jetty/lib/http2-server-9.3.11.v20160721.jar +0 -0
  390. data/lib/rubyfox/server/data/lib/jetty/lib/jaspi/javax.security.auth.message-1.0.0.v201108011116.jar +0 -0
  391. data/lib/rubyfox/server/data/lib/jetty/lib/javax-websocket-client-impl-9.3.11.v20160721.jar +0 -0
  392. data/lib/rubyfox/server/data/lib/jetty/lib/javax-websocket-server-impl-9.3.11.v20160721.jar +0 -0
  393. data/lib/rubyfox/server/data/lib/jetty/lib/javax.annotation-api-1.2.jar +0 -0
  394. data/lib/rubyfox/server/data/lib/jetty/lib/javax.websocket-api-1.0.jar +0 -0
  395. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-alpn-server-9.3.11.v20160721.jar +0 -0
  396. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-annotations-9.3.11.v20160721.jar +0 -0
  397. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-client-9.3.11.v20160721.jar +0 -0
  398. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-continuation-9.3.11.v20160721.jar +0 -0
  399. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-deploy-9.3.11.v20160721.jar +0 -0
  400. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-gcloud-memcached-session-manager-9.3.11.v20160721.jar +0 -0
  401. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-gcloud-session-manager-9.3.11.v20160721.jar +0 -0
  402. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-http-9.3.11.v20160721.jar +0 -0
  403. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-infinispan-9.3.11.v20160721.jar +0 -0
  404. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-io-9.3.11.v20160721.jar +0 -0
  405. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-jaas-9.3.11.v20160721.jar +0 -0
  406. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-jaspi-9.3.11.v20160721.jar +0 -0
  407. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-jmx-9.3.11.v20160721.jar +0 -0
  408. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-jndi-9.3.11.v20160721.jar +0 -0
  409. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-nosql-9.3.11.v20160721.jar +0 -0
  410. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-plus-9.3.11.v20160721.jar +0 -0
  411. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-proxy-9.3.11.v20160721.jar +0 -0
  412. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-quickstart-9.3.11.v20160721.jar +0 -0
  413. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-rewrite-9.3.11.v20160721.jar +0 -0
  414. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-schemas-3.1.jar +0 -0
  415. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-security-9.3.11.v20160721.jar +0 -0
  416. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-server-9.3.11.v20160721.jar +0 -0
  417. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-servlet-9.3.11.v20160721.jar +0 -0
  418. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-servlets-9.3.11.v20160721.jar +0 -0
  419. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-util-9.3.11.v20160721.jar +0 -0
  420. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-webapp-9.3.11.v20160721.jar +0 -0
  421. data/lib/rubyfox/server/data/lib/jetty/lib/jetty-xml-9.3.11.v20160721.jar +0 -0
  422. data/lib/rubyfox/server/data/lib/jetty/lib/jndi/javax.mail.glassfish-1.4.1.v201005082020.jar +0 -0
  423. data/lib/rubyfox/server/data/lib/jetty/lib/jndi/javax.transaction-api-1.2.jar +0 -0
  424. data/lib/rubyfox/server/data/lib/jetty/lib/monitor/jetty-monitor-9.3.11.v20160721.jar +0 -0
  425. data/lib/rubyfox/server/data/lib/jetty/lib/org.apache.taglibs.taglibs-standard-impl-1.2.5.jar +0 -0
  426. data/lib/rubyfox/server/data/lib/jetty/lib/org.apache.taglibs.taglibs-standard-spec-1.2.5.jar +0 -0
  427. data/lib/rubyfox/server/data/lib/jetty/lib/org.eclipse.jdt.core.compiler.ecj-4.4.2.jar +0 -0
  428. data/lib/rubyfox/server/data/lib/jetty/lib/org.eclipse.jetty.apache-jsp-9.3.11.v20160721.jar +0 -0
  429. data/lib/rubyfox/server/data/lib/jetty/lib/org.mortbay.jasper.apache-el-8.0.33.jar +0 -0
  430. data/lib/rubyfox/server/data/lib/jetty/lib/org.mortbay.jasper.apache-jsp-8.0.33.jar +0 -0
  431. data/lib/rubyfox/server/data/lib/jetty/lib/servlet-api-3.1.jar +0 -0
  432. data/lib/rubyfox/server/data/lib/jetty/lib/setuid/jetty-setuid-java-1.0.3.jar +0 -0
  433. data/lib/rubyfox/server/data/lib/jetty/lib/setuid/libsetuid-linux.so +0 -0
  434. data/lib/rubyfox/server/data/lib/jetty/lib/setuid/libsetuid-osx.so +0 -0
  435. data/lib/rubyfox/server/data/lib/jetty/lib/spring/jetty-spring-9.3.11.v20160721.jar +0 -0
  436. data/lib/rubyfox/server/data/lib/jetty/lib/start.jar +0 -0
  437. data/lib/rubyfox/server/data/lib/jetty/lib/websocket-api-9.3.11.v20160721.jar +0 -0
  438. data/lib/rubyfox/server/data/lib/jetty/lib/websocket-client-9.3.11.v20160721.jar +0 -0
  439. data/lib/rubyfox/server/data/lib/jetty/lib/websocket-common-9.3.11.v20160721.jar +0 -0
  440. data/lib/rubyfox/server/data/lib/jetty/lib/websocket-server-9.3.11.v20160721.jar +0 -0
  441. data/lib/rubyfox/server/data/lib/jetty/lib/websocket-servlet-9.3.11.v20160721.jar +0 -0
  442. data/lib/rubyfox/server/data/lib/jetty/license-eplv10-aslv20.html +0 -576
  443. data/lib/rubyfox/server/data/lib/jetty/modules/.donotdelete +0 -0
  444. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0.mod +0 -8
  445. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_05.mod +0 -8
  446. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_101.mod +0 -8
  447. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_102.mod +0 -8
  448. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_11.mod +0 -8
  449. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_20.mod +0 -8
  450. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_25.mod +0 -8
  451. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_31.mod +0 -8
  452. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_40.mod +0 -8
  453. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_45.mod +0 -8
  454. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_51.mod +0 -8
  455. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_60.mod +0 -8
  456. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_65.mod +0 -8
  457. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_66.mod +0 -8
  458. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_71.mod +0 -8
  459. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_72.mod +0 -8
  460. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_73.mod +0 -8
  461. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_74.mod +0 -8
  462. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_77.mod +0 -8
  463. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_91.mod +0 -8
  464. data/lib/rubyfox/server/data/lib/jetty/modules/alpn-impl/alpn-1.8.0_92.mod +0 -8
  465. data/lib/rubyfox/server/data/lib/jetty/modules/alpn.mod +0 -53
  466. data/lib/rubyfox/server/data/lib/jetty/modules/annotations.mod +0 -17
  467. data/lib/rubyfox/server/data/lib/jetty/modules/apache-jsp.mod +0 -10
  468. data/lib/rubyfox/server/data/lib/jetty/modules/apache-jstl.mod +0 -9
  469. data/lib/rubyfox/server/data/lib/jetty/modules/cdi.mod +0 -39
  470. data/lib/rubyfox/server/data/lib/jetty/modules/client.mod +0 -6
  471. data/lib/rubyfox/server/data/lib/jetty/modules/continuation.mod +0 -6
  472. data/lib/rubyfox/server/data/lib/jetty/modules/debug.mod +0 -29
  473. data/lib/rubyfox/server/data/lib/jetty/modules/debuglog.mod +0 -25
  474. data/lib/rubyfox/server/data/lib/jetty/modules/deploy.mod +0 -31
  475. data/lib/rubyfox/server/data/lib/jetty/modules/ext.mod +0 -11
  476. data/lib/rubyfox/server/data/lib/jetty/modules/fcgi.mod +0 -15
  477. data/lib/rubyfox/server/data/lib/jetty/modules/gcloud-memcached-sessions.mod +0 -26
  478. data/lib/rubyfox/server/data/lib/jetty/modules/gcloud-session-idmgr.mod +0 -63
  479. data/lib/rubyfox/server/data/lib/jetty/modules/gcloud-sessions.mod +0 -11
  480. data/lib/rubyfox/server/data/lib/jetty/modules/gzip.mod +0 -23
  481. data/lib/rubyfox/server/data/lib/jetty/modules/hawtio.mod +0 -28
  482. data/lib/rubyfox/server/data/lib/jetty/modules/home-base-warning.mod +0 -7
  483. data/lib/rubyfox/server/data/lib/jetty/modules/http-forwarded.mod +0 -20
  484. data/lib/rubyfox/server/data/lib/jetty/modules/http.mod +0 -39
  485. data/lib/rubyfox/server/data/lib/jetty/modules/http2.mod +0 -20
  486. data/lib/rubyfox/server/data/lib/jetty/modules/http2c.mod +0 -22
  487. data/lib/rubyfox/server/data/lib/jetty/modules/https.mod +0 -14
  488. data/lib/rubyfox/server/data/lib/jetty/modules/infinispan.mod +0 -33
  489. data/lib/rubyfox/server/data/lib/jetty/modules/ipaccess.mod +0 -9
  490. data/lib/rubyfox/server/data/lib/jetty/modules/jaas.mod +0 -17
  491. data/lib/rubyfox/server/data/lib/jetty/modules/jamon.mod +0 -31
  492. data/lib/rubyfox/server/data/lib/jetty/modules/jaspi.mod +0 -10
  493. data/lib/rubyfox/server/data/lib/jetty/modules/jdbc-sessions.mod +0 -27
  494. data/lib/rubyfox/server/data/lib/jetty/modules/jminix.mod +0 -41
  495. data/lib/rubyfox/server/data/lib/jetty/modules/jmx-remote.mod +0 -16
  496. data/lib/rubyfox/server/data/lib/jetty/modules/jmx.mod +0 -13
  497. data/lib/rubyfox/server/data/lib/jetty/modules/jndi.mod +0 -11
  498. data/lib/rubyfox/server/data/lib/jetty/modules/jolokia.mod +0 -19
  499. data/lib/rubyfox/server/data/lib/jetty/modules/jsp.mod +0 -9
  500. data/lib/rubyfox/server/data/lib/jetty/modules/jstl.mod +0 -8
  501. data/lib/rubyfox/server/data/lib/jetty/modules/jvm.mod +0 -22
  502. data/lib/rubyfox/server/data/lib/jetty/modules/logging.mod +0 -36
  503. data/lib/rubyfox/server/data/lib/jetty/modules/lowresources.mod +0 -28
  504. data/lib/rubyfox/server/data/lib/jetty/modules/monitor.mod +0 -13
  505. data/lib/rubyfox/server/data/lib/jetty/modules/nosql.mod +0 -31
  506. data/lib/rubyfox/server/data/lib/jetty/modules/plus.mod +0 -15
  507. data/lib/rubyfox/server/data/lib/jetty/modules/proxy-protocol-ssl.mod +0 -9
  508. data/lib/rubyfox/server/data/lib/jetty/modules/proxy-protocol.mod +0 -9
  509. data/lib/rubyfox/server/data/lib/jetty/modules/proxy.mod +0 -22
  510. data/lib/rubyfox/server/data/lib/jetty/modules/quickstart.mod +0 -11
  511. data/lib/rubyfox/server/data/lib/jetty/modules/requestlog.mod +0 -40
  512. data/lib/rubyfox/server/data/lib/jetty/modules/resources.mod +0 -10
  513. data/lib/rubyfox/server/data/lib/jetty/modules/rewrite-compactpath.mod +0 -10
  514. data/lib/rubyfox/server/data/lib/jetty/modules/rewrite-customizer.mod +0 -24
  515. data/lib/rubyfox/server/data/lib/jetty/modules/rewrite.mod +0 -23
  516. data/lib/rubyfox/server/data/lib/jetty/modules/security.mod +0 -9
  517. data/lib/rubyfox/server/data/lib/jetty/modules/server.mod +0 -79
  518. data/lib/rubyfox/server/data/lib/jetty/modules/servlet.mod +0 -9
  519. data/lib/rubyfox/server/data/lib/jetty/modules/servlets.mod +0 -11
  520. data/lib/rubyfox/server/data/lib/jetty/modules/setuid.mod +0 -19
  521. data/lib/rubyfox/server/data/lib/jetty/modules/spring.mod +0 -17
  522. data/lib/rubyfox/server/data/lib/jetty/modules/ssl.mod +0 -97
  523. data/lib/rubyfox/server/data/lib/jetty/modules/stats.mod +0 -9
  524. data/lib/rubyfox/server/data/lib/jetty/modules/webapp.mod +0 -10
  525. data/lib/rubyfox/server/data/lib/jetty/modules/websocket.mod +0 -12
  526. data/lib/rubyfox/server/data/lib/jetty/notice.html +0 -111
  527. data/lib/rubyfox/server/data/lib/jetty/start.d/README.TXT +0 -24
  528. data/lib/rubyfox/server/data/lib/jetty/start.d/http.ini +0 -7
  529. data/lib/rubyfox/server/data/lib/jetty/start.d/https.ini +0 -10
  530. data/lib/rubyfox/server/data/lib/jetty/start.d/ssl.ini +0 -19
  531. data/lib/rubyfox/server/data/lib/jetty/start.ini +0 -83
  532. data/lib/rubyfox/server/data/www/.keep +0 -0
  533. data/lib/rubyfox/server/data/www/HelloServlet/META-INF/context.xml +0 -2
  534. data/lib/rubyfox/server/data/www/PyServletExample/MyModule$py.class +0 -0
  535. data/lib/rubyfox/server/data/www/PyServletExample/MyModule.py +0 -5
  536. data/lib/rubyfox/server/data/www/PyServletExample/WEB-INF/web.xml +0 -37
  537. data/lib/rubyfox/server/data/www/PyServletExample/errors/404.htm +0 -20
  538. data/lib/rubyfox/server/data/www/PyServletExample/index.py +0 -42
  539. data/lib/rubyfox/server/data/www/root/admin/.keep +0 -0
  540. data/lib/rubyfox/server/data/www/root/admin/AdminTool.swf +0 -0
  541. data/lib/rubyfox/server/data/www/root/admin/ReleaseNotes.txt +0 -192
  542. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/adobeFlashPlayer.png +0 -0
  543. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/advanced.png +0 -0
  544. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/analytics.png +0 -0
  545. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/banManager.png +0 -0
  546. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/bannedIPs.png +0 -0
  547. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/bannedUsernames.png +0 -0
  548. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/bookmarks.png +0 -0
  549. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/bootLog.png +0 -0
  550. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/buddyList.png +0 -0
  551. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/buddyProperties.png +0 -0
  552. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/connection.png +0 -0
  553. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/databaseManager.png +0 -0
  554. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/floodFilter.png +0 -0
  555. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/gameSettings.png +0 -0
  556. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/general.png +0 -0
  557. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/globalServerStatus.png +0 -0
  558. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/hTML5WebSockets.png +0 -0
  559. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/iPDiscovery.png +0 -0
  560. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/iPFilter.png +0 -0
  561. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/jVMSettings.png +0 -0
  562. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/logsDownload.png +0 -0
  563. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/mMOSettings.png +0 -0
  564. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/mailer.png +0 -0
  565. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/permissionsAndEvents.png +0 -0
  566. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/privilegeManager.png +0 -0
  567. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/remoteAdmin.png +0 -0
  568. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/roomExtension.png +0 -0
  569. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/roomVariables.png +0 -0
  570. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/roomsAndGroups.png +0 -0
  571. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/runtimeLog.png +0 -0
  572. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/runtimeRoomSettings.png +0 -0
  573. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/runtimeUserSettings.png +0 -0
  574. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/runtimeZoneSettings.png +0 -0
  575. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/statsApplication.png +0 -0
  576. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/statsDemographics.png +0 -0
  577. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/statsExceptions.png +0 -0
  578. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/statsOverview.png +0 -0
  579. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/statsTechnology.png +0 -0
  580. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/systemQueueStatus.png +0 -0
  581. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/threadPools.png +0 -0
  582. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/userManagement.png +0 -0
  583. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/userVariables.png +0 -0
  584. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/webServer.png +0 -0
  585. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/wordsFilter.png +0 -0
  586. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/zoneExtension.png +0 -0
  587. data/lib/rubyfox/server/data/www/root/admin/assets/icons/tabs/zoneTraffic.png +0 -0
  588. data/lib/rubyfox/server/data/www/root/admin/expressInstall.swf +0 -0
  589. data/lib/rubyfox/server/data/www/root/admin/index.html +0 -124
  590. data/lib/rubyfox/server/data/www/root/admin/modules/Analytics.swf +0 -0
  591. data/lib/rubyfox/server/data/www/root/admin/modules/BanManager.swf +0 -0
  592. data/lib/rubyfox/server/data/www/root/admin/modules/BlueBoxMonitor.swf +0 -0
  593. data/lib/rubyfox/server/data/www/root/admin/modules/Console.swf +0 -0
  594. data/lib/rubyfox/server/data/www/root/admin/modules/Dashboard.swf +0 -0
  595. data/lib/rubyfox/server/data/www/root/admin/modules/ExtensionManager.swf +0 -0
  596. data/lib/rubyfox/server/data/www/root/admin/modules/LicenseManager.swf +0 -0
  597. data/lib/rubyfox/server/data/www/root/admin/modules/LogViewer.swf +0 -0
  598. data/lib/rubyfox/server/data/www/root/admin/modules/ServerConfigurator.swf +0 -0
  599. data/lib/rubyfox/server/data/www/root/admin/modules/ZoneConfigurator.swf +0 -0
  600. data/lib/rubyfox/server/data/www/root/admin/modules/ZoneMonitor.swf +0 -0
  601. data/lib/rubyfox/server/data/www/root/admin/swfobject.js +0 -4
  602. data/lib/rubyfox/server/data/www/root/examples/.keep +0 -0
  603. data/lib/rubyfox/server/data/www/sfs2x-ws.war +0 -0
  604. data/lib/rubyfox/server/data/www/sfs2x-ws.xml +0 -30
  605. data/lib/rubyfox/server/data/zones/BasicExamples.zone.xml +0 -147
@@ -0,0 +1,71 @@
1
+ /*! (c) gotoAndPlay | All rights reserved */
2
+ (window["webpackJsonpapplication"] = window["webpackJsonpapplication"] || []).push([["module-11"],{
3
+
4
+ /***/ "./src/modules/template.js":
5
+ /*!*********************************!*\
6
+ !*** ./src/modules/template.js ***!
7
+ \*********************************/
8
+ /*! exports provided: default */
9
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
10
+
11
+ "use strict";
12
+ __webpack_require__.r(__webpack_exports__);
13
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Template; });
14
+ /* harmony import */ var _base_module__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base-module */ "./src/modules/base-module.js");
15
+
16
+
17
+ class Template extends _base_module__WEBPACK_IMPORTED_MODULE_0__["BaseModule"]
18
+ {
19
+ constructor()
20
+ {
21
+ super('template');
22
+ }
23
+
24
+ //------------------------------------
25
+ // COMMON MODULE INTERFACE METHODS
26
+ // This members are used by the main controller
27
+ // to communicate with the module's controller.
28
+ //------------------------------------
29
+
30
+ initialize(idData, shellController)
31
+ {
32
+ // Call super method
33
+ super.initialize(idData, shellController);
34
+
35
+ }
36
+
37
+ destroy()
38
+ {
39
+ // Call super method
40
+ super.destroy();
41
+ }
42
+
43
+ onExtensionCommand(command, data)
44
+ {
45
+
46
+ }
47
+
48
+ //---------------------------------
49
+ // UI EVENT LISTENERS
50
+ //---------------------------------
51
+
52
+
53
+
54
+ //------------------------------------
55
+ // PRIVATE METHODS
56
+ //------------------------------------
57
+
58
+
59
+
60
+ //---------------------------------
61
+ // PRIVATE GETTERS
62
+ //---------------------------------
63
+
64
+
65
+ }
66
+
67
+
68
+ /***/ })
69
+
70
+ }]);
71
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXRzL2pzL2NvcmUvbW9kdWxlcy9tb2R1bGUtMTEuYnVuZGxlLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYXBwbGljYXRpb24vLi9zcmMvbW9kdWxlcy90ZW1wbGF0ZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0Jhc2VNb2R1bGV9IGZyb20gJy4vYmFzZS1tb2R1bGUnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUZW1wbGF0ZSBleHRlbmRzIEJhc2VNb2R1bGVcbntcblx0Y29uc3RydWN0b3IoKVxuXHR7XG5cdCAgICBzdXBlcigndGVtcGxhdGUnKTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vIENPTU1PTiBNT0RVTEUgSU5URVJGQUNFIE1FVEhPRFNcblx0Ly8gVGhpcyBtZW1iZXJzIGFyZSB1c2VkIGJ5IHRoZSBtYWluIGNvbnRyb2xsZXJcblx0Ly8gdG8gY29tbXVuaWNhdGUgd2l0aCB0aGUgbW9kdWxlJ3MgY29udHJvbGxlci5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRpbml0aWFsaXplKGlkRGF0YSwgc2hlbGxDb250cm9sbGVyKVxuXHR7XG5cdFx0Ly8gQ2FsbCBzdXBlciBtZXRob2Rcblx0XHRzdXBlci5pbml0aWFsaXplKGlkRGF0YSwgc2hlbGxDb250cm9sbGVyKTtcblxuXHR9XG5cblx0ZGVzdHJveSgpXG5cdHtcblx0XHQvLyBDYWxsIHN1cGVyIG1ldGhvZFxuXHRcdHN1cGVyLmRlc3Ryb3koKTtcblx0fVxuXG5cdG9uRXh0ZW5zaW9uQ29tbWFuZChjb21tYW5kLCBkYXRhKVxuXHR7XG5cblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vIFVJIEVWRU5UIExJU1RFTkVSU1xuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLyBQUklWQVRFIE1FVEhPRFNcblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8gUFJJVkFURSBHRVRURVJTXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QSIsInNvdXJjZVJvb3QiOiIifQ==
@@ -0,0 +1,1184 @@
1
+ /*! (c) gotoAndPlay | All rights reserved */
2
+ (window["webpackJsonpapplication"] = window["webpackJsonpapplication"] || []).push([["module-12"],{
3
+
4
+ /***/ "./src/components/sidebar-layout.js":
5
+ /*!******************************************!*\
6
+ !*** ./src/components/sidebar-layout.js ***!
7
+ \******************************************/
8
+ /*! exports provided: SidebarLayout */
9
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
10
+
11
+ "use strict";
12
+ __webpack_require__.r(__webpack_exports__);
13
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SidebarLayout", function() { return SidebarLayout; });
14
+ class SidebarLayout extends HTMLElement
15
+ {
16
+ constructor()
17
+ {
18
+ super();
19
+
20
+ // Attach a shadow root
21
+ const shadowRoot = this.attachShadow({mode: 'open'});
22
+ shadowRoot.innerHTML = `
23
+ <style>
24
+ :host {
25
+ display: flex;
26
+ flex-direction: row;
27
+ }
28
+
29
+ @media (max-width: 575.98px) {
30
+ :host(.split-xs) ::slotted(:not([aria-selected="true"])) {
31
+ display: none !important;
32
+ }
33
+
34
+ :host(.split-xs) ::slotted([aria-selected="true"]) {
35
+ flex-grow: 1;
36
+ }
37
+ }
38
+
39
+ @media (max-width: 767.98px) {
40
+ :host(.split-sm) ::slotted(:not([aria-selected="true"])) {
41
+ display: none !important;
42
+ }
43
+
44
+ :host(.split-sm) ::slotted([aria-selected="true"]) {
45
+ flex-grow: 1;
46
+ }
47
+ }
48
+
49
+ @media (max-width: 991.98px) {
50
+ :host(.split-md) ::slotted(:not([aria-selected="true"])) {
51
+ display: none !important;
52
+ }
53
+
54
+ :host(.split-md) ::slotted([aria-selected="true"]) {
55
+ flex-grow: 1;
56
+ }
57
+ }
58
+
59
+ @media (max-width: 1199.98px) {
60
+ :host(.split-lg) ::slotted(:not([aria-selected="true"])) {
61
+ display: none !important;
62
+ }
63
+
64
+ :host(.split-lg) ::slotted([aria-selected="true"]) {
65
+ flex-grow: 1;
66
+ }
67
+ }
68
+
69
+ .side-col::slotted(*) {
70
+ }
71
+
72
+ .main-col::slotted(*) {
73
+ flex-grow: 1;
74
+ }
75
+ </style>
76
+
77
+ <slot class="side-col" name="side-column"></slot>
78
+ <slot class="main-col" name="main-column"></slot>
79
+ `;
80
+
81
+ // Set initial selection
82
+ this.selectedIndex = 0;
83
+ }
84
+
85
+ get selectedPanel()
86
+ {
87
+ return this._selectedPanel;
88
+ }
89
+
90
+ set selectedPanel(element) // 'side' or 'main'
91
+ {
92
+ if (element != null && element.parentNode == this)
93
+ {
94
+ this._selectedPanel = element;
95
+
96
+ for (let element of this.children)
97
+ {
98
+ if (element == this._selectedPanel)
99
+ element.setAttribute('aria-selected', 'true');
100
+ else
101
+ element.removeAttribute('aria-selected');
102
+ }
103
+ }
104
+ else
105
+ {
106
+ console.error('Element is not a child of SidebarLayout');
107
+ }
108
+ }
109
+
110
+ get selectedIndex()
111
+ {
112
+ return Array.from(this.children).indexOf(this._selectedPanel);
113
+ }
114
+
115
+ set selectedIndex(index)
116
+ {
117
+ if (this.children.length > 0)
118
+ {
119
+ if (this.children[index] == null)
120
+ {
121
+ console.error('Invalid SidebarLayout index');
122
+ return;
123
+ }
124
+
125
+ let element = this.children[index];
126
+ this.selectedPanel = element;
127
+ }
128
+ }
129
+ }
130
+
131
+ // DEFINE COMPONENT
132
+ if (!window.customElements.get('sidebar-layout'))
133
+ window.customElements.define('sidebar-layout', SidebarLayout);
134
+
135
+
136
+ /***/ }),
137
+
138
+ /***/ "./src/modules/zone-configurator.js":
139
+ /*!******************************************!*\
140
+ !*** ./src/modules/zone-configurator.js ***!
141
+ \******************************************/
142
+ /*! exports provided: default */
143
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
144
+
145
+ "use strict";
146
+ __webpack_require__.r(__webpack_exports__);
147
+ /* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return ZoneConfigurator; });
148
+ /* harmony import */ var _base_module__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base-module */ "./src/modules/base-module.js");
149
+ /* harmony import */ var _components_view_stack__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components/view-stack */ "./src/components/view-stack.js");
150
+ /* harmony import */ var _components_sidebar_layout__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../components/sidebar-layout */ "./src/components/sidebar-layout.js");
151
+ /* harmony import */ var _utils_uibuilder_config_interface_builder__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/uibuilder/config-interface-builder */ "./src/utils/uibuilder/config-interface-builder.js");
152
+ /* harmony import */ var _utils_utilities__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/utilities */ "./src/utils/utilities.js");
153
+
154
+
155
+
156
+
157
+
158
+
159
+ class ZoneConfigurator extends _base_module__WEBPACK_IMPORTED_MODULE_0__["BaseModule"]
160
+ {
161
+ constructor()
162
+ {
163
+ super('zoneConfig');
164
+
165
+ this.ITEM_TYPE_ZONE = 'zone';
166
+ this.ITEM_TYPE_ROOM = 'room';
167
+
168
+ // Outgoing requests
169
+ this.REQ_GET_ZONES = 'getZones';
170
+
171
+ this.REQ_GET_ZONE_CONFIG = 'getZoneConfig';
172
+ this.REQ_SAVE_ZONE_CONFIG = 'saveZoneConfig';
173
+ this.REQ_NEW_ZONE_CONFIG = 'newZoneConfig';
174
+ this.REQ_DELETE_ZONE_CONFIG = 'delZoneConfig';
175
+ this.REQ_ACTIVATE_ZONE = 'actZone';
176
+
177
+ this.REQ_GET_ROOM_CONFIG = 'getRoomConfig';
178
+ this.REQ_SAVE_ROOM_CONFIG = 'saveRoomConfig';
179
+ this.REQ_NEW_ROOM_CONFIG = 'newRoomConfig';
180
+ this.REQ_DELETE_ROOM_CONFIG = 'delRoomConfig';
181
+
182
+ // Incoming responses
183
+ this.RESP_ZONES = 'zones';
184
+
185
+ this.RESP_ZONE_CONFIG = 'zoneConfig';
186
+ this.RESP_ZONE_CONFIG_UPDATE_CONFIRM = 'zoneCfgUpd';
187
+ this.RESP_ZONE_ADDED = 'zoneAdded';
188
+ this.RESP_ZONE_REFUSED = 'zoneRefused';
189
+ this.RESP_ZONE_DELETED = 'zoneDel';
190
+ this.RESP_ZONE_ACTIVATED = 'zoneAct';
191
+ this.RESP_ZONE_ACTIVATION_ERROR = 'zoneActErr';
192
+
193
+ this.RESP_ROOM_CONFIG = 'roomConfig';
194
+ this.RESP_ROOM_CONFIG_UPDATE_CONFIRM = 'roomCfgUpd';
195
+ this.RESP_ROOM_ADDED = 'roomAdded';
196
+ this.RESP_ROOM_REFUSED = 'roomRefused';
197
+ this.RESP_ROOM_DELETED = 'roomDel';
198
+ }
199
+
200
+ //------------------------------------
201
+ // COMMON MODULE INTERFACE METHODS
202
+ // This members are used by the main controller
203
+ // to communicate with the module's controller.
204
+ // This methods override those in BaseModule class.
205
+ //------------------------------------
206
+
207
+ initialize(idData, shellController)
208
+ {
209
+ // Call super method
210
+ super.initialize(idData, shellController);
211
+
212
+ // Create interface builder instance
213
+ this._interfaceBuilder = new _utils_uibuilder_config_interface_builder__WEBPACK_IMPORTED_MODULE_3__["ConfigInterfaceBuilder"]();
214
+
215
+ // Set listener for custom actions triggered by configuration interface
216
+ $('#znc-tabNavigator').on('value-set', $.proxy(this._onConfigValueSet, this));
217
+
218
+ // Initialize Zones/Rooms treeview
219
+ this._treeview = $('#znc-treeView').kendoTreeView({
220
+ loadOnDemand: false,
221
+ dataTextField: 'name',
222
+ template: kendo.template('<span class="# if (!item.active) { # inactive-list-item # } #">#: item.name #</span>'),
223
+ change: $.proxy(this._onZoneRoomChange, this),
224
+ }).data('kendoTreeView');
225
+
226
+ // Lestend to treeview double-click event
227
+ $('#znc-treeView').on('dblclick', $.proxy(this._onTreeItemDoubleClick, this));
228
+
229
+ // Request zones & rooms list to server instance
230
+ this.sendExtensionRequest(this.REQ_GET_ZONES);
231
+
232
+ // Initialize progress bar
233
+ $('#znc-progressBar').kendoProgressBar({
234
+ min: 0,
235
+ max: 100,
236
+ value: false,
237
+ type: 'value',
238
+ animation: {
239
+ duration: 400
240
+ }
241
+ });
242
+
243
+ // Add listeners to utility buttons
244
+ $('#znc-addZoneButton').on('click', $.proxy(this._onAddZoneClick, this));
245
+ $('#znc-addRoomButton').on('click', $.proxy(this._onAddRoomClick, this));
246
+ $('#znc-editButton').on('click', $.proxy(this._onEditClick, this));
247
+ $('#znc-removeButton').on('click', $.proxy(this._onRemoveClick, this));
248
+ $('#znc-activateButton').on('click', $.proxy(this._onActivateClick, this));
249
+
250
+ // Add listener to interface buttons
251
+ $('#znc-cancelButton').on('click', $.proxy(this._onCancelClick, this));
252
+ $('#znc-reloadButton').on('click', $.proxy(this._onReloadClick, this));
253
+ $('#znc-submitButton').on('click', $.proxy(this._onSubmitClick, this));
254
+ }
255
+
256
+ destroy()
257
+ {
258
+ // Call super method
259
+ super.destroy();
260
+
261
+ // Remove tree view doubleclick listener
262
+ $('#znc-treeView').off('dblclick');
263
+
264
+ // Remove listener for custom actions triggered by configuration interface
265
+ $('#znc-tabNavigator').off('value-set');
266
+
267
+ // Remove listener for zone/room activation event
268
+ $('#znc-addZoneButton').off('click');
269
+ $('#znc-addRoomButton').off('click');
270
+ $('#znc-editButton').off('click');
271
+ $('#znc-removeButton').off('click');
272
+ $('#znc-activateButton').off('click');
273
+
274
+ // Remove interface buttons click listeners
275
+ $('#znc-cancelButton').off('click');
276
+ $('#znc-reloadButton').off('click');
277
+ $('#znc-submitButton').off('click');
278
+
279
+ // Clear tabs container
280
+ this._clearTabs();
281
+ }
282
+
283
+ onExtensionCommand(command, data)
284
+ {
285
+ const username = data.getUtfString('user');
286
+
287
+ /****** ZONES & ROOMS ******/
288
+
289
+ // Zones & rooms list received
290
+ if (command == this.RESP_ZONES)
291
+ this._populateTree(data);
292
+
293
+ // Zone or room configuration data received
294
+ else if (command == this.RESP_ZONE_CONFIG || command == this.RESP_ROOM_CONFIG)
295
+ {
296
+ // Build user interface based on received data
297
+ this._interfaceBuilder.buildInterface(data.getSFSArray('settings'), 'znc-tabNavigator', false);
298
+
299
+ // Enable scrolling tabs (if needed)
300
+ if (this._reinitTabs)
301
+ {
302
+ $('#znc-tabNavigator #tabs').scrollingTabs({
303
+ bootstrapVersion: 4,
304
+ scrollToTabEdge: true,
305
+ enableSwiping: true,
306
+ disableScrollArrowsOnFullyScrolled: true,
307
+ cssClassLeftArrow: 'fa fa-chevron-left',
308
+ cssClassRightArrow: 'fa fa-chevron-right'
309
+ });
310
+ }
311
+
312
+ // Enable interface
313
+ this._enableConfigInterface(true);
314
+ }
315
+
316
+ /****** ZONES ******/
317
+
318
+ // Zone configuration update confirmation
319
+ else if (command == this.RESP_ZONE_CONFIG_UPDATE_CONFIRM)
320
+ {
321
+ // If a 'name' parameter is received, it means the zone name changed, and we have to update the zones list
322
+ if (data.getUtfString('zName') != null)
323
+ this._updateZoneNameInList(data.getInt('zId'), data.getUtfString('zName'));
324
+
325
+ // If the current user is the updater, show a notification; otherwise, show a dialog box suggesting to reload
326
+ if (username == this.smartFox.mySelf.name)
327
+ {
328
+ // Enable interface
329
+ this._enableConfigInterface(true);
330
+
331
+ // Display notification
332
+ this.shellCtrl.showNotification('Zone modified', `Zone settings updated successfully; changes will be applied on next <strong>server restart</strong>`);
333
+
334
+ // Reset the 'modified' flag
335
+ this._interfaceBuilder.resetIsModified();
336
+ }
337
+ else
338
+ {
339
+ // An alert box is displayed if the user is currently editing the same zone
340
+ if (data.getInt('zId') == this._editedZoneId)
341
+ {
342
+ // Show alert
343
+ this.shellCtrl.showSimpleAlert(`Administrator ${username} has modified the Zone you are currently editing; please reload to update your view.`);
344
+
345
+ // Disable submit button
346
+ $('#znc-submitButton').attr('disabled', true);
347
+ }
348
+ else
349
+ {
350
+ // Display notification
351
+ if (data.getUtfString('zName') != null)
352
+ this.shellCtrl.showNotification('Zone renamed', `Administrator ${username} has changed the name on one of the Zones`);
353
+ }
354
+ }
355
+ }
356
+
357
+ // New zone added
358
+ else if (command == this.RESP_ZONE_ADDED)
359
+ {
360
+ const zoneName = data.getSFSObject('zone').getUtfString('name');
361
+
362
+ // If the current user is the updater, reset the interface; otherwise, just show a notification
363
+ if (username == this.smartFox.mySelf.name)
364
+ {
365
+ // Reset interface
366
+ this._onCancelClick();
367
+
368
+ // Display notification
369
+ this.shellCtrl.showNotification('Zone added', `Zone '${zoneName}' created successfully`);
370
+ }
371
+ else
372
+ {
373
+ // Display notification
374
+ this.shellCtrl.showNotification('Zone added', `Administrator ${username} created Zone '${zoneName}'`);
375
+ }
376
+
377
+ // Add new zone to tree
378
+ let zonesDS = this._treeview.dataSource;
379
+ zonesDS.add(this._createZoneObject(data.getSFSObject('zone')));
380
+ zonesDS.sync();
381
+ }
382
+
383
+ // New zone creation refused due to invalid zone name
384
+ else if (command == this.RESP_ZONE_REFUSED)
385
+ {
386
+ // Re-enable interface
387
+ this._enableConfigInterface(true);
388
+
389
+ // Show warning
390
+ this.shellCtrl.showSimpleAlert('Zone configuration can\'t be saved because another Zone with the same name already exists.', true);
391
+ }
392
+
393
+ // Existing zone deleted
394
+ else if (command == this.RESP_ZONE_DELETED)
395
+ {
396
+ // If the current user is the deleter, reset the interface; otherwise, just show a notification
397
+ if (username == this.smartFox.mySelf.name)
398
+ {
399
+ // Re-enable interface
400
+ this._enableListInterface(true);
401
+
402
+ // Display notification
403
+ this.shellCtrl.showNotification('Zone removed', `Zone '${data.getUtfString('zName')}' deleted successfully`);
404
+ }
405
+ else
406
+ {
407
+ // An alert box is displayed if the user is currently editing the same zone
408
+ if (data.getInt('zId') == this._editedZoneId)
409
+ {
410
+ // Show alert
411
+ this.shellCtrl.showSimpleAlert(`Administrator ${username} has deleted the Zone you are currently modifying; you have to cancel your editing.`);
412
+
413
+ // Disable submit and reload buttons
414
+ $('#znc-reloadButton').attr('disabled', true);
415
+ $('#znc-submitButton').attr('disabled', true);
416
+ }
417
+ else
418
+ {
419
+ // Display notification
420
+ this.shellCtrl.showNotification('Zone removed', `Administrator ${username} deleted Zone '${data.getUtfString('zName')}'`);
421
+ }
422
+ }
423
+
424
+ // Reset selection if the currently selected item or its parent is being removed
425
+ let selectedNode = this._treeview.select();
426
+ let selectedDataItem = this._treeview.dataItem(selectedNode);
427
+ if (selectedDataItem)
428
+ {
429
+ if (selectedDataItem.type == this.ITEM_TYPE_ZONE && selectedDataItem.id == data.getInt('zId'))
430
+ this._deselectTreeItem();
431
+
432
+ if (selectedDataItem.type == this.ITEM_TYPE_ROOM)
433
+ {
434
+ let parentDataItem = this._treeview.dataItem(this._treeview.parent(selectedNode));
435
+
436
+ if (parentDataItem.id == data.getInt('zId'))
437
+ this._deselectTreeItem();
438
+ }
439
+ }
440
+
441
+ // Remove zone from tree
442
+ let dataItem = this._getZoneDataItemById(data.getInt('zId'));
443
+ let zonesDS = this._treeview.dataSource;
444
+ zonesDS.remove(dataItem);
445
+ zonesDS.sync();
446
+ }
447
+
448
+ // Zone activated
449
+ else if (command == this.RESP_ZONE_ACTIVATED)
450
+ {
451
+ // Set zone activation status
452
+ const zoneName = this._setZoneActivationStatus(data.getInt('zId'), data.getUtfString('actRooms'), true);
453
+
454
+ // Display notification
455
+ if (username == this.smartFox.mySelf.name)
456
+ this.shellCtrl.showNotification('Zone activated', `Zone '${zoneName}' activated successfully`);
457
+ else
458
+ this.shellCtrl.showNotification('Zone activated', `Administrator ${username} activated Zone '${zoneName}'`);
459
+ }
460
+
461
+ // Zone activation error
462
+ else if (command == this.RESP_ZONE_ACTIVATION_ERROR)
463
+ {
464
+ // Set zone activation status
465
+ this._setZoneActivationStatus(data.getInt('zId'), '', false);
466
+
467
+ // Show alert
468
+ this.shellCtrl.showSimpleAlert(data.getUtfString('error'), true);
469
+ }
470
+
471
+ /****** ROOMS ******/
472
+
473
+ // Room configuration update confirmation
474
+ else if (command == this.RESP_ROOM_CONFIG_UPDATE_CONFIRM)
475
+ {
476
+ if (data.getUtfString('rName') != null)
477
+ this._updateRoomNameInList(data.getInt('zId'), data.getInt('rId'), data.getUtfString('rName'));
478
+
479
+ // If the current user is the updater, show a notification; otherwise, show a dialog box suggesting to reload
480
+ if (username == this.smartFox.mySelf.name)
481
+ {
482
+ // Enable interface
483
+ this._enableConfigInterface(true);
484
+
485
+ // Display notification
486
+ this.shellCtrl.showNotification('Room modified', `Room settings updated successfully; changes will be applied on next <strong>server restart</strong>`);
487
+
488
+ // Reset the 'modified' flag
489
+ this._interfaceBuilder.resetIsModified();
490
+ }
491
+ else
492
+ {
493
+ // An alert box is displayed if the user is currently editing the same room
494
+ if (data.getInt('rId') == this._editedRoomId)
495
+ {
496
+ // Show alert
497
+ this.shellCtrl.showSimpleAlert(`Administrator ${username} has modified the Room you are currently editing; please reload to update your view.`);
498
+
499
+ // Disable submit button
500
+ $('#znc-submitButton').attr('disabled', true);
501
+ }
502
+ else
503
+ {
504
+ // Display notification
505
+ if (data.getUtfString('rName') != null)
506
+ this.shellCtrl.showNotification('Room renamed', `Administrator ${username} has changed the name on one of the Rooms`);
507
+ }
508
+ }
509
+ }
510
+
511
+ // New room added
512
+ else if (command == this.RESP_ROOM_ADDED)
513
+ {
514
+ const roomData = data.getSFSObject('room');
515
+ const zoneId = data.getInt('zId');
516
+
517
+ let zonesDS = this._treeview.dataSource;
518
+ let zoneItem = zonesDS.get(zoneId);
519
+
520
+ // If the current user is the updater, reset the interface; otherwise, just show a notification
521
+ if (username == this.smartFox.mySelf.name)
522
+ {
523
+ // Reset interface
524
+ this._onCancelClick();
525
+
526
+ // Display notification
527
+ this.shellCtrl.showNotification('Room added', `Room '${roomData.getUtfString('name')}' created successfully`);
528
+ }
529
+ else
530
+ {
531
+ // Display notification
532
+ this.shellCtrl.showNotification('Room added', `Administrator ${username} created Room '${roomData.getUtfString('name')}' in Zone '${zoneItem.name}'`);
533
+ }
534
+
535
+ // Add new room to tree
536
+ zoneItem.append(this._createRoomObject(roomData, zoneId));
537
+ zonesDS.sync();
538
+
539
+ // Expand zone node where room was added
540
+ this._treeview.expand(this._treeview.select());
541
+ }
542
+
543
+ // New room creation refused due to invalid room name
544
+ else if (command == this.RESP_ROOM_REFUSED)
545
+ {
546
+ // Re-enable interface
547
+ this._enableConfigInterface(true);
548
+
549
+ // Show warning
550
+ this.shellCtrl.showSimpleAlert('Room configuration can\'t be saved because another Room with the same name already exists.', true);
551
+ }
552
+
553
+ // Existing room deleted
554
+ else if (command == this.RESP_ROOM_DELETED)
555
+ {
556
+ let zoneItem = this._getZoneDataItemById(data.getInt('zId'));
557
+ let roomItem = this._getRoomDataItemById(data.getInt('zId'), data.getInt('rId'));
558
+
559
+ // If the current user is the deleter, reset the interface; otherwise, just show a notification
560
+ if (username == this.smartFox.mySelf.name)
561
+ {
562
+ // Re-enable interface
563
+ this._enableListInterface(true);
564
+
565
+ // Display notification
566
+ this.shellCtrl.showNotification('Room removed', `Room '${roomItem.name}' deleted successfully`);
567
+ }
568
+ else
569
+ {
570
+ // An alert box is displayed if the user is currently editing the same room
571
+ if (data.getInt('rId') == this._editedRoomId)
572
+ {
573
+ // Show alert
574
+ this.shellCtrl.showSimpleAlert(`Administrator ${username} has deleted the Room you are currently modifying; you have to cancel your editing.`);
575
+
576
+ // Disable submit and reload buttons
577
+ $('#znc-reloadButton').attr('disabled', true);
578
+ $('#znc-submitButton').attr('disabled', true);
579
+ }
580
+ else
581
+ {
582
+ // Display notification
583
+ this.shellCtrl.showNotification('Room removed', `Administrator ${username} deleted Room '${roomItem.name}' from Zone '${zoneItem.name}'`);
584
+ }
585
+ }
586
+
587
+ // Reset selection if the currently selected item or its parent is being removed
588
+ let selectedNode = this._treeview.select();
589
+ let selectedDataItem = this._treeview.dataItem(selectedNode);
590
+ if (selectedDataItem)
591
+ {
592
+ if (selectedDataItem.type == this.ITEM_TYPE_ROOM && selectedDataItem.id == data.getInt('rId'))
593
+ this._deselectTreeItem();
594
+ }
595
+
596
+ // Remove room from tree
597
+ zoneItem.children.remove(roomItem);
598
+ this._treeview.dataSource.sync();
599
+ }
600
+
601
+ // else if ()
602
+ }
603
+
604
+ //---------------------------------
605
+ // UI EVENT LISTENERS
606
+ //---------------------------------
607
+
608
+ _onTreeItemDoubleClick(e)
609
+ {
610
+ // Get event target's closest tree node
611
+ let treeNode = $(e.target).closest('.k-item[role=treeitem]');
612
+
613
+ // Get associated data item
614
+ let dataItem = this._treeview.dataItem(treeNode);
615
+
616
+ // Load configuration
617
+ this._loadConfiguration(dataItem.type);
618
+ }
619
+
620
+ _onZoneRoomChange()
621
+ {
622
+ // Reset utility buttons
623
+ this._setUtilityButtonsState(this._selectedItem);
624
+ }
625
+
626
+ // Utility buttons listeners
627
+
628
+ _onAddZoneClick()
629
+ {
630
+ // Deselect list item
631
+ this._deselectTreeItem();
632
+
633
+ // Load configuration
634
+ this._loadConfiguration(this.ITEM_TYPE_ZONE);
635
+ }
636
+
637
+ _onAddRoomClick()
638
+ {
639
+ // Select parent list item
640
+ this._selectParentTreeItem();
641
+
642
+ // Load configuration
643
+ this._loadConfiguration(this.ITEM_TYPE_ROOM);
644
+ }
645
+
646
+ _onEditClick()
647
+ {
648
+ // Load configuration
649
+ this._loadConfiguration(this._selectedItem.type);
650
+ }
651
+
652
+ _onRemoveClick()
653
+ {
654
+ this.shellCtrl.showConfirmWarning(`Are you sure you want to delete the selected ${this._selectedItem.type == this.ITEM_TYPE_ZONE ? 'Zone' : 'Room'} configuration?`, $.proxy(this._onRemoveConfirm, this));
655
+ }
656
+
657
+ _onRemoveConfirm()
658
+ {
659
+ // Disable zone/room selection list
660
+ this._enableListInterface(false);
661
+
662
+ let params = new SFS2X.SFSObject();
663
+
664
+ // Request zone removal
665
+ if (this._selectedItem.type == this.ITEM_TYPE_ZONE)
666
+ {
667
+ params.putInt('zId', this._selectedItem.id);
668
+ this.sendExtensionRequest(this.REQ_DELETE_ZONE_CONFIG, params);
669
+ }
670
+ else
671
+ {
672
+ params.putInt('zId', this._selectedItemParent.id);
673
+ params.putInt('rId', this._selectedItem.id);
674
+ this.sendExtensionRequest(this.REQ_DELETE_ROOM_CONFIG, params);
675
+ }
676
+ }
677
+
678
+ _onActivateClick()
679
+ {
680
+ // Get selected data item
681
+ if (this._selectedItem.type == this.ITEM_TYPE_ZONE)
682
+ {
683
+ let params = new SFS2X.SFSObject();
684
+ params.putInt('zId', this._selectedItem.id);
685
+
686
+ this.sendExtensionRequest(this.REQ_ACTIVATE_ZONE, params);
687
+ }
688
+ }
689
+
690
+ // Configuration buttons listeners
691
+
692
+ _onCancelClick()
693
+ {
694
+ // Enable zone/room selection lists
695
+ this._enableListInterface(true);
696
+
697
+ // Disable configuration interface
698
+ this._enableConfigInterface(false);
699
+
700
+ // Clear main container
701
+ this._resetTabsContainer(false, true);
702
+
703
+ // Set isEditing flag
704
+ this._isEditing = false;
705
+ this._editedItemType = '';
706
+
707
+ // Switch panel
708
+ this._switchPanel('znc-sidebarPanel');
709
+ }
710
+
711
+ _onReloadClick()
712
+ {
713
+ // Hide validation messages
714
+ this._interfaceBuilder.resetValidation();
715
+
716
+ // Reload configuration
717
+ this._loadConfiguration(this._editedItemType, false);
718
+ }
719
+
720
+ _onSubmitClick()
721
+ {
722
+ // Check validity
723
+ if (this._interfaceBuilder.checkIsValid())
724
+ {
725
+ let changes = this._interfaceBuilder.getChangedData();
726
+
727
+ if (changes.size() > 0)
728
+ {
729
+ //console.log(changes.getDump())
730
+
731
+ // In case the zone/room name changed, check it against the list (duplicate names not allowed!)
732
+ if (this._validateName(changes))
733
+ {
734
+ // Disable configuration interface
735
+ this._enableConfigInterface(false);
736
+
737
+ // Send settings to server instance
738
+ let params = new SFS2X.SFSObject();
739
+ params.putSFSArray('settings', changes);
740
+ params.putBool('backup', $('#znc-backupCheck').prop('checked'));
741
+ params.putInt('zId', this._editedZoneId);
742
+ params.putInt('rId', this._editedRoomId);
743
+
744
+ if (this._editedItemType == this.ITEM_TYPE_ZONE)
745
+ {
746
+ // Submit zone settings
747
+ if (this._editedZoneId > -1)
748
+ this.sendExtensionRequest(this.REQ_SAVE_ZONE_CONFIG, params);
749
+ else
750
+ this.sendExtensionRequest(this.REQ_NEW_ZONE_CONFIG, params);
751
+ }
752
+ else
753
+ {
754
+ // Submit room settings
755
+ if (this._editedRoomId > -1)
756
+ this.sendExtensionRequest(this.REQ_SAVE_ROOM_CONFIG, params);
757
+ else
758
+ this.sendExtensionRequest(this.REQ_NEW_ROOM_CONFIG, params);
759
+ }
760
+ }
761
+ else
762
+ {
763
+ // Show alert
764
+ this.shellCtrl.showSimpleAlert(`Unable to submit configuration because the ${Object(_utils_utilities__WEBPACK_IMPORTED_MODULE_4__["capitalizeFirst"])(this._editedItemType)} name already exists; duplicate names are not allowed.`, true);
765
+ }
766
+ }
767
+ }
768
+ else
769
+ {
770
+ // Show alert
771
+ this.shellCtrl.showSimpleAlert('Unable to submit configuration changes due to an invalid value; please verify the highlighted form fields in all tabs.', true);
772
+ }
773
+ }
774
+
775
+ _onConfigValueSet(e) // SAME METHOD DUPLICATED IN zone-monitor.js
776
+ {
777
+ const configParam = e.target.data;
778
+
779
+ // Handle extension name/type dropdowns update and update the main class dropdown datasource accordingly
780
+ if (configParam.name == 'extension.name' || configParam.name == 'extension.type' || configParam.name == 'extension.filterClass')
781
+ {
782
+ // All involved ConfigFormItems must be available and initialized to proceed
783
+ const nameFormItem = this._interfaceBuilder.getConfigFormItem('extension.name');
784
+ const typeFormItem = this._interfaceBuilder.getConfigFormItem('extension.type');
785
+ const classFormItem = this._interfaceBuilder.getConfigFormItem('extension.file');
786
+ const filterFormItem = this._interfaceBuilder.getConfigFormItem('extension.filterClass');
787
+
788
+ if (nameFormItem != null && typeFormItem != null && classFormItem != null && filterFormItem != null)
789
+ {
790
+ const source = nameFormItem.data;
791
+ let classesList = [];
792
+
793
+ let data = source.triggerData;
794
+ for (let i = 0; i < data.size(); i++)
795
+ {
796
+ let ext = data.getSFSObject(i);
797
+
798
+ if (ext.getUtfString('name') == nameFormItem.data.value && ext.getUtfString('type') == typeFormItem.data.value)
799
+ {
800
+ let classes = ext.getUtfString('classesString').split(',');
801
+
802
+ if (filterFormItem.data.value == true)
803
+ {
804
+ let filteredClasses = classes.filter(_utils_utilities__WEBPACK_IMPORTED_MODULE_4__["filterClassName"]);
805
+ classes = filteredClasses;
806
+ }
807
+
808
+ classesList = classesList.concat(classes);
809
+ }
810
+ }
811
+
812
+ let currentClass = classFormItem.data.value;
813
+
814
+ // If the classes list doesn't contain the current value, create an empty entry and reset the value
815
+ if (classesList.indexOf(currentClass) < 0)
816
+ {
817
+ if (classesList.length == 0)
818
+ {
819
+ classesList.push('');
820
+ currentClass = '';
821
+ }
822
+ else
823
+ currentClass = classesList[0];
824
+ }
825
+
826
+ let mainClassDropDown = classFormItem._innerWidget;
827
+ mainClassDropDown.setDataSource(classesList);
828
+
829
+ classFormItem.data.value = currentClass;
830
+ classFormItem._setWidgetValue();
831
+ }
832
+ }
833
+ }
834
+
835
+ //---------------------------------
836
+ // PRIVATE METHODS
837
+ //---------------------------------
838
+
839
+ _enableListInterface(enabled)
840
+ {
841
+ $('#znc-utilButtons').attr('disabled', !enabled);
842
+ $('#znc-treeView').attr('disabled', !enabled);
843
+ }
844
+
845
+ _setUtilityButtonsState(dataItem = null)
846
+ {
847
+ let disable = true;
848
+
849
+ if (dataItem)
850
+ {
851
+ // Enable 'activate zone' button if zone is inactive
852
+ $('#znc-activateButton').attr('disabled', (dataItem.type != this.ITEM_TYPE_ZONE || dataItem.active));
853
+
854
+ disable = false;
855
+ }
856
+ else
857
+ {
858
+ // Disable 'activate zone' button
859
+ $('#znc-activateButton').attr('disabled', true);
860
+ }
861
+
862
+ // Enable/disable other utility buttons
863
+ $('#znc-addZoneButton').attr('disabled', false); // Always enabled
864
+ $('#znc-addRoomButton').attr('disabled', disable);
865
+ $('#znc-editButton').attr('disabled', disable);
866
+ $('#znc-removeButton').attr('disabled', disable);
867
+ }
868
+
869
+ _enableConfigInterface(enabled)
870
+ {
871
+ $('#znc-cancelButton').attr('disabled', !enabled);
872
+ $('#znc-reloadButton').attr('disabled', !enabled);
873
+ $('#znc-submitButton').attr('disabled', !enabled);
874
+ $('#znc-backupCheck').attr('disabled', !enabled);
875
+
876
+ this._interfaceBuilder.disableInterface(!enabled);
877
+
878
+ // Also switch view when enabled
879
+ if (enabled)
880
+ this._switchView('znc-main');
881
+ }
882
+
883
+ _switchView(viewId)
884
+ {
885
+ document.getElementById('znc-viewstack').selectedElement = document.getElementById(viewId);
886
+ }
887
+
888
+ _clearTabs()
889
+ {
890
+ // Destroy scrolling tabs
891
+ $('#znc-tabNavigator #tabs').scrollingTabs('destroy');
892
+
893
+ // Remove all tab navigator content
894
+ this._interfaceBuilder.destroyInterface();
895
+
896
+ // Set flag to re-initialize tabs if needed
897
+ this._reinitTabs = true;
898
+ }
899
+
900
+ _populateTree(data)
901
+ {
902
+ let zData = data.getSFSArray('zones');
903
+
904
+ let zonesArr = [];
905
+ for (let z = 0; z < zData.size(); z++)
906
+ zonesArr.push( this._createZoneObject(zData.getSFSObject(z)) );
907
+
908
+ // Create datasource
909
+ let zones = new kendo.data.HierarchicalDataSource({
910
+ data: zonesArr,
911
+ sort: {
912
+ field: 'name',
913
+ dir: 'asc'
914
+ },
915
+ schema: {
916
+ model: {
917
+ id: 'id',
918
+ children: {
919
+ schema: {
920
+ data: 'rooms',
921
+ sort: {
922
+ field: 'name',
923
+ dir: 'asc'
924
+ }
925
+ }
926
+ }
927
+ }
928
+ }
929
+ });
930
+
931
+ // Set tree view dataprovider
932
+ this._treeview.setDataSource(zones);
933
+
934
+ // Set utility buttons state (add, remove, edit, etc)
935
+ this._setUtilityButtonsState();
936
+ }
937
+
938
+ _createZoneObject(zoneData)
939
+ {
940
+ let zone = {
941
+ type: this.ITEM_TYPE_ZONE,
942
+ name: zoneData.getUtfString('name'),
943
+ id: zoneData.getInt('id'),
944
+ active: zoneData.getBool('act')
945
+ }
946
+
947
+ // Create rooms list dataprovider
948
+ let rData = zoneData.getSFSArray('rooms');
949
+
950
+ let roomsArr = [];
951
+ for (let r = 0; r < rData.size(); r++)
952
+ roomsArr.push( this._createRoomObject(rData.getSFSObject(r), zoneData.getInt('id')) );
953
+
954
+ zone.rooms = roomsArr;
955
+
956
+ return zone;
957
+ }
958
+
959
+ _createRoomObject(roomData, zoneId)
960
+ {
961
+ let room = {
962
+ type: this.ITEM_TYPE_ROOM,
963
+ name: roomData.getUtfString('name'),
964
+ id: roomData.getInt('id'),
965
+ active: roomData.getBool('act'),
966
+ parentId: zoneId,
967
+ spriteCssClass: this._getRoomListIconCssClass(roomData.getBool('act'))
968
+ };
969
+
970
+ return room;
971
+ }
972
+
973
+ _getRoomListIconCssClass(isActive)
974
+ {
975
+ return isActive ? 'fas fa-door-open' : 'fas fa-door-closed inactive-list-item';
976
+ }
977
+
978
+ _setZoneActivationStatus(zoneId, activeRooms, isActive)
979
+ {
980
+ let zoneDI = this._getZoneDataItemById(zoneId);
981
+
982
+ zoneDI.active = isActive;
983
+
984
+ let activeRoomsArr = activeRooms.split(',');
985
+
986
+ if (zoneDI.hasChildren)
987
+ {
988
+ for (let i = 0; i < zoneDI.children.data().length; i++)
989
+ {
990
+ let room = zoneDI.children.data()[i];
991
+ room.active = (isActive && activeRoomsArr.indexOf(room.name) > -1);
992
+ room.spriteCssClass = this._getRoomListIconCssClass(room.active)
993
+ }
994
+ }
995
+
996
+ // Refresh list
997
+ this._treeview.dataSource.sync();
998
+
999
+ // Return zone name
1000
+ return zoneDI.name;
1001
+ }
1002
+
1003
+ _deselectTreeItem()
1004
+ {
1005
+ this._treeview.select($());
1006
+ }
1007
+
1008
+ _selectParentTreeItem()
1009
+ {
1010
+ let selectedNode = this._treeview.select();
1011
+ let selectedDataItem = this._treeview.dataItem(selectedNode);
1012
+
1013
+ if (selectedDataItem.type == this.ITEM_TYPE_ROOM)
1014
+ {
1015
+ let parentNode = this._treeview.parent(selectedNode);
1016
+ this._treeview.select(parentNode);
1017
+ }
1018
+ }
1019
+
1020
+ _loadConfiguration(type, resetTabs = true)
1021
+ {
1022
+ // Disable zone/room selection list
1023
+ this._enableListInterface(false);
1024
+
1025
+ // Disable configuration interface
1026
+ this._enableConfigInterface(false);
1027
+
1028
+ // Clear main container
1029
+ this._resetTabsContainer(true, resetTabs);
1030
+
1031
+ // Set isEditing flag
1032
+ this._isEditing = true;
1033
+ this._editedItemType = type;
1034
+
1035
+ // Request zone or room configuration data to server instance
1036
+ let params = new SFS2X.SFSObject();
1037
+ params.putInt('zId', this._editedZoneId);
1038
+ params.putInt('rId', this._editedRoomId);
1039
+
1040
+ // If no room is selected, then we are editing a zone
1041
+ if (this._editedItemType == this.ITEM_TYPE_ZONE)
1042
+ this.sendExtensionRequest(this.REQ_GET_ZONE_CONFIG, params);
1043
+ else
1044
+ this.sendExtensionRequest(this.REQ_GET_ROOM_CONFIG, params);
1045
+
1046
+ // Switch panel
1047
+ this._switchPanel('znc-mainPanel');
1048
+ }
1049
+
1050
+ _resetTabsContainer(isLoading, resetTabs)
1051
+ {
1052
+ if (resetTabs)
1053
+ this._clearTabs();
1054
+ else
1055
+ this._reinitTabs = false;
1056
+
1057
+ if (!isLoading)
1058
+ this._switchView('znc-select');
1059
+ else
1060
+ this._switchView('znc-loading');
1061
+ }
1062
+
1063
+ _switchPanel(panelId)
1064
+ {
1065
+ document.getElementById('znc-view').selectedPanel = document.getElementById(panelId);
1066
+ }
1067
+
1068
+ _getZoneDataItemById(zoneId)
1069
+ {
1070
+ let zonesDS = this._treeview.dataSource;
1071
+ return zonesDS.get(zoneId);
1072
+ }
1073
+
1074
+ _getRoomDataItemById(zoneId, roomId)
1075
+ {
1076
+ let zoneDI = this._getZoneDataItemById(zoneId);
1077
+
1078
+ if (zoneDI.hasChildren)
1079
+ return zoneDI.children.get(roomId);
1080
+
1081
+ return null;
1082
+ }
1083
+
1084
+ _updateZoneNameInList(zoneId, zoneName)
1085
+ {
1086
+ this._getZoneDataItemById(zoneId).name = zoneName;
1087
+ this._treeview.dataSource.sync();
1088
+ }
1089
+
1090
+ _updateRoomNameInList(zoneId, roomId, roomName)
1091
+ {
1092
+ this._getRoomDataItemById(zoneId, roomId).name = roomName;
1093
+ this._treeview.dataSource.sync();
1094
+ }
1095
+
1096
+ _validateName(changes)
1097
+ {
1098
+ const zoneId = this._editedZoneId;
1099
+
1100
+ for (let i = 0; i < changes.size(); i++)
1101
+ {
1102
+ const setting = changes.getSFSObject(i);
1103
+
1104
+ if (setting.containsKey('name') && setting.getUtfString('name') == 'name')
1105
+ {
1106
+ // Get name value
1107
+ const name = setting.getText('value');
1108
+
1109
+ // Get data source
1110
+ let ds = [];
1111
+
1112
+ if (this._editedItemType == this.ITEM_TYPE_ZONE)
1113
+ ds = this._treeview.dataSource.data();
1114
+ else
1115
+ {
1116
+ if (this._getZoneDataItemById(zoneId).hasChildren)
1117
+ ds = this._getZoneDataItemById(zoneId).children.data();
1118
+ }
1119
+
1120
+
1121
+ // Check if name exists in data source
1122
+ for (let j = 0; j < ds.length; j++)
1123
+ {
1124
+ if (ds[j].name == name)
1125
+ {
1126
+ return false;
1127
+ }
1128
+ }
1129
+
1130
+ break;
1131
+ }
1132
+ }
1133
+
1134
+ return true;
1135
+ }
1136
+
1137
+ //---------------------------------
1138
+ // PRIVATE GETTERS
1139
+ //---------------------------------
1140
+
1141
+ get _selectedItem()
1142
+ {
1143
+ return this._treeview.dataItem(this._treeview.select());
1144
+ }
1145
+
1146
+ get _selectedItemParent()
1147
+ {
1148
+ let selectedNode = this._treeview.select();
1149
+ let parentNode = this._treeview.parent(selectedNode);
1150
+
1151
+ return this._treeview.dataItem(parentNode);
1152
+ }
1153
+
1154
+ get _editedZoneId()
1155
+ {
1156
+ if (this._isEditing && this._selectedItem)
1157
+ {
1158
+ if (this._selectedItem.type == this.ITEM_TYPE_ZONE)
1159
+ return this._selectedItem.id;
1160
+ else
1161
+ return this._selectedItemParent.id;
1162
+ }
1163
+
1164
+ return -1;
1165
+ }
1166
+
1167
+ get _editedRoomId()
1168
+ {
1169
+ if (this._isEditing && this._selectedItem)
1170
+ {
1171
+ if (this._selectedItem.type == this.ITEM_TYPE_ROOM)
1172
+ return this._selectedItem.id;
1173
+ }
1174
+
1175
+ return -1;
1176
+ }
1177
+ }
1178
+
1179
+ /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery")))
1180
+
1181
+ /***/ })
1182
+
1183
+ }]);
1184
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXRzL2pzL2NvcmUvbW9kdWxlcy9tb2R1bGUtMTIuYnVuZGxlLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vYXBwbGljYXRpb24vLi9zcmMvY29tcG9uZW50cy9zaWRlYmFyLWxheW91dC5qcyIsIndlYnBhY2s6Ly9hcHBsaWNhdGlvbi8uL3NyYy9tb2R1bGVzL3pvbmUtY29uZmlndXJhdG9yLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjbGFzcyBTaWRlYmFyTGF5b3V0IGV4dGVuZHMgSFRNTEVsZW1lbnRcbntcblx0Y29uc3RydWN0b3IoKVxuXHR7XG5cdCAgICBzdXBlcigpO1xuXG5cdFx0Ly8gQXR0YWNoIGEgc2hhZG93IHJvb3Rcblx0XHRjb25zdCBzaGFkb3dSb290ID0gdGhpcy5hdHRhY2hTaGFkb3coe21vZGU6ICdvcGVuJ30pO1xuXHRcdHNoYWRvd1Jvb3QuaW5uZXJIVE1MID0gYFxuXHRcdFx0PHN0eWxlPlxuXHRcdFx0XHQ6aG9zdCB7XG5cdFx0XHRcdFx0ZGlzcGxheTogZmxleDtcblx0XHRcdFx0XHRmbGV4LWRpcmVjdGlvbjogcm93O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0QG1lZGlhIChtYXgtd2lkdGg6IDU3NS45OHB4KSB7XG5cdFx0XHRcdFx0Omhvc3QoLnNwbGl0LXhzKSA6OnNsb3R0ZWQoOm5vdChbYXJpYS1zZWxlY3RlZD1cInRydWVcIl0pKSB7XG5cdFx0XHRcdFx0XHRkaXNwbGF5OiBub25lICFpbXBvcnRhbnQ7XG5cdFx0XHRcdCAgICB9XG5cblx0XHRcdFx0XHQ6aG9zdCguc3BsaXQteHMpIDo6c2xvdHRlZChbYXJpYS1zZWxlY3RlZD1cInRydWVcIl0pIHtcblx0XHRcdFx0XHRcdGZsZXgtZ3JvdzogMTtcblx0XHRcdFx0ICAgIH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdEBtZWRpYSAobWF4LXdpZHRoOiA3NjcuOThweCkge1xuXHRcdFx0XHRcdDpob3N0KC5zcGxpdC1zbSkgOjpzbG90dGVkKDpub3QoW2FyaWEtc2VsZWN0ZWQ9XCJ0cnVlXCJdKSkge1xuXHRcdFx0XHRcdFx0ZGlzcGxheTogbm9uZSAhaW1wb3J0YW50O1xuXHRcdFx0XHQgICAgfVxuXG5cdFx0XHRcdFx0Omhvc3QoLnNwbGl0LXNtKSA6OnNsb3R0ZWQoW2FyaWEtc2VsZWN0ZWQ9XCJ0cnVlXCJdKSB7XG5cdFx0XHRcdFx0XHRmbGV4LWdyb3c6IDE7XG5cdFx0XHRcdCAgICB9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRAbWVkaWEgKG1heC13aWR0aDogOTkxLjk4cHgpIHtcblx0XHRcdFx0XHQ6aG9zdCguc3BsaXQtbWQpIDo6c2xvdHRlZCg6bm90KFthcmlhLXNlbGVjdGVkPVwidHJ1ZVwiXSkpIHtcblx0XHRcdFx0XHRcdGRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDtcblx0XHRcdFx0ICAgIH1cblxuXHRcdFx0XHRcdDpob3N0KC5zcGxpdC1tZCkgOjpzbG90dGVkKFthcmlhLXNlbGVjdGVkPVwidHJ1ZVwiXSkge1xuXHRcdFx0XHRcdFx0ZmxleC1ncm93OiAxO1xuXHRcdFx0XHQgICAgfVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0QG1lZGlhIChtYXgtd2lkdGg6IDExOTkuOThweCkge1xuXHRcdFx0XHRcdDpob3N0KC5zcGxpdC1sZykgOjpzbG90dGVkKDpub3QoW2FyaWEtc2VsZWN0ZWQ9XCJ0cnVlXCJdKSkge1xuXHRcdFx0XHRcdFx0ZGlzcGxheTogbm9uZSAhaW1wb3J0YW50O1xuXHRcdFx0XHQgICAgfVxuXG5cdFx0XHRcdFx0Omhvc3QoLnNwbGl0LWxnKSA6OnNsb3R0ZWQoW2FyaWEtc2VsZWN0ZWQ9XCJ0cnVlXCJdKSB7XG5cdFx0XHRcdFx0XHRmbGV4LWdyb3c6IDE7XG5cdFx0XHRcdCAgICB9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQuc2lkZS1jb2w6OnNsb3R0ZWQoKikge1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Lm1haW4tY29sOjpzbG90dGVkKCopIHtcblx0XHRcdFx0XHRmbGV4LWdyb3c6IDE7XG5cdFx0XHRcdH1cblx0XHRcdDwvc3R5bGU+XG5cblx0XHRcdDxzbG90IGNsYXNzPVwic2lkZS1jb2xcIiBuYW1lPVwic2lkZS1jb2x1bW5cIj48L3Nsb3Q+XG5cdFx0XHQ8c2xvdCBjbGFzcz1cIm1haW4tY29sXCIgbmFtZT1cIm1haW4tY29sdW1uXCI+PC9zbG90PlxuXHRcdGA7XG5cblx0XHQvLyBTZXQgaW5pdGlhbCBzZWxlY3Rpb25cblx0XHR0aGlzLnNlbGVjdGVkSW5kZXggPSAwO1xuXHR9XG5cblx0Z2V0IHNlbGVjdGVkUGFuZWwoKVxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX3NlbGVjdGVkUGFuZWw7XG5cdH1cblxuXHRzZXQgc2VsZWN0ZWRQYW5lbChlbGVtZW50KSAvLyAnc2lkZScgb3IgJ21haW4nXG5cdHtcblx0XHRpZiAoZWxlbWVudCAhPSBudWxsICYmIGVsZW1lbnQucGFyZW50Tm9kZSA9PSB0aGlzKVxuXHRcdHtcblx0XHRcdHRoaXMuX3NlbGVjdGVkUGFuZWwgPSBlbGVtZW50O1xuXG5cdFx0XHRmb3IgKGxldCBlbGVtZW50IG9mIHRoaXMuY2hpbGRyZW4pXG5cdFx0XHR7XG5cdFx0XHRcdGlmIChlbGVtZW50ID09IHRoaXMuX3NlbGVjdGVkUGFuZWwpXG5cdFx0XHRcdFx0ZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2FyaWEtc2VsZWN0ZWQnLCAndHJ1ZScpO1xuXHRcdFx0XHRlbHNlXG5cdFx0XHRcdFx0ZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ2FyaWEtc2VsZWN0ZWQnKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0ZWxzZVxuXHRcdHtcblx0XHRcdGNvbnNvbGUuZXJyb3IoJ0VsZW1lbnQgaXMgbm90IGEgY2hpbGQgb2YgU2lkZWJhckxheW91dCcpO1xuXHRcdH1cblx0fVxuXG5cdGdldCBzZWxlY3RlZEluZGV4KClcblx0e1xuXHRcdHJldHVybiBBcnJheS5mcm9tKHRoaXMuY2hpbGRyZW4pLmluZGV4T2YodGhpcy5fc2VsZWN0ZWRQYW5lbCk7XG5cdH1cblxuXHRzZXQgc2VsZWN0ZWRJbmRleChpbmRleClcblx0e1xuXHRcdGlmICh0aGlzLmNoaWxkcmVuLmxlbmd0aCA+IDApXG5cdFx0e1xuXHRcdFx0aWYgKHRoaXMuY2hpbGRyZW5baW5kZXhdID09IG51bGwpXG5cdFx0XHR7XG5cdFx0XHRcdGNvbnNvbGUuZXJyb3IoJ0ludmFsaWQgU2lkZWJhckxheW91dCBpbmRleCcpO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGxldCBlbGVtZW50ID0gdGhpcy5jaGlsZHJlbltpbmRleF07XG5cdFx0XHR0aGlzLnNlbGVjdGVkUGFuZWwgPSBlbGVtZW50O1xuXHRcdH1cblx0fVxufVxuXG4vLyBERUZJTkUgQ09NUE9ORU5UXG5pZiAoIXdpbmRvdy5jdXN0b21FbGVtZW50cy5nZXQoJ3NpZGViYXItbGF5b3V0JykpXG5cdHdpbmRvdy5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ3NpZGViYXItbGF5b3V0JywgU2lkZWJhckxheW91dCk7XG4iLCJpbXBvcnQge0Jhc2VNb2R1bGV9IGZyb20gJy4vYmFzZS1tb2R1bGUnO1xuaW1wb3J0IHtWaWV3U3RhY2t9IGZyb20gJy4uL2NvbXBvbmVudHMvdmlldy1zdGFjayc7XG5pbXBvcnQge1NpZGViYXJMYXlvdXR9IGZyb20gJy4uL2NvbXBvbmVudHMvc2lkZWJhci1sYXlvdXQnO1xuaW1wb3J0IHtDb25maWdJbnRlcmZhY2VCdWlsZGVyfSBmcm9tICcuLi91dGlscy91aWJ1aWxkZXIvY29uZmlnLWludGVyZmFjZS1idWlsZGVyJztcbmltcG9ydCB7Y2FwaXRhbGl6ZUZpcnN0LCBmaWx0ZXJDbGFzc05hbWV9IGZyb20gJy4uL3V0aWxzL3V0aWxpdGllcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFpvbmVDb25maWd1cmF0b3IgZXh0ZW5kcyBCYXNlTW9kdWxlXG57XG5cdGNvbnN0cnVjdG9yKClcblx0e1xuXHQgICAgc3VwZXIoJ3pvbmVDb25maWcnKTtcblxuXHRcdHRoaXMuSVRFTV9UWVBFX1pPTkUgPSAnem9uZSc7XG5cdFx0dGhpcy5JVEVNX1RZUEVfUk9PTSA9ICdyb29tJztcblxuXHRcdC8vIE91dGdvaW5nIHJlcXVlc3RzXG5cdFx0dGhpcy5SRVFfR0VUX1pPTkVTID0gJ2dldFpvbmVzJztcblxuXHRcdHRoaXMuUkVRX0dFVF9aT05FX0NPTkZJRyA9ICdnZXRab25lQ29uZmlnJztcblx0XHR0aGlzLlJFUV9TQVZFX1pPTkVfQ09ORklHID0gJ3NhdmVab25lQ29uZmlnJztcblx0XHR0aGlzLlJFUV9ORVdfWk9ORV9DT05GSUcgPSAnbmV3Wm9uZUNvbmZpZyc7XG5cdFx0dGhpcy5SRVFfREVMRVRFX1pPTkVfQ09ORklHID0gJ2RlbFpvbmVDb25maWcnO1xuXHRcdHRoaXMuUkVRX0FDVElWQVRFX1pPTkUgPSAnYWN0Wm9uZSc7XG5cblx0XHR0aGlzLlJFUV9HRVRfUk9PTV9DT05GSUcgPSAnZ2V0Um9vbUNvbmZpZyc7XG5cdFx0dGhpcy5SRVFfU0FWRV9ST09NX0NPTkZJRyA9ICdzYXZlUm9vbUNvbmZpZyc7XG5cdFx0dGhpcy5SRVFfTkVXX1JPT01fQ09ORklHID0gJ25ld1Jvb21Db25maWcnO1xuXHRcdHRoaXMuUkVRX0RFTEVURV9ST09NX0NPTkZJRyA9ICdkZWxSb29tQ29uZmlnJztcblxuXHRcdC8vIEluY29taW5nIHJlc3BvbnNlc1xuXHRcdHRoaXMuUkVTUF9aT05FUyA9ICd6b25lcyc7XG5cblx0XHR0aGlzLlJFU1BfWk9ORV9DT05GSUcgPSAnem9uZUNvbmZpZyc7XG5cdFx0dGhpcy5SRVNQX1pPTkVfQ09ORklHX1VQREFURV9DT05GSVJNID0gJ3pvbmVDZmdVcGQnO1xuXHRcdHRoaXMuUkVTUF9aT05FX0FEREVEID0gJ3pvbmVBZGRlZCc7XG5cdFx0dGhpcy5SRVNQX1pPTkVfUkVGVVNFRCA9ICd6b25lUmVmdXNlZCc7XG5cdFx0dGhpcy5SRVNQX1pPTkVfREVMRVRFRCA9ICd6b25lRGVsJztcblx0XHR0aGlzLlJFU1BfWk9ORV9BQ1RJVkFURUQgPSAnem9uZUFjdCc7XG5cdFx0dGhpcy5SRVNQX1pPTkVfQUNUSVZBVElPTl9FUlJPUiA9ICd6b25lQWN0RXJyJztcblxuXHRcdHRoaXMuUkVTUF9ST09NX0NPTkZJRyA9ICdyb29tQ29uZmlnJztcblx0XHR0aGlzLlJFU1BfUk9PTV9DT05GSUdfVVBEQVRFX0NPTkZJUk0gPSAncm9vbUNmZ1VwZCc7XG5cdFx0dGhpcy5SRVNQX1JPT01fQURERUQgPSAncm9vbUFkZGVkJztcblx0XHR0aGlzLlJFU1BfUk9PTV9SRUZVU0VEID0gJ3Jvb21SZWZ1c2VkJztcblx0XHR0aGlzLlJFU1BfUk9PTV9ERUxFVEVEID0gJ3Jvb21EZWwnO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8gQ09NTU9OIE1PRFVMRSBJTlRFUkZBQ0UgTUVUSE9EU1xuXHQvLyBUaGlzIG1lbWJlcnMgYXJlIHVzZWQgYnkgdGhlIG1haW4gY29udHJvbGxlclxuXHQvLyB0byBjb21tdW5pY2F0ZSB3aXRoIHRoZSBtb2R1bGUncyBjb250cm9sbGVyLlxuXHQvLyBUaGlzIG1ldGhvZHMgb3ZlcnJpZGUgdGhvc2UgaW4gQmFzZU1vZHVsZSBjbGFzcy5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRpbml0aWFsaXplKGlkRGF0YSwgc2hlbGxDb250cm9sbGVyKVxuXHR7XG5cdFx0Ly8gQ2FsbCBzdXBlciBtZXRob2Rcblx0XHRzdXBlci5pbml0aWFsaXplKGlkRGF0YSwgc2hlbGxDb250cm9sbGVyKTtcblxuXHRcdC8vIENyZWF0ZSBpbnRlcmZhY2UgYnVpbGRlciBpbnN0YW5jZVxuXHRcdHRoaXMuX2ludGVyZmFjZUJ1aWxkZXIgPSBuZXcgQ29uZmlnSW50ZXJmYWNlQnVpbGRlcigpO1xuXG5cdFx0Ly8gU2V0IGxpc3RlbmVyIGZvciBjdXN0b20gYWN0aW9ucyB0cmlnZ2VyZWQgYnkgY29uZmlndXJhdGlvbiBpbnRlcmZhY2Vcblx0XHQkKCcjem5jLXRhYk5hdmlnYXRvcicpLm9uKCd2YWx1ZS1zZXQnLCAkLnByb3h5KHRoaXMuX29uQ29uZmlnVmFsdWVTZXQsIHRoaXMpKTtcblxuXHRcdC8vIEluaXRpYWxpemUgWm9uZXMvUm9vbXMgdHJlZXZpZXdcblx0XHR0aGlzLl90cmVldmlldyA9ICQoJyN6bmMtdHJlZVZpZXcnKS5rZW5kb1RyZWVWaWV3KHtcblx0XHRcdGxvYWRPbkRlbWFuZDogZmFsc2UsXG5cdFx0XHRkYXRhVGV4dEZpZWxkOiAnbmFtZScsXG5cdFx0XHR0ZW1wbGF0ZToga2VuZG8udGVtcGxhdGUoJzxzcGFuIGNsYXNzPVwiIyBpZiAoIWl0ZW0uYWN0aXZlKSB7ICMgaW5hY3RpdmUtbGlzdC1pdGVtICMgfSAjXCI+IzogaXRlbS5uYW1lICM8L3NwYW4+JyksXG5cdFx0XHRjaGFuZ2U6ICQucHJveHkodGhpcy5fb25ab25lUm9vbUNoYW5nZSwgdGhpcyksXG5cdFx0fSkuZGF0YSgna2VuZG9UcmVlVmlldycpO1xuXG5cdFx0Ly8gTGVzdGVuZCB0byB0cmVldmlldyBkb3VibGUtY2xpY2sgZXZlbnRcblx0XHQkKCcjem5jLXRyZWVWaWV3Jykub24oJ2RibGNsaWNrJywgJC5wcm94eSh0aGlzLl9vblRyZWVJdGVtRG91YmxlQ2xpY2ssIHRoaXMpKTtcblxuXHRcdC8vIFJlcXVlc3Qgem9uZXMgJiByb29tcyBsaXN0IHRvIHNlcnZlciBpbnN0YW5jZVxuXHRcdHRoaXMuc2VuZEV4dGVuc2lvblJlcXVlc3QodGhpcy5SRVFfR0VUX1pPTkVTKTtcblxuXHRcdC8vIEluaXRpYWxpemUgcHJvZ3Jlc3MgYmFyXG5cdFx0JCgnI3puYy1wcm9ncmVzc0JhcicpLmtlbmRvUHJvZ3Jlc3NCYXIoe1xuXHRcdFx0bWluOiAwLFxuICAgICAgICAgICAgbWF4OiAxMDAsXG5cdFx0XHR2YWx1ZTogZmFsc2UsXG4gICAgICAgICAgICB0eXBlOiAndmFsdWUnLFxuICAgICAgICAgICAgYW5pbWF0aW9uOiB7XG4gICAgICAgICAgICAgICAgZHVyYXRpb246IDQwMFxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuXHRcdC8vIEFkZCBsaXN0ZW5lcnMgdG8gdXRpbGl0eSBidXR0b25zXG5cdFx0JCgnI3puYy1hZGRab25lQnV0dG9uJykub24oJ2NsaWNrJywgJC5wcm94eSh0aGlzLl9vbkFkZFpvbmVDbGljaywgdGhpcykpO1xuXHRcdCQoJyN6bmMtYWRkUm9vbUJ1dHRvbicpLm9uKCdjbGljaycsICQucHJveHkodGhpcy5fb25BZGRSb29tQ2xpY2ssIHRoaXMpKTtcblx0XHQkKCcjem5jLWVkaXRCdXR0b24nKS5vbignY2xpY2snLCAkLnByb3h5KHRoaXMuX29uRWRpdENsaWNrLCB0aGlzKSk7XG5cdFx0JCgnI3puYy1yZW1vdmVCdXR0b24nKS5vbignY2xpY2snLCAkLnByb3h5KHRoaXMuX29uUmVtb3ZlQ2xpY2ssIHRoaXMpKTtcblx0XHQkKCcjem5jLWFjdGl2YXRlQnV0dG9uJykub24oJ2NsaWNrJywgJC5wcm94eSh0aGlzLl9vbkFjdGl2YXRlQ2xpY2ssIHRoaXMpKTtcblxuXHRcdC8vIEFkZCBsaXN0ZW5lciB0byBpbnRlcmZhY2UgYnV0dG9uc1xuXHRcdCQoJyN6bmMtY2FuY2VsQnV0dG9uJykub24oJ2NsaWNrJywgJC5wcm94eSh0aGlzLl9vbkNhbmNlbENsaWNrLCB0aGlzKSk7XG5cdFx0JCgnI3puYy1yZWxvYWRCdXR0b24nKS5vbignY2xpY2snLCAkLnByb3h5KHRoaXMuX29uUmVsb2FkQ2xpY2ssIHRoaXMpKTtcblx0XHQkKCcjem5jLXN1Ym1pdEJ1dHRvbicpLm9uKCdjbGljaycsICQucHJveHkodGhpcy5fb25TdWJtaXRDbGljaywgdGhpcykpO1xuXHR9XG5cblx0ZGVzdHJveSgpXG5cdHtcblx0XHQvLyBDYWxsIHN1cGVyIG1ldGhvZFxuXHRcdHN1cGVyLmRlc3Ryb3koKTtcblxuXHRcdC8vIFJlbW92ZSB0cmVlIHZpZXcgZG91YmxlY2xpY2sgbGlzdGVuZXJcblx0XHQkKCcjem5jLXRyZWVWaWV3Jykub2ZmKCdkYmxjbGljaycpO1xuXG5cdFx0Ly8gUmVtb3ZlIGxpc3RlbmVyIGZvciBjdXN0b20gYWN0aW9ucyB0cmlnZ2VyZWQgYnkgY29uZmlndXJhdGlvbiBpbnRlcmZhY2Vcblx0XHQkKCcjem5jLXRhYk5hdmlnYXRvcicpLm9mZigndmFsdWUtc2V0Jyk7XG5cblx0XHQvLyBSZW1vdmUgbGlzdGVuZXIgZm9yIHpvbmUvcm9vbSBhY3RpdmF0aW9uIGV2ZW50XG5cdFx0JCgnI3puYy1hZGRab25lQnV0dG9uJykub2ZmKCdjbGljaycpO1xuXHRcdCQoJyN6bmMtYWRkUm9vbUJ1dHRvbicpLm9mZignY2xpY2snKTtcblx0XHQkKCcjem5jLWVkaXRCdXR0b24nKS5vZmYoJ2NsaWNrJyk7XG5cdFx0JCgnI3puYy1yZW1vdmVCdXR0b24nKS5vZmYoJ2NsaWNrJyk7XG5cdFx0JCgnI3puYy1hY3RpdmF0ZUJ1dHRvbicpLm9mZignY2xpY2snKTtcblxuXHRcdC8vIFJlbW92ZSBpbnRlcmZhY2UgYnV0dG9ucyBjbGljayBsaXN0ZW5lcnNcblx0XHQkKCcjem5jLWNhbmNlbEJ1dHRvbicpLm9mZignY2xpY2snKTtcblx0XHQkKCcjem5jLXJlbG9hZEJ1dHRvbicpLm9mZignY2xpY2snKTtcblx0XHQkKCcjem5jLXN1Ym1pdEJ1dHRvbicpLm9mZignY2xpY2snKTtcblxuXHRcdC8vIENsZWFyIHRhYnMgY29udGFpbmVyXG5cdFx0dGhpcy5fY2xlYXJUYWJzKCk7XG5cdH1cblxuXHRvbkV4dGVuc2lvbkNvbW1hbmQoY29tbWFuZCwgZGF0YSlcblx0e1xuXHRcdGNvbnN0IHVzZXJuYW1lID0gZGF0YS5nZXRVdGZTdHJpbmcoJ3VzZXInKTtcblxuXHRcdC8qKioqKiogWk9ORVMgJiBST09NUyAqKioqKiovXG5cblx0XHQvLyBab25lcyAmIHJvb21zIGxpc3QgcmVjZWl2ZWRcblx0XHRpZiAoY29tbWFuZCA9PSB0aGlzLlJFU1BfWk9ORVMpXG5cdFx0XHR0aGlzLl9wb3B1bGF0ZVRyZWUoZGF0YSk7XG5cblx0XHQvLyBab25lIG9yIHJvb20gY29uZmlndXJhdGlvbiBkYXRhIHJlY2VpdmVkXG5cdFx0ZWxzZSBpZiAoY29tbWFuZCA9PSB0aGlzLlJFU1BfWk9ORV9DT05GSUcgfHwgY29tbWFuZCA9PSB0aGlzLlJFU1BfUk9PTV9DT05GSUcpXG5cdFx0e1xuXHRcdFx0Ly8gQnVpbGQgdXNlciBpbnRlcmZhY2UgYmFzZWQgb24gcmVjZWl2ZWQgZGF0YVxuXHRcdFx0dGhpcy5faW50ZXJmYWNlQnVpbGRlci5idWlsZEludGVyZmFjZShkYXRhLmdldFNGU0FycmF5KCdzZXR0aW5ncycpLCAnem5jLXRhYk5hdmlnYXRvcicsIGZhbHNlKTtcblxuXHRcdFx0Ly8gRW5hYmxlIHNjcm9sbGluZyB0YWJzIChpZiBuZWVkZWQpXG5cdFx0XHRpZiAodGhpcy5fcmVpbml0VGFicylcblx0XHRcdHtcblx0XHRcdFx0JCgnI3puYy10YWJOYXZpZ2F0b3IgI3RhYnMnKS5zY3JvbGxpbmdUYWJzKHtcblx0XHRcdFx0XHRib290c3RyYXBWZXJzaW9uOiA0LFxuXHRcdFx0XHRcdHNjcm9sbFRvVGFiRWRnZTogdHJ1ZSxcblx0XHRcdFx0XHRlbmFibGVTd2lwaW5nOiB0cnVlLFxuXHRcdFx0XHRcdGRpc2FibGVTY3JvbGxBcnJvd3NPbkZ1bGx5U2Nyb2xsZWQ6IHRydWUsXG5cdFx0XHRcdFx0Y3NzQ2xhc3NMZWZ0QXJyb3c6ICdmYSBmYS1jaGV2cm9uLWxlZnQnLFxuXHRcdFx0XHRcdGNzc0NsYXNzUmlnaHRBcnJvdzogJ2ZhIGZhLWNoZXZyb24tcmlnaHQnXG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBFbmFibGUgaW50ZXJmYWNlXG5cdFx0XHR0aGlzLl9lbmFibGVDb25maWdJbnRlcmZhY2UodHJ1ZSk7XG5cdFx0fVxuXG5cdFx0LyoqKioqKiBaT05FUyAqKioqKiovXG5cblx0XHQvLyBab25lIGNvbmZpZ3VyYXRpb24gdXBkYXRlIGNvbmZpcm1hdGlvblxuXHRcdGVsc2UgaWYgKGNvbW1hbmQgPT0gdGhpcy5SRVNQX1pPTkVfQ09ORklHX1VQREFURV9DT05GSVJNKVxuXHRcdHtcblx0XHRcdC8vIElmIGEgJ25hbWUnIHBhcmFtZXRlciBpcyByZWNlaXZlZCwgaXQgbWVhbnMgdGhlIHpvbmUgbmFtZSBjaGFuZ2VkLCBhbmQgd2UgaGF2ZSB0byB1cGRhdGUgdGhlIHpvbmVzIGxpc3Rcblx0XHRcdGlmIChkYXRhLmdldFV0ZlN0cmluZygnek5hbWUnKSAhPSBudWxsKVxuXHRcdFx0XHR0aGlzLl91cGRhdGVab25lTmFtZUluTGlzdChkYXRhLmdldEludCgneklkJyksIGRhdGEuZ2V0VXRmU3RyaW5nKCd6TmFtZScpKTtcblxuXHRcdFx0Ly8gSWYgdGhlIGN1cnJlbnQgdXNlciBpcyB0aGUgdXBkYXRlciwgc2hvdyBhIG5vdGlmaWNhdGlvbjsgb3RoZXJ3aXNlLCBzaG93IGEgZGlhbG9nIGJveCBzdWdnZXN0aW5nIHRvIHJlbG9hZFxuXHRcdFx0aWYgKHVzZXJuYW1lID09IHRoaXMuc21hcnRGb3gubXlTZWxmLm5hbWUpXG5cdFx0XHR7XG5cdFx0XHRcdC8vIEVuYWJsZSBpbnRlcmZhY2Vcblx0XHRcdFx0dGhpcy5fZW5hYmxlQ29uZmlnSW50ZXJmYWNlKHRydWUpO1xuXG5cdFx0XHRcdC8vIERpc3BsYXkgbm90aWZpY2F0aW9uXG5cdFx0XHRcdHRoaXMuc2hlbGxDdHJsLnNob3dOb3RpZmljYXRpb24oJ1pvbmUgbW9kaWZpZWQnLCBgWm9uZSBzZXR0aW5ncyB1cGRhdGVkIHN1Y2Nlc3NmdWxseTsgY2hhbmdlcyB3aWxsIGJlIGFwcGxpZWQgb24gbmV4dCA8c3Ryb25nPnNlcnZlciByZXN0YXJ0PC9zdHJvbmc+YCk7XG5cblx0XHRcdFx0Ly8gUmVzZXQgdGhlICdtb2RpZmllZCcgZmxhZ1xuXHRcdFx0XHR0aGlzLl9pbnRlcmZhY2VCdWlsZGVyLnJlc2V0SXNNb2RpZmllZCgpO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZVxuXHRcdFx0e1xuXHRcdFx0XHQvLyBBbiBhbGVydCBib3ggaXMgZGlzcGxheWVkIGlmIHRoZSB1c2VyIGlzIGN1cnJlbnRseSBlZGl0aW5nIHRoZSBzYW1lIHpvbmVcblx0XHRcdFx0aWYgKGRhdGEuZ2V0SW50KCd6SWQnKSA9PSB0aGlzLl9lZGl0ZWRab25lSWQpXG5cdFx0XHRcdHtcblx0XHRcdFx0XHQvLyBTaG93IGFsZXJ0XG5cdFx0XHRcdFx0dGhpcy5zaGVsbEN0cmwuc2hvd1NpbXBsZUFsZXJ0KGBBZG1pbmlzdHJhdG9yICR7dXNlcm5hbWV9IGhhcyBtb2RpZmllZCB0aGUgWm9uZSB5b3UgYXJlIGN1cnJlbnRseSBlZGl0aW5nOyBwbGVhc2UgcmVsb2FkIHRvIHVwZGF0ZSB5b3VyIHZpZXcuYCk7XG5cblx0XHRcdFx0XHQvLyBEaXNhYmxlIHN1Ym1pdCBidXR0b25cblx0XHRcdFx0XHQkKCcjem5jLXN1Ym1pdEJ1dHRvbicpLmF0dHIoJ2Rpc2FibGVkJywgdHJ1ZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZVxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0Ly8gRGlzcGxheSBub3RpZmljYXRpb25cblx0XHRcdFx0XHRpZiAoZGF0YS5nZXRVdGZTdHJpbmcoJ3pOYW1lJykgIT0gbnVsbClcblx0XHRcdFx0XHRcdHRoaXMuc2hlbGxDdHJsLnNob3dOb3RpZmljYXRpb24oJ1pvbmUgcmVuYW1lZCcsIGBBZG1pbmlzdHJhdG9yICR7dXNlcm5hbWV9IGhhcyBjaGFuZ2VkIHRoZSBuYW1lIG9uIG9uZSBvZiB0aGUgWm9uZXNgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIE5ldyB6b25lIGFkZGVkXG5cdFx0ZWxzZSBpZiAoY29tbWFuZCA9PSB0aGlzLlJFU1BfWk9ORV9BRERFRClcblx0XHR7XG5cdFx0XHRjb25zdCB6b25lTmFtZSA9IGRhdGEuZ2V0U0ZTT2JqZWN0KCd6b25lJykuZ2V0VXRmU3RyaW5nKCduYW1lJyk7XG5cblx0XHRcdC8vIElmIHRoZSBjdXJyZW50IHVzZXIgaXMgdGhlIHVwZGF0ZXIsIHJlc2V0IHRoZSBpbnRlcmZhY2U7IG90aGVyd2lzZSwganVzdCBzaG93IGEgbm90aWZpY2F0aW9uXG5cdFx0XHRpZiAodXNlcm5hbWUgPT0gdGhpcy5zbWFydEZveC5teVNlbGYubmFtZSlcblx0XHRcdHtcblx0XHRcdFx0Ly8gUmVzZXQgaW50ZXJmYWNlXG5cdFx0XHRcdHRoaXMuX29uQ2FuY2VsQ2xpY2soKTtcblxuXHRcdFx0XHQvLyBEaXNwbGF5IG5vdGlmaWNhdGlvblxuXHRcdFx0XHR0aGlzLnNoZWxsQ3RybC5zaG93Tm90aWZpY2F0aW9uKCdab25lIGFkZGVkJywgYFpvbmUgJyR7em9uZU5hbWV9JyBjcmVhdGVkIHN1Y2Nlc3NmdWxseWApO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZVxuXHRcdFx0e1xuXHRcdFx0XHQvLyBEaXNwbGF5IG5vdGlmaWNhdGlvblxuXHRcdFx0XHR0aGlzLnNoZWxsQ3RybC5zaG93Tm90aWZpY2F0aW9uKCdab25lIGFkZGVkJywgYEFkbWluaXN0cmF0b3IgJHt1c2VybmFtZX0gY3JlYXRlZCBab25lICcke3pvbmVOYW1lfSdgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQWRkIG5ldyB6b25lIHRvIHRyZWVcblx0XHRcdGxldCB6b25lc0RTID0gdGhpcy5fdHJlZXZpZXcuZGF0YVNvdXJjZTtcblx0XHRcdHpvbmVzRFMuYWRkKHRoaXMuX2NyZWF0ZVpvbmVPYmplY3QoZGF0YS5nZXRTRlNPYmplY3QoJ3pvbmUnKSkpO1xuXHRcdFx0em9uZXNEUy5zeW5jKCk7XG5cdFx0fVxuXG5cdFx0Ly8gTmV3IHpvbmUgY3JlYXRpb24gcmVmdXNlZCBkdWUgdG8gaW52YWxpZCB6b25lIG5hbWVcblx0XHRlbHNlIGlmIChjb21tYW5kID09IHRoaXMuUkVTUF9aT05FX1JFRlVTRUQpXG5cdFx0e1xuXHRcdFx0Ly8gUmUtZW5hYmxlIGludGVyZmFjZVxuXHRcdFx0dGhpcy5fZW5hYmxlQ29uZmlnSW50ZXJmYWNlKHRydWUpO1xuXG5cdFx0XHQvLyBTaG93IHdhcm5pbmdcblx0XHRcdHRoaXMuc2hlbGxDdHJsLnNob3dTaW1wbGVBbGVydCgnWm9uZSBjb25maWd1cmF0aW9uIGNhblxcJ3QgYmUgc2F2ZWQgYmVjYXVzZSBhbm90aGVyIFpvbmUgd2l0aCB0aGUgc2FtZSBuYW1lIGFscmVhZHkgZXhpc3RzLicsIHRydWUpO1xuXHRcdH1cblxuXHRcdC8vIEV4aXN0aW5nIHpvbmUgZGVsZXRlZFxuXHRcdGVsc2UgaWYgKGNvbW1hbmQgPT0gdGhpcy5SRVNQX1pPTkVfREVMRVRFRClcblx0XHR7XG5cdFx0XHQvLyBJZiB0aGUgY3VycmVudCB1c2VyIGlzIHRoZSBkZWxldGVyLCByZXNldCB0aGUgaW50ZXJmYWNlOyBvdGhlcndpc2UsIGp1c3Qgc2hvdyBhIG5vdGlmaWNhdGlvblxuXHRcdFx0aWYgKHVzZXJuYW1lID09IHRoaXMuc21hcnRGb3gubXlTZWxmLm5hbWUpXG5cdFx0XHR7XG5cdFx0XHRcdC8vIFJlLWVuYWJsZSBpbnRlcmZhY2Vcblx0XHRcdFx0dGhpcy5fZW5hYmxlTGlzdEludGVyZmFjZSh0cnVlKTtcblxuXHRcdFx0XHQvLyBEaXNwbGF5IG5vdGlmaWNhdGlvblxuXHRcdFx0XHR0aGlzLnNoZWxsQ3RybC5zaG93Tm90aWZpY2F0aW9uKCdab25lIHJlbW92ZWQnLCBgWm9uZSAnJHtkYXRhLmdldFV0ZlN0cmluZygnek5hbWUnKX0nIGRlbGV0ZWQgc3VjY2Vzc2Z1bGx5YCk7XG5cdFx0XHR9XG5cdFx0XHRlbHNlXG5cdFx0XHR7XG5cdFx0XHRcdC8vIEFuIGFsZXJ0IGJveCBpcyBkaXNwbGF5ZWQgaWYgdGhlIHVzZXIgaXMgY3VycmVudGx5IGVkaXRpbmcgdGhlIHNhbWUgem9uZVxuXHRcdFx0XHRpZiAoZGF0YS5nZXRJbnQoJ3pJZCcpID09IHRoaXMuX2VkaXRlZFpvbmVJZClcblx0XHRcdFx0e1xuXHRcdFx0XHRcdC8vIFNob3cgYWxlcnRcblx0XHRcdFx0XHR0aGlzLnNoZWxsQ3RybC5zaG93U2ltcGxlQWxlcnQoYEFkbWluaXN0cmF0b3IgJHt1c2VybmFtZX0gaGFzIGRlbGV0ZWQgdGhlIFpvbmUgeW91IGFyZSBjdXJyZW50bHkgbW9kaWZ5aW5nOyB5b3UgaGF2ZSB0byBjYW5jZWwgeW91ciBlZGl0aW5nLmApO1xuXG5cdFx0XHRcdFx0Ly8gRGlzYWJsZSBzdWJtaXQgYW5kIHJlbG9hZCBidXR0b25zXG5cdFx0XHRcdFx0JCgnI3puYy1yZWxvYWRCdXR0b24nKS5hdHRyKCdkaXNhYmxlZCcsIHRydWUpO1xuXHRcdFx0XHRcdCQoJyN6bmMtc3VibWl0QnV0dG9uJykuYXR0cignZGlzYWJsZWQnLCB0cnVlKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRlbHNlXG5cdFx0XHRcdHtcblx0XHRcdFx0XHQvLyBEaXNwbGF5IG5vdGlmaWNhdGlvblxuXHRcdFx0XHRcdHRoaXMuc2hlbGxDdHJsLnNob3dOb3RpZmljYXRpb24oJ1pvbmUgcmVtb3ZlZCcsIGBBZG1pbmlzdHJhdG9yICR7dXNlcm5hbWV9IGRlbGV0ZWQgWm9uZSAnJHtkYXRhLmdldFV0ZlN0cmluZygnek5hbWUnKX0nYCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gUmVzZXQgc2VsZWN0aW9uIGlmIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgaXRlbSBvciBpdHMgcGFyZW50IGlzIGJlaW5nIHJlbW92ZWRcblx0XHRcdGxldCBzZWxlY3RlZE5vZGUgPSB0aGlzLl90cmVldmlldy5zZWxlY3QoKTtcblx0XHRcdGxldCBzZWxlY3RlZERhdGFJdGVtID0gdGhpcy5fdHJlZXZpZXcuZGF0YUl0ZW0oc2VsZWN0ZWROb2RlKTtcblx0XHRcdGlmIChzZWxlY3RlZERhdGFJdGVtKVxuXHRcdFx0e1xuXHRcdFx0XHRpZiAoc2VsZWN0ZWREYXRhSXRlbS50eXBlID09IHRoaXMuSVRFTV9UWVBFX1pPTkUgJiYgc2VsZWN0ZWREYXRhSXRlbS5pZCA9PSBkYXRhLmdldEludCgneklkJykpXG5cdFx0XHRcdFx0dGhpcy5fZGVzZWxlY3RUcmVlSXRlbSgpO1xuXG5cdFx0XHRcdGlmIChzZWxlY3RlZERhdGFJdGVtLnR5cGUgPT0gdGhpcy5JVEVNX1RZUEVfUk9PTSlcblx0XHRcdFx0e1xuXHRcdFx0XHRcdGxldCBwYXJlbnREYXRhSXRlbSA9IHRoaXMuX3RyZWV2aWV3LmRhdGFJdGVtKHRoaXMuX3RyZWV2aWV3LnBhcmVudChzZWxlY3RlZE5vZGUpKTtcblxuXHRcdFx0XHRcdGlmIChwYXJlbnREYXRhSXRlbS5pZCA9PSBkYXRhLmdldEludCgneklkJykpXG5cdFx0XHRcdFx0XHR0aGlzLl9kZXNlbGVjdFRyZWVJdGVtKCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gUmVtb3ZlIHpvbmUgZnJvbSB0cmVlXG5cdFx0XHRsZXQgZGF0YUl0ZW0gPSB0aGlzLl9nZXRab25lRGF0YUl0ZW1CeUlkKGRhdGEuZ2V0SW50KCd6SWQnKSk7XG5cdFx0XHRsZXQgem9uZXNEUyA9IHRoaXMuX3RyZWV2aWV3LmRhdGFTb3VyY2U7XG5cdFx0XHR6b25lc0RTLnJlbW92ZShkYXRhSXRlbSk7XG5cdFx0XHR6b25lc0RTLnN5bmMoKTtcblx0XHR9XG5cblx0XHQvLyBab25lIGFjdGl2YXRlZFxuXHRcdGVsc2UgaWYgKGNvbW1hbmQgPT0gdGhpcy5SRVNQX1pPTkVfQUNUSVZBVEVEKVxuXHRcdHtcblx0XHRcdC8vIFNldCB6b25lIGFjdGl2YXRpb24gc3RhdHVzXG5cdFx0XHRjb25zdCB6b25lTmFtZSA9IHRoaXMuX3NldFpvbmVBY3RpdmF0aW9uU3RhdHVzKGRhdGEuZ2V0SW50KCd6SWQnKSwgZGF0YS5nZXRVdGZTdHJpbmcoJ2FjdFJvb21zJyksIHRydWUpO1xuXG5cdFx0XHQvLyBEaXNwbGF5IG5vdGlmaWNhdGlvblxuXHRcdFx0aWYgKHVzZXJuYW1lID09IHRoaXMuc21hcnRGb3gubXlTZWxmLm5hbWUpXG5cdFx0XHRcdHRoaXMuc2hlbGxDdHJsLnNob3dOb3RpZmljYXRpb24oJ1pvbmUgYWN0aXZhdGVkJywgYFpvbmUgJyR7em9uZU5hbWV9JyBhY3RpdmF0ZWQgc3VjY2Vzc2Z1bGx5YCk7XG5cdFx0XHRlbHNlXG5cdFx0XHRcdHRoaXMuc2hlbGxDdHJsLnNob3dOb3RpZmljYXRpb24oJ1pvbmUgYWN0aXZhdGVkJywgYEFkbWluaXN0cmF0b3IgJHt1c2VybmFtZX0gYWN0aXZhdGVkIFpvbmUgJyR7em9uZU5hbWV9J2ApO1xuXHRcdH1cblxuXHRcdC8vIFpvbmUgYWN0aXZhdGlvbiBlcnJvclxuXHRcdGVsc2UgaWYgKGNvbW1hbmQgPT0gdGhpcy5SRVNQX1pPTkVfQUNUSVZBVElPTl9FUlJPUilcblx0XHR7XG5cdFx0XHQvLyBTZXQgem9uZSBhY3RpdmF0aW9uIHN0YXR1c1xuXHRcdFx0dGhpcy5fc2V0Wm9uZUFjdGl2YXRpb25TdGF0dXMoZGF0YS5nZXRJbnQoJ3pJZCcpLCAnJywgZmFsc2UpO1xuXG5cdFx0XHQvLyBTaG93IGFsZXJ0XG5cdFx0XHR0aGlzLnNoZWxsQ3RybC5zaG93U2ltcGxlQWxlcnQoZGF0YS5nZXRVdGZTdHJpbmcoJ2Vycm9yJyksIHRydWUpO1xuXHRcdH1cblxuXHRcdC8qKioqKiogUk9PTVMgKioqKioqL1xuXG5cdFx0Ly8gUm9vbSBjb25maWd1cmF0aW9uIHVwZGF0ZSBjb25maXJtYXRpb25cblx0XHRlbHNlIGlmIChjb21tYW5kID09IHRoaXMuUkVTUF9ST09NX0NPTkZJR19VUERBVEVfQ09ORklSTSlcblx0XHR7XG5cdFx0XHRpZiAoZGF0YS5nZXRVdGZTdHJpbmcoJ3JOYW1lJykgIT0gbnVsbClcblx0XHRcdFx0dGhpcy5fdXBkYXRlUm9vbU5hbWVJbkxpc3QoZGF0YS5nZXRJbnQoJ3pJZCcpLCBkYXRhLmdldEludCgncklkJyksIGRhdGEuZ2V0VXRmU3RyaW5nKCdyTmFtZScpKTtcblxuXHRcdFx0Ly8gSWYgdGhlIGN1cnJlbnQgdXNlciBpcyB0aGUgdXBkYXRlciwgc2hvdyBhIG5vdGlmaWNhdGlvbjsgb3RoZXJ3aXNlLCBzaG93IGEgZGlhbG9nIGJveCBzdWdnZXN0aW5nIHRvIHJlbG9hZFxuXHRcdFx0aWYgKHVzZXJuYW1lID09IHRoaXMuc21hcnRGb3gubXlTZWxmLm5hbWUpXG5cdFx0XHR7XG5cdFx0XHRcdC8vIEVuYWJsZSBpbnRlcmZhY2Vcblx0XHRcdFx0dGhpcy5fZW5hYmxlQ29uZmlnSW50ZXJmYWNlKHRydWUpO1xuXG5cdFx0XHRcdC8vIERpc3BsYXkgbm90aWZpY2F0aW9uXG5cdFx0XHRcdHRoaXMuc2hlbGxDdHJsLnNob3dOb3RpZmljYXRpb24oJ1Jvb20gbW9kaWZpZWQnLCBgUm9vbSBzZXR0aW5ncyB1cGRhdGVkIHN1Y2Nlc3NmdWxseTsgY2hhbmdlcyB3aWxsIGJlIGFwcGxpZWQgb24gbmV4dCA8c3Ryb25nPnNlcnZlciByZXN0YXJ0PC9zdHJvbmc+YCk7XG5cblx0XHRcdFx0Ly8gUmVzZXQgdGhlICdtb2RpZmllZCcgZmxhZ1xuXHRcdFx0XHR0aGlzLl9pbnRlcmZhY2VCdWlsZGVyLnJlc2V0SXNNb2RpZmllZCgpO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZVxuXHRcdFx0e1xuXHRcdFx0XHQvLyBBbiBhbGVydCBib3ggaXMgZGlzcGxheWVkIGlmIHRoZSB1c2VyIGlzIGN1cnJlbnRseSBlZGl0aW5nIHRoZSBzYW1lIHJvb21cblx0XHRcdFx0aWYgKGRhdGEuZ2V0SW50KCdySWQnKSA9PSB0aGlzLl9lZGl0ZWRSb29tSWQpXG5cdFx0XHRcdHtcblx0XHRcdFx0XHQvLyBTaG93IGFsZXJ0XG5cdFx0XHRcdFx0dGhpcy5zaGVsbEN0cmwuc2hvd1NpbXBsZUFsZXJ0KGBBZG1pbmlzdHJhdG9yICR7dXNlcm5hbWV9IGhhcyBtb2RpZmllZCB0aGUgUm9vbSB5b3UgYXJlIGN1cnJlbnRseSBlZGl0aW5nOyBwbGVhc2UgcmVsb2FkIHRvIHVwZGF0ZSB5b3VyIHZpZXcuYCk7XG5cblx0XHRcdFx0XHQvLyBEaXNhYmxlIHN1Ym1pdCBidXR0b25cblx0XHRcdFx0XHQkKCcjem5jLXN1Ym1pdEJ1dHRvbicpLmF0dHIoJ2Rpc2FibGVkJywgdHJ1ZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZVxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0Ly8gRGlzcGxheSBub3RpZmljYXRpb25cblx0XHRcdFx0XHRpZiAoZGF0YS5nZXRVdGZTdHJpbmcoJ3JOYW1lJykgIT0gbnVsbClcblx0XHRcdFx0XHRcdHRoaXMuc2hlbGxDdHJsLnNob3dOb3RpZmljYXRpb24oJ1Jvb20gcmVuYW1lZCcsIGBBZG1pbmlzdHJhdG9yICR7dXNlcm5hbWV9IGhhcyBjaGFuZ2VkIHRoZSBuYW1lIG9uIG9uZSBvZiB0aGUgUm9vbXNgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIE5ldyByb29tIGFkZGVkXG5cdFx0ZWxzZSBpZiAoY29tbWFuZCA9PSB0aGlzLlJFU1BfUk9PTV9BRERFRClcblx0XHR7XG5cdFx0XHRjb25zdCByb29tRGF0YSA9IGRhdGEuZ2V0U0ZTT2JqZWN0KCdyb29tJyk7XG5cdFx0XHRjb25zdCB6b25lSWQgPSBkYXRhLmdldEludCgneklkJyk7XG5cblx0XHRcdGxldCB6b25lc0RTID0gdGhpcy5fdHJlZXZpZXcuZGF0YVNvdXJjZTtcblx0XHRcdGxldCB6b25lSXRlbSA9IHpvbmVzRFMuZ2V0KHpvbmVJZCk7XG5cblx0XHRcdC8vIElmIHRoZSBjdXJyZW50IHVzZXIgaXMgdGhlIHVwZGF0ZXIsIHJlc2V0IHRoZSBpbnRlcmZhY2U7IG90aGVyd2lzZSwganVzdCBzaG93IGEgbm90aWZpY2F0aW9uXG5cdFx0XHRpZiAodXNlcm5hbWUgPT0gdGhpcy5zbWFydEZveC5teVNlbGYubmFtZSlcblx0XHRcdHtcblx0XHRcdFx0Ly8gUmVzZXQgaW50ZXJmYWNlXG5cdFx0XHRcdHRoaXMuX29uQ2FuY2VsQ2xpY2soKTtcblxuXHRcdFx0XHQvLyBEaXNwbGF5IG5vdGlmaWNhdGlvblxuXHRcdFx0XHR0aGlzLnNoZWxsQ3RybC5zaG93Tm90aWZpY2F0aW9uKCdSb29tIGFkZGVkJywgYFJvb20gJyR7cm9vbURhdGEuZ2V0VXRmU3RyaW5nKCduYW1lJyl9JyBjcmVhdGVkIHN1Y2Nlc3NmdWxseWApO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZVxuXHRcdFx0e1xuXHRcdFx0XHQvLyBEaXNwbGF5IG5vdGlmaWNhdGlvblxuXHRcdFx0XHR0aGlzLnNoZWxsQ3RybC5zaG93Tm90aWZpY2F0aW9uKCdSb29tIGFkZGVkJywgYEFkbWluaXN0cmF0b3IgJHt1c2VybmFtZX0gY3JlYXRlZCBSb29tICcke3Jvb21EYXRhLmdldFV0ZlN0cmluZygnbmFtZScpfScgaW4gWm9uZSAnJHt6b25lSXRlbS5uYW1lfSdgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQWRkIG5ldyByb29tIHRvIHRyZWVcblx0XHRcdHpvbmVJdGVtLmFwcGVuZCh0aGlzLl9jcmVhdGVSb29tT2JqZWN0KHJvb21EYXRhLCB6b25lSWQpKTtcblx0XHRcdHpvbmVzRFMuc3luYygpO1xuXG5cdFx0XHQvLyBFeHBhbmQgem9uZSBub2RlIHdoZXJlIHJvb20gd2FzIGFkZGVkXG5cdFx0XHR0aGlzLl90cmVldmlldy5leHBhbmQodGhpcy5fdHJlZXZpZXcuc2VsZWN0KCkpO1xuXHRcdH1cblxuXHRcdC8vIE5ldyByb29tIGNyZWF0aW9uIHJlZnVzZWQgZHVlIHRvIGludmFsaWQgcm9vbSBuYW1lXG5cdFx0ZWxzZSBpZiAoY29tbWFuZCA9PSB0aGlzLlJFU1BfUk9PTV9SRUZVU0VEKVxuXHRcdHtcblx0XHRcdC8vIFJlLWVuYWJsZSBpbnRlcmZhY2Vcblx0XHRcdHRoaXMuX2VuYWJsZUNvbmZpZ0ludGVyZmFjZSh0cnVlKTtcblxuXHRcdFx0Ly8gU2hvdyB3YXJuaW5nXG5cdFx0XHR0aGlzLnNoZWxsQ3RybC5zaG93U2ltcGxlQWxlcnQoJ1Jvb20gY29uZmlndXJhdGlvbiBjYW5cXCd0IGJlIHNhdmVkIGJlY2F1c2UgYW5vdGhlciBSb29tIHdpdGggdGhlIHNhbWUgbmFtZSBhbHJlYWR5IGV4aXN0cy4nLCB0cnVlKTtcblx0XHR9XG5cblx0XHQvLyBFeGlzdGluZyByb29tIGRlbGV0ZWRcblx0XHRlbHNlIGlmIChjb21tYW5kID09IHRoaXMuUkVTUF9ST09NX0RFTEVURUQpXG5cdFx0e1xuXHRcdFx0bGV0IHpvbmVJdGVtID0gdGhpcy5fZ2V0Wm9uZURhdGFJdGVtQnlJZChkYXRhLmdldEludCgneklkJykpO1xuXHRcdFx0bGV0IHJvb21JdGVtID0gdGhpcy5fZ2V0Um9vbURhdGFJdGVtQnlJZChkYXRhLmdldEludCgneklkJyksIGRhdGEuZ2V0SW50KCdySWQnKSk7XG5cblx0XHRcdC8vIElmIHRoZSBjdXJyZW50IHVzZXIgaXMgdGhlIGRlbGV0ZXIsIHJlc2V0IHRoZSBpbnRlcmZhY2U7IG90aGVyd2lzZSwganVzdCBzaG93IGEgbm90aWZpY2F0aW9uXG5cdFx0XHRpZiAodXNlcm5hbWUgPT0gdGhpcy5zbWFydEZveC5teVNlbGYubmFtZSlcblx0XHRcdHtcblx0XHRcdFx0Ly8gUmUtZW5hYmxlIGludGVyZmFjZVxuXHRcdFx0XHR0aGlzLl9lbmFibGVMaXN0SW50ZXJmYWNlKHRydWUpO1xuXG5cdFx0XHRcdC8vIERpc3BsYXkgbm90aWZpY2F0aW9uXG5cdFx0XHRcdHRoaXMuc2hlbGxDdHJsLnNob3dOb3RpZmljYXRpb24oJ1Jvb20gcmVtb3ZlZCcsIGBSb29tICcke3Jvb21JdGVtLm5hbWV9JyBkZWxldGVkIHN1Y2Nlc3NmdWxseWApO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZVxuXHRcdFx0e1xuXHRcdFx0XHQvLyBBbiBhbGVydCBib3ggaXMgZGlzcGxheWVkIGlmIHRoZSB1c2VyIGlzIGN1cnJlbnRseSBlZGl0aW5nIHRoZSBzYW1lIHJvb21cblx0XHRcdFx0aWYgKGRhdGEuZ2V0SW50KCdySWQnKSA9PSB0aGlzLl9lZGl0ZWRSb29tSWQpXG5cdFx0XHRcdHtcblx0XHRcdFx0XHQvLyBTaG93IGFsZXJ0XG5cdFx0XHRcdFx0dGhpcy5zaGVsbEN0cmwuc2hvd1NpbXBsZUFsZXJ0KGBBZG1pbmlzdHJhdG9yICR7dXNlcm5hbWV9IGhhcyBkZWxldGVkIHRoZSBSb29tIHlvdSBhcmUgY3VycmVudGx5IG1vZGlmeWluZzsgeW91IGhhdmUgdG8gY2FuY2VsIHlvdXIgZWRpdGluZy5gKTtcblxuXHRcdFx0XHRcdC8vIERpc2FibGUgc3VibWl0IGFuZCByZWxvYWQgYnV0dG9uc1xuXHRcdFx0XHRcdCQoJyN6bmMtcmVsb2FkQnV0dG9uJykuYXR0cignZGlzYWJsZWQnLCB0cnVlKTtcblx0XHRcdFx0XHQkKCcjem5jLXN1Ym1pdEJ1dHRvbicpLmF0dHIoJ2Rpc2FibGVkJywgdHJ1ZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZVxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0Ly8gRGlzcGxheSBub3RpZmljYXRpb25cblx0XHRcdFx0XHR0aGlzLnNoZWxsQ3RybC5zaG93Tm90aWZpY2F0aW9uKCdSb29tIHJlbW92ZWQnLCBgQWRtaW5pc3RyYXRvciAke3VzZXJuYW1lfSBkZWxldGVkIFJvb20gJyR7cm9vbUl0ZW0ubmFtZX0nIGZyb20gWm9uZSAnJHt6b25lSXRlbS5uYW1lfSdgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZXNldCBzZWxlY3Rpb24gaWYgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBpdGVtIG9yIGl0cyBwYXJlbnQgaXMgYmVpbmcgcmVtb3ZlZFxuXHRcdFx0bGV0IHNlbGVjdGVkTm9kZSA9IHRoaXMuX3RyZWV2aWV3LnNlbGVjdCgpO1xuXHRcdFx0bGV0IHNlbGVjdGVkRGF0YUl0ZW0gPSB0aGlzLl90cmVldmlldy5kYXRhSXRlbShzZWxlY3RlZE5vZGUpO1xuXHRcdFx0aWYgKHNlbGVjdGVkRGF0YUl0ZW0pXG5cdFx0XHR7XG5cdFx0XHRcdGlmIChzZWxlY3RlZERhdGFJdGVtLnR5cGUgPT0gdGhpcy5JVEVNX1RZUEVfUk9PTSAmJiBzZWxlY3RlZERhdGFJdGVtLmlkID09IGRhdGEuZ2V0SW50KCdySWQnKSlcblx0XHRcdFx0XHR0aGlzLl9kZXNlbGVjdFRyZWVJdGVtKCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJlbW92ZSByb29tIGZyb20gdHJlZVxuXHRcdFx0em9uZUl0ZW0uY2hpbGRyZW4ucmVtb3ZlKHJvb21JdGVtKTtcblx0XHRcdHRoaXMuX3RyZWV2aWV3LmRhdGFTb3VyY2Uuc3luYygpO1xuXHRcdH1cblxuXHRcdC8vIGVsc2UgaWYgKClcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vIFVJIEVWRU5UIExJU1RFTkVSU1xuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdF9vblRyZWVJdGVtRG91YmxlQ2xpY2soZSlcblx0e1xuXHRcdC8vIEdldCBldmVudCB0YXJnZXQncyBjbG9zZXN0IHRyZWUgbm9kZVxuXHRcdGxldCB0cmVlTm9kZSA9ICQoZS50YXJnZXQpLmNsb3Nlc3QoJy5rLWl0ZW1bcm9sZT10cmVlaXRlbV0nKTtcblxuXHRcdC8vIEdldCBhc3NvY2lhdGVkIGRhdGEgaXRlbVxuXHRcdGxldCBkYXRhSXRlbSA9IHRoaXMuX3RyZWV2aWV3LmRhdGFJdGVtKHRyZWVOb2RlKTtcblxuXHRcdC8vIExvYWQgY29uZmlndXJhdGlvblxuXHRcdHRoaXMuX2xvYWRDb25maWd1cmF0aW9uKGRhdGFJdGVtLnR5cGUpO1xuXHR9XG5cblx0X29uWm9uZVJvb21DaGFuZ2UoKVxuXHR7XG5cdFx0Ly8gUmVzZXQgdXRpbGl0eSBidXR0b25zXG5cdFx0dGhpcy5fc2V0VXRpbGl0eUJ1dHRvbnNTdGF0ZSh0aGlzLl9zZWxlY3RlZEl0ZW0pO1xuXHR9XG5cblx0Ly8gVXRpbGl0eSBidXR0b25zIGxpc3RlbmVyc1xuXG5cdF9vbkFkZFpvbmVDbGljaygpXG5cdHtcblx0XHQvLyBEZXNlbGVjdCBsaXN0IGl0ZW1cblx0XHR0aGlzLl9kZXNlbGVjdFRyZWVJdGVtKCk7XG5cblx0XHQvLyBMb2FkIGNvbmZpZ3VyYXRpb25cblx0XHR0aGlzLl9sb2FkQ29uZmlndXJhdGlvbih0aGlzLklURU1fVFlQRV9aT05FKTtcblx0fVxuXG5cdF9vbkFkZFJvb21DbGljaygpXG5cdHtcblx0XHQvLyBTZWxlY3QgcGFyZW50IGxpc3QgaXRlbVxuXHRcdHRoaXMuX3NlbGVjdFBhcmVudFRyZWVJdGVtKCk7XG5cblx0XHQvLyBMb2FkIGNvbmZpZ3VyYXRpb25cblx0XHR0aGlzLl9sb2FkQ29uZmlndXJhdGlvbih0aGlzLklURU1fVFlQRV9ST09NKTtcblx0fVxuXG5cdF9vbkVkaXRDbGljaygpXG5cdHtcblx0XHQvLyBMb2FkIGNvbmZpZ3VyYXRpb25cblx0XHR0aGlzLl9sb2FkQ29uZmlndXJhdGlvbih0aGlzLl9zZWxlY3RlZEl0ZW0udHlwZSk7XG5cdH1cblxuXHRfb25SZW1vdmVDbGljaygpXG5cdHtcblx0XHR0aGlzLnNoZWxsQ3RybC5zaG93Q29uZmlybVdhcm5pbmcoYEFyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGUgdGhlIHNlbGVjdGVkICR7dGhpcy5fc2VsZWN0ZWRJdGVtLnR5cGUgPT0gdGhpcy5JVEVNX1RZUEVfWk9ORSA/ICdab25lJyA6ICdSb29tJ30gY29uZmlndXJhdGlvbj9gLCAkLnByb3h5KHRoaXMuX29uUmVtb3ZlQ29uZmlybSwgdGhpcykpO1xuXHR9XG5cblx0X29uUmVtb3ZlQ29uZmlybSgpXG5cdHtcblx0XHQvLyBEaXNhYmxlIHpvbmUvcm9vbSBzZWxlY3Rpb24gbGlzdFxuXHRcdHRoaXMuX2VuYWJsZUxpc3RJbnRlcmZhY2UoZmFsc2UpO1xuXG5cdFx0bGV0IHBhcmFtcyA9IG5ldyBTRlMyWC5TRlNPYmplY3QoKTtcblxuXHRcdC8vIFJlcXVlc3Qgem9uZSByZW1vdmFsXG5cdFx0aWYgKHRoaXMuX3NlbGVjdGVkSXRlbS50eXBlID09IHRoaXMuSVRFTV9UWVBFX1pPTkUpXG5cdFx0e1xuXHRcdFx0cGFyYW1zLnB1dEludCgneklkJywgdGhpcy5fc2VsZWN0ZWRJdGVtLmlkKTtcblx0XHRcdHRoaXMuc2VuZEV4dGVuc2lvblJlcXVlc3QodGhpcy5SRVFfREVMRVRFX1pPTkVfQ09ORklHLCBwYXJhbXMpO1xuXHRcdH1cblx0XHRlbHNlXG5cdFx0e1xuXHRcdFx0cGFyYW1zLnB1dEludCgneklkJywgdGhpcy5fc2VsZWN0ZWRJdGVtUGFyZW50LmlkKTtcblx0XHRcdHBhcmFtcy5wdXRJbnQoJ3JJZCcsIHRoaXMuX3NlbGVjdGVkSXRlbS5pZCk7XG5cdFx0XHR0aGlzLnNlbmRFeHRlbnNpb25SZXF1ZXN0KHRoaXMuUkVRX0RFTEVURV9ST09NX0NPTkZJRywgcGFyYW1zKTtcblx0XHR9XG5cdH1cblxuXHRfb25BY3RpdmF0ZUNsaWNrKClcblx0e1xuXHRcdC8vIEdldCBzZWxlY3RlZCBkYXRhIGl0ZW1cblx0XHRpZiAodGhpcy5fc2VsZWN0ZWRJdGVtLnR5cGUgPT0gdGhpcy5JVEVNX1RZUEVfWk9ORSlcblx0XHR7XG5cdFx0XHRsZXQgcGFyYW1zID0gbmV3IFNGUzJYLlNGU09iamVjdCgpO1xuXHRcdFx0cGFyYW1zLnB1dEludCgneklkJywgdGhpcy5fc2VsZWN0ZWRJdGVtLmlkKTtcblxuXHRcdFx0dGhpcy5zZW5kRXh0ZW5zaW9uUmVxdWVzdCh0aGlzLlJFUV9BQ1RJVkFURV9aT05FLCBwYXJhbXMpO1xuXHRcdH1cblx0fVxuXG5cdC8vIENvbmZpZ3VyYXRpb24gYnV0dG9ucyBsaXN0ZW5lcnNcblxuXHRfb25DYW5jZWxDbGljaygpXG5cdHtcblx0XHQvLyBFbmFibGUgem9uZS9yb29tIHNlbGVjdGlvbiBsaXN0c1xuXHRcdHRoaXMuX2VuYWJsZUxpc3RJbnRlcmZhY2UodHJ1ZSk7XG5cblx0XHQvLyBEaXNhYmxlIGNvbmZpZ3VyYXRpb24gaW50ZXJmYWNlXG5cdFx0dGhpcy5fZW5hYmxlQ29uZmlnSW50ZXJmYWNlKGZhbHNlKTtcblxuXHRcdC8vIENsZWFyIG1haW4gY29udGFpbmVyXG5cdFx0dGhpcy5fcmVzZXRUYWJzQ29udGFpbmVyKGZhbHNlLCB0cnVlKTtcblxuXHRcdC8vIFNldCBpc0VkaXRpbmcgZmxhZ1xuXHRcdHRoaXMuX2lzRWRpdGluZyA9IGZhbHNlO1xuXHRcdHRoaXMuX2VkaXRlZEl0ZW1UeXBlID0gJyc7XG5cblx0XHQvLyBTd2l0Y2ggcGFuZWxcblx0XHR0aGlzLl9zd2l0Y2hQYW5lbCgnem5jLXNpZGViYXJQYW5lbCcpO1xuXHR9XG5cblx0X29uUmVsb2FkQ2xpY2soKVxuXHR7XG5cdFx0Ly8gSGlkZSB2YWxpZGF0aW9uIG1lc3NhZ2VzXG5cdFx0dGhpcy5faW50ZXJmYWNlQnVpbGRlci5yZXNldFZhbGlkYXRpb24oKTtcblxuXHRcdC8vIFJlbG9hZCBjb25maWd1cmF0aW9uXG5cdFx0dGhpcy5fbG9hZENvbmZpZ3VyYXRpb24odGhpcy5fZWRpdGVkSXRlbVR5cGUsIGZhbHNlKTtcblx0fVxuXG5cdF9vblN1Ym1pdENsaWNrKClcblx0e1xuXHRcdC8vIENoZWNrIHZhbGlkaXR5XG5cdFx0aWYgKHRoaXMuX2ludGVyZmFjZUJ1aWxkZXIuY2hlY2tJc1ZhbGlkKCkpXG5cdFx0e1xuXHRcdFx0bGV0IGNoYW5nZXMgPSB0aGlzLl9pbnRlcmZhY2VCdWlsZGVyLmdldENoYW5nZWREYXRhKCk7XG5cblx0XHRcdGlmIChjaGFuZ2VzLnNpemUoKSA+IDApXG5cdFx0XHR7XG5cdFx0XHRcdC8vY29uc29sZS5sb2coY2hhbmdlcy5nZXREdW1wKCkpXG5cblx0XHRcdFx0Ly8gSW4gY2FzZSB0aGUgem9uZS9yb29tIG5hbWUgY2hhbmdlZCwgY2hlY2sgaXQgYWdhaW5zdCB0aGUgbGlzdCAoZHVwbGljYXRlIG5hbWVzIG5vdCBhbGxvd2VkISlcblx0XHRcdFx0aWYgKHRoaXMuX3ZhbGlkYXRlTmFtZShjaGFuZ2VzKSlcblx0XHRcdFx0e1xuXHRcdFx0XHRcdC8vIERpc2FibGUgY29uZmlndXJhdGlvbiBpbnRlcmZhY2Vcblx0XHRcdFx0XHR0aGlzLl9lbmFibGVDb25maWdJbnRlcmZhY2UoZmFsc2UpO1xuXG5cdFx0XHRcdFx0Ly8gU2VuZCBzZXR0aW5ncyB0byBzZXJ2ZXIgaW5zdGFuY2Vcblx0XHRcdFx0XHRsZXQgcGFyYW1zID0gbmV3IFNGUzJYLlNGU09iamVjdCgpO1xuXHRcdFx0XHRcdHBhcmFtcy5wdXRTRlNBcnJheSgnc2V0dGluZ3MnLCBjaGFuZ2VzKTtcblx0XHRcdFx0XHRwYXJhbXMucHV0Qm9vbCgnYmFja3VwJywgJCgnI3puYy1iYWNrdXBDaGVjaycpLnByb3AoJ2NoZWNrZWQnKSk7XG5cdFx0XHRcdFx0cGFyYW1zLnB1dEludCgneklkJywgdGhpcy5fZWRpdGVkWm9uZUlkKTtcblx0XHRcdFx0XHRwYXJhbXMucHV0SW50KCdySWQnLCB0aGlzLl9lZGl0ZWRSb29tSWQpO1xuXG5cdFx0XHRcdFx0aWYgKHRoaXMuX2VkaXRlZEl0ZW1UeXBlID09IHRoaXMuSVRFTV9UWVBFX1pPTkUpXG5cdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0Ly8gU3VibWl0IHpvbmUgc2V0dGluZ3Ncblx0XHRcdFx0XHRcdGlmICh0aGlzLl9lZGl0ZWRab25lSWQgPiAtMSlcblx0XHRcdFx0XHRcdFx0dGhpcy5zZW5kRXh0ZW5zaW9uUmVxdWVzdCh0aGlzLlJFUV9TQVZFX1pPTkVfQ09ORklHLCBwYXJhbXMpO1xuXHRcdFx0XHRcdFx0ZWxzZVxuXHRcdFx0XHRcdFx0XHR0aGlzLnNlbmRFeHRlbnNpb25SZXF1ZXN0KHRoaXMuUkVRX05FV19aT05FX0NPTkZJRywgcGFyYW1zKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZWxzZVxuXHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdC8vIFN1Ym1pdCByb29tIHNldHRpbmdzXG5cdFx0XHRcdFx0XHRpZiAodGhpcy5fZWRpdGVkUm9vbUlkID4gLTEpXG5cdFx0XHRcdFx0XHRcdHRoaXMuc2VuZEV4dGVuc2lvblJlcXVlc3QodGhpcy5SRVFfU0FWRV9ST09NX0NPTkZJRywgcGFyYW1zKTtcblx0XHRcdFx0XHRcdGVsc2Vcblx0XHRcdFx0XHRcdFx0dGhpcy5zZW5kRXh0ZW5zaW9uUmVxdWVzdCh0aGlzLlJFUV9ORVdfUk9PTV9DT05GSUcsIHBhcmFtcyk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdGVsc2Vcblx0XHRcdFx0e1xuXHRcdFx0XHRcdC8vIFNob3cgYWxlcnRcblx0XHRcdFx0XHR0aGlzLnNoZWxsQ3RybC5zaG93U2ltcGxlQWxlcnQoYFVuYWJsZSB0byBzdWJtaXQgY29uZmlndXJhdGlvbiBiZWNhdXNlIHRoZSAke2NhcGl0YWxpemVGaXJzdCh0aGlzLl9lZGl0ZWRJdGVtVHlwZSl9IG5hbWUgYWxyZWFkeSBleGlzdHM7IGR1cGxpY2F0ZSBuYW1lcyBhcmUgbm90IGFsbG93ZWQuYCwgdHJ1ZSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0ZWxzZVxuXHRcdHtcblx0XHRcdC8vIFNob3cgYWxlcnRcblx0XHRcdHRoaXMuc2hlbGxDdHJsLnNob3dTaW1wbGVBbGVydCgnVW5hYmxlIHRvIHN1Ym1pdCBjb25maWd1cmF0aW9uIGNoYW5nZXMgZHVlIHRvIGFuIGludmFsaWQgdmFsdWU7IHBsZWFzZSB2ZXJpZnkgdGhlIGhpZ2hsaWdodGVkIGZvcm0gZmllbGRzIGluIGFsbCB0YWJzLicsIHRydWUpO1xuXHRcdH1cblx0fVxuXG5cdF9vbkNvbmZpZ1ZhbHVlU2V0KGUpIC8vIFNBTUUgTUVUSE9EIERVUExJQ0FURUQgSU4gem9uZS1tb25pdG9yLmpzXG5cdHtcblx0XHRjb25zdCBjb25maWdQYXJhbSA9IGUudGFyZ2V0LmRhdGE7XG5cblx0XHQvLyBIYW5kbGUgZXh0ZW5zaW9uIG5hbWUvdHlwZSBkcm9wZG93bnMgdXBkYXRlIGFuZCB1cGRhdGUgdGhlIG1haW4gY2xhc3MgZHJvcGRvd24gZGF0YXNvdXJjZSBhY2NvcmRpbmdseVxuXHRcdGlmIChjb25maWdQYXJhbS5uYW1lID09ICdleHRlbnNpb24ubmFtZScgfHwgY29uZmlnUGFyYW0ubmFtZSA9PSAnZXh0ZW5zaW9uLnR5cGUnIHx8IGNvbmZpZ1BhcmFtLm5hbWUgPT0gJ2V4dGVuc2lvbi5maWx0ZXJDbGFzcycpXG5cdFx0e1xuXHRcdFx0Ly8gQWxsIGludm9sdmVkIENvbmZpZ0Zvcm1JdGVtcyBtdXN0IGJlIGF2YWlsYWJsZSBhbmQgaW5pdGlhbGl6ZWQgdG8gcHJvY2VlZFxuXHRcdFx0Y29uc3QgbmFtZUZvcm1JdGVtID0gdGhpcy5faW50ZXJmYWNlQnVpbGRlci5nZXRDb25maWdGb3JtSXRlbSgnZXh0ZW5zaW9uLm5hbWUnKTtcblx0XHRcdGNvbnN0IHR5cGVGb3JtSXRlbSA9IHRoaXMuX2ludGVyZmFjZUJ1aWxkZXIuZ2V0Q29uZmlnRm9ybUl0ZW0oJ2V4dGVuc2lvbi50eXBlJyk7XG5cdFx0XHRjb25zdCBjbGFzc0Zvcm1JdGVtID0gdGhpcy5faW50ZXJmYWNlQnVpbGRlci5nZXRDb25maWdGb3JtSXRlbSgnZXh0ZW5zaW9uLmZpbGUnKTtcblx0XHRcdGNvbnN0IGZpbHRlckZvcm1JdGVtID0gdGhpcy5faW50ZXJmYWNlQnVpbGRlci5nZXRDb25maWdGb3JtSXRlbSgnZXh0ZW5zaW9uLmZpbHRlckNsYXNzJyk7XG5cblx0XHRcdGlmIChuYW1lRm9ybUl0ZW0gIT0gbnVsbCAmJiB0eXBlRm9ybUl0ZW0gIT0gbnVsbCAmJiBjbGFzc0Zvcm1JdGVtICE9IG51bGwgJiYgZmlsdGVyRm9ybUl0ZW0gIT0gbnVsbClcblx0XHRcdHtcblx0XHRcdFx0Y29uc3Qgc291cmNlID0gbmFtZUZvcm1JdGVtLmRhdGE7XG5cdFx0XHRcdGxldCBjbGFzc2VzTGlzdCA9IFtdO1xuXG5cdFx0XHRcdGxldCBkYXRhID0gc291cmNlLnRyaWdnZXJEYXRhO1xuXHRcdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEuc2l6ZSgpOyBpKyspXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRsZXQgZXh0ID0gZGF0YS5nZXRTRlNPYmplY3QoaSk7XG5cblx0XHRcdFx0XHRpZiAoZXh0LmdldFV0ZlN0cmluZygnbmFtZScpID09IG5hbWVGb3JtSXRlbS5kYXRhLnZhbHVlICYmIGV4dC5nZXRVdGZTdHJpbmcoJ3R5cGUnKSA9PSB0eXBlRm9ybUl0ZW0uZGF0YS52YWx1ZSlcblx0XHRcdFx0XHR7XG5cdFx0XHRcdFx0XHRsZXQgY2xhc3NlcyA9IGV4dC5nZXRVdGZTdHJpbmcoJ2NsYXNzZXNTdHJpbmcnKS5zcGxpdCgnLCcpO1xuXG5cdFx0XHRcdFx0XHRpZiAoZmlsdGVyRm9ybUl0ZW0uZGF0YS52YWx1ZSA9PSB0cnVlKVxuXHRcdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0XHRsZXQgZmlsdGVyZWRDbGFzc2VzID0gY2xhc3Nlcy5maWx0ZXIoZmlsdGVyQ2xhc3NOYW1lKTtcblx0XHRcdFx0XHRcdFx0Y2xhc3NlcyA9IGZpbHRlcmVkQ2xhc3Nlcztcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Y2xhc3Nlc0xpc3QgPSBjbGFzc2VzTGlzdC5jb25jYXQoY2xhc3Nlcyk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0bGV0IGN1cnJlbnRDbGFzcyA9IGNsYXNzRm9ybUl0ZW0uZGF0YS52YWx1ZTtcblxuXHRcdFx0XHQvLyBJZiB0aGUgY2xhc3NlcyBsaXN0IGRvZXNuJ3QgY29udGFpbiB0aGUgY3VycmVudCB2YWx1ZSwgY3JlYXRlIGFuIGVtcHR5IGVudHJ5IGFuZCByZXNldCB0aGUgdmFsdWVcblx0XHRcdFx0aWYgKGNsYXNzZXNMaXN0LmluZGV4T2YoY3VycmVudENsYXNzKSA8IDApXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRpZiAoY2xhc3Nlc0xpc3QubGVuZ3RoID09IDApXG5cdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0Y2xhc3Nlc0xpc3QucHVzaCgnJyk7XG5cdFx0XHRcdFx0XHRjdXJyZW50Q2xhc3MgPSAnJztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZWxzZVxuXHRcdFx0XHRcdFx0Y3VycmVudENsYXNzID0gY2xhc3Nlc0xpc3RbMF07XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRsZXQgbWFpbkNsYXNzRHJvcERvd24gPSBjbGFzc0Zvcm1JdGVtLl9pbm5lcldpZGdldDtcblx0XHRcdFx0bWFpbkNsYXNzRHJvcERvd24uc2V0RGF0YVNvdXJjZShjbGFzc2VzTGlzdCk7XG5cblx0XHRcdFx0Y2xhc3NGb3JtSXRlbS5kYXRhLnZhbHVlID0gY3VycmVudENsYXNzO1xuXHRcdFx0XHRjbGFzc0Zvcm1JdGVtLl9zZXRXaWRnZXRWYWx1ZSgpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vIFBSSVZBVEUgTUVUSE9EU1xuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdF9lbmFibGVMaXN0SW50ZXJmYWNlKGVuYWJsZWQpXG5cdHtcblx0XHQkKCcjem5jLXV0aWxCdXR0b25zJykuYXR0cignZGlzYWJsZWQnLCAhZW5hYmxlZCk7XG5cdFx0JCgnI3puYy10cmVlVmlldycpLmF0dHIoJ2Rpc2FibGVkJywgIWVuYWJsZWQpO1xuXHR9XG5cblx0X3NldFV0aWxpdHlCdXR0b25zU3RhdGUoZGF0YUl0ZW0gPSBudWxsKVxuXHR7XG5cdFx0bGV0IGRpc2FibGUgPSB0cnVlO1xuXG5cdFx0aWYgKGRhdGFJdGVtKVxuXHRcdHtcblx0XHRcdC8vIEVuYWJsZSAnYWN0aXZhdGUgem9uZScgYnV0dG9uIGlmIHpvbmUgaXMgaW5hY3RpdmVcblx0XHRcdCQoJyN6bmMtYWN0aXZhdGVCdXR0b24nKS5hdHRyKCdkaXNhYmxlZCcsIChkYXRhSXRlbS50eXBlICE9IHRoaXMuSVRFTV9UWVBFX1pPTkUgfHwgZGF0YUl0ZW0uYWN0aXZlKSk7XG5cblx0XHRcdGRpc2FibGUgPSBmYWxzZTtcblx0XHR9XG5cdFx0ZWxzZVxuXHRcdHtcblx0XHRcdC8vIERpc2FibGUgJ2FjdGl2YXRlIHpvbmUnIGJ1dHRvblxuXHRcdFx0JCgnI3puYy1hY3RpdmF0ZUJ1dHRvbicpLmF0dHIoJ2Rpc2FibGVkJywgdHJ1ZSk7XG5cdFx0fVxuXG5cdFx0Ly8gRW5hYmxlL2Rpc2FibGUgb3RoZXIgdXRpbGl0eSBidXR0b25zXG5cdFx0JCgnI3puYy1hZGRab25lQnV0dG9uJykuYXR0cignZGlzYWJsZWQnLCBmYWxzZSk7IC8vIEFsd2F5cyBlbmFibGVkXG5cdFx0JCgnI3puYy1hZGRSb29tQnV0dG9uJykuYXR0cignZGlzYWJsZWQnLCBkaXNhYmxlKTtcblx0XHQkKCcjem5jLWVkaXRCdXR0b24nKS5hdHRyKCdkaXNhYmxlZCcsIGRpc2FibGUpO1xuXHRcdCQoJyN6bmMtcmVtb3ZlQnV0dG9uJykuYXR0cignZGlzYWJsZWQnLCBkaXNhYmxlKTtcblx0fVxuXG5cdF9lbmFibGVDb25maWdJbnRlcmZhY2UoZW5hYmxlZClcblx0e1xuXHRcdCQoJyN6bmMtY2FuY2VsQnV0dG9uJykuYXR0cignZGlzYWJsZWQnLCAhZW5hYmxlZCk7XG5cdFx0JCgnI3puYy1yZWxvYWRCdXR0b24nKS5hdHRyKCdkaXNhYmxlZCcsICFlbmFibGVkKTtcblx0XHQkKCcjem5jLXN1Ym1pdEJ1dHRvbicpLmF0dHIoJ2Rpc2FibGVkJywgIWVuYWJsZWQpO1xuXHRcdCQoJyN6bmMtYmFja3VwQ2hlY2snKS5hdHRyKCdkaXNhYmxlZCcsICFlbmFibGVkKTtcblxuXHRcdHRoaXMuX2ludGVyZmFjZUJ1aWxkZXIuZGlzYWJsZUludGVyZmFjZSghZW5hYmxlZCk7XG5cblx0XHQvLyBBbHNvIHN3aXRjaCB2aWV3IHdoZW4gZW5hYmxlZFxuXHRcdGlmIChlbmFibGVkKVxuXHRcdFx0dGhpcy5fc3dpdGNoVmlldygnem5jLW1haW4nKTtcblx0fVxuXG5cdF9zd2l0Y2hWaWV3KHZpZXdJZClcblx0e1xuXHRcdGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd6bmMtdmlld3N0YWNrJykuc2VsZWN0ZWRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodmlld0lkKTtcblx0fVxuXG5cdF9jbGVhclRhYnMoKVxuXHR7XG5cdFx0Ly8gRGVzdHJveSBzY3JvbGxpbmcgdGFic1xuXHRcdCQoJyN6bmMtdGFiTmF2aWdhdG9yICN0YWJzJykuc2Nyb2xsaW5nVGFicygnZGVzdHJveScpO1xuXG5cdFx0Ly8gUmVtb3ZlIGFsbCB0YWIgbmF2aWdhdG9yIGNvbnRlbnRcblx0XHR0aGlzLl9pbnRlcmZhY2VCdWlsZGVyLmRlc3Ryb3lJbnRlcmZhY2UoKTtcblxuXHRcdC8vIFNldCBmbGFnIHRvIHJlLWluaXRpYWxpemUgdGFicyBpZiBuZWVkZWRcblx0XHR0aGlzLl9yZWluaXRUYWJzID0gdHJ1ZTtcblx0fVxuXG5cdF9wb3B1bGF0ZVRyZWUoZGF0YSlcblx0e1xuXHRcdGxldCB6RGF0YSA9IGRhdGEuZ2V0U0ZTQXJyYXkoJ3pvbmVzJyk7XG5cblx0XHRsZXQgem9uZXNBcnIgPSBbXTtcblx0XHRmb3IgKGxldCB6ID0gMDsgeiA8IHpEYXRhLnNpemUoKTsgeisrKVxuXHRcdFx0em9uZXNBcnIucHVzaCggdGhpcy5fY3JlYXRlWm9uZU9iamVjdCh6RGF0YS5nZXRTRlNPYmplY3QoeikpICk7XG5cblx0XHQvLyBDcmVhdGUgZGF0YXNvdXJjZVxuXHRcdGxldCB6b25lcyA9IG5ldyBrZW5kby5kYXRhLkhpZXJhcmNoaWNhbERhdGFTb3VyY2Uoe1xuICAgICAgICAgICAgZGF0YTogem9uZXNBcnIsXG5cdFx0XHRzb3J0OiB7XG5cdFx0XHRcdGZpZWxkOiAnbmFtZScsXG5cdFx0XHRcdGRpcjogJ2FzYydcblx0XHRcdH0sXG4gICAgICAgICAgICBzY2hlbWE6IHtcbiAgICAgICAgICAgICAgICBtb2RlbDoge1xuXHRcdFx0XHRcdGlkOiAnaWQnLFxuICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbjoge1xuXHRcdFx0XHRcdFx0c2NoZW1hOiB7XG5cdFx0XHRcdFx0XHRcdGRhdGE6ICdyb29tcycsXG5cdFx0XHRcdFx0XHRcdHNvcnQ6IHtcblx0XHRcdFx0XHRcdFx0XHRmaWVsZDogJ25hbWUnLFxuXHRcdFx0XHRcdFx0XHRcdGRpcjogJ2FzYydcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG5cdFx0Ly8gU2V0IHRyZWUgdmlldyBkYXRhcHJvdmlkZXJcblx0XHR0aGlzLl90cmVldmlldy5zZXREYXRhU291cmNlKHpvbmVzKTtcblxuXHRcdC8vIFNldCB1dGlsaXR5IGJ1dHRvbnMgc3RhdGUgKGFkZCwgcmVtb3ZlLCBlZGl0LCBldGMpXG5cdFx0dGhpcy5fc2V0VXRpbGl0eUJ1dHRvbnNTdGF0ZSgpO1xuXHR9XG5cblx0X2NyZWF0ZVpvbmVPYmplY3Qoem9uZURhdGEpXG5cdHtcblx0XHRsZXQgem9uZSA9IHtcblx0XHRcdHR5cGU6IHRoaXMuSVRFTV9UWVBFX1pPTkUsXG5cdFx0XHRuYW1lOiB6b25lRGF0YS5nZXRVdGZTdHJpbmcoJ25hbWUnKSxcblx0XHRcdGlkOiB6b25lRGF0YS5nZXRJbnQoJ2lkJyksXG5cdFx0XHRhY3RpdmU6IHpvbmVEYXRhLmdldEJvb2woJ2FjdCcpXG5cdFx0fVxuXG5cdFx0Ly8gQ3JlYXRlIHJvb21zIGxpc3QgZGF0YXByb3ZpZGVyXG5cdFx0bGV0IHJEYXRhID0gem9uZURhdGEuZ2V0U0ZTQXJyYXkoJ3Jvb21zJyk7XG5cblx0XHRsZXQgcm9vbXNBcnIgPSBbXTtcblx0XHRmb3IgKGxldCByID0gMDsgciA8IHJEYXRhLnNpemUoKTsgcisrKVxuXHRcdFx0cm9vbXNBcnIucHVzaCggdGhpcy5fY3JlYXRlUm9vbU9iamVjdChyRGF0YS5nZXRTRlNPYmplY3QociksIHpvbmVEYXRhLmdldEludCgnaWQnKSkgKTtcblxuXHRcdHpvbmUucm9vbXMgPSByb29tc0FycjtcblxuXHRcdHJldHVybiB6b25lO1xuXHR9XG5cblx0X2NyZWF0ZVJvb21PYmplY3Qocm9vbURhdGEsIHpvbmVJZClcblx0e1xuXHRcdGxldCByb29tID0ge1xuXHRcdFx0dHlwZTogdGhpcy5JVEVNX1RZUEVfUk9PTSxcblx0XHRcdG5hbWU6IHJvb21EYXRhLmdldFV0ZlN0cmluZygnbmFtZScpLFxuXHRcdFx0aWQ6IHJvb21EYXRhLmdldEludCgnaWQnKSxcblx0XHRcdGFjdGl2ZTogcm9vbURhdGEuZ2V0Qm9vbCgnYWN0JyksXG5cdFx0XHRwYXJlbnRJZDogem9uZUlkLFxuXHRcdFx0c3ByaXRlQ3NzQ2xhc3M6IHRoaXMuX2dldFJvb21MaXN0SWNvbkNzc0NsYXNzKHJvb21EYXRhLmdldEJvb2woJ2FjdCcpKVxuXHRcdH07XG5cblx0XHRyZXR1cm4gcm9vbTtcblx0fVxuXG5cdF9nZXRSb29tTGlzdEljb25Dc3NDbGFzcyhpc0FjdGl2ZSlcblx0e1xuXHRcdHJldHVybiBpc0FjdGl2ZSA/ICdmYXMgZmEtZG9vci1vcGVuJyA6ICdmYXMgZmEtZG9vci1jbG9zZWQgaW5hY3RpdmUtbGlzdC1pdGVtJztcblx0fVxuXG5cdF9zZXRab25lQWN0aXZhdGlvblN0YXR1cyh6b25lSWQsIGFjdGl2ZVJvb21zLCBpc0FjdGl2ZSlcblx0e1xuXHRcdGxldCB6b25lREkgPSB0aGlzLl9nZXRab25lRGF0YUl0ZW1CeUlkKHpvbmVJZCk7XG5cblx0XHR6b25lREkuYWN0aXZlID0gaXNBY3RpdmU7XG5cblx0XHRsZXQgYWN0aXZlUm9vbXNBcnIgPSBhY3RpdmVSb29tcy5zcGxpdCgnLCcpO1xuXG5cdFx0aWYgKHpvbmVESS5oYXNDaGlsZHJlbilcblx0XHR7XG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHpvbmVESS5jaGlsZHJlbi5kYXRhKCkubGVuZ3RoOyBpKyspXG5cdFx0XHR7XG5cdFx0XHRcdGxldCByb29tID0gem9uZURJLmNoaWxkcmVuLmRhdGEoKVtpXTtcblx0XHRcdFx0cm9vbS5hY3RpdmUgPSAoaXNBY3RpdmUgJiYgYWN0aXZlUm9vbXNBcnIuaW5kZXhPZihyb29tLm5hbWUpID4gLTEpO1xuXHRcdFx0XHRyb29tLnNwcml0ZUNzc0NsYXNzID0gdGhpcy5fZ2V0Um9vbUxpc3RJY29uQ3NzQ2xhc3Mocm9vbS5hY3RpdmUpXG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUmVmcmVzaCBsaXN0XG5cdFx0dGhpcy5fdHJlZXZpZXcuZGF0YVNvdXJjZS5zeW5jKCk7XG5cblx0XHQvLyBSZXR1cm4gem9uZSBuYW1lXG5cdFx0cmV0dXJuIHpvbmVESS5uYW1lO1xuXHR9XG5cblx0X2Rlc2VsZWN0VHJlZUl0ZW0oKVxuXHR7XG5cdFx0dGhpcy5fdHJlZXZpZXcuc2VsZWN0KCQoKSk7XG5cdH1cblxuXHRfc2VsZWN0UGFyZW50VHJlZUl0ZW0oKVxuXHR7XG5cdFx0bGV0IHNlbGVjdGVkTm9kZSA9IHRoaXMuX3RyZWV2aWV3LnNlbGVjdCgpO1xuXHRcdGxldCBzZWxlY3RlZERhdGFJdGVtID0gdGhpcy5fdHJlZXZpZXcuZGF0YUl0ZW0oc2VsZWN0ZWROb2RlKTtcblxuXHRcdGlmIChzZWxlY3RlZERhdGFJdGVtLnR5cGUgPT0gdGhpcy5JVEVNX1RZUEVfUk9PTSlcblx0XHR7XG5cdFx0XHRsZXQgcGFyZW50Tm9kZSA9IHRoaXMuX3RyZWV2aWV3LnBhcmVudChzZWxlY3RlZE5vZGUpO1xuXHRcdFx0dGhpcy5fdHJlZXZpZXcuc2VsZWN0KHBhcmVudE5vZGUpO1xuXHRcdH1cblx0fVxuXG5cdF9sb2FkQ29uZmlndXJhdGlvbih0eXBlLCByZXNldFRhYnMgPSB0cnVlKVxuXHR7XG5cdFx0Ly8gRGlzYWJsZSB6b25lL3Jvb20gc2VsZWN0aW9uIGxpc3Rcblx0XHR0aGlzLl9lbmFibGVMaXN0SW50ZXJmYWNlKGZhbHNlKTtcblxuXHRcdC8vIERpc2FibGUgY29uZmlndXJhdGlvbiBpbnRlcmZhY2Vcblx0XHR0aGlzLl9lbmFibGVDb25maWdJbnRlcmZhY2UoZmFsc2UpO1xuXG5cdFx0Ly8gQ2xlYXIgbWFpbiBjb250YWluZXJcblx0XHR0aGlzLl9yZXNldFRhYnNDb250YWluZXIodHJ1ZSwgcmVzZXRUYWJzKTtcblxuXHRcdC8vIFNldCBpc0VkaXRpbmcgZmxhZ1xuXHRcdHRoaXMuX2lzRWRpdGluZyA9IHRydWU7XG5cdFx0dGhpcy5fZWRpdGVkSXRlbVR5cGUgPSB0eXBlO1xuXG5cdFx0Ly8gUmVxdWVzdCB6b25lIG9yIHJvb20gY29uZmlndXJhdGlvbiBkYXRhIHRvIHNlcnZlciBpbnN0YW5jZVxuXHRcdGxldCBwYXJhbXMgPSBuZXcgU0ZTMlguU0ZTT2JqZWN0KCk7XG5cdFx0cGFyYW1zLnB1dEludCgneklkJywgdGhpcy5fZWRpdGVkWm9uZUlkKTtcblx0XHRwYXJhbXMucHV0SW50KCdySWQnLCB0aGlzLl9lZGl0ZWRSb29tSWQpO1xuXG5cdFx0Ly8gSWYgbm8gcm9vbSBpcyBzZWxlY3RlZCwgdGhlbiB3ZSBhcmUgZWRpdGluZyBhIHpvbmVcblx0XHRpZiAodGhpcy5fZWRpdGVkSXRlbVR5cGUgPT0gdGhpcy5JVEVNX1RZUEVfWk9ORSlcblx0XHRcdHRoaXMuc2VuZEV4dGVuc2lvblJlcXVlc3QodGhpcy5SRVFfR0VUX1pPTkVfQ09ORklHLCBwYXJhbXMpO1xuXHRcdGVsc2Vcblx0XHRcdHRoaXMuc2VuZEV4dGVuc2lvblJlcXVlc3QodGhpcy5SRVFfR0VUX1JPT01fQ09ORklHLCBwYXJhbXMpO1xuXG5cdFx0Ly8gU3dpdGNoIHBhbmVsXG5cdFx0dGhpcy5fc3dpdGNoUGFuZWwoJ3puYy1tYWluUGFuZWwnKTtcblx0fVxuXG5cdF9yZXNldFRhYnNDb250YWluZXIoaXNMb2FkaW5nLCByZXNldFRhYnMpXG5cdHtcblx0XHRpZiAocmVzZXRUYWJzKVxuXHRcdFx0dGhpcy5fY2xlYXJUYWJzKCk7XG5cdFx0ZWxzZVxuXHRcdFx0dGhpcy5fcmVpbml0VGFicyA9IGZhbHNlO1xuXG5cdFx0aWYgKCFpc0xvYWRpbmcpXG5cdFx0XHR0aGlzLl9zd2l0Y2hWaWV3KCd6bmMtc2VsZWN0Jyk7XG5cdFx0ZWxzZVxuXHRcdFx0dGhpcy5fc3dpdGNoVmlldygnem5jLWxvYWRpbmcnKTtcblx0fVxuXG5cdF9zd2l0Y2hQYW5lbChwYW5lbElkKVxuXHR7XG5cdFx0ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3puYy12aWV3Jykuc2VsZWN0ZWRQYW5lbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHBhbmVsSWQpO1xuXHR9XG5cblx0X2dldFpvbmVEYXRhSXRlbUJ5SWQoem9uZUlkKVxuXHR7XG5cdFx0bGV0IHpvbmVzRFMgPSB0aGlzLl90cmVldmlldy5kYXRhU291cmNlO1xuXHRcdHJldHVybiB6b25lc0RTLmdldCh6b25lSWQpO1xuXHR9XG5cblx0X2dldFJvb21EYXRhSXRlbUJ5SWQoem9uZUlkLCByb29tSWQpXG5cdHtcblx0XHRsZXQgem9uZURJID0gdGhpcy5fZ2V0Wm9uZURhdGFJdGVtQnlJZCh6b25lSWQpO1xuXG5cdFx0aWYgKHpvbmVESS5oYXNDaGlsZHJlbilcblx0XHRcdHJldHVybiB6b25lREkuY2hpbGRyZW4uZ2V0KHJvb21JZCk7XG5cblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdF91cGRhdGVab25lTmFtZUluTGlzdCh6b25lSWQsIHpvbmVOYW1lKVxuXHR7XG5cdFx0dGhpcy5fZ2V0Wm9uZURhdGFJdGVtQnlJZCh6b25lSWQpLm5hbWUgPSB6b25lTmFtZTtcblx0XHR0aGlzLl90cmVldmlldy5kYXRhU291cmNlLnN5bmMoKTtcblx0fVxuXG5cdF91cGRhdGVSb29tTmFtZUluTGlzdCh6b25lSWQsIHJvb21JZCwgcm9vbU5hbWUpXG5cdHtcblx0XHR0aGlzLl9nZXRSb29tRGF0YUl0ZW1CeUlkKHpvbmVJZCwgcm9vbUlkKS5uYW1lID0gcm9vbU5hbWU7XG5cdFx0dGhpcy5fdHJlZXZpZXcuZGF0YVNvdXJjZS5zeW5jKCk7XG5cdH1cblxuXHRfdmFsaWRhdGVOYW1lKGNoYW5nZXMpXG5cdHtcblx0XHRjb25zdCB6b25lSWQgPSB0aGlzLl9lZGl0ZWRab25lSWQ7XG5cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGNoYW5nZXMuc2l6ZSgpOyBpKyspXG5cdFx0e1xuXHRcdFx0Y29uc3Qgc2V0dGluZyA9IGNoYW5nZXMuZ2V0U0ZTT2JqZWN0KGkpO1xuXG5cdFx0XHRpZiAoc2V0dGluZy5jb250YWluc0tleSgnbmFtZScpICYmIHNldHRpbmcuZ2V0VXRmU3RyaW5nKCduYW1lJykgPT0gJ25hbWUnKVxuXHRcdFx0e1xuXHRcdFx0XHQvLyBHZXQgbmFtZSB2YWx1ZVxuXHRcdFx0XHRjb25zdCBuYW1lID0gc2V0dGluZy5nZXRUZXh0KCd2YWx1ZScpO1xuXG5cdFx0XHRcdC8vIEdldCBkYXRhIHNvdXJjZVxuXHRcdFx0XHRsZXQgZHMgPSBbXTtcblxuXHRcdFx0XHRpZiAodGhpcy5fZWRpdGVkSXRlbVR5cGUgPT0gdGhpcy5JVEVNX1RZUEVfWk9ORSlcblx0XHRcdFx0XHRkcyA9IHRoaXMuX3RyZWV2aWV3LmRhdGFTb3VyY2UuZGF0YSgpO1xuXHRcdFx0XHRlbHNlXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRpZiAodGhpcy5fZ2V0Wm9uZURhdGFJdGVtQnlJZCh6b25lSWQpLmhhc0NoaWxkcmVuKVxuXHRcdFx0XHRcdFx0ZHMgPSB0aGlzLl9nZXRab25lRGF0YUl0ZW1CeUlkKHpvbmVJZCkuY2hpbGRyZW4uZGF0YSgpO1xuXHRcdFx0XHR9XG5cblxuXHRcdFx0XHQvLyBDaGVjayBpZiBuYW1lIGV4aXN0cyBpbiBkYXRhIHNvdXJjZVxuXHRcdFx0XHRmb3IgKGxldCBqID0gMDsgaiA8IGRzLmxlbmd0aDsgaisrKVxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0aWYgKGRzW2pdLm5hbWUgPT0gbmFtZSlcblx0XHRcdFx0XHR7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLyBQUklWQVRFIEdFVFRFUlNcblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRnZXQgX3NlbGVjdGVkSXRlbSgpXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fdHJlZXZpZXcuZGF0YUl0ZW0odGhpcy5fdHJlZXZpZXcuc2VsZWN0KCkpO1xuXHR9XG5cblx0Z2V0IF9zZWxlY3RlZEl0ZW1QYXJlbnQoKVxuXHR7XG5cdFx0bGV0IHNlbGVjdGVkTm9kZSA9IHRoaXMuX3RyZWV2aWV3LnNlbGVjdCgpO1xuXHRcdGxldCBwYXJlbnROb2RlID0gdGhpcy5fdHJlZXZpZXcucGFyZW50KHNlbGVjdGVkTm9kZSk7XG5cblx0XHRyZXR1cm4gdGhpcy5fdHJlZXZpZXcuZGF0YUl0ZW0ocGFyZW50Tm9kZSk7XG5cdH1cblxuXHRnZXQgX2VkaXRlZFpvbmVJZCgpXG5cdHtcblx0XHRpZiAodGhpcy5faXNFZGl0aW5nICYmIHRoaXMuX3NlbGVjdGVkSXRlbSlcblx0XHR7XG5cdFx0XHRpZiAodGhpcy5fc2VsZWN0ZWRJdGVtLnR5cGUgPT0gdGhpcy5JVEVNX1RZUEVfWk9ORSlcblx0XHRcdFx0cmV0dXJuIHRoaXMuX3NlbGVjdGVkSXRlbS5pZDtcblx0XHRcdGVsc2Vcblx0XHRcdFx0cmV0dXJuIHRoaXMuX3NlbGVjdGVkSXRlbVBhcmVudC5pZDtcblx0XHR9XG5cblx0XHRyZXR1cm4gLTE7XG5cdH1cblxuXHRnZXQgX2VkaXRlZFJvb21JZCgpXG5cdHtcblx0XHRpZiAodGhpcy5faXNFZGl0aW5nICYmIHRoaXMuX3NlbGVjdGVkSXRlbSlcblx0XHR7XG5cdFx0XHRpZiAodGhpcy5fc2VsZWN0ZWRJdGVtLnR5cGUgPT0gdGhpcy5JVEVNX1RZUEVfUk9PTSlcblx0XHRcdFx0cmV0dXJuIHRoaXMuX3NlbGVjdGVkSXRlbS5pZDtcblx0XHR9XG5cblx0XHRyZXR1cm4gLTE7XG5cdH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDdkhBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7O0EiLCJzb3VyY2VSb290IjoiIn0=