passenger 5.1.4 → 5.1.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (542) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +9 -0
  3. data/CHANGELOG +9 -0
  4. data/build/cxx_tests.rb +11 -1
  5. data/build/documentation.rb +0 -32
  6. data/build/support/cxx_dependency_map.rb +602 -2
  7. data/build/test_basics.rb +3 -3
  8. data/dev/boost-patches/0001-Patch-boost-thread-so-that-oxt-thread-can-use-it.patch +48 -0
  9. data/dev/boost-patches/0002-Make-boost-thread_interrupted-derive-from-oxt-tracab.patch +33 -0
  10. data/dev/boost-patches/0003-Disable-a-Clang-pragma-to-prevent-warnings-on-OS-X.patch +25 -0
  11. data/dev/ci/README.md +121 -0
  12. data/dev/ci/lib/functions.sh +129 -0
  13. data/dev/ci/lib/set-container-envvars.sh +46 -0
  14. data/dev/ci/lib/setup-container.sh +43 -0
  15. data/dev/ci/run-tests-natively +24 -0
  16. data/dev/ci/run-tests-with-docker +42 -0
  17. data/dev/ci/scripts/debug-console-wrapper.sh +27 -0
  18. data/dev/ci/scripts/docker-entrypoint-stage2.sh +17 -0
  19. data/dev/ci/scripts/docker-entrypoint.sh +17 -0
  20. data/dev/ci/scripts/inituidgid +17 -0
  21. data/dev/ci/scripts/run-tests-natively-stage2.sh +17 -0
  22. data/dev/ci/scripts/setup-host-natively.sh +11 -0
  23. data/dev/ci/setup-host +50 -0
  24. data/dev/ci/tests/apache2/run +6 -0
  25. data/dev/ci/tests/apache2/setup +4 -0
  26. data/dev/ci/tests/cxx/run +9 -0
  27. data/dev/ci/tests/cxx/setup +4 -0
  28. data/dev/ci/tests/nginx-dynamic/run +20 -0
  29. data/dev/ci/tests/nginx-dynamic/setup +4 -0
  30. data/dev/ci/tests/nginx/run +5 -0
  31. data/dev/ci/tests/nginx/setup +4 -0
  32. data/dev/ci/tests/nodejs/run +4 -0
  33. data/dev/ci/tests/nodejs/setup +4 -0
  34. data/dev/ci/tests/ruby/run +4 -0
  35. data/dev/ci/tests/ruby/setup +4 -0
  36. data/dev/ci/tests/source-packaging/run +4 -0
  37. data/dev/ci/tests/source-packaging/setup +4 -0
  38. data/dev/ci/tests/standalone/run +4 -0
  39. data/dev/ci/tests/standalone/setup +4 -0
  40. data/dev/copy_boost_headers +8 -2
  41. data/src/agent/Core/ApiServer.h +11 -5
  42. data/src/agent/Core/Controller.h +12 -46
  43. data/src/agent/Core/Controller/CheckoutSession.cpp +1 -1
  44. data/src/agent/Core/Controller/Config.h +369 -0
  45. data/src/agent/Core/Controller/ForwardResponse.cpp +4 -4
  46. data/src/agent/Core/Controller/Hooks.cpp +15 -3
  47. data/src/agent/Core/Controller/Implementation.cpp +1 -1
  48. data/src/agent/Core/Controller/InitRequest.cpp +28 -39
  49. data/src/agent/Core/Controller/InitializationAndShutdown.cpp +25 -60
  50. data/src/agent/Core/Controller/InternalUtils.cpp +0 -16
  51. data/src/agent/Core/Controller/Miscellaneous.cpp +0 -17
  52. data/src/agent/Core/Controller/Request.h +2 -0
  53. data/src/agent/Core/Controller/SendRequest.cpp +4 -4
  54. data/src/agent/Core/Controller/{StateInspectionAndConfiguration.cpp → StateInspection.cpp} +0 -22
  55. data/src/agent/Core/Controller/TurboCaching.h +11 -10
  56. data/src/agent/Core/CoreMain.cpp +16 -6
  57. data/src/agent/Core/ResponseCache.h +3 -3
  58. data/src/agent/Core/SpawningKit/SmartSpawner.h +9 -3
  59. data/src/agent/Core/SpawningKit/Spawner.h +7 -3
  60. data/src/agent/UstRouter/ApiServer.h +3 -2
  61. data/src/agent/UstRouter/Controller.h +66 -32
  62. data/src/agent/UstRouter/UstRouterMain.cpp +10 -2
  63. data/src/agent/Watchdog/ApiServer.h +3 -2
  64. data/src/agent/Watchdog/WatchdogMain.cpp +3 -1
  65. data/src/apache2_module/ConfigurationCommands.cpp +1 -1
  66. data/src/cxx_supportlib/ConfigKit/Common.h +125 -0
  67. data/src/cxx_supportlib/ConfigKit/ConfigKit.h +34 -0
  68. data/src/cxx_supportlib/ConfigKit/README.md +895 -0
  69. data/src/cxx_supportlib/ConfigKit/Schema.h +331 -0
  70. data/src/cxx_supportlib/ConfigKit/Store.h +385 -0
  71. data/src/cxx_supportlib/ConfigKit/TableTranslator.h +185 -0
  72. data/src/cxx_supportlib/ConfigKit/Utils.h +141 -0
  73. data/src/cxx_supportlib/ConfigKit/VariantMapUtils.h +81 -0
  74. data/src/cxx_supportlib/Constants.h +1 -1
  75. data/src/cxx_supportlib/Crypto.cpp +2 -2
  76. data/src/cxx_supportlib/Logging.h +0 -35
  77. data/src/cxx_supportlib/ServerKit/HttpServer.h +35 -16
  78. data/src/cxx_supportlib/ServerKit/Server.h +65 -25
  79. data/src/cxx_supportlib/oxt/macros.hpp +3 -0
  80. data/src/cxx_supportlib/vendor-modified/boost/algorithm/string/replace.hpp +0 -2
  81. data/src/cxx_supportlib/vendor-modified/boost/array.hpp +53 -42
  82. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/atomic_template.hpp +11 -5
  83. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/bitwise_cast.hpp +13 -2
  84. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/caps_gcc_x86.hpp +23 -0
  85. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/caps_msvc_x86.hpp +5 -0
  86. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/config.hpp +3 -2
  87. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/interlocked.hpp +8 -1
  88. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_emulated.hpp +3 -1
  89. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_gcc_alpha.hpp +2 -0
  90. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_gcc_arm.hpp +2 -0
  91. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_gcc_atomic.hpp +5 -0
  92. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_gcc_ppc.hpp +2 -0
  93. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_gcc_sparc.hpp +6 -4
  94. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_gcc_sync.hpp +2 -0
  95. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_gcc_x86.hpp +3 -1
  96. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_gcc_x86_dcas.hpp +28 -17
  97. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_linux_arm.hpp +2 -0
  98. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_msvc_arm.hpp +2 -0
  99. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/ops_msvc_x86.hpp +9 -4
  100. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/platform.hpp +3 -3
  101. data/src/cxx_supportlib/vendor-modified/boost/bind/arg.hpp +10 -3
  102. data/src/cxx_supportlib/vendor-modified/boost/bind/bind.hpp +90 -18
  103. data/src/cxx_supportlib/vendor-modified/boost/cerrno.hpp +2 -2
  104. data/src/cxx_supportlib/vendor-modified/boost/chrono/duration.hpp +1 -1
  105. data/src/cxx_supportlib/vendor-modified/boost/config/auto_link.hpp +8 -3
  106. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/borland.hpp +2 -0
  107. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/clang.hpp +35 -6
  108. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/codegear.hpp +2 -0
  109. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/comeau.hpp +1 -1
  110. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/common_edg.hpp +2 -0
  111. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/compaq_cxx.hpp +1 -1
  112. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/cray.hpp +3 -1
  113. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/digitalmars.hpp +2 -0
  114. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/gcc.hpp +19 -4
  115. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/gcc_xml.hpp +3 -1
  116. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/greenhills.hpp +1 -1
  117. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/hp_acc.hpp +3 -1
  118. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/intel.hpp +29 -7
  119. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/kai.hpp +1 -1
  120. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/metrowerks.hpp +2 -0
  121. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/mpw.hpp +2 -0
  122. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/nvcc.hpp +16 -0
  123. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/pathscale.hpp +2 -0
  124. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/pgi.hpp +2 -0
  125. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/sgi_mipspro.hpp +1 -1
  126. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/sunpro_cc.hpp +10 -1
  127. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/vacpp.hpp +2 -0
  128. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/visualc.hpp +44 -16
  129. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/xlcpp.hpp +4 -0
  130. data/src/cxx_supportlib/vendor-modified/boost/config/platform/cygwin.hpp +1 -2
  131. data/src/cxx_supportlib/vendor-modified/boost/config/platform/linux.hpp +1 -1
  132. data/src/cxx_supportlib/vendor-modified/boost/config/select_compiler_config.hpp +21 -21
  133. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/dinkumware.hpp +42 -1
  134. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/libcomo.hpp +7 -0
  135. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/libcpp.hpp +40 -7
  136. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/libstdcpp3.hpp +39 -6
  137. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/modena.hpp +7 -0
  138. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/msl.hpp +7 -0
  139. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/roguewave.hpp +7 -0
  140. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/sgi.hpp +8 -1
  141. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/stlport.hpp +7 -0
  142. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/vacpp.hpp +7 -0
  143. data/src/cxx_supportlib/vendor-modified/boost/config/suffix.hpp +33 -4
  144. data/src/cxx_supportlib/vendor-modified/boost/container/adaptive_pool.hpp +0 -2
  145. data/src/cxx_supportlib/vendor-modified/boost/container/allocator.hpp +0 -3
  146. data/src/cxx_supportlib/vendor-modified/boost/container/allocator_traits.hpp +34 -27
  147. data/src/cxx_supportlib/vendor-modified/boost/container/deque.hpp +62 -26
  148. data/src/cxx_supportlib/vendor-modified/boost/container/detail/addressof.hpp +2 -2
  149. data/src/cxx_supportlib/vendor-modified/boost/container/detail/advanced_insert_int.hpp +4 -4
  150. data/src/cxx_supportlib/vendor-modified/boost/container/detail/compare_functors.hpp +4 -4
  151. data/src/cxx_supportlib/vendor-modified/boost/container/detail/config_begin.hpp +2 -0
  152. data/src/cxx_supportlib/vendor-modified/boost/container/detail/construct_in_place.hpp +39 -5
  153. data/src/cxx_supportlib/vendor-modified/boost/container/detail/copy_move_algo.hpp +49 -32
  154. data/src/cxx_supportlib/vendor-modified/boost/container/detail/dispatch_uses_allocator.hpp +175 -7
  155. data/src/cxx_supportlib/vendor-modified/boost/container/detail/flat_tree.hpp +223 -98
  156. data/src/cxx_supportlib/vendor-modified/boost/container/detail/is_sorted.hpp +57 -0
  157. data/src/cxx_supportlib/vendor-modified/boost/container/detail/iterators.hpp +88 -41
  158. data/src/cxx_supportlib/vendor-modified/boost/container/detail/mpl.hpp +7 -8
  159. data/src/cxx_supportlib/vendor-modified/boost/container/detail/mutex.hpp +4 -9
  160. data/src/cxx_supportlib/vendor-modified/boost/container/detail/node_alloc_holder.hpp +45 -18
  161. data/src/cxx_supportlib/vendor-modified/boost/container/detail/pair.hpp +205 -26
  162. data/src/cxx_supportlib/vendor-modified/boost/container/detail/tree.hpp +290 -181
  163. data/src/cxx_supportlib/vendor-modified/boost/container/detail/value_init.hpp +2 -0
  164. data/src/cxx_supportlib/vendor-modified/boost/container/detail/variadic_templates_tools.hpp +24 -19
  165. data/src/cxx_supportlib/vendor-modified/boost/container/detail/workaround.hpp +38 -0
  166. data/src/cxx_supportlib/vendor-modified/boost/container/flat_map.hpp +320 -46
  167. data/src/cxx_supportlib/vendor-modified/boost/container/flat_set.hpp +91 -18
  168. data/src/cxx_supportlib/vendor-modified/boost/container/list.hpp +23 -19
  169. data/src/cxx_supportlib/vendor-modified/boost/container/map.hpp +491 -120
  170. data/src/cxx_supportlib/vendor-modified/boost/container/new_allocator.hpp +4 -4
  171. data/src/cxx_supportlib/vendor-modified/boost/container/node_allocator.hpp +0 -3
  172. data/src/cxx_supportlib/vendor-modified/boost/container/node_handle.hpp +399 -0
  173. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/deque.hpp +2 -0
  174. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/flat_map.hpp +4 -0
  175. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/flat_set.hpp +4 -0
  176. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/list.hpp +2 -0
  177. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/map.hpp +4 -0
  178. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/set.hpp +4 -0
  179. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/slist.hpp +2 -0
  180. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/small_vector.hpp +2 -0
  181. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/stable_vector.hpp +2 -0
  182. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/string.hpp +2 -0
  183. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/vector.hpp +2 -0
  184. data/src/cxx_supportlib/vendor-modified/boost/container/set.hpp +101 -20
  185. data/src/cxx_supportlib/vendor-modified/boost/container/slist.hpp +19 -14
  186. data/src/cxx_supportlib/vendor-modified/boost/container/small_vector.hpp +117 -59
  187. data/src/cxx_supportlib/vendor-modified/boost/container/stable_vector.hpp +8 -6
  188. data/src/cxx_supportlib/vendor-modified/boost/container/static_vector.hpp +33 -28
  189. data/src/cxx_supportlib/vendor-modified/boost/container/string.hpp +414 -70
  190. data/src/cxx_supportlib/vendor-modified/boost/container/throw_exception.hpp +1 -0
  191. data/src/cxx_supportlib/vendor-modified/boost/container/uses_allocator_fwd.hpp +2 -2
  192. data/src/cxx_supportlib/vendor-modified/boost/container/vector.hpp +134 -117
  193. data/src/cxx_supportlib/vendor-modified/boost/core/addressof.hpp +202 -99
  194. data/src/cxx_supportlib/vendor-modified/boost/core/demangle.hpp +8 -10
  195. data/src/cxx_supportlib/vendor-modified/boost/core/lightweight_test.hpp +217 -1
  196. data/src/cxx_supportlib/vendor-modified/boost/core/scoped_enum.hpp +29 -27
  197. data/src/cxx_supportlib/vendor-modified/boost/current_function.hpp +5 -1
  198. data/src/cxx_supportlib/vendor-modified/boost/date_time/c_time.hpp +13 -13
  199. data/src/cxx_supportlib/vendor-modified/boost/date_time/constrained_value.hpp +3 -3
  200. data/src/cxx_supportlib/vendor-modified/boost/date_time/date.hpp +2 -1
  201. data/src/cxx_supportlib/vendor-modified/boost/date_time/date_duration.hpp +4 -3
  202. data/src/cxx_supportlib/vendor-modified/boost/date_time/date_duration_types.hpp +6 -5
  203. data/src/cxx_supportlib/vendor-modified/boost/date_time/date_facet.hpp +2 -2
  204. data/src/cxx_supportlib/vendor-modified/boost/date_time/date_names_put.hpp +8 -7
  205. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_calendar.hpp +2 -1
  206. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_date.hpp +2 -1
  207. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_day.hpp +4 -3
  208. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_day_of_year.hpp +3 -2
  209. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_duration.hpp +2 -1
  210. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_duration_types.hpp +4 -3
  211. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_facet.hpp +27 -7
  212. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_month.hpp +5 -5
  213. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_serialize.hpp +5 -0
  214. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_weekday.hpp +4 -4
  215. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian/greg_year.hpp +4 -5
  216. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian_calendar.hpp +2 -1
  217. data/src/cxx_supportlib/vendor-modified/boost/date_time/local_time/local_date_time.hpp +5 -4
  218. data/src/cxx_supportlib/vendor-modified/boost/date_time/local_time/posix_time_zone.hpp +4 -3
  219. data/src/cxx_supportlib/vendor-modified/boost/date_time/period.hpp +3 -2
  220. data/src/cxx_supportlib/vendor-modified/boost/date_time/posix_time/date_duration_operators.hpp +1 -1
  221. data/src/cxx_supportlib/vendor-modified/boost/date_time/posix_time/posix_time_config.hpp +2 -2
  222. data/src/cxx_supportlib/vendor-modified/boost/date_time/posix_time/posix_time_duration.hpp +5 -4
  223. data/src/cxx_supportlib/vendor-modified/boost/date_time/posix_time/ptime.hpp +6 -5
  224. data/src/cxx_supportlib/vendor-modified/boost/date_time/posix_time/time_parsers.hpp +4 -0
  225. data/src/cxx_supportlib/vendor-modified/boost/date_time/time_duration.hpp +2 -2
  226. data/src/cxx_supportlib/vendor-modified/boost/date_time/time_facet.hpp +5 -4
  227. data/src/cxx_supportlib/vendor-modified/boost/date_time/time_zone_base.hpp +2 -1
  228. data/src/cxx_supportlib/vendor-modified/boost/date_time/year_month_day.hpp +3 -1
  229. data/src/cxx_supportlib/vendor-modified/boost/detail/iterator.hpp +13 -0
  230. data/src/cxx_supportlib/vendor-modified/boost/detail/lcast_precision.hpp +1 -0
  231. data/src/cxx_supportlib/vendor-modified/boost/detail/workaround.hpp +5 -0
  232. data/src/cxx_supportlib/vendor-modified/boost/exception/detail/error_info_impl.hpp +11 -0
  233. data/src/cxx_supportlib/vendor-modified/boost/exception/detail/shared_ptr.hpp +17 -0
  234. data/src/cxx_supportlib/vendor-modified/boost/exception/exception.hpp +25 -3
  235. data/src/cxx_supportlib/vendor-modified/boost/exception/get_error_info.hpp +2 -1
  236. data/src/cxx_supportlib/vendor-modified/boost/exception/info.hpp +114 -1
  237. data/src/cxx_supportlib/vendor-modified/boost/function/function_base.hpp +116 -142
  238. data/src/cxx_supportlib/vendor-modified/boost/function/function_template.hpp +57 -69
  239. data/src/cxx_supportlib/vendor-modified/boost/functional/hash/detail/hash_float.hpp +1 -1
  240. data/src/cxx_supportlib/vendor-modified/boost/functional/hash/extensions.hpp +3 -3
  241. data/src/cxx_supportlib/vendor-modified/boost/functional/hash/hash.hpp +27 -13
  242. data/src/cxx_supportlib/vendor-modified/boost/intrusive/any_hook.hpp +4 -2
  243. data/src/cxx_supportlib/vendor-modified/boost/intrusive/avl_set.hpp +99 -12
  244. data/src/cxx_supportlib/vendor-modified/boost/intrusive/avl_set_hook.hpp +4 -2
  245. data/src/cxx_supportlib/vendor-modified/boost/intrusive/avltree.hpp +35 -4
  246. data/src/cxx_supportlib/vendor-modified/boost/intrusive/avltree_algorithms.hpp +37 -6
  247. data/src/cxx_supportlib/vendor-modified/boost/intrusive/bs_set.hpp +95 -8
  248. data/src/cxx_supportlib/vendor-modified/boost/intrusive/bs_set_hook.hpp +4 -2
  249. data/src/cxx_supportlib/vendor-modified/boost/intrusive/bstree.hpp +209 -72
  250. data/src/cxx_supportlib/vendor-modified/boost/intrusive/bstree_algorithms.hpp +86 -20
  251. data/src/cxx_supportlib/vendor-modified/boost/intrusive/circular_list_algorithms.hpp +11 -11
  252. data/src/cxx_supportlib/vendor-modified/boost/intrusive/circular_slist_algorithms.hpp +6 -6
  253. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/algo_type.hpp +4 -1
  254. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/any_node_and_algorithms.hpp +58 -45
  255. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/avltree_node.hpp +27 -26
  256. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/bstree_algorithms_base.hpp +2 -2
  257. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/common_slist_algorithms.hpp +7 -7
  258. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/config_begin.hpp +8 -3
  259. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/default_header_holder.hpp +4 -3
  260. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/ebo_functor_holder.hpp +27 -26
  261. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/equal_to_value.hpp +3 -1
  262. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/exception_disposer.hpp +4 -2
  263. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/generic_hook.hpp +9 -7
  264. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/has_member_function_callable_with.hpp +83 -57
  265. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/hashtable_node.hpp +30 -30
  266. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/hook_traits.hpp +9 -8
  267. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/iiterator.hpp +8 -7
  268. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/iterator.hpp +16 -15
  269. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/key_nodeptr_comp.hpp +70 -44
  270. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/list_iterator.hpp +22 -21
  271. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/list_node.hpp +7 -6
  272. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/parent_from_member.hpp +5 -4
  273. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/rbtree_node.hpp +29 -28
  274. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/reverse_iterator.hpp +33 -12
  275. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/size_holder.hpp +19 -12
  276. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/slist_iterator.hpp +21 -20
  277. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/slist_node.hpp +4 -3
  278. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/to_raw_pointer.hpp +3 -2
  279. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/transform_iterator.hpp +23 -22
  280. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/tree_iterator.hpp +23 -22
  281. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/tree_node.hpp +10 -9
  282. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/tree_value_compare.hpp +103 -29
  283. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/workaround.hpp +15 -0
  284. data/src/cxx_supportlib/vendor-modified/boost/intrusive/hashtable.hpp +295 -211
  285. data/src/cxx_supportlib/vendor-modified/boost/intrusive/linear_slist_algorithms.hpp +2 -2
  286. data/src/cxx_supportlib/vendor-modified/boost/intrusive/list.hpp +20 -7
  287. data/src/cxx_supportlib/vendor-modified/boost/intrusive/list_hook.hpp +4 -2
  288. data/src/cxx_supportlib/vendor-modified/boost/intrusive/member_value_traits.hpp +5 -4
  289. data/src/cxx_supportlib/vendor-modified/boost/intrusive/options.hpp +4 -4
  290. data/src/cxx_supportlib/vendor-modified/boost/intrusive/parent_from_member.hpp +3 -2
  291. data/src/cxx_supportlib/vendor-modified/boost/intrusive/pointer_plus_bits.hpp +4 -4
  292. data/src/cxx_supportlib/vendor-modified/boost/intrusive/pointer_traits.hpp +4 -4
  293. data/src/cxx_supportlib/vendor-modified/boost/intrusive/priority_compare.hpp +22 -4
  294. data/src/cxx_supportlib/vendor-modified/boost/intrusive/rbtree.hpp +36 -4
  295. data/src/cxx_supportlib/vendor-modified/boost/intrusive/rbtree_algorithms.hpp +43 -13
  296. data/src/cxx_supportlib/vendor-modified/boost/intrusive/set.hpp +95 -8
  297. data/src/cxx_supportlib/vendor-modified/boost/intrusive/set_hook.hpp +4 -2
  298. data/src/cxx_supportlib/vendor-modified/boost/intrusive/sg_set.hpp +96 -12
  299. data/src/cxx_supportlib/vendor-modified/boost/intrusive/sgtree.hpp +102 -5
  300. data/src/cxx_supportlib/vendor-modified/boost/intrusive/sgtree_algorithms.hpp +48 -4
  301. data/src/cxx_supportlib/vendor-modified/boost/intrusive/slist.hpp +20 -11
  302. data/src/cxx_supportlib/vendor-modified/boost/intrusive/slist_hook.hpp +9 -2
  303. data/src/cxx_supportlib/vendor-modified/boost/intrusive/splay_set.hpp +95 -8
  304. data/src/cxx_supportlib/vendor-modified/boost/intrusive/splaytree.hpp +36 -4
  305. data/src/cxx_supportlib/vendor-modified/boost/intrusive/splaytree_algorithms.hpp +27 -0
  306. data/src/cxx_supportlib/vendor-modified/boost/intrusive/treap.hpp +167 -23
  307. data/src/cxx_supportlib/vendor-modified/boost/intrusive/treap_algorithms.hpp +28 -0
  308. data/src/cxx_supportlib/vendor-modified/boost/intrusive/treap_set.hpp +100 -46
  309. data/src/cxx_supportlib/vendor-modified/boost/intrusive/trivial_value_traits.hpp +5 -4
  310. data/src/cxx_supportlib/vendor-modified/boost/intrusive/unordered_set.hpp +37 -27
  311. data/src/cxx_supportlib/vendor-modified/boost/intrusive/unordered_set_hook.hpp +30 -14
  312. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast.hpp +1 -1
  313. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/converter_lexical_streams.hpp +35 -36
  314. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/converter_numeric.hpp +6 -28
  315. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/try_lexical_convert.hpp +20 -5
  316. data/src/cxx_supportlib/vendor-modified/boost/libs/regex/src/posix_api.cpp +4 -2
  317. data/src/cxx_supportlib/vendor-modified/boost/libs/regex/src/regex.cpp +3 -1
  318. data/src/cxx_supportlib/vendor-modified/boost/libs/thread/src/pthread/once.cpp +5 -0
  319. data/src/cxx_supportlib/vendor-modified/boost/libs/thread/src/pthread/thread.cpp +11 -7
  320. data/src/cxx_supportlib/vendor-modified/boost/math/policies/policy.hpp +1 -3
  321. data/src/cxx_supportlib/vendor-modified/boost/math/special_functions/fpclassify.hpp +5 -1
  322. data/src/cxx_supportlib/vendor-modified/boost/math/special_functions/math_fwd.hpp +11 -0
  323. data/src/cxx_supportlib/vendor-modified/boost/math/tools/config.hpp +10 -2
  324. data/src/cxx_supportlib/vendor-modified/boost/move/adl_move_swap.hpp +40 -7
  325. data/src/cxx_supportlib/vendor-modified/boost/move/algo/adaptive_merge.hpp +67 -0
  326. data/src/cxx_supportlib/vendor-modified/boost/move/algo/adaptive_sort.hpp +63 -0
  327. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/adaptive_sort_merge.hpp +2437 -0
  328. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/basic_op.hpp +121 -0
  329. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/insertion_sort.hpp +127 -0
  330. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/merge.hpp +637 -0
  331. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/merge_sort.hpp +139 -0
  332. data/src/cxx_supportlib/vendor-modified/boost/move/algo/move.hpp +155 -0
  333. data/src/cxx_supportlib/vendor-modified/boost/move/algorithm.hpp +1 -116
  334. data/src/cxx_supportlib/vendor-modified/boost/move/core.hpp +14 -13
  335. data/src/cxx_supportlib/vendor-modified/boost/move/default_delete.hpp +17 -1
  336. data/src/cxx_supportlib/vendor-modified/boost/move/detail/config_begin.hpp +2 -0
  337. data/src/cxx_supportlib/vendor-modified/boost/move/detail/destruct_n.hpp +67 -0
  338. data/src/cxx_supportlib/vendor-modified/boost/move/detail/fwd_macros.hpp +227 -32
  339. data/src/cxx_supportlib/vendor-modified/boost/move/detail/iterator_traits.hpp +4 -0
  340. data/src/cxx_supportlib/vendor-modified/boost/move/detail/meta_utils.hpp +30 -9
  341. data/src/cxx_supportlib/vendor-modified/boost/move/detail/meta_utils_core.hpp +12 -0
  342. data/src/cxx_supportlib/vendor-modified/boost/move/detail/move_helpers.hpp +84 -80
  343. data/src/cxx_supportlib/vendor-modified/boost/move/detail/placement_new.hpp +30 -0
  344. data/src/cxx_supportlib/vendor-modified/boost/move/detail/reverse_iterator.hpp +171 -0
  345. data/src/cxx_supportlib/vendor-modified/boost/move/detail/type_traits.hpp +14 -20
  346. data/src/cxx_supportlib/vendor-modified/boost/move/detail/unique_ptr_meta_utils.hpp +1 -1
  347. data/src/cxx_supportlib/vendor-modified/boost/move/detail/workaround.hpp +14 -0
  348. data/src/cxx_supportlib/vendor-modified/boost/move/iterator.hpp +32 -33
  349. data/src/cxx_supportlib/vendor-modified/boost/move/make_unique.hpp +2 -1
  350. data/src/cxx_supportlib/vendor-modified/boost/move/unique_ptr.hpp +49 -49
  351. data/src/cxx_supportlib/vendor-modified/boost/move/utility.hpp +8 -7
  352. data/src/cxx_supportlib/vendor-modified/boost/move/utility_core.hpp +17 -16
  353. data/src/cxx_supportlib/vendor-modified/boost/mpl/print.hpp +3 -0
  354. data/src/cxx_supportlib/vendor-modified/boost/none.hpp +1 -1
  355. data/src/cxx_supportlib/vendor-modified/boost/none_t.hpp +2 -3
  356. data/src/cxx_supportlib/vendor-modified/boost/operators.hpp +197 -255
  357. data/src/cxx_supportlib/vendor-modified/boost/optional/detail/old_optional_implementation.hpp +1059 -0
  358. data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_aligned_storage.hpp +75 -0
  359. data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_config.hpp +116 -0
  360. data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_factory_support.hpp +36 -0
  361. data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_reference_spec.hpp +253 -0
  362. data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_relops.hpp +196 -0
  363. data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_swap.hpp +117 -0
  364. data/src/cxx_supportlib/vendor-modified/boost/optional/optional.hpp +372 -554
  365. data/src/cxx_supportlib/vendor-modified/boost/optional/optional_fwd.hpp +12 -1
  366. data/src/cxx_supportlib/vendor-modified/boost/pool/detail/mutex.hpp +15 -7
  367. data/src/cxx_supportlib/vendor-modified/boost/pool/pool_alloc.hpp +24 -0
  368. data/src/cxx_supportlib/vendor-modified/boost/predef/compiler/intel.h +9 -2
  369. data/src/cxx_supportlib/vendor-modified/boost/predef/compiler/visualc.h +15 -1
  370. data/src/cxx_supportlib/vendor-modified/boost/predef/hardware/simd.h +16 -4
  371. data/src/cxx_supportlib/vendor-modified/boost/predef/hardware/simd/x86.h +3 -3
  372. data/src/cxx_supportlib/vendor-modified/boost/predef/hardware/simd/x86_amd.h +4 -4
  373. data/src/cxx_supportlib/vendor-modified/boost/predef/hardware/simd/x86_amd/versions.h +4 -4
  374. data/src/cxx_supportlib/vendor-modified/boost/predef/os/cygwin.h +1 -1
  375. data/src/cxx_supportlib/vendor-modified/boost/predef/version.h +2 -2
  376. data/src/cxx_supportlib/vendor-modified/boost/predef/version_number.h +20 -1
  377. data/src/cxx_supportlib/vendor-modified/boost/preprocessor/cat.hpp +1 -1
  378. data/src/cxx_supportlib/vendor-modified/boost/preprocessor/config/config.hpp +6 -6
  379. data/src/cxx_supportlib/vendor-modified/boost/preprocessor/seq/detail/binary_transform.hpp +5 -6
  380. data/src/cxx_supportlib/vendor-modified/boost/preprocessor/seq/detail/to_list_msvc.hpp +55 -0
  381. data/src/cxx_supportlib/vendor-modified/boost/preprocessor/seq/to_list.hpp +12 -0
  382. data/src/cxx_supportlib/vendor-modified/boost/range/const_iterator.hpp +4 -4
  383. data/src/cxx_supportlib/vendor-modified/boost/range/size_type.hpp +0 -5
  384. data/src/cxx_supportlib/vendor-modified/boost/regex/concepts.hpp +16 -16
  385. data/src/cxx_supportlib/vendor-modified/boost/regex/config.hpp +4 -4
  386. data/src/cxx_supportlib/vendor-modified/boost/regex/pending/unicode_iterator.hpp +3 -0
  387. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/basic_regex_creator.hpp +102 -87
  388. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/basic_regex_parser.hpp +45 -21
  389. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/cpp_regex_traits.hpp +4 -4
  390. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/fileiter.hpp +2 -2
  391. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/instances.hpp +1 -1
  392. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/match_flags.hpp +14 -2
  393. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/mem_block_cache.hpp +46 -0
  394. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/perl_matcher.hpp +5 -2
  395. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/perl_matcher_common.hpp +5 -14
  396. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/perl_matcher_non_recursive.hpp +116 -13
  397. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/perl_matcher_recursive.hpp +34 -0
  398. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_format.hpp +2 -2
  399. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_traits.hpp +1 -1
  400. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_traits_defaults.hpp +3 -3
  401. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/regex_workaround.hpp +1 -0
  402. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/w32_regex_traits.hpp +2 -2
  403. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/allocate_shared_array.hpp +1004 -159
  404. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/bad_weak_ptr.hpp +9 -0
  405. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/atomic_count.hpp +3 -0
  406. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/shared_count.hpp +4 -58
  407. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base.hpp +5 -2
  408. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base_clang.hpp +9 -0
  409. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_impl.hpp +0 -8
  410. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_has_sync.hpp +3 -3
  411. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_noexcept.hpp +30 -0
  412. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/spinlock.hpp +3 -0
  413. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/enable_shared_from_this.hpp +5 -4
  414. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/intrusive_ptr.hpp +28 -3
  415. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/intrusive_ref_counter.hpp +187 -0
  416. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/make_shared_array.hpp +52 -144
  417. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/make_shared_object.hpp +120 -450
  418. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/scoped_array.hpp +2 -1
  419. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/scoped_ptr.hpp +2 -1
  420. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/shared_array.hpp +7 -6
  421. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/shared_ptr.hpp +70 -8
  422. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/weak_ptr.hpp +6 -5
  423. data/src/cxx_supportlib/vendor-modified/boost/system/error_code.hpp +9 -8
  424. data/src/cxx_supportlib/vendor-modified/boost/system/system_error.hpp +3 -3
  425. data/src/cxx_supportlib/vendor-modified/boost/thread/barrier.hpp +5 -4
  426. data/src/cxx_supportlib/vendor-modified/boost/thread/completion_latch.hpp +0 -1
  427. data/src/cxx_supportlib/vendor-modified/boost/thread/concurrent_queues/queue_views.hpp +0 -11
  428. data/src/cxx_supportlib/vendor-modified/boost/thread/concurrent_queues/sync_timed_queue.hpp +6 -4
  429. data/src/cxx_supportlib/vendor-modified/boost/thread/detail/config.hpp +11 -2
  430. data/src/cxx_supportlib/vendor-modified/boost/thread/detail/thread.hpp +11 -4
  431. data/src/cxx_supportlib/vendor-modified/boost/thread/exceptions.hpp +8 -8
  432. data/src/cxx_supportlib/vendor-modified/boost/thread/executors/executor.hpp +1 -1
  433. data/src/cxx_supportlib/vendor-modified/boost/thread/executors/generic_executor_ref.hpp +5 -5
  434. data/src/cxx_supportlib/vendor-modified/boost/thread/executors/loop_executor.hpp +22 -18
  435. data/src/cxx_supportlib/vendor-modified/boost/thread/future.hpp +163 -55
  436. data/src/cxx_supportlib/vendor-modified/boost/thread/futures/launch.hpp +1 -0
  437. data/src/cxx_supportlib/vendor-modified/boost/thread/futures/wait_for_all.hpp +1 -1
  438. data/src/cxx_supportlib/vendor-modified/boost/thread/lock_types.hpp +9 -9
  439. data/src/cxx_supportlib/vendor-modified/boost/thread/locks.hpp +1 -0
  440. data/src/cxx_supportlib/vendor-modified/boost/thread/pthread/condition_variable.hpp +6 -7
  441. data/src/cxx_supportlib/vendor-modified/boost/thread/pthread/condition_variable_fwd.hpp +17 -2
  442. data/src/cxx_supportlib/vendor-modified/boost/thread/pthread/shared_mutex.hpp +2 -2
  443. data/src/cxx_supportlib/vendor-modified/boost/thread/pthread/thread_data.hpp +5 -5
  444. data/src/cxx_supportlib/vendor-modified/boost/thread/pthread/timespec.hpp +29 -0
  445. data/src/cxx_supportlib/vendor-modified/boost/thread/scoped_thread.hpp +23 -18
  446. data/src/cxx_supportlib/vendor-modified/boost/thread/synchronized_value.hpp +6 -6
  447. data/src/cxx_supportlib/vendor-modified/boost/thread/thread_functors.hpp +19 -4
  448. data/src/cxx_supportlib/vendor-modified/boost/thread/thread_guard.hpp +3 -3
  449. data/src/cxx_supportlib/vendor-modified/boost/thread/user_scheduler.hpp +1 -1
  450. data/src/cxx_supportlib/vendor-modified/boost/type_index.hpp +265 -0
  451. data/src/cxx_supportlib/vendor-modified/boost/type_index/stl_type_index.hpp +272 -0
  452. data/src/cxx_supportlib/vendor-modified/boost/type_index/type_index_facade.hpp +300 -0
  453. data/src/cxx_supportlib/vendor-modified/boost/type_traits/add_reference.hpp +3 -3
  454. data/src/cxx_supportlib/vendor-modified/boost/type_traits/aligned_storage.hpp +6 -6
  455. data/src/cxx_supportlib/vendor-modified/boost/type_traits/common_type.hpp +1 -0
  456. data/src/cxx_supportlib/vendor-modified/boost/type_traits/detail/common_arithmetic_type.hpp +9 -3
  457. data/src/cxx_supportlib/vendor-modified/boost/type_traits/detail/mp_defer.hpp +3 -3
  458. data/src/cxx_supportlib/vendor-modified/boost/type_traits/extent.hpp +1 -0
  459. data/src/cxx_supportlib/vendor-modified/boost/type_traits/has_nothrow_assign.hpp +2 -1
  460. data/src/cxx_supportlib/vendor-modified/boost/type_traits/has_nothrow_constructor.hpp +2 -1
  461. data/src/cxx_supportlib/vendor-modified/boost/type_traits/has_nothrow_destructor.hpp +1 -1
  462. data/src/cxx_supportlib/vendor-modified/boost/type_traits/has_trivial_assign.hpp +2 -1
  463. data/src/cxx_supportlib/vendor-modified/boost/type_traits/has_trivial_copy.hpp +1 -0
  464. data/src/cxx_supportlib/vendor-modified/boost/type_traits/has_trivial_destructor.hpp +1 -1
  465. data/src/cxx_supportlib/vendor-modified/boost/type_traits/has_trivial_move_assign.hpp +1 -0
  466. data/src/cxx_supportlib/vendor-modified/boost/type_traits/has_trivial_move_constructor.hpp +1 -0
  467. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_abstract.hpp +1 -0
  468. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_array.hpp +1 -1
  469. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_assignable.hpp +1 -0
  470. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_const.hpp +2 -1
  471. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_default_constructible.hpp +21 -1
  472. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_destructible.hpp +1 -0
  473. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_nothrow_move_assignable.hpp +1 -1
  474. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_nothrow_move_constructible.hpp +2 -1
  475. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_pod.hpp +1 -0
  476. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_rvalue_reference.hpp +1 -1
  477. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_virtual_base_of.hpp +1 -1
  478. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_volatile.hpp +2 -1
  479. data/src/cxx_supportlib/vendor-modified/boost/type_traits/make_void.hpp +52 -0
  480. data/src/cxx_supportlib/vendor-modified/boost/type_traits/rank.hpp +1 -0
  481. data/src/cxx_supportlib/vendor-modified/boost/type_traits/remove_all_extents.hpp +1 -1
  482. data/src/cxx_supportlib/vendor-modified/boost/type_traits/remove_const.hpp +1 -1
  483. data/src/cxx_supportlib/vendor-modified/boost/type_traits/remove_cv.hpp +1 -1
  484. data/src/cxx_supportlib/vendor-modified/boost/type_traits/remove_extent.hpp +1 -1
  485. data/src/cxx_supportlib/vendor-modified/boost/type_traits/remove_pointer.hpp +1 -1
  486. data/src/cxx_supportlib/vendor-modified/boost/type_traits/remove_volatile.hpp +1 -1
  487. data/src/cxx_supportlib/vendor-modified/boost/type_traits/type_with_alignment.hpp +1 -1
  488. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/fwd.hpp +40 -6
  489. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/implementation.hpp +4986 -0
  490. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/map.hpp +107 -0
  491. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/set.hpp +105 -0
  492. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_map.hpp +1814 -1255
  493. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_map_fwd.hpp +41 -45
  494. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_set.hpp +1498 -1161
  495. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_set_fwd.hpp +40 -44
  496. data/src/cxx_supportlib/vendor-modified/boost/utility.hpp +2 -2
  497. data/src/cxx_supportlib/vendor-modified/boost/utility/base_from_member.hpp +7 -6
  498. data/src/cxx_supportlib/vendor-modified/boost/utility/compare_pointees.hpp +10 -2
  499. data/src/cxx_supportlib/vendor-modified/boost/utility/string_ref.hpp +39 -22
  500. data/src/cxx_supportlib/vendor-modified/boost/utility/string_view.hpp +690 -0
  501. data/src/cxx_supportlib/vendor-modified/boost/utility/string_view_fwd.hpp +39 -0
  502. data/src/cxx_supportlib/vendor-modified/boost/version.hpp +2 -2
  503. data/src/helper-scripts/crash-watch.rb +3 -0
  504. data/src/ruby_supportlib/phusion_passenger.rb +1 -1
  505. data/src/ruby_supportlib/phusion_passenger/apache2/config_options.rb +1 -0
  506. data/src/ruby_supportlib/phusion_passenger/packaging.rb +2 -12
  507. metadata +77 -38
  508. data/dev/ci/inituidgid +0 -24
  509. data/dev/ci/run_jenkins.sh +0 -70
  510. data/dev/ci/run_travis.sh +0 -314
  511. data/doc/Design and Architecture.html +0 -2421
  512. data/doc/Design and Architecture.txt +0 -511
  513. data/doc/Security of user switching support.html +0 -1833
  514. data/doc/Users guide Apache.html +0 -3101
  515. data/doc/Users guide Apache.idmap.txt +0 -451
  516. data/doc/Users guide Apache.txt +0 -534
  517. data/doc/Users guide Nginx.html +0 -3026
  518. data/doc/Users guide Nginx.idmap.txt +0 -431
  519. data/doc/Users guide Nginx.txt +0 -451
  520. data/doc/Users guide Standalone.html +0 -2092
  521. data/doc/Users guide Standalone.idmap.txt +0 -137
  522. data/doc/Users guide Standalone.txt +0 -81
  523. data/doc/Users guide.html +0 -1606
  524. data/doc/Users guide.txt +0 -8
  525. data/src/cxx_supportlib/vendor-modified/boost/align/align.hpp +0 -20
  526. data/src/cxx_supportlib/vendor-modified/boost/align/detail/address.hpp +0 -29
  527. data/src/cxx_supportlib/vendor-modified/boost/align/detail/align.hpp +0 -40
  528. data/src/cxx_supportlib/vendor-modified/boost/align/detail/align_cxx11.hpp +0 -22
  529. data/src/cxx_supportlib/vendor-modified/boost/align/detail/is_alignment.hpp +0 -29
  530. data/src/cxx_supportlib/vendor-modified/boost/container/detail/hash_table.hpp +0 -383
  531. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/array_allocator.hpp +0 -318
  532. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/array_count_impl.hpp +0 -67
  533. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/array_traits.hpp +0 -60
  534. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/array_utility.hpp +0 -214
  535. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_if_array.hpp +0 -34
  536. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/allocate.hpp +0 -1128
  537. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/buckets.hpp +0 -928
  538. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/equivalent.hpp +0 -686
  539. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/extract_key.hpp +0 -188
  540. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/table.hpp +0 -873
  541. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/unique.hpp +0 -628
  542. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/util.hpp +0 -266
@@ -1,314 +0,0 @@
1
- #!/bin/bash
2
- # This script is run by Travis, to execute tests in the CI environment.
3
-
4
- set -e
5
-
6
- PASSENGER_ROOT=`dirname "$0"`
7
- PASSENGER_ROOT=`cd "$PASSENGER_ROOT/../.." && pwd`
8
- PASSENGER_ROOT_ON_DOCKER_HOST=${PASSENGER_ROOT_ON_DOCKER_HOST:-$PASSENGER_ROOT}
9
-
10
- if [[ "$CACHE_DIR_ON_DOCKER_HOST" != "" ]]; then
11
- CACHE_DIR=/host_cache
12
- else
13
- CACHE_DIR="$PWD/cache"
14
- CACHE_DIR_ON_DOCKER_HOST="$PWD/cache"
15
- fi
16
-
17
- COMPILE_CONCURRENCY=${COMPILE_CONCURRENCY:-2}
18
-
19
- TEST_DYNAMIC_WITH_NGINX_VERSION=1.9.15
20
-
21
- export VERBOSE=1
22
- export TRACE=1
23
- export DEVDEPS_DEFAULT=no
24
- export rvmsudo_secure_path=1
25
- export LC_CTYPE=C.UTF-8
26
- export DEPS_TARGET="$CACHE_DIR/bundle"
27
- export USE_CCACHE=true
28
- export CCACHE_DIR="$CACHE_DIR/ccache"
29
- export CCACHE_COMPRESS=1
30
- export CCACHE_COMPRESS_LEVEL=3
31
- unset BUNDLE_GEMFILE
32
-
33
- if [[ -e /etc/workaround-docker-2267 ]]; then
34
- HOSTS_FILE=/etc/workaround-docker-2267/hosts
35
- sudo ln -s /etc/hosts /etc/workaround-docker-2267/hosts
36
- sudo workaround-docker-2267
37
- find /usr/local/rvm/rubies/*/lib/ruby -name resolv.rb | sudo xargs sed -i 's|/etc/hosts|/cte/hosts|g'
38
- else
39
- HOSTS_FILE=/etc/hosts
40
- fi
41
-
42
- mkdir -p "$DEPS_TARGET"
43
- mkdir -p "$CCACHE_DIR"
44
-
45
- sudo sh -c "cat >> $HOSTS_FILE" <<EOF
46
- 127.0.0.1 passenger.test
47
- 127.0.0.1 mycook.passenger.test
48
- 127.0.0.1 zsfa.passenger.test
49
- 127.0.0.1 norails.passenger.test
50
- 127.0.0.1 1.passenger.test 2.passenger.test 3.passenger.test
51
- 127.0.0.1 4.passenger.test 5.passenger.test 6.passenger.test
52
- 127.0.0.1 7.passenger.test 8.passenger.test 9.passenger.test
53
- EOF
54
-
55
- function run()
56
- {
57
- echo "$ $@"
58
- "$@"
59
- }
60
-
61
- function retry_run()
62
- {
63
- local reset='\x1B[0m'
64
- local red='\x1B[31m'
65
- local yellow='\x1B[33m'
66
-
67
- local max_tries="$1"
68
- local number=2
69
- shift
70
-
71
- echo "$ $@"
72
- while true; do
73
- if "$@"; then
74
- return 0
75
- elif [[ $number -le $max_tries ]]; then
76
- echo -e "${yellow}The command \"$@\" failed. Retrying, $number of $max_tries:${reset}"
77
- (( number++ ))
78
- else
79
- echo -e "${red}The command \"$@\" failed after $max_tries attempts. Giving up.${reset}"
80
- return 1
81
- fi
82
- done
83
- }
84
-
85
- function apt_get_update() {
86
- if [[ "$apt_get_updated" = "" ]]; then
87
- apt_get_updated=1
88
- run sudo apt-get update
89
- fi
90
- }
91
-
92
- function brew_update() {
93
- if [[ "$brew_updated" = "" ]]; then
94
- brew_updated=1
95
- run brew update
96
- fi
97
- }
98
-
99
- function rake_test_install_deps()
100
- {
101
- # We do not use Bundler here because the goal might be to
102
- # install the Rake version as specified in the Gemfile,
103
- # which we may not have yet.
104
- run env NOEXEC_DISABLE=1 rake test:install_deps "$@"
105
- local code=$?
106
- if [[ $code != 0 ]]; then
107
- return $code
108
- fi
109
-
110
- local bundle_path
111
- if ! bundle_path=`bundle show rake`; then
112
- bundle_path=`bundle show nokogiri`
113
- fi
114
- bundle_path=`dirname "$bundle_path"`
115
- bundle_path=`dirname "$bundle_path"`
116
- echo "Adding bundle path $bundle_path to GEM_PATH"
117
- export GEM_PATH="$bundle_path:$GEM_PATH"
118
- if [[ "$TRAVIS_OS_NAME" == 'osx' ]]; then
119
- run brew install ccache
120
- fi
121
- }
122
-
123
- function install_test_deps_with_doctools()
124
- {
125
- if [[ "$install_test_deps_with_doctools" = "" ]]; then
126
- install_test_deps_with_doctools=1
127
- retry_run 3 rake_test_install_deps BASE_DEPS=yes DOCTOOLS=yes
128
- fi
129
- }
130
-
131
- function install_base_test_deps()
132
- {
133
- if [[ "$install_base_test_deps" = "" ]]; then
134
- install_base_test_deps=1
135
- if [[ "$TRAVIS_OS_NAME" == 'osx' ]]; then
136
- run brew install ccache
137
- fi
138
- retry_run 3 rake_test_install_deps BASE_DEPS=yes
139
- fi
140
- }
141
-
142
- function install_node_and_modules()
143
- {
144
- if [[ "$install_node_and_modules" = "" ]]; then
145
- install_node_and_modules=1
146
- if [[ -e /host_cache ]]; then
147
- if [[ "$TRAVIS_OS_NAME" == 'osx' ]]; then
148
- if [[ ! -e /host_cache/node-v4.7.2-darwin-x64.tar.gz ]]; then
149
- run curl --fail -L -o /host_cache/node-v4.7.2-darwin-x64.tar.gz \
150
- https://nodejs.org/dist/v4.7.2/node-v4.7.2-darwin-x64.tar.gz
151
- fi
152
- run tar xzf /host_cache/node-v4.7.2-darwin-x64.tar.gz
153
- else
154
- if [[ ! -e /host_cache/node-v4.7.2-linux-x64.tar.gz ]]; then
155
- run curl --fail -L -o /host_cache/node-v4.7.2-linux-x64.tar.gz \
156
- https://nodejs.org/dist/v4.7.2/node-v4.7.2-linux-x64.tar.gz
157
- fi
158
- run tar xzf /host_cache/node-v4.7.2-linux-x64.tar.gz
159
- fi
160
- else
161
- if [[ "$TRAVIS_OS_NAME" == 'osx' ]]; then
162
- run curl --fail -L -O https://nodejs.org/dist/v4.7.2/node-v4.7.2-darwin-x64.tar.gz
163
- run tar xzf node-v4.7.2-darwin-x64.tar.gz
164
- else
165
- run curl --fail -L -O https://nodejs.org/dist/v4.7.2/node-v4.7.2-linux-x64.tar.gz
166
- run tar xzf node-v4.7.2-linux-x64.tar.gz
167
- fi
168
- fi
169
- if [[ "$TRAVIS_OS_NAME" == 'osx' ]]; then
170
- export PATH=`pwd`/node-v4.7.2-darwin-x64/bin:$PATH
171
- else
172
- export PATH=`pwd`/node-v4.7.2-linux-x64/bin:$PATH
173
- fi
174
- retry_run 3 rake_test_install_deps NODE_MODULES=yes
175
- fi
176
- }
177
-
178
- run uname -a
179
- if [[ "$TRAVIS_OS_NAME" == 'osx' ]]; then
180
- run sysctl -a
181
- echo '$ sed -e "s/_USER_/'$USER'/" test/config.json.travis-osx > test/config.json'
182
- sed -e "s/_USER_/$USER/" test/config.json.travis-osx > test/config.json
183
- else
184
- run lsb_release -a
185
- run sudo tee /etc/dpkg/dpkg.cfg.d/02apt-speedup >/dev/null <<<"force-unsafe-io"
186
- run cp test/config.json.travis test/config.json
187
- fi
188
-
189
- # Relax permissions on home directory so that the application root
190
- # permission checks pass.
191
- run chmod g+x,o+x $HOME
192
-
193
- if [[ "$TEST_RUBY_VERSION" != "" ]]; then
194
- if [[ -f ~/.rvm/scripts/rvm ]]; then
195
- source ~/.rvm/scripts/rvm
196
- else
197
- source /usr/local/rvm/scripts/rvm
198
- fi
199
- echo "$ rvm list"
200
- rvm list
201
- echo "$ rvm install $TEST_RUBY_VERSION"
202
- rvm install $TEST_RUBY_VERSION
203
- echo "$ rvm use $TEST_RUBY_VERSION"
204
- rvm use $TEST_RUBY_VERSION
205
- if [[ "$TEST_RUBYGEMS_VERSION" = "" ]]; then
206
- run gem --version
207
- fi
208
- fi
209
-
210
- if [[ "$TEST_RUBYGEMS_VERSION" != "" ]]; then
211
- retry_run 3 rvm install rubygems $TEST_RUBYGEMS_VERSION
212
- run gem --version
213
- fi
214
-
215
- ORIG_GEM_PATH="$GEM_PATH"
216
-
217
- if [[ "$INSTALL_ALL_DEPS" = 1 ]]; then
218
- run rake_test_install_deps DEVDEPS_DEFAULT=yes
219
- INSTALL_DEPS=0
220
- fi
221
-
222
- if [[ "$TEST_CXX" = 1 ]]; then
223
- install_base_test_deps
224
- run bundle exec drake -j$COMPILE_CONCURRENCY test:cxx
225
- run bundle exec rake test:oxt
226
- fi
227
-
228
- if [[ "$TEST_RUBY" = 1 ]]; then
229
- retry_run 3 rake_test_install_deps BASE_DEPS=yes
230
- run bundle exec drake -j$COMPILE_CONCURRENCY test:ruby
231
- fi
232
-
233
- if [[ "$TEST_USH" = 1 ]]; then
234
- retry_run 3 rake_test_install_deps BASE_DEPS=yes USH_BUNDLES=yes
235
- export PASSENGER_CONFIG="$PWD/bin/passenger-config"
236
- run "$PASSENGER_CONFIG" install-standalone-runtime --auto
237
-
238
- # RVM is bad and should feel bad
239
- builtin pushd src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core
240
- bundle exec rake spec:travis TRAVIS_WITH_SUDO=1
241
- builtin popd
242
-
243
- builtin pushd src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_rails
244
- bundle exec rake spec:travis GEM_BUNDLE_PATH="$DEPS_TARGET"
245
- builtin popd
246
- fi
247
-
248
- if [[ "$TEST_NODE" = 1 ]]; then
249
- install_node_and_modules
250
- run bundle exec drake -j$COMPILE_CONCURRENCY test:node
251
- fi
252
-
253
- if [[ "$TEST_NGINX" = 1 ]]; then
254
- install_base_test_deps
255
- install_node_and_modules
256
- run ./bin/passenger-install-nginx-module --auto --prefix=/tmp/nginx --auto-download
257
- run bundle exec drake -j$COMPILE_CONCURRENCY test:integration:nginx
258
-
259
- run curl -sSLO http://www.nginx.org/download/nginx-$TEST_DYNAMIC_WITH_NGINX_VERSION.tar.gz
260
- run tar zxf nginx-$TEST_DYNAMIC_WITH_NGINX_VERSION.tar.gz
261
- run cd nginx-$TEST_DYNAMIC_WITH_NGINX_VERSION
262
- run ./configure --add-dynamic-module=$(../bin/passenger-config --nginx-addon-dir)
263
- run make
264
- run cd ..
265
- fi
266
-
267
- if [[ "$TEST_APACHE2" = 1 ]]; then
268
- if [[ "$TRAVIS_OS_NAME" == 'osx' ]]; then
269
- brew_update
270
- run brew upgrade openssl || run brew install openssl
271
- run brew upgrade pcre || run brew install pcre
272
- if [[ "`sw_vers -productVersion | sed 's/^10\.\(.*\)/\1>=12.0/' | bc -l`" == "1" ]] ; then
273
- run brew install apr apr-util
274
- run brew link apr apr-util --force
275
- export APR_CONFIG=`brew --prefix`/opt/apr/bin/apr-1-config
276
- export APU_CONFIG=`brew --prefix`/opt/apr-util/bin/apu-1-config
277
- fi
278
- else
279
- apt_get_update
280
- run sudo apt-get install -y --no-install-recommends \
281
- apache2-mpm-worker apache2-threaded-dev
282
- fi
283
- install_base_test_deps
284
- install_node_and_modules
285
- run ./bin/passenger-install-apache2-module --auto #--no-update-config
286
- if [[ "$TRAVIS_OS_NAME" == 'osx' ]]; then
287
- # rvmsudo only preserves env vars matching /^(rvm|gemset|http_|PATH|IRBRC)|RUBY|GEM/
288
- # https://github.com/rvm/rvm/blob/aae6505001e2d6b5e4dc9a355c18ffcbd073bab2/bin/rvmsudo#L83
289
- run sudo -E ./bin/passenger-install-apache2-module --auto --no-compile
290
- else
291
- run rvmsudo ./bin/passenger-install-apache2-module --auto --no-compile
292
- fi
293
- run bundle exec drake -j$COMPILE_CONCURRENCY test:integration:apache2
294
- fi
295
-
296
- if [[ "$TEST_STANDALONE" = 1 ]]; then
297
- install_base_test_deps
298
- run bundle exec drake -j$COMPILE_CONCURRENCY test:integration:standalone
299
- fi
300
-
301
- if [[ "$TEST_SOURCE_PACKAGING" = 1 ]]; then
302
- if [[ "$TRAVIS_OS_NAME" == 'osx' ]]; then
303
- brew_update
304
- run brew install source-highlight
305
- else
306
- apt_get_update
307
- run sudo apt-get install -y --no-install-recommends source-highlight
308
- fi
309
- install_test_deps_with_doctools
310
- run bundle _1.11.2_ exec rspec -f s -c test/integration_tests/source_packaging_test.rb
311
- fi
312
- if [[ "$TRAVIS_OS_NAME" == 'osx' ]]; then
313
- trap - EXIT
314
- fi
@@ -1,2421 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5
- <meta name="generator" content="AsciiDoc 8.6.7">
6
- <title>Phusion Passenger Design and Architecture</title>
7
- <style type="text/css">
8
- /* Shared CSS for AsciiDoc xhtml11 and html5 backends */
9
-
10
- /* Default font. */
11
- body {
12
- font-family: Georgia,serif;
13
- }
14
-
15
- /* Title font. */
16
- h1, h2, h3, h4, h5, h6,
17
- div.title, caption.title,
18
- thead, p.table.header,
19
- #toctitle,
20
- #author, #revnumber, #revdate, #revremark,
21
- #footer {
22
- font-family: Arial,Helvetica,sans-serif;
23
- }
24
-
25
- body {
26
- margin: 1em 5% 1em 5%;
27
- }
28
-
29
- a {
30
- color: blue;
31
- text-decoration: underline;
32
- }
33
- a:visited {
34
- color: fuchsia;
35
- }
36
-
37
- em {
38
- font-style: italic;
39
- color: navy;
40
- }
41
-
42
- strong {
43
- font-weight: bold;
44
- color: #083194;
45
- }
46
-
47
- h1, h2, h3, h4, h5, h6 {
48
- color: #527bbd;
49
- margin-top: 1.2em;
50
- margin-bottom: 0.5em;
51
- line-height: 1.3;
52
- }
53
-
54
- h1, h2, h3 {
55
- border-bottom: 2px solid silver;
56
- }
57
- h2 {
58
- padding-top: 0.5em;
59
- }
60
- h3 {
61
- float: left;
62
- }
63
- h3 + * {
64
- clear: left;
65
- }
66
- h5 {
67
- font-size: 1.0em;
68
- }
69
-
70
- div.sectionbody {
71
- margin-left: 0;
72
- }
73
-
74
- hr {
75
- border: 1px solid silver;
76
- }
77
-
78
- p {
79
- margin-top: 0.5em;
80
- margin-bottom: 0.5em;
81
- }
82
-
83
- ul, ol, li > p {
84
- margin-top: 0;
85
- }
86
- ul > li { color: #aaa; }
87
- ul > li > * { color: black; }
88
-
89
- pre {
90
- padding: 0;
91
- margin: 0;
92
- overflow: auto;
93
- }
94
-
95
- #author {
96
- color: #527bbd;
97
- font-weight: bold;
98
- font-size: 1.1em;
99
- }
100
- #email {
101
- }
102
- #revnumber, #revdate, #revremark {
103
- }
104
-
105
- #footer {
106
- font-size: small;
107
- border-top: 2px solid silver;
108
- padding-top: 0.5em;
109
- margin-top: 4.0em;
110
- }
111
- #footer-text {
112
- float: left;
113
- padding-bottom: 0.5em;
114
- }
115
- #footer-badges {
116
- float: right;
117
- padding-bottom: 0.5em;
118
- }
119
-
120
- #preamble {
121
- margin-top: 1.5em;
122
- margin-bottom: 1.5em;
123
- }
124
- div.imageblock, div.exampleblock, div.verseblock,
125
- div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
126
- div.admonitionblock {
127
- margin-top: 1.0em;
128
- margin-bottom: 1.5em;
129
- }
130
- div.admonitionblock {
131
- margin-top: 2.0em;
132
- margin-bottom: 2.0em;
133
- margin-right: 10%;
134
- color: #606060;
135
- }
136
-
137
- div.content { /* Block element content. */
138
- padding: 0;
139
- }
140
-
141
- /* Block element titles. */
142
- div.title, caption.title {
143
- color: #527bbd;
144
- font-weight: bold;
145
- text-align: left;
146
- margin-top: 1.0em;
147
- margin-bottom: 0.5em;
148
- }
149
- div.title + * {
150
- margin-top: 0;
151
- }
152
-
153
- td div.title:first-child {
154
- margin-top: 0.0em;
155
- }
156
- div.content div.title:first-child {
157
- margin-top: 0.0em;
158
- }
159
- div.content + div.title {
160
- margin-top: 0.0em;
161
- }
162
-
163
- div.sidebarblock > div.content {
164
- background: #ffffee;
165
- border: 1px solid #dddddd;
166
- border-left: 4px solid #f0f0f0;
167
- padding: 0.5em;
168
- }
169
-
170
- div.listingblock > div.content {
171
- border: 1px solid #dddddd;
172
- border-left: 5px solid #f0f0f0;
173
- background: #f8f8f8;
174
- padding: 0.5em;
175
- }
176
-
177
- div.quoteblock, div.verseblock {
178
- padding-left: 1.0em;
179
- margin-left: 1.0em;
180
- margin-right: 10%;
181
- border-left: 5px solid #f0f0f0;
182
- color: #777777;
183
- }
184
-
185
- div.quoteblock > div.attribution {
186
- padding-top: 0.5em;
187
- text-align: right;
188
- }
189
-
190
- div.verseblock > pre.content {
191
- font-family: inherit;
192
- font-size: inherit;
193
- }
194
- div.verseblock > div.attribution {
195
- padding-top: 0.75em;
196
- text-align: left;
197
- }
198
- /* DEPRECATED: Pre version 8.2.7 verse style literal block. */
199
- div.verseblock + div.attribution {
200
- text-align: left;
201
- }
202
-
203
- div.admonitionblock .icon {
204
- vertical-align: top;
205
- font-size: 1.1em;
206
- font-weight: bold;
207
- text-decoration: underline;
208
- color: #527bbd;
209
- padding-right: 0.5em;
210
- }
211
- div.admonitionblock td.content {
212
- padding-left: 0.5em;
213
- border-left: 3px solid #dddddd;
214
- }
215
-
216
- div.exampleblock > div.content {
217
- border-left: 3px solid #dddddd;
218
- padding-left: 0.5em;
219
- }
220
-
221
- div.imageblock div.content { padding-left: 0; }
222
- span.image img { border-style: none; }
223
- a.image:visited { color: white; }
224
-
225
- dl {
226
- margin-top: 0.8em;
227
- margin-bottom: 0.8em;
228
- }
229
- dt {
230
- margin-top: 0.5em;
231
- margin-bottom: 0;
232
- font-style: normal;
233
- color: navy;
234
- }
235
- dd > *:first-child {
236
- margin-top: 0.1em;
237
- }
238
-
239
- ul, ol {
240
- list-style-position: outside;
241
- }
242
- ol.arabic {
243
- list-style-type: decimal;
244
- }
245
- ol.loweralpha {
246
- list-style-type: lower-alpha;
247
- }
248
- ol.upperalpha {
249
- list-style-type: upper-alpha;
250
- }
251
- ol.lowerroman {
252
- list-style-type: lower-roman;
253
- }
254
- ol.upperroman {
255
- list-style-type: upper-roman;
256
- }
257
-
258
- div.compact ul, div.compact ol,
259
- div.compact p, div.compact p,
260
- div.compact div, div.compact div {
261
- margin-top: 0.1em;
262
- margin-bottom: 0.1em;
263
- }
264
-
265
- tfoot {
266
- font-weight: bold;
267
- }
268
- td > div.verse {
269
- white-space: pre;
270
- }
271
-
272
- div.hdlist {
273
- margin-top: 0.8em;
274
- margin-bottom: 0.8em;
275
- }
276
- div.hdlist tr {
277
- padding-bottom: 15px;
278
- }
279
- dt.hdlist1.strong, td.hdlist1.strong {
280
- font-weight: bold;
281
- }
282
- td.hdlist1 {
283
- vertical-align: top;
284
- font-style: normal;
285
- padding-right: 0.8em;
286
- color: navy;
287
- }
288
- td.hdlist2 {
289
- vertical-align: top;
290
- }
291
- div.hdlist.compact tr {
292
- margin: 0;
293
- padding-bottom: 0;
294
- }
295
-
296
- .comment {
297
- background: yellow;
298
- }
299
-
300
- .footnote, .footnoteref {
301
- font-size: 0.8em;
302
- }
303
-
304
- span.footnote, span.footnoteref {
305
- vertical-align: super;
306
- }
307
-
308
- #footnotes {
309
- margin: 20px 0 20px 0;
310
- padding: 7px 0 0 0;
311
- }
312
-
313
- #footnotes div.footnote {
314
- margin: 0 0 5px 0;
315
- }
316
-
317
- #footnotes hr {
318
- border: none;
319
- border-top: 1px solid silver;
320
- height: 1px;
321
- text-align: left;
322
- margin-left: 0;
323
- width: 20%;
324
- min-width: 100px;
325
- }
326
-
327
- div.colist td {
328
- padding-right: 0.5em;
329
- padding-bottom: 0.3em;
330
- vertical-align: top;
331
- }
332
- div.colist td img {
333
- margin-top: 0.3em;
334
- }
335
-
336
- @media print {
337
- #footer-badges { display: none; }
338
- }
339
-
340
- #toc {
341
- margin-bottom: 2.5em;
342
- }
343
-
344
- #toctitle {
345
- color: #527bbd;
346
- font-size: 1.1em;
347
- font-weight: bold;
348
- margin-top: 1.0em;
349
- margin-bottom: 0.1em;
350
- }
351
-
352
- div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
353
- margin-top: 0;
354
- margin-bottom: 0;
355
- }
356
- div.toclevel2 {
357
- margin-left: 2em;
358
- font-size: 0.9em;
359
- }
360
- div.toclevel3 {
361
- margin-left: 4em;
362
- font-size: 0.9em;
363
- }
364
- div.toclevel4 {
365
- margin-left: 6em;
366
- font-size: 0.9em;
367
- }
368
-
369
- span.aqua { color: aqua; }
370
- span.black { color: black; }
371
- span.blue { color: blue; }
372
- span.fuchsia { color: fuchsia; }
373
- span.gray { color: gray; }
374
- span.green { color: green; }
375
- span.lime { color: lime; }
376
- span.maroon { color: maroon; }
377
- span.navy { color: navy; }
378
- span.olive { color: olive; }
379
- span.purple { color: purple; }
380
- span.red { color: red; }
381
- span.silver { color: silver; }
382
- span.teal { color: teal; }
383
- span.white { color: white; }
384
- span.yellow { color: yellow; }
385
-
386
- span.aqua-background { background: aqua; }
387
- span.black-background { background: black; }
388
- span.blue-background { background: blue; }
389
- span.fuchsia-background { background: fuchsia; }
390
- span.gray-background { background: gray; }
391
- span.green-background { background: green; }
392
- span.lime-background { background: lime; }
393
- span.maroon-background { background: maroon; }
394
- span.navy-background { background: navy; }
395
- span.olive-background { background: olive; }
396
- span.purple-background { background: purple; }
397
- span.red-background { background: red; }
398
- span.silver-background { background: silver; }
399
- span.teal-background { background: teal; }
400
- span.white-background { background: white; }
401
- span.yellow-background { background: yellow; }
402
-
403
- span.big { font-size: 2em; }
404
- span.small { font-size: 0.6em; }
405
-
406
- span.underline { text-decoration: underline; }
407
- span.overline { text-decoration: overline; }
408
- span.line-through { text-decoration: line-through; }
409
-
410
-
411
- /*
412
- * xhtml11 specific
413
- *
414
- * */
415
-
416
- tt {
417
- font-family: monospace;
418
- font-size: inherit;
419
- color: navy;
420
- }
421
-
422
- div.tableblock {
423
- margin-top: 1.0em;
424
- margin-bottom: 1.5em;
425
- }
426
- div.tableblock > table {
427
- border: 3px solid #527bbd;
428
- }
429
- thead, p.table.header {
430
- font-weight: bold;
431
- color: #527bbd;
432
- }
433
- p.table {
434
- margin-top: 0;
435
- }
436
- /* Because the table frame attribute is overriden by CSS in most browsers. */
437
- div.tableblock > table[frame="void"] {
438
- border-style: none;
439
- }
440
- div.tableblock > table[frame="hsides"] {
441
- border-left-style: none;
442
- border-right-style: none;
443
- }
444
- div.tableblock > table[frame="vsides"] {
445
- border-top-style: none;
446
- border-bottom-style: none;
447
- }
448
-
449
-
450
- /*
451
- * html5 specific
452
- *
453
- * */
454
-
455
- .monospaced {
456
- font-family: monospace;
457
- font-size: inherit;
458
- color: navy;
459
- }
460
-
461
- table.tableblock {
462
- margin-top: 1.0em;
463
- margin-bottom: 1.5em;
464
- }
465
- thead, p.tableblock.header {
466
- font-weight: bold;
467
- color: #527bbd;
468
- }
469
- p.tableblock {
470
- margin-top: 0;
471
- }
472
- table.tableblock {
473
- border-width: 3px;
474
- border-spacing: 0px;
475
- border-style: solid;
476
- border-color: #527bbd;
477
- border-collapse: collapse;
478
- }
479
- th.tableblock, td.tableblock {
480
- border-width: 1px;
481
- padding: 4px;
482
- border-style: solid;
483
- border-color: #527bbd;
484
- }
485
-
486
- table.tableblock.frame-topbot {
487
- border-left-style: hidden;
488
- border-right-style: hidden;
489
- }
490
- table.tableblock.frame-sides {
491
- border-top-style: hidden;
492
- border-bottom-style: hidden;
493
- }
494
- table.tableblock.frame-none {
495
- border-style: hidden;
496
- }
497
-
498
- th.tableblock.halign-left, td.tableblock.halign-left {
499
- text-align: left;
500
- }
501
- th.tableblock.halign-center, td.tableblock.halign-center {
502
- text-align: center;
503
- }
504
- th.tableblock.halign-right, td.tableblock.halign-right {
505
- text-align: right;
506
- }
507
-
508
- th.tableblock.valign-top, td.tableblock.valign-top {
509
- vertical-align: top;
510
- }
511
- th.tableblock.valign-middle, td.tableblock.valign-middle {
512
- vertical-align: middle;
513
- }
514
- th.tableblock.valign-bottom, td.tableblock.valign-bottom {
515
- vertical-align: bottom;
516
- }
517
-
518
-
519
- /*
520
- * manpage specific
521
- *
522
- * */
523
-
524
- body.manpage h1 {
525
- padding-top: 0.5em;
526
- padding-bottom: 0.5em;
527
- border-top: 2px solid silver;
528
- border-bottom: 2px solid silver;
529
- }
530
- body.manpage h2 {
531
- border-style: none;
532
- }
533
- body.manpage div.sectionbody {
534
- margin-left: 3em;
535
- }
536
-
537
- @media print {
538
- body.manpage div#toc { display: none; }
539
- }
540
-
541
-
542
- /*
543
- * Theme specific overrides of the preceding (asciidoc.css) CSS.
544
- *
545
- */
546
- body {
547
- font-family: Garamond, Georgia, serif;
548
- font-size: 17px;
549
- color: #3E4349;
550
- line-height: 1.3em;
551
- }
552
- h1, h2, h3, h4, h5, h6,
553
- div.title, caption.title,
554
- thead, p.table.header,
555
- #toctitle,
556
- #author, #revnumber, #revdate, #revremark,
557
- #footer {
558
- font-family: Garmond, Georgia, serif;
559
- font-weight: normal;
560
- border-bottom-width: 0;
561
- color: #3E4349;
562
- }
563
- div.title, caption.title { color: #596673; font-weight: bold; }
564
- h1 { font-size: 240%; }
565
- h2 { font-size: 180%; }
566
- h3 { font-size: 150%; }
567
- h4 { font-size: 130%; }
568
- h5 { font-size: 115%; }
569
- h6 { font-size: 100%; }
570
- #header h1 { margin-top: 0; }
571
- #toc {
572
- color: #444444;
573
- line-height: 1.5;
574
- padding-top: 1.5em;
575
- }
576
- #toctitle {
577
- font-size: 20px;
578
- }
579
- #toc a {
580
- border-bottom: 1px dotted #999999;
581
- color: #444444 !important;
582
- text-decoration: none !important;
583
- }
584
- #toc a:hover {
585
- border-bottom: 1px solid #6D4100;
586
- color: #6D4100 !important;
587
- text-decoration: none !important;
588
- }
589
- div.toclevel1 { margin-top: 0.2em; font-size: 16px; }
590
- div.toclevel2 { margin-top: 0.15em; font-size: 14px; }
591
- em, dt, td.hdlist1 { color: black; }
592
- strong { color: #3E4349; }
593
- a { color: #004B6B; text-decoration: none; border-bottom: 1px dotted #004B6B; }
594
- a:visited { color: #615FA0; border-bottom: 1px dotted #615FA0; }
595
- a:hover { color: #6D4100; border-bottom: 1px solid #6D4100; }
596
- div.tableblock > table, table.tableblock { border: 3px solid #E8E8E8; }
597
- th.tableblock, td.tableblock { border: 1px solid #E8E8E8; }
598
- ul > li > * { color: #3E4349; }
599
- pre, tt, .monospaced { font-family: Consolas,Menlo,'Deja Vu Sans Mono','Bitstream Vera Sans Mono',monospace; }
600
- tt, .monospaced { font-size: 0.9em; color: black;
601
- }
602
- div.exampleblock > div.content, div.sidebarblock > div.content, div.listingblock > div.content { border-width: 0 0 0 3px; border-color: #E8E8E8; }
603
- div.verseblock { border-left-width: 0; margin-left: 3em; }
604
- div.quoteblock { border-left-width: 3px; margin-left: 0; margin-right: 0;}
605
- div.admonitionblock td.content { border-left: 3px solid #E8E8E8; }
606
- </style>
607
- <script type="text/javascript">
608
- /*<![CDATA[*/
609
- var asciidoc = { // Namespace.
610
-
611
- /////////////////////////////////////////////////////////////////////
612
- // Table Of Contents generator
613
- /////////////////////////////////////////////////////////////////////
614
-
615
- /* Author: Mihai Bazon, September 2002
616
- * http://students.infoiasi.ro/~mishoo
617
- *
618
- * Table Of Content generator
619
- * Version: 0.4
620
- *
621
- * Feel free to use this script under the terms of the GNU General Public
622
- * License, as long as you do not remove or alter this notice.
623
- */
624
-
625
- /* modified by Troy D. Hanson, September 2006. License: GPL */
626
- /* modified by Stuart Rackham, 2006, 2009. License: GPL */
627
-
628
- // toclevels = 1..4.
629
- toc: function (toclevels) {
630
-
631
- function getText(el) {
632
- var text = "";
633
- for (var i = el.firstChild; i != null; i = i.nextSibling) {
634
- if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
635
- text += i.data;
636
- else if (i.firstChild != null)
637
- text += getText(i);
638
- }
639
- return text;
640
- }
641
-
642
- function TocEntry(el, text, toclevel) {
643
- this.element = el;
644
- this.text = text;
645
- this.toclevel = toclevel;
646
- }
647
-
648
- function tocEntries(el, toclevels) {
649
- var result = new Array;
650
- var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
651
- // Function that scans the DOM tree for header elements (the DOM2
652
- // nodeIterator API would be a better technique but not supported by all
653
- // browsers).
654
- var iterate = function (el) {
655
- for (var i = el.firstChild; i != null; i = i.nextSibling) {
656
- if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
657
- var mo = re.exec(i.tagName);
658
- if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
659
- result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
660
- }
661
- iterate(i);
662
- }
663
- }
664
- }
665
- iterate(el);
666
- return result;
667
- }
668
-
669
- var toc = document.getElementById("toc");
670
- if (!toc) {
671
- return;
672
- }
673
-
674
- // Delete existing TOC entries in case we're reloading the TOC.
675
- var tocEntriesToRemove = [];
676
- var i;
677
- for (i = 0; i < toc.childNodes.length; i++) {
678
- var entry = toc.childNodes[i];
679
- if (entry.nodeName.toLowerCase() == 'div'
680
- && entry.getAttribute("class")
681
- && entry.getAttribute("class").match(/^toclevel/))
682
- tocEntriesToRemove.push(entry);
683
- }
684
- for (i = 0; i < tocEntriesToRemove.length; i++) {
685
- toc.removeChild(tocEntriesToRemove[i]);
686
- }
687
-
688
- // Rebuild TOC entries.
689
- var entries = tocEntries(document.getElementById("content"), toclevels);
690
- for (var i = 0; i < entries.length; ++i) {
691
- var entry = entries[i];
692
- if (entry.element.id == "")
693
- entry.element.id = "_toc_" + i;
694
- var a = document.createElement("a");
695
- a.href = "#" + entry.element.id;
696
- a.appendChild(document.createTextNode(entry.text));
697
- var div = document.createElement("div");
698
- div.appendChild(a);
699
- div.className = "toclevel" + entry.toclevel;
700
- toc.appendChild(div);
701
- }
702
- if (entries.length == 0)
703
- toc.parentNode.removeChild(toc);
704
- },
705
-
706
-
707
- /////////////////////////////////////////////////////////////////////
708
- // Footnotes generator
709
- /////////////////////////////////////////////////////////////////////
710
-
711
- /* Based on footnote generation code from:
712
- * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
713
- */
714
-
715
- footnotes: function () {
716
- // Delete existing footnote entries in case we're reloading the footnodes.
717
- var i;
718
- var noteholder = document.getElementById("footnotes");
719
- if (!noteholder) {
720
- return;
721
- }
722
- var entriesToRemove = [];
723
- for (i = 0; i < noteholder.childNodes.length; i++) {
724
- var entry = noteholder.childNodes[i];
725
- if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
726
- entriesToRemove.push(entry);
727
- }
728
- for (i = 0; i < entriesToRemove.length; i++) {
729
- noteholder.removeChild(entriesToRemove[i]);
730
- }
731
-
732
- // Rebuild footnote entries.
733
- var cont = document.getElementById("content");
734
- var spans = cont.getElementsByTagName("span");
735
- var refs = {};
736
- var n = 0;
737
- for (i=0; i<spans.length; i++) {
738
- if (spans[i].className == "footnote") {
739
- n++;
740
- var note = spans[i].getAttribute("data-note");
741
- if (!note) {
742
- // Use [\s\S] in place of . so multi-line matches work.
743
- // Because JavaScript has no s (dotall) regex flag.
744
- note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
745
- spans[i].innerHTML =
746
- "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
747
- "' title='View footnote' class='footnote'>" + n + "</a>]";
748
- spans[i].setAttribute("data-note", note);
749
- }
750
- noteholder.innerHTML +=
751
- "<div class='footnote' id='_footnote_" + n + "'>" +
752
- "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
753
- n + "</a>. " + note + "</div>";
754
- var id =spans[i].getAttribute("id");
755
- if (id != null) refs["#"+id] = n;
756
- }
757
- }
758
- if (n == 0)
759
- noteholder.parentNode.removeChild(noteholder);
760
- else {
761
- // Process footnoterefs.
762
- for (i=0; i<spans.length; i++) {
763
- if (spans[i].className == "footnoteref") {
764
- var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
765
- href = href.match(/#.*/)[0]; // Because IE return full URL.
766
- n = refs[href];
767
- spans[i].innerHTML =
768
- "[<a href='#_footnote_" + n +
769
- "' title='View footnote' class='footnote'>" + n + "</a>]";
770
- }
771
- }
772
- }
773
- },
774
-
775
- install: function(toclevels) {
776
- var timerId;
777
-
778
- function reinstall() {
779
- asciidoc.footnotes();
780
- if (toclevels) {
781
- asciidoc.toc(toclevels);
782
- }
783
- }
784
-
785
- function reinstallAndRemoveTimer() {
786
- clearInterval(timerId);
787
- reinstall();
788
- }
789
-
790
- timerId = setInterval(reinstall, 500);
791
- if (document.addEventListener)
792
- document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
793
- else
794
- window.onload = reinstallAndRemoveTimer;
795
- }
796
-
797
- }
798
- asciidoc.install();
799
- /*]]>*/
800
- </script>
801
- <style type="text/css">
802
- body {
803
- margin: 1em auto 1em auto;
804
- padding: 0 1em 0 1em;
805
- max-width: 800px;
806
- }
807
-
808
- a.image {
809
- border: none;
810
- }
811
-
812
- .comments {
813
- display: block;
814
- background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAgCAYAAAB6kdqOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAB0wAAAdMBc2+PegAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAASjSURBVFiFvZdPaBxVHMc/b/7sbNLdxG13s0sbE1jBxELVbVGEgqmQiiBiDxZqKRWhR0Fqe/BSmoNQSNmrt4ISTyV3byWLHorVU5dYtgVpk4DGhXZ1a7rZmXkeMm99eZn9k1b9wY/3Z2f2fX7f3++9mRFSSnQTQgjAAkTkaO2zmtRaCYTSABBqrIEkS6VS9vTp069lMpmClFL4vt8BCsNwWwsQBAHm7+Y4CAKEEEGtVvtlYWHhbqvVagJ/AE90MCGlVDD2xYsXiydPnvza87wXksnk8NDQUFIPQPW7zfXyMAwJw5BGo/FXs9ncvHfv3tKFCxe+aLfbDyKwQEopFZBdLpdfnp2d/Tafz4+5rhsxghAC1d+h/y5gzH69XvdrtdqDs2fPfuT7/jLQkFIGlhBC5HK5oZmZmW8KhUI+kUgIy7KwLAvbtrFte1vfdHVtnKtg9L7yffv2OcViceLSpUufA88DSSGEcABrfn7+zdHR0UnXdWNv1tXqpY6phGVZnRoy/0MIQT6fdw4ePHgUKAK/AU8sQOzfv/+tdDq9x4xKd1MVU51uSvTzVCrlTU9PTwN7AGEBYmRk5FXXdTvk+gI6kJnGQQG6KQQwMjLiTk1NTQIJBQTgmAWst2rhfiBxC3ab00wAbtRugZjb2LzR3O7d2rh7+s2Ztg1IwajChK2DTSlggpuFrHs34H7BOHELqN0Rl5K4P+4GNQioPt8BUqeoqpd+MGYQvQ7DfrCxKVNAcTCws0B7RdrvhO4HtS1lCkYtbKrT7WB8GihdQf2B3FFIPbEH2cY6iAljjk1l4qB2KKSrMwjMblXqpVpfIF2lXjBxULsB06HigDb1lA2ijgm0WyithmS73faJ3iYdgHq9/tOBAwfe9jyvJ4wam1H1O196QT18+HBzeXl5FQgVkLxz5873k5OTzWw2m+oHE6dMHEw3EGBbuh4/fuyvrKysAS1AOkA4Nzf3w5EjR+6m0+mS/tTvBhMH1U2lXgqtra21l5aWvgNWgCYQ2tH/hY1G48epqal3Pc/b4ziOGLQegiCIPVv0ubhDcXV1dfP27dv3y+Xyl0AVqAO+/pKfmpiYeHFubm4+m82+kkgkPNd1nbjI9TaZTNqu61rRQpbrujiOs+O6MAx59OhRuL6+3mq1Wq1KpXJjYWFhMYK5DzSljF7yo7RYwBCQBfKlUml6bGxsMggCLwgC/Ruts4CRPpFMJodnZmbeKBaLLxUKheFMJmPr6a5Wq0+uXLmyWK1WK8DPwBrwO7AhpQxB+y6LoARbhe4Bw0AyGlv0N/Vd56VSqb3nzp378PDhw+/ncrnnCoWCZ1kWvu9z69at9fPnz3+6sbFxE/gVaEkNYhuQBqUvsBtTSnrAKDB25syZ944dO/ZxNpvNjY+PDzebTb9Sqdy8fPnyZ0AN+FOpEwv0rKYFZEdgaSB7/PjxoydOnPgkl8tNAN7169fLi4uLX7G1w/5RadDnz9N4pJbNVupzwHSpVPrg6tWrN65du/broUOHZoEMYHXu+S+BYsA8YC9QHB8ff/3UqVPvREC2uvZfT1kvi9KpNo7LVo1uApsqZf8rkAHWMX2X/Q1tcUY1hl3QyQAAAABJRU5ErkJggg==') top left no-repeat;
815
- float: left;
816
- margin-left: -55px;
817
- width: 36px;
818
- height: 48px;
819
- line-height: 0;
820
- color: black;
821
- text-decoration: none !important;
822
- border: none !important;
823
- }
824
-
825
- #toc .comments {
826
- margin-top: 0.25em;
827
- }
828
-
829
- .sect1 .comments {
830
- margin-top: 0.5em;
831
- }
832
-
833
- .sect2 .comments {
834
- margin-top: 1.15em;
835
- }
836
-
837
- .sect3 .comments {
838
- margin-top: -1em;
839
- }
840
-
841
- .comments.empty {
842
- opacity: 0.2;
843
- }
844
-
845
- .comments.empty:hover,
846
- .comments.nonempty {
847
- opacity: 1;
848
- }
849
-
850
- .comments .count {
851
- display: block;
852
- font-size: 80%;
853
- padding-top: 12px;
854
- text-align: center;
855
- text-shadow: 1px 1px 2px white;
856
- }
857
-
858
- #comments_lightbox_shadow {
859
- position: fixed;
860
- top: 0;
861
- left: 0;
862
- right: 0;
863
- bottom: 0;
864
- background: black;
865
- opacity: 0.7;
866
- z-index: 10;
867
- }
868
-
869
- #comments_lightbox_contents {
870
- position: fixed;
871
- top: 10%;
872
- left: 20%;
873
- right: 20%;
874
- bottom: 10%;
875
- background: white;
876
- overflow: auto;
877
- z-index: 11;
878
- }
879
-
880
- #comments_lightbox_contents > .shell {
881
- margin: 2em;
882
- }
883
-
884
- pre {
885
- overflow: auto;
886
- }
887
-
888
- @media print {
889
- body {
890
- font-size: 18pt;
891
- }
892
-
893
- #header h1 {
894
- page-break-after: always;
895
- font-size: 500%;
896
- vertical-align: middle;
897
- }
898
-
899
- #header {
900
- page-break-after: always;
901
- }
902
-
903
- #toctitle {
904
- font-size: 200%;
905
- margin-bottom: 1em;
906
- }
907
-
908
- div.toclevel1 {
909
- font-size: 100%;
910
- }
911
-
912
- div.toclevel2 {
913
- font-size: 90%;
914
- }
915
-
916
- div.toclevel3 {
917
- font-size: 80%;
918
- }
919
-
920
- #content .comments {
921
- display: none;
922
- }
923
-
924
- @page :left {
925
- @bottom-left {
926
- content: counter(page);
927
- }
928
- }
929
- }
930
-
931
- #topbar {
932
- position: fixed;
933
- left: 0;
934
- top: 0;
935
- right: 0;
936
- height: 2.5em;
937
- padding-left: 10%;
938
- padding-right: 10%;
939
- z-index: 1;
940
- background: #880000;
941
- overflow: hidden;
942
- white-space: nowrap;
943
- box-shadow: 0px 3px 6px #555555;
944
- -moz-box-shadow: 0px 3px 6px #555555;
945
- -webkit-box-shadow: 0px 3px 6px #555555;
946
- -o-box-shadow: 0px 3px 6px #555555;
947
- }
948
-
949
- #topbar .title {
950
- display: inline-block;
951
- margin: 0.6em 1em 0 0;
952
- vertical-align: top;
953
- }
954
-
955
- #topbar .title img {
956
- display: none;
957
- margin-right: 6px;
958
- vertical-align: middle;
959
- }
960
-
961
- #topbar .title a {
962
- color: #fffafa;
963
- border: 0;
964
- }
965
-
966
- #topbar .title:hover img,
967
- .mobile #topbar .title img {
968
- display: inline-block;
969
- margin-left: -17px;
970
- }
971
-
972
- #topbar .title:hover a,
973
- .mobile #topbar .title a {
974
- color: #ffffdd;
975
- }
976
-
977
- #floattoc {
978
- position: fixed;
979
- z-index: 1;
980
- top: 2em;
981
- bottom: 20%;
982
- width: 50%;
983
- background: #f0f0f0;
984
- color: black;
985
- box-shadow: 0px 6px 6px #555555;
986
- -moz-box-shadow: 0px 6px 6px #555555;
987
- -webkit-box-shadow: 0px 6px 6px #555555;
988
- -o-box-shadow: 0px 6px 6px #555555;
989
- overflow: auto;
990
- padding: 1em;
991
- border-radius: 6px;
992
- -webkit-border-radius: 8px;
993
- -webkit-border-top-left-radius: 0;
994
- -webkit-border-top-right-radius: 0;
995
- -moz-border-radius: 8px;
996
- -moz-border-radius-topleft: 0;
997
- -moz-border-top-right-radius: 0;
998
- -o-border-radius: 8px;
999
- -o-border-radius-topleft: 0;
1000
- -o-border-top-right-radius: 0;
1001
- border-radius: 8px;
1002
- border-top-left-radius: 0;
1003
- border-top-right-radius: 0;
1004
- }
1005
-
1006
- #floattoc a.current {
1007
- font-weight: bold;
1008
- color: black;
1009
- }
1010
-
1011
- #current_section {
1012
- display: inline-block;
1013
- margin: 0.5em 0 0 0;
1014
- padding: 0.2em 0.5em 0.2em 0.5em;
1015
- background: #550000;
1016
- font-size: 90%;
1017
- vertical-align: top;
1018
- color: white;
1019
- border: none;
1020
- -webkit-border-radius: 8px;
1021
- -moz-border-radius: 8px;
1022
- -o-border-radius: 8px;
1023
- border-radius: 8px;
1024
- }
1025
-
1026
- #current_section:hover {
1027
- text-decoration: none;
1028
- border: none;
1029
- }
1030
-
1031
- #current_section.pressed {
1032
- background: #f0f0f0;
1033
- color: black;
1034
- -webkit-border-top-left-radius: 8px;
1035
- -webkit-border-top-right-radius: 8px;
1036
- -webkit-border-bottom-left-radius: 0;
1037
- -webkit-border-bottom-right-radius: 0;
1038
- -moz-border-radius-topleft: 8px;
1039
- -moz-border-radius-topright: 8px;
1040
- -moz-border-bottom-left-radius: 0;
1041
- -moz-border-bottom-right-radius: 0;
1042
- border-top-left-radius: 8px;
1043
- border-top-right-radius: 8px;
1044
- border-bottom-left-radius: 0;
1045
- border-bottom-right-radius: 0;
1046
- }
1047
-
1048
- /* http://nicolasgallagher.com/jump-links-and-viewport-positioning/ */
1049
- .anchor_helper {
1050
- position: relative;
1051
- display: block;
1052
- top: -50px;
1053
- width: 1px;
1054
- height: 1px;
1055
- }
1056
-
1057
- </style>
1058
- </head>
1059
- <body class="article">
1060
- <div id="topbar" style="display: none">
1061
- <div class="title">
1062
- <!-- Don't put a space between the img and a. That will break the hover layout. -->
1063
- <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAKCAYAAAEV95QVAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sGCRMSACDxkZwAAAAidEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVAgb24gYSBNYWOHqHdDAAAAZUlEQVQY032PSxbAIAjEIlfygL6ePF3UUvpzNjgSYWwqAMEhUQnANnsC7TQPeJpsVWzMuh2sog4vDTUbqP081zECrW4dtdaQGSIKlWluPyjK+VXxAz5XfcKufCzA130AfQHWB30HZxlPaP080xsAAAAASUVORK5CYII=" width="11" height="10" alt=""><a href="javascript:void(Mizuho.smoothlyScrollToToc())">Phusion Passenger Design and Architecture</a>
1064
- </div>
1065
- <a href="javascript:void(0)" id="current_section"></a>
1066
- </div>
1067
- <div id="header">
1068
- <h1>Phusion Passenger Design and Architecture</h1>
1069
- <div id="preamble">
1070
- <div class="sectionbody">
1071
- <div class="paragraph"><p><span class="image">
1072
- <a class="image" href="http://www.phusion.nl/">
1073
- <img src="images/phusion_banner.png" alt="images/phusion_banner.png">
1074
- </a>
1075
- </span></p></div>
1076
- <div class="paragraph"><p>This guide describes <a href="https://www.phusionpassenger.com/">Phusion Passenger</a>'s design and architecture in detail. With this guide, we hope that contributors can quickly find their way around the Phusion Passenger codebase.</p></div>
1077
- <div class="paragraph"><p>The guide assumes that you’re familiar with using Phusion Passenger and with Nginx or Apache, and that you’ve read the <a href="https://github.com/phusion/passenger/blob/master/CONTRIBUTING.md">Contributors Guide</a> and the <a href="https://github.com/phusion/passenger/blob/master/doc/DeveloperQuickstart.md">Developer QuickStart</a>.</p></div>
1078
- <div class="paragraph"><p><span class="image">
1079
- <a class="image" href="http://vimeo.com/phusionnl/review/98027409/03ba678684">
1080
- <img src="images/code_walkthrough.jpg" alt="images/code_walkthrough.jpg">
1081
- </a>
1082
- </span><br>
1083
- <em>You should also watch the complementary video: <a href="http://vimeo.com/phusionnl/review/98027409/03ba678684">Phusion Passenger Code Walkthrough</a></em></p></div>
1084
- </div>
1085
- </div>
1086
- <div id="toc">
1087
- <div id="toctitle">Table of Contents</div>
1088
- <div class="foo toclevel2"><a href="#_introduction">1. Introduction</a></div>
1089
- <div class="foo toclevel3"><a href="#web_app_models">1.1. Web application models and the role of the application server</a></div>
1090
- <div class="foo toclevel4"><a href="#_common_models">1.1.1. Common models</a></div>
1091
- <div class="foo toclevel4"><a href="#_the_rationale_behind_reverse_proxying">1.1.2. The rationale behind reverse proxying</a></div>
1092
- <div class="foo toclevel3"><a href="#_phusion_passenger_architecture_overview">1.2. Phusion Passenger architecture overview</a></div>
1093
- <div class="foo toclevel4"><a href="#_web_server_module">1.2.1. Web server module</a></div>
1094
- <div class="foo toclevel4"><a href="#_passenger_core">1.2.2. Passenger core</a></div>
1095
- <div class="foo toclevel4"><a href="#_ustrouter">1.2.3. UstRouter</a></div>
1096
- <div class="foo toclevel4"><a href="#_watchdog">1.2.4. Watchdog</a></div>
1097
- <div class="foo toclevel4"><a href="#_command_line_tools">1.2.5. Command line tools</a></div>
1098
- <div class="foo toclevel4"><a href="#_passenger_standalone">1.2.6. Passenger Standalone</a></div>
1099
- <div class="foo toclevel3"><a href="#_build_system_and_source_tree">1.3. Build system and source tree</a></div>
1100
- <div class="foo toclevel2"><a href="#_initialization">2. Initialization</a></div>
1101
- <div class="foo toclevel2"><a href="#passenger_core_architecture">3. Passenger core architecture</a></div>
1102
- <div class="foo toclevel3"><a href="#_request_handling">3.1. Request handling</a></div>
1103
- <div class="foo toclevel4"><a href="#_one_client_per_request">3.1.1. One client per request</a></div>
1104
- <div class="foo toclevel4"><a href="#request_handler_forwarding_to_app">3.1.2. Forwarding to the application</a></div>
1105
- <div class="foo toclevel4"><a href="#_i_o_model">3.1.3. I/O model</a></div>
1106
- <div class="foo toclevel3"><a href="#_the_applicationpool_subsystem">3.2. The ApplicationPool subsystem</a></div>
1107
- <div class="foo toclevel3"><a href="#spawner_subsystem">3.3. The Spawner subsystem</a></div>
1108
- <div class="foo toclevel2"><a href="#app_spawning_and_loading">4. Application spawning and loading</a></div>
1109
- <div class="foo toclevel3"><a href="#_preparation_work">4.1. Preparation work</a></div>
1110
- <div class="foo toclevel4"><a href="#basic_setup_and_forking">4.1.1. Basic setup and forking</a></div>
1111
- <div class="foo toclevel4"><a href="#_loading_spawnpreparer_possibly_through_bash">4.1.2. Loading SpawnPreparer, possibly through bash</a></div>
1112
- <div class="foo toclevel4"><a href="#_spawnpreparer_further_sets_up_the_environment">4.1.3. SpawnPreparer further sets up the environment</a></div>
1113
- <div class="foo toclevel4"><a href="#_executing_the_loader_or_preloader">4.1.4. Executing the loader or preloader</a></div>
1114
- <div class="foo toclevel3"><a href="#loaders">4.2. Loaders</a></div>
1115
- <div class="foo toclevel4"><a href="#loader_handshake">4.2.1. Handshake</a></div>
1116
- <div class="foo toclevel4"><a href="#application_loading">4.2.2. Application loading</a></div>
1117
- <div class="foo toclevel4"><a href="#loader_setting_up_server">4.2.3. Setting up a server</a></div>
1118
- <div class="foo toclevel4"><a href="#loader_report_readiness">4.2.4. Reporting readiness</a></div>
1119
- <div class="foo toclevel4"><a href="#loader_error_reporting">4.2.5. Error reporting</a></div>
1120
- <div class="foo toclevel4"><a href="#loader_main_loop">4.2.6. Main loop and termination</a></div>
1121
- <div class="foo toclevel4"><a href="#_stdout_and_stderr_forwarding">4.2.7. Stdout and stderr forwarding</a></div>
1122
- <div class="foo toclevel3"><a href="#preloaders">4.3. Preloaders</a></div>
1123
- <div class="foo toclevel3"><a href="#app_types_registry">4.4. The AppTypes registry</a></div>
1124
- <div class="foo toclevel2"><a href="#instance_state_and_communication">5. Instance state and communication</a></div>
1125
- <div class="foo toclevel2"><a href="#_about_rack">6. Appendix A: About Rack</a></div>
1126
- <div class="foo toclevel2"><a href="#_about_apache">7. Appendix B: About Apache</a></div>
1127
- <div class="foo toclevel2"><a href="#_about_nginx">8. Appendix C: About Nginx</a></div>
1128
- </div>
1129
- </div>
1130
- <div id="content">
1131
-
1132
- <div class="sect1">
1133
- <span class="anchor_helper" id="_introduction"></span><h2 data-anchor="_introduction">1. Introduction</h2>
1134
- <div class="sectionbody">
1135
- <div class="sect2">
1136
- <span class="anchor_helper" id="web_app_models"></span><h3 data-anchor="web_app_models">1.1. Web application models and the role of the application server</h3>
1137
- <div class="paragraph"><p>Before we describe Phusion Passenger, it is important to understand how typical web applications work from the viewpoint of someone who wants to connect a web application to a web server.</p></div>
1138
- <div class="paragraph"><p>A typical, isolated, web application accepts an HTTP request from some I/O channel, processes it internally, and outputs an HTTP response, which is sent back to the client. This is done in a loop, until the application is commanded to exit. This does not necessarily mean that the web application speaks HTTP directly: it just means that the web application accepts some kind of representation of an HTTP request.</p></div>
1139
- <div class="paragraph"><p><span class="image">
1140
- <img src="images/typical_isolated_web_application.png" alt="Architecture of a typical web application in isolation">
1141
- </span></p></div>
1142
- <div class="paragraph"><p>Some web applications are directly accessible through the HTTP protocol, while others are not. It depends on the language and framework that the web application is built on. For example, Ruby (Rack/Rails) and Python (WSGI) web applications are typically not directly accessible through the HTTP protocol. On the other hand, Node.js web applications <strong>do</strong> tend to be accessible through the HTTP protocol. The reasons for this are historical, but they’re outside the scope of this guide.</p></div>
1143
- <div class="sect3">
1144
- <span class="anchor_helper" id="_common_models"></span><h4 data-anchor="_common_models">1.1.1. Common models</h4>
1145
- <div class="paragraph"><p>Here are some common models that are in use:</p></div>
1146
- <div class="olist arabic"><ol class="arabic">
1147
- <li>
1148
- <p>
1149
- The web application is contained in an application server. This application server may or may not be able to contain multiple web applications. The administrator then connects the application server to a web server through some kind of protocol. This protocol may be HTTP, FastCGI, SCGI, AJP or whatever. The web server dispatches (forwards) requests to the application server, which in turn dispatches requests to the correct web application, in a format that the web application understands. Conversely, HTTP responses outputted by the web application are sent to the application server, which in turn sends them to the web server, and eventually to the HTTP client.
1150
- </p>
1151
- <div class="paragraph"><p>Typical examples of such a model:</p></div>
1152
- <div class="ulist"><ul>
1153
- <li>
1154
- <p>
1155
- A J2EE application, contained in the Tomcat application server, reverse proxied behind the Apache web server. Tomcat can contain multiple web applications in a single Tomcat instance.
1156
- </p>
1157
- </li>
1158
- <li>
1159
- <p>
1160
- Most Ruby application servers besides Phusion Passenger (Thin, Unicorn, Goliath, etc). These application servers can only contain a single Ruby web application per instance. They load the web application into their own process and are put behind a web server (Apache, Nginx) in a reverse proxy setup.
1161
- </p>
1162
- </li>
1163
- <li>
1164
- <p>
1165
- Green Unicorn, the Python (WSGI) application server, behind a reverse proxy setup.
1166
- </p>
1167
- </li>
1168
- <li>
1169
- <p>
1170
- PHP web applications spawned by the FastCGI Process Manager (FPM), behind an Nginx reverse proxy setup.
1171
- </p>
1172
- </li>
1173
- </ul></div>
1174
- </li>
1175
- <li>
1176
- <p>
1177
- The web application is contained directly in a web server. In this case, the web server acts like an application server. Typical examples include:
1178
- </p>
1179
- <div class="openblock">
1180
- <div class="content">
1181
- <div class="ulist"><ul>
1182
- <li>
1183
- <p>
1184
- PHP web applications running on Apache through mod_php.
1185
- </p>
1186
- </li>
1187
- <li>
1188
- <p>
1189
- Python (WSGI) web applications running on Apache through mod_uwsgi or mod_python.
1190
- </p>
1191
- </li>
1192
- </ul></div>
1193
- </div>
1194
- </div>
1195
- <div class="paragraph"><p>Note that this does not necessarily mean that the web application is run inside the same process as the web server: it just means that the web server manages applications. In case of mod_php, PHP runs directly inside the Apache worker processes, but in case of mod_uwsgi the Python processes can be configured to run out-of-process.</p></div>
1196
- <div class="paragraph"><p>Phusion Passenger for Apache and Phusion Passenger for Nginx implement this model, and run applications outside the web server process.</p></div>
1197
- </li>
1198
- <li>
1199
- <p>
1200
- The web application <strong>is</strong> a web server, and can accept HTTP requests directly. Examples of this model:
1201
- </p>
1202
- <div class="openblock">
1203
- <div class="content">
1204
- <div class="ulist"><ul>
1205
- <li>
1206
- <p>
1207
- Almost all Node.js and Meteor JS web applications.
1208
- </p>
1209
- </li>
1210
- <li>
1211
- <p>
1212
- The Trac bug tracking software, running in its standalone server.
1213
- </p>
1214
- </li>
1215
- </ul></div>
1216
- </div>
1217
- </div>
1218
- <div class="paragraph"><p>In most setups, the administrator puts them in a reverse proxy configuration, behind a real web server such as Apache or Nginx, instead of letting them accept HTTP requests directly.</p></div>
1219
- <div class="paragraph"><p>Phusion Passenger Standalone implements this model. However, you can expose Phusion Passenger Standalone directly to the Internet because it uses Nginx internally.</p></div>
1220
- </li>
1221
- <li>
1222
- <p>
1223
- The web application does not speak HTTP directly, but is connected directly to the web server through some communication adapter. CGI, FastCGI and SCGI are good examples of this.
1224
- </p>
1225
- </li>
1226
- </ol></div>
1227
- <div class="paragraph"><p>The above models cover how nearly all web applications work, whether they’re based on PHP, Django, J2EE, ASP.NET, Ruby on Rails, or whatever. Note that all of these models provide the same functionality, i.e. no model can do something that a different model can’t. The critical reader will notice that all of these models are identical to the one described in the first diagram, if the combination of web servers, application servers, web applications etc. are considered to be a single entity; a black box if you will.</p></div>
1228
- <div class="paragraph"><p>It should also be noted that these models do not enforce any particular I/O processing implementation. The web servers, application servers, web applications, etc. could process I/O serially (i.e. one request at a time),
1229
- could multiplex I/O with a single thread (e.g. by using <span class="monospaced">select(2)</span> or <span class="monospaced">poll(2)</span>) or it could process I/O with multiple threads and/or multiple processes. It depends on the implementation.</p></div>
1230
- <div class="paragraph"><p>Of course, there are many variations possible. For example, load balancers could be used. But that is outside the scope of this document.</p></div>
1231
- </div>
1232
- <div class="sect3">
1233
- <span class="anchor_helper" id="_the_rationale_behind_reverse_proxying"></span><h4 data-anchor="_the_rationale_behind_reverse_proxying">1.1.2. The rationale behind reverse proxying</h4>
1234
- <div class="paragraph"><p>As you’ve seen, administrators often put the web application or its application server behind a real web server in a reverse proxy setup, even when the web app/app server already speaks HTTP. This is because implementing HTTP in a proper, secure way involves more than just speaking the protocol. The public Internet is a hostile environment where clients can send any arbitrary data and can exhibit any arbitrary I/O patterns. If you don’t properly implement I/O handling, then you could open yourself either to parser vulnerabilities, or denial-of-service attacks.</p></div>
1235
- <div class="paragraph"><p>Web servers like Apache and Nginx have already implemented world-class I/O and connection handling code and it would be a waste to reinvent their wheel. In the end, putting the application in a reverse proxying setup often makes the whole system more robust and and more secure. This is the reason why it’s considered good practice.</p></div>
1236
- <div class="paragraph"><p>A typical problem involves dealing with <strong>slow clients</strong>. These clients may send HTTP requests slowly and read HTTP responses slowly, perhaps taking many seconds to complete their work. A naive single-threaded HTTP server implementation that reads an HTTP requests, processes, and sends the HTTP response in a loop may end up spending so much time waiting for I/O that spends very little time doing actual work. Worse: suppose that the client is malicious, just leaves the socket open and never reads the HTTP response, then the server will spend forever waiting for the client, not being able to handle any more requests. A real-world attack based on this principle is <a href="http://en.wikipedia.org/wiki/Slowloris">Slowloris</a>.</p></div>
1237
- <div class="listingblock">
1238
- <div class="title">An example of a naive HTTP server implementation</div>
1239
- <div class="content monospaced">
1240
- <pre>while true
1241
- client = accept_next_client()
1242
- request = read_http_request(client)
1243
- response = process_request(request)
1244
- send_http_response(client, response)
1245
- end</pre>
1246
- </div>
1247
- </div>
1248
- <div class="paragraph"><p>There are many ways to solve this problem. One could use one thread per client, one could implement I/O timeouts, one could use an evented I/O architecture, one could have a dedicated I/O thread or process buffer requests and responses. The point is, implementing all this properly is non-trivial. Instead of reimplementing these over and over in each application server, it’s better to let a real web server deal with all the details and let the application server and the web application do what they’re best at: their own core business logic.</p></div>
1249
- </div>
1250
- </div>
1251
- <div class="sect2">
1252
- <span class="anchor_helper" id="_phusion_passenger_architecture_overview"></span><h3 data-anchor="_phusion_passenger_architecture_overview">1.2. Phusion Passenger architecture overview</h3>
1253
- <div class="paragraph"><p><span class="image">
1254
- <img src="images/passenger_architecture_overview.png" alt="An overview of Phusion Passenger’s architecture">
1255
- </span></p></div>
1256
- <div class="paragraph"><p>Phusion Passenger is not a single, monolithic entity. Instead, it consists of multiple components and processes that work together. Part of the reason why Phusion Passenger is split like this, is because it’s technically necessary (no other way to implement it). But another part of the reason is stability and robustness. Individual components can crash and can be restarted independently from each other. If we were to put everything inside a single process, then a crash will take down all of Phusion Passenger.</p></div>
1257
- <div class="paragraph"><p>Thus, if the Passenger core crashes, or if an application process crashes, they can both be restarted without affecting the web server’s stability.</p></div>
1258
- <div class="sect3">
1259
- <span class="anchor_helper" id="_web_server_module"></span><h4 data-anchor="_web_server_module">1.2.1. Web server module</h4>
1260
- <div class="paragraph"><p>When an HTTP client sends a request, it is received by the web server (Nginx or Apache). Both Apache and Nginx can be extended with <strong>modules</strong>. Phusion Passenger provides such a module. The module is loaded into Nginx/Apache. It checks whether the request should be handled by a Phusion Passenger-served web application, and if so, forwards the request to the Passenger core. The internal wire protocol used during this forwarding, is a modified version of <a href="http://en.wikipedia.org/wiki/SCGI">SCGI</a>.</p></div>
1261
- <div class="paragraph"><p>The Nginx module and Apache module have an entirely different code base. Their code bases are in <span class="monospaced">src/nginx_module</span> and <span class="monospaced">src/apache2_module</span>, respectively. Both modules are relatively small because they outsource most logic to the Passenger core, and because they utilize a common library (<span class="monospaced">src/cxx_supportlib</span>). This allows us to support both Nginx and Apache without having to write a lot of things twice.</p></div>
1262
- </div>
1263
- <div class="sect3">
1264
- <span class="anchor_helper" id="_passenger_core"></span><h4 data-anchor="_passenger_core">1.2.2. Passenger core</h4>
1265
- <div class="paragraph"><p>The <strong>Passenger core</strong> is where most of the processing is done. The core keeps track of which application processes currently exist, and using load balancing rules, determines which process a request should be forwarded to. The core also takes care of <strong>application spawning</strong>: if it determines that having more application processes is necessary or beneficial, then it will make that happen. Process spawning is subject to user-configured limits: the core will never spawn more processes than a user-configured maximum.</p></div>
1266
- <div class="paragraph"><p>The core also has monitoring and statistics gathering capabilities. It constantly keeps track of applications' memory usage, how many requests they’ve handled, etc. This information can later be queried from administration tools. And if an application process crashes, the core restarts it.</p></div>
1267
- <div class="paragraph"><p>The core is by far the largest and most complex part of the system, but it is itself composed of several smaller subsystems. Most of the <a href="#passenger_core_architecture">core architecture</a> chapter is devoted to describing the core.</p></div>
1268
- </div>
1269
- <div class="sect3">
1270
- <span class="anchor_helper" id="_ustrouter"></span><h4 data-anchor="_ustrouter">1.2.3. UstRouter</h4>
1271
- <div class="paragraph"><p>The core cooperates with the <strong>UstRouter</strong>. This latter is responsible for sending data to <a href="https://www.unionstationapp.com">Union Station</a>, a monitoring web service. If you didn’t explicitly tell Phusion Passenger to send data to Union Station, then the UstRouter sits idle and does not consume resources.</p></div>
1272
- </div>
1273
- <div class="sect3">
1274
- <span class="anchor_helper" id="_watchdog"></span><h4 data-anchor="_watchdog">1.2.4. Watchdog</h4>
1275
- <div class="paragraph"><p>The core and the UstRouter contain complex logic, so they could contain bugs which could crash them.
1276
- So as a safety measure, they are both monitored by the <strong>Watchdog</strong>. If either of them crash, they are restarted by the Watchdog. This setup seeks to ensure that the system stays up, no matter what.</p></div>
1277
- <div class="paragraph"><p>You might now wonder: what happens if the Watchdog crashes? Shouldn’t the Watchdog be monitored by another Watchdog? We’ve contemplated this possibility, but the Watchdog is very simple, and since 2012 we haven’t seen a single report of the Watchdog crashing, nor have we been able to make it crash since that time. So, for the sake of keeping the codebase as simple as possible, we’ve chosen not to introduce multiple Watchdogs.</p></div>
1278
- </div>
1279
- <div class="sect3">
1280
- <span class="anchor_helper" id="_command_line_tools"></span><h4 data-anchor="_command_line_tools">1.2.5. Command line tools</h4>
1281
- <div class="paragraph"><p>Finally, there is an array of <strong>command line tools</strong> which support Phusion Passenger. The installers — <span class="monospaced">passenger-install-*-module</span> — are responsible for installing Phusion Passenger. There are administrative tools such as <span class="monospaced">passenger-status</span> and <span class="monospaced">passenger-memory-stats</span>. And many more. Some of these tools may communicate with one of the agents. For example, the <span class="monospaced">passenger-status</span> queries the core for information that the core has collected. How this communication is done, is described in <a href="#instance_state_and_communication">Instance state and communication</a>.</p></div>
1282
- </div>
1283
- <div class="sect3">
1284
- <span class="anchor_helper" id="_passenger_standalone"></span><h4 data-anchor="_passenger_standalone">1.2.6. Passenger Standalone</h4>
1285
- <div class="paragraph"><p>You might have noticed that Phusion Passenger Standalone is not part of the diagram. So how does it fit into the architecture? Well, Phusion Passenger Standalone is actually just Phusion Passenger for Nginx. The <span class="monospaced">passenger start</span> command simply sets up a modified and stripped-down Nginx web server (which we call the <span class="monospaced">WebHelper</span>) with the Phusion Passenger Nginx module loaded.</p></div>
1286
- </div>
1287
- </div>
1288
- <div class="sect2">
1289
- <span class="anchor_helper" id="_build_system_and_source_tree"></span><h3 data-anchor="_build_system_and_source_tree">1.3. Build system and source tree</h3>
1290
- <div class="paragraph"><p>Phusion Passenger is written mostly in C++ and Ruby. The web server modules, core, UstRouter and Watchdog are written in C++. Most command line tools are written in Ruby. You can find each component here:</p></div>
1291
- <div class="ulist"><ul>
1292
- <li>
1293
- <p>
1294
- The web server modules can be found in <span class="monospaced">src/apache2_module</span> and <span class="monospaced">src/nginx_module</span>.
1295
- </p>
1296
- </li>
1297
- <li>
1298
- <p>
1299
- The Passenger core, UstRouter and Watchdog can be found in <span class="monospaced">src/agent</span>.
1300
- </p>
1301
- </li>
1302
- <li>
1303
- <p>
1304
- The command line tools can be found in <span class="monospaced">bin</span>, with some parts of their code in <span class="monospaced">lib</span>.
1305
- </p>
1306
- </li>
1307
- </ul></div>
1308
- <div class="paragraph"><p>More information can be found in the <a href="https://github.com/phusion/passenger/blob/master/CONTRIBUTING.md">Contributors Guide</a>. This guide also teaches you how to compile Phusion Passenger.</p></div>
1309
- </div>
1310
- </div>
1311
- </div>
1312
- <div class="sect1">
1313
- <span class="anchor_helper" id="_initialization"></span><h2 data-anchor="_initialization">2. Initialization</h2>
1314
- <div class="sectionbody">
1315
- <div class="paragraph"><p><span class="image">
1316
- <img src="images/startup_sequence.png" alt="Startup sequence">
1317
- </span></p></div>
1318
- <div class="paragraph"><p>Phusion Passenger initializes as follows.</p></div>
1319
- <div class="olist arabic"><ol class="arabic">
1320
- <li>
1321
- <p>
1322
- First, the user begins with starting the web server. This for example be done by running <span class="monospaced">sudo service apache2 start</span> or <span class="monospaced">sudo service nginx start</span>. Or perhaps the web server is configured to be automatically started by the OS, in which case the user doesn’t have to do anything. In case of Phusion Passenger Standalone, the user runs <span class="monospaced">passenger start</span> which in turn starts Nginx.
1323
- </p>
1324
- </li>
1325
- <li>
1326
- <p>
1327
- The Phusion Passenger module inside Nginx/Apache proceeds with starting the Watchdog. This is implemented in:
1328
- </p>
1329
- <div class="ulist"><ul>
1330
- <li>
1331
- <p>
1332
- <span class="monospaced">src/nginx_module/ngx_http_passenger_module.c</span>, function <span class="monospaced">start_watchdog()</span>.
1333
- </p>
1334
- </li>
1335
- <li>
1336
- <p>
1337
- <span class="monospaced">src/apache2_module/Hooks.cpp</span>, in the constructor for the <span class="monospaced">Hooks</span> class.
1338
- </p>
1339
- </li>
1340
- <li>
1341
- <p>
1342
- <span class="monospaced">src/cxx_supportlib/WatchdogLauncher.h</span> and <span class="monospaced">WatchdogLauncher.cpp</span>. Most of the logic pertaining starting the Watchdog is in this file.
1343
- </p>
1344
- </li>
1345
- </ul></div>
1346
- </li>
1347
- <li>
1348
- <p>
1349
- The Watchdog first initializes a <a href="#instance_state_and_communication">"instance directory"</a>, which is a temporary directory containing files that will be used during the life time of this Phusion Passenger instance. For example, the directory contains Unix domain socket files, so that the different Phusion Passenger processes can communicate with each other. The Watchdog is implemented in <span class="monospaced">src/agent/Watchdog/Main.cpp</span>.
1350
- </p>
1351
- </li>
1352
- <li>
1353
- <p>
1354
- The Watchdog starts the Passenger core and the UstRouter simultaneously. Each performs its own initialization.
1355
- </p>
1356
- </li>
1357
- <li>
1358
- <p>
1359
- When the core is done initializing, it will send a message back to the Watchdog saying that it’s done. The UstRouter does something similar. When the Watchdog has received both acknowledgment messages, it finishes initialization. If the Watchdog notices that one of the agents have exited without sending an acknowledgment message, then it enters an error state.
1360
- </p>
1361
- </li>
1362
- <li>
1363
- <p>
1364
- The Watchdog reports successful startup back to the Phusion Passenger module that’s running inside Nginx/Apache. Or, if initialization didn’t success, the Watchdog reports back an error. The Phusion Passenger module inside Nginx/Apache then logs the error.
1365
- </p>
1366
- </li>
1367
- </ol></div>
1368
- <div class="paragraph"><p>After initialization, Phusion Passenger is ready to receive and to process requests.</p></div>
1369
- </div>
1370
- </div>
1371
- <div class="sect1">
1372
- <span class="anchor_helper" id="passenger_core_architecture"></span><h2 data-anchor="passenger_core_architecture">3. Passenger core architecture</h2>
1373
- <div class="sectionbody">
1374
- <div class="paragraph"><p><span class="image">
1375
- <img src="images/passenger_core_architecture.png" alt="Passenger core architecture">
1376
- </span></p></div>
1377
- <div class="paragraph"><p>The Passenger core consists of two subsystems. One is the <strong>request handling subsystem</strong>. The other is <strong>the ApplicationPool subsystem</strong>, which performs the bulk of process management. The core also uses a number of support libraries. The largest third-party support libraries are shown in the diagram. Many more — internal — support libraries are used, but they’re omitted from the diagram. You can find these internal support libraries in the directory <span class="monospaced">src/cxx_supportlib/Utils</span>.</p></div>
1378
- <div class="sect2">
1379
- <span class="anchor_helper" id="_request_handling"></span><h3 data-anchor="_request_handling">3.1. Request handling</h3>
1380
- <div class="paragraph"><p>Recall that requests are first received from the web server. The web server serializes the request into a slightly modified version of <a href="http://en.wikipedia.org/wiki/SCGI">the SCGI format</a>, and sends it to the core’s RequestHandler. The RequestHandler performs some work, and eventually sends back a regular HTTP response. The web server parses the RequestHandler response, and sends a response to the original HTTP client.</p></div>
1381
- <div class="paragraph"><p>The RequestHandler listens on a Unix domain socket file. This Unix domain socket file is called <span class="monospaced">request</span>, and is located in <a href="#instance_state_and_communication">the instance directory</a>.</p></div>
1382
- <div class="sect3">
1383
- <span class="anchor_helper" id="_one_client_per_request"></span><h4 data-anchor="_one_client_per_request">3.1.1. One client per request</h4>
1384
- <div class="paragraph"><p>The web server creates a new connection to the core on every request. Thus, from the viewpoint of the RequestHandler, its client is the web server. Every time a client connects (i.e. a new request is forwarded), the RequestHandler creates a new Client object which represents that request. All request-specific state is stored inside the Client. After the RequestHandler is done processing a request, it closes the client socket.</p></div>
1385
- <div class="paragraph"><p>Note that in the diagram, a Client has a 0..1 association with RequestHandler. That’s because when a Client is disconnected, the pointer to the associated RequestHandler is set to NULL. There might be background operations left which still have a pointer to the Client. As soon as those background operations finish, they check whether the Client has a valid pointer to the RequestHandler. If so, they commit their work; if not, they discard their work. The Client is destroyed when all its associated background operations have finished.</p></div>
1386
- </div>
1387
- <div class="sect3">
1388
- <span class="anchor_helper" id="request_handler_forwarding_to_app"></span><h4 data-anchor="request_handler_forwarding_to_app">3.1.2. Forwarding to the application</h4>
1389
- <div class="paragraph"><p>The RequestHandler asynchronously asks the ApplicationPool subsystem to select an appropriate application process to handle this request. The ApplicationPool checks whether there is an appropriate process, and if not, tries to spawn one. Maybe spawning is not possible right now because of configured resource limits, and we have to wait. In any case, the ApplicationPool takes care of all the nasty details and book keeping, and eventually replies back to the RequestHandler with either a Session object, or an exception.</p></div>
1390
- <div class="paragraph"><p>A Session object represents a single request/response cycle with a particular application process. The RequestHandler uses the information in this Session object to establish a connection with that process and forwards the request, using <a href="#loader_setting_up_server">a protocol that the application prefers</a> and that the RequestHandler supports. The process performs work, and replies back with an HTTP response. The RequestHandler parses and postprocesses the response, and sends a response back to the web server.</p></div>
1391
- <div class="paragraph"><p>If the ApplicationPool replied with an exception, the RequestHandler sends back an error response.</p></div>
1392
- </div>
1393
- <div class="sect3">
1394
- <span class="anchor_helper" id="_i_o_model"></span><h4 data-anchor="_i_o_model">3.1.3. I/O model</h4>
1395
- <div class="paragraph"><p>The RequestHandler uses the <strong>evented I/O model</strong>. This means that the RequestHandler handles many clients (requests) at the same time, using a single thread, inside a single process. This is possible through the use of I/O event multiplexing mechanisms, which are provided by the OS. Examples of such mechanisms include the <span class="monospaced">select()</span>, <span class="monospaced">poll()</span>, <span class="monospaced">epoll()</span> and <span class="monospaced">kqueue()</span> system calls. But those mechanisms are very low-level and OS-specific, so the RequestHandler uses two libraries which abstract away the differences and provide a higher-level API: <a href="http://software.schmorp.de/pkg/libev.html">libev</a> and <a href="https://github.com/libuv/libuv">libuv</a>.</p></div>
1396
- <div class="paragraph"><p>The evented I/O model is also used in Nginx. It is in contrast to the single-threaded multi-process model which handles 1 client per process (used by Apache with the prefork MPM), or the multi-threaded model which handles 1 client per thread (used by Apache with the worker MPM). You can learn more about evented I/O and the different I/O models through these resources:</p></div>
1397
- <div class="ulist"><ul>
1398
- <li>
1399
- <p>
1400
- <a href="http://www.slideshare.net/marc.seeger/seeger-aysnc-io">Event-Driven I/O: A hands-on introduction</a> — Marc Seeger, 2010
1401
- </p>
1402
- </li>
1403
- <li>
1404
- <p>
1405
- <a href="http://stackoverflow.com/questions/5807246/event-driven-io-and-blocking-vs-nonblocking">Event Driven IO And Blocking vs NonBlocking</a> — Stack Overflow
1406
- </p>
1407
- </li>
1408
- <li>
1409
- <p>
1410
- <a href="http://stackoverflow.com/questions/3231018/how-does-event-driven-i-o-allow-multiprocessing">How does event driven I/O allow multiprocessing?</a> — Stack Overflow
1411
- </p>
1412
- </li>
1413
- <li>
1414
- <p>
1415
- <a href="http://www.kegel.com/c10k.html">The C10K problem</a> — an overview of the different I/O models used in different servers; Dan Kegel
1416
- </p>
1417
- </li>
1418
- </ul></div>
1419
- </div>
1420
- </div>
1421
- <div class="sect2">
1422
- <span class="anchor_helper" id="_the_applicationpool_subsystem"></span><h3 data-anchor="_the_applicationpool_subsystem">3.2. The ApplicationPool subsystem</h3>
1423
- <div class="paragraph"><p>The ApplicationPool subsystem is responsible for:</p></div>
1424
- <div class="ulist"><ul>
1425
- <li>
1426
- <p>
1427
- Keeping track of which application processes exist.
1428
- </p>
1429
- </li>
1430
- <li>
1431
- <p>
1432
- Spawning processes.
1433
- </p>
1434
- </li>
1435
- <li>
1436
- <p>
1437
- Routing requests to an appropriate process. This also implies that it load balances requests between processes.
1438
- </p>
1439
- </li>
1440
- <li>
1441
- <p>
1442
- Monitoring processes (CPU usage, memory usage, etc).
1443
- </p>
1444
- </li>
1445
- <li>
1446
- <p>
1447
- Enforcing resource limits. Ensuring that not too many processes are spawned, ensuring that processes that use too much memory are shut down, etc.
1448
- </p>
1449
- </li>
1450
- <li>
1451
- <p>
1452
- Restarting processes on demand (e.g. when the timestamp of <span class="monospaced">restart.txt</span> has changed).
1453
- </p>
1454
- </li>
1455
- <li>
1456
- <p>
1457
- Restarting processes that have crashed.
1458
- </p>
1459
- </li>
1460
- <li>
1461
- <p>
1462
- Queuing requests and limiting concurrency. Each process tells the ApplicationPool how many concurrent requests it can handle. If more concurrent requests come in than the processes says it can handle, then the excess requests are queued within the ApplicationPool subsystem. Similarly, if requests come in while a process is being spawned, then those requests are queued until the process is done spawning.
1463
- </p>
1464
- </li>
1465
- </ul></div>
1466
- <div class="paragraph"><p>The main interface into the subsystem is the Pool class, with its <span class="monospaced">asyncGet()</span> method. The RequestHandler calls something like <span class="monospaced">pool-&gt;asyncGet(options, callback)</span> inside its <span class="monospaced">checkoutSession()</span> method. <span class="monospaced">asyncGet()</span> replies with a Session, or an exception.</p></div>
1467
- <div class="paragraph"><p>The Pool class is the core of the subsystem. It contains high-level process management logic but not low-level details, such as the details of spawning processes. The code is further divided into the following classes, each of which contain the core code managing its respective domain:</p></div>
1468
- <div class="dlist"><dl>
1469
- <dt class="hdlist1">
1470
- <strong>Group</strong>
1471
- </dt>
1472
- <dd>
1473
- <p>
1474
- Represents an application. It can contain multiple processes, all belonging to the same application.
1475
- </p>
1476
- </dd>
1477
- <dt class="hdlist1">
1478
- <strong>Process</strong>
1479
- </dt>
1480
- <dd>
1481
- <p>
1482
- Represents an OS process; an instance of a certain application. A process may have multiple server sockets on which it listens for requests. The Process class contains various book keeping information, such as the number of sessions that are currently open. It also contains the communication channel with the underlying OS process. Process objects are created through <a href="#spawner_subsystem">the ApplicationPool Spawner sub-subsystem</a>.
1483
- </p>
1484
- </dd>
1485
- <dt class="hdlist1">
1486
- <strong>Socket</strong>
1487
- </dt>
1488
- <dd>
1489
- <p>
1490
- Represents a single server socket, on which a process listens for requests. Session objects are created through Socket. Socket maintains book keeping information about how many sessions are currently open for that particular socket.
1491
- </p>
1492
- </dd>
1493
- <dt class="hdlist1">
1494
- <strong>Session</strong>
1495
- </dt>
1496
- <dd>
1497
- <p>
1498
- Represents a single request/response cycle with a particular process. Upon creation and destruction, various book keeping information is updated.
1499
- </p>
1500
- </dd>
1501
- <dt class="hdlist1">
1502
- <strong>Options (not shown in diagram)</strong>
1503
- </dt>
1504
- <dd>
1505
- <p>
1506
- A configuration object for the <span class="monospaced">Pool::asyncGet()</span> method.
1507
- </p>
1508
- </dd>
1509
- </dl></div>
1510
- <div class="paragraph"><p>If you look at the diagram, then you see that Group and Process all have 0..1 associations with their containing classes. An object that has a NULL association with its containing object, is considered invalid and should not be used. The fact that the association can be NULL is a detail of the memory management scheme that we employ.</p></div>
1511
- </div>
1512
- <div class="sect2">
1513
- <span class="anchor_helper" id="spawner_subsystem"></span><h3 data-anchor="spawner_subsystem">3.3. The Spawner subsystem</h3>
1514
- <div class="paragraph"><p>The Spawner subsystem is a sub-subsystem within ApplicationPool. It is responsible for actually spawning application processes, and then creating Process objects with the correct information in it.</p></div>
1515
- <div class="paragraph"><p>The <span class="monospaced">Spawner</span> interface encapsulates all low-level process spawning logic. Pool calls Spawner whenever it needs to spawn another application process.</p></div>
1516
- <div class="paragraph"><p>Recall that Phusion Passenger supports multiple spawn methods. For example, the <span class="monospaced">smart</span> spawn method spawns processes through an intermediate preloader process, and can utilize copy-on-write. This is explained in detail in <a href="https://www.phusionpassenger.com/library/indepth/spawn_methods/">Spawn methods explained</a> in the Phusion Passenger manual. Each spawn method corresponds to a different implementation of the Spawner interface. The following implementations are available:</p></div>
1517
- <div class="ulist"><ul>
1518
- <li>
1519
- <p>
1520
- DirectSpawner — implements the <span class="monospaced">direct</span> spawn method.
1521
- </p>
1522
- </li>
1523
- <li>
1524
- <p>
1525
- SmartSpawner — implements the <span class="monospaced">smart</span> spawn method.
1526
- </p>
1527
- </li>
1528
- <li>
1529
- <p>
1530
- DummySpawner (not shown in diagram) — only used in unit tests.
1531
- </p>
1532
- </li>
1533
- </ul></div>
1534
- <div class="paragraph"><p>The spawn method is user-configurable through the <span class="monospaced">spawnMethod</span> field in the <span class="monospaced">Options</span> object. To avoid convoluting the Pool code with spawner implementation selection logic, we also have a SpawnerFactory class, which the Pool uses.</p></div>
1535
- <div class="paragraph"><p>The details of the spawning process is described in <a href="#app_spawning_and_loading">Application spawning and loading</a>.</p></div>
1536
- </div>
1537
- </div>
1538
- </div>
1539
- <div class="sect1">
1540
- <span class="anchor_helper" id="app_spawning_and_loading"></span><h2 data-anchor="app_spawning_and_loading">4. Application spawning and loading</h2>
1541
- <div class="sectionbody">
1542
- <div class="paragraph"><p>Application processes are spawned from the Passenger core process. Spawning a process involves a lot of <strong>preparation work</strong>, such as setting up communication channels, setting up the current working directory, environment variables, etc. This preparation work is done by <a href="#spawner_subsystem">a Spawner object</a>, together with various support executables.</p></div>
1543
- <div class="paragraph"><p>When preparation is done, your application’s entry point has to be loaded somehow. That loading is done through a language-specific <strong>loader program</strong>. The loader program communicates with the Spawner through the communication channel that was set up earlier, initializes the language-specific environment, sets up a server, and reports back to the Spawner. This communication is done through a certain <strong>protocol</strong>.</p></div>
1544
- <div class="sect2">
1545
- <span class="anchor_helper" id="_preparation_work"></span><h3 data-anchor="_preparation_work">4.1. Preparation work</h3>
1546
- <div class="paragraph"><p><span class="image">
1547
- <img src="images/spawning_preparation_work.png" alt="Spawning preparation work">
1548
- </span></p></div>
1549
- <div class="sect3">
1550
- <span class="anchor_helper" id="basic_setup_and_forking"></span><h4 data-anchor="basic_setup_and_forking">4.1.1. Basic setup and forking</h4>
1551
- <div class="paragraph"><p>Spawning begins when the <span class="monospaced">spawn()</span> method is called on a <a href="#spawner_subsystem">Spawner object</a>. The Spawner determines <a href="https://www.phusionpassenger.com/library/deploy/nginx/user_sandboxing.html">which user the process should run as</a>, and sets up some communication channels (anonymous Unix domain socket pairs), and forks a process. The parent waits until the child exits, or replies with something over the communication channel.</p></div>
1552
- <div class="paragraph"><p>The communication channel in question is — from the viewpoint of the (pre)loader — actually just stdin, stdout and stderr! The anonymous Unix domain socket pairs that the Spawner creates, is mapped to the child process’s stdin, stdout and stderr file descriptors. Thus, Spawner sends data to the (pre)loader by writing stuff to its stdin, and the (pre)loader sends data back to the Spawner by writing stuff to stdout or stderr.</p></div>
1553
- </div>
1554
- <div class="sect3">
1555
- <span class="anchor_helper" id="_loading_spawnpreparer_possibly_through_bash"></span><h4 data-anchor="_loading_spawnpreparer_possibly_through_bash">4.1.2. Loading SpawnPreparer, possibly through bash</h4>
1556
- <div class="paragraph"><p>Because the Passenger core is heavily multi-threaded, the child process has been forked by the Spawner <a href="http://pubs.opengroup.org/onlinepubs/009695399/functions/fork.html">may only perform async-signal-safe operations</a>:</p></div>
1557
- <div class="quoteblock">
1558
- <div class="content">"A process shall be created with a single thread. If a multi-threaded process calls fork(), the new process shall contain a replica of the calling thread and its entire address space, possibly including the states of mutexes and other resources. Consequently, to avoid errors, the child process may only execute async-signal-safe operations until such time as one of the exec functions is called. Fork handlers may be established by means of the pthread_atfork() function in order to maintain application invariants across fork() calls."</div>
1559
- <div class="attribution">
1560
- <em>fork() man page</em><br>
1561
- — The Open Group's POSIX specification
1562
- </div>
1563
- </div>
1564
- <div class="paragraph"><p>Don’t worry if you don’t know what this means. The point is, there’s almost nothing the forked process can safely do at that stage. So it outsources most of the remaining preparation work to an external executable, the SpawnPreparer. The SpawnPreparer starts with a clean environment where it can safely execute code.</p></div>
1565
- <div class="paragraph"><p>To execute the SpawnPreparer, the child process executes one of the following commands:</p></div>
1566
- <div class="ulist"><ul>
1567
- <li>
1568
- <p>
1569
- If the target user’s shell is bash, and the <span class="monospaced">passenger_load_shell_envvars</span> option is turned on:
1570
- </p>
1571
- <div class="paragraph"><p><span class="monospaced">bash -l -c '/path-to/SpawnPreparer /path-to-loader-or-preloader'</span></p></div>
1572
- <div class="paragraph"><p>This causes bash to load its startup files, e.g. bashrc, profile, etc, after which it executes the SpawnPreparer with the given parameters. The reason why we do this is because a lot of users try to set environment variables in their bashrc, and they expect these environment variables to be picked up by applications spawned by Phusion Passenger. Unfortunately environment variables <a href="https://www.phusionpassenger.com/library/indepth/environment_variables.html">don’t work that way</a>, but we support it anyway because it is good for usability.</p></div>
1573
- </li>
1574
- <li>
1575
- <p>
1576
- Otherwise, the SpawnPreparer is executed directly, without bash:
1577
- </p>
1578
- <div class="paragraph"><p><span class="monospaced">/path-to/SpawnPreparer /path-to-loader-or-preloader</span></p></div>
1579
- </li>
1580
- </ul></div>
1581
- <div class="paragraph"><p>How <span class="monospaced">path-to-loader-or-preloader</span> is determined, is described in <a href="#app_types_registry">The AppTypes registry</a>.</p></div>
1582
- </div>
1583
- <div class="sect3">
1584
- <span class="anchor_helper" id="_spawnpreparer_further_sets_up_the_environment"></span><h4 data-anchor="_spawnpreparer_further_sets_up_the_environment">4.1.3. SpawnPreparer further sets up the environment</h4>
1585
- <div class="paragraph"><p>The SpawnPreparer is responsible for setting up certain environment variables, current working directory, and other process environmental conditions. When SpawnPreparer is done, it executes the loader or the preloader.</p></div>
1586
- </div>
1587
- <div class="sect3">
1588
- <span class="anchor_helper" id="_executing_the_loader_or_preloader"></span><h4 data-anchor="_executing_the_loader_or_preloader">4.1.4. Executing the loader or preloader</h4>
1589
- <div class="paragraph"><p>If <span class="monospaced">passenger_spawn_method</span> is set to <span class="monospaced">smart</span> (the default), and there is a preloader available for the application’s programming language, then this step executes the language-specific <strong>preloader</strong>. If either of the previous conditions are not met (and thus the <span class="monospaced">passenger_spawn_method</span> is automatically forced to <span class="monospaced">direct</span>), then this step executes the language-specific <strong>loader</strong>.</p></div>
1590
- <div class="paragraph"><p>All (pre)loaders are located in the <span class="monospaced">helper-scripts</span> directory in the source tree. Here are some of the (pre)loaders that are used:</p></div>
1591
- <table class="tableblock frame-all grid-all" style="
1592
- width:100%;
1593
- ">
1594
- <col style="width:33%;">
1595
- <col style="width:33%;">
1596
- <col style="width:33%;">
1597
- <thead>
1598
- <tr>
1599
- <th class="tableblock halign-left valign-top"> Language/Framework </th>
1600
- <th class="tableblock halign-left valign-top"> Loader </th>
1601
- <th class="tableblock halign-left valign-top"> Preloader</th>
1602
- </tr>
1603
- </thead>
1604
- <tbody>
1605
- <tr>
1606
- <td class="tableblock halign-left valign-top"><p class="tableblock">Ruby Rack and Rails</p></td>
1607
- <td class="tableblock halign-left valign-top"><p class="tableblock">rack-loader.rb</p></td>
1608
- <td class="tableblock halign-left valign-top"><p class="tableblock">rack-preloader.rb</p></td>
1609
- </tr>
1610
- <tr>
1611
- <td class="tableblock halign-left valign-top"><p class="tableblock">Python</p></td>
1612
- <td class="tableblock halign-left valign-top"><p class="tableblock">wsgi-loader.py</p></td>
1613
- <td class="tableblock halign-left valign-top"><p class="tableblock">-</p></td>
1614
- </tr>
1615
- <tr>
1616
- <td class="tableblock halign-left valign-top"><p class="tableblock">Node.js and bundled Meteor</p></td>
1617
- <td class="tableblock halign-left valign-top"><p class="tableblock">node-loader.js</p></td>
1618
- <td class="tableblock halign-left valign-top"><p class="tableblock">-</p></td>
1619
- </tr>
1620
- <tr>
1621
- <td class="tableblock halign-left valign-top"><p class="tableblock">Unbundled Meteor</p></td>
1622
- <td class="tableblock halign-left valign-top"><p class="tableblock">meteor-loader.rb</p></td>
1623
- <td class="tableblock halign-left valign-top"><p class="tableblock">-</p></td>
1624
- </tr>
1625
- </tbody>
1626
- </table>
1627
- <div class="paragraph"><p><a href="#app_types_registry">The AppTypes registry</a> keeps a list of available (pre)loaders, and which languages they belong to.</p></div>
1628
- <div class="paragraph"><p>What the loader does is described in <a href="#loaders">Loaders</a>. Likewise, preloaders are described in <a href="#preloaders">Preloaders</a>.</p></div>
1629
- </div>
1630
- </div>
1631
- <div class="sect2">
1632
- <span class="anchor_helper" id="loaders"></span><h3 data-anchor="loaders">4.2. Loaders</h3>
1633
- <div class="paragraph"><p>A loader initializes in 4 stages:</p></div>
1634
- <div class="olist arabic"><ol class="arabic">
1635
- <li>
1636
- <p>
1637
- It first goes through a <a href="#loader_handshake">handshake</a>, where it reads the parameters that the Spawner has sent over the communication channel.
1638
- </p>
1639
- </li>
1640
- <li>
1641
- <p>
1642
- It <a href="#application_loading">loads the application</a>. The behavior of this stage may be customized by the received parameters.
1643
- </p>
1644
- </li>
1645
- <li>
1646
- <p>
1647
- It <a href="#loader_setting_up_server">sets up a server</a>, on which this application process listens for requests.
1648
- </p>
1649
- </li>
1650
- <li>
1651
- <p>
1652
- It <a href="#loader_report_readiness">sends a response back</a> to the Spawner, in which it tells Spawner whether initialization was successful, and if so, where the socket is on which this application process listens for requests.
1653
- </p>
1654
- </li>
1655
- </ol></div>
1656
- <div class="paragraph"><p>Once initialized, the loader enters a main loop, in which it keeps handling requests until a signal has been received that says it should terminate.</p></div>
1657
- <div class="paragraph"><p>As explained in <a href="#basic_setup_and_forking">Basic setup and forking</a>, the communication channels that the loader uses are just plain old stdin and stdout. Every programming language supports reading and writing from these channels. This also means that you can easily test a loader by simply executing it and entering messages in the terminal.</p></div>
1658
- <div class="paragraph"><p>But stdout can also be used for printing normal output. How does the Spawner distinguish between control messages, and normal messages that should be displayed? The answer is that control messages must start with `!&gt; ` (including the trailing whitespace), and must end with a newline. The Spawner reads messages line-by-line, processes lines that start with `!&gt; `, and prints lines that don’t start with that marker.</p></div>
1659
- <div class="sect3">
1660
- <span class="anchor_helper" id="loader_handshake"></span><h4 data-anchor="loader_handshake">4.2.1. Handshake</h4>
1661
- <div class="paragraph"><p>The handshaking process begins with a protocol version handshake. The loader printing the line <span class="monospaced">!&gt; I have control 1.0</span>. The Spawner then sends "You have control 1.0", which the loader checks. If the loader observes that the version handshake does not match the expectation, then it aborts with an error.</p></div>
1662
- <div class="paragraph"><p>The Spawner also sends a list of key-value pairs, which is terminated by an empty newline. Upon receiving the empty newline, the Spawner proceeds with <a href="#application_loading">loading the application</a>.</p></div>
1663
- <div class="paragraph"><p>Example:</p></div>
1664
- <div class="listingblock">
1665
- <div class="content monospaced">
1666
- <pre>Loader Spawner
1667
-
1668
- !&gt; I have control 1.0
1669
- You have control 1.0
1670
- passenger_root: ...
1671
- passenger_version: 4.0.45
1672
- ruby_libdir: /Users/hongli/Projects/passenger/lib
1673
- generation_dir: /tmp/passenger.1.0.2082/generation-0
1674
- gupid: 1647ad4-ovJJMiPkAAt
1675
- connect_password: jXGaSzo8vRX5oGe2uuSv5tJsf1uX7ZgIeEH2x0nfOEa
1676
- app_root: /Users/hongli/Sites/rack.test
1677
- startup_file: config.ru
1678
- process_title: Passenger RackApp
1679
- log_level: 3
1680
- environment: development
1681
- base_uri: /
1682
- ...
1683
- (empty newline)</pre>
1684
- </div>
1685
- </div>
1686
- </div>
1687
- <div class="sect3">
1688
- <span class="anchor_helper" id="application_loading"></span><h4 data-anchor="application_loading">4.2.2. Application loading</h4>
1689
- <div class="paragraph"><p>How the application is loaded, depends on the programming language. Here are some examples:</p></div>
1690
- <div class="ulist"><ul>
1691
- <li>
1692
- <p>
1693
- The Ruby Rack loader does it by <span class="monospaced">load()</span>-ing the startup file, which by default is <span class="monospaced">config.ru</span>.
1694
- </p>
1695
- </li>
1696
- <li>
1697
- <p>
1698
- The Python loader does it by calling <span class="monospaced">imp.load_source('passenger_wsgi', 'passenger_wsgi.py')</span>.
1699
- </p>
1700
- </li>
1701
- <li>
1702
- <p>
1703
- The Node.js (and bundled Meteor) loader does it by <span class="monospaced">require()</span>-ing the startup file, which by default is <span class="monospaced">app.js</span>.
1704
- </p>
1705
- </li>
1706
- <li>
1707
- <p>
1708
- The unbundled Meteor loader does it by executing the <span class="monospaced">meteor run</span> command.
1709
- </p>
1710
- </li>
1711
- </ul></div>
1712
- <div class="paragraph"><p>If no errors occur, the loader proceeds with <a href="#loader_setting_up_server">setting up a server</a>. Otherwise, it <a href="#loader_error_reporting">reports an error</a>.</p></div>
1713
- </div>
1714
- <div class="sect3">
1715
- <span class="anchor_helper" id="loader_setting_up_server"></span><h4 data-anchor="loader_setting_up_server">4.2.3. Setting up a server</h4>
1716
- <div class="paragraph"><p>The loader sets up a server on which the application listens for requests. The Spawner doesn’t care how this is done, how this server works, or even what its concurrency is. It only cares about how it can contact the server. So the loader has full freedom in this step.</p></div>
1717
- <div class="paragraph"><p>As explained in <a href="#request_handler_forwarding_to_app">section <em>Request handling</em> and subsection <em>Forwarding to the application</em></a>, the RequestHandler can talk with the application process in a protocol that the application prefers. The RequestHandler supports two protocols:</p></div>
1718
- <div class="ulist"><ul>
1719
- <li>
1720
- <p>
1721
- A Phusion Passenger internal protocol which we call the <em>session</em> protocol. This protocol is used by the Ruby loaders and the Python loader. A description of this protocol is outside the scope of this document, but if you’re interested in how it looks like and how it behaves, you can study the source code of the Ruby and Python loaders, as well as <span class="monospaced">src/cxx_supportlib/Utils/MessageIO.h</span>.
1722
- </p>
1723
- </li>
1724
- <li>
1725
- <p>
1726
- The HTTP protocol. This protocol is used by the Node.js and Meteor loaders. If you’re writing a new loader then, it’s probably easiest to use this protocol, together with whatever HTTP library is available for the loader’s target language.
1727
- </p>
1728
- </li>
1729
- </ul></div>
1730
- <div class="paragraph"><p>Typically, the server is setup to listen on a Unix domain socket file, inside the <span class="monospaced">backends</span> subdirectory of the <em>generation directory</em>. The path to the generation directory was passed during handshake. However the server may also listen on a TCP socket.</p></div>
1731
- <div class="paragraph"><p>Once a server has been setup, the loader can <a href="#load_report_readiness">report readiness</a>.</p></div>
1732
- </div>
1733
- <div class="sect3">
1734
- <span class="anchor_helper" id="loader_report_readiness"></span><h4 data-anchor="loader_report_readiness">4.2.4. Reporting readiness</h4>
1735
- <div class="paragraph"><p>Once the server is set up, the loader sends back a <span class="monospaced">!&gt; Ready</span> response, followed by information about where the server socket listens on, and what protocol it expects. The response is terminated with a `!&gt; ` line (notice the trailing whitespace, which is required).</p></div>
1736
- <div class="paragraph"><p>The information about where the server socket listens on, is a 4-tuple:</p></div>
1737
- <div class="ulist"><ul>
1738
- <li>
1739
- <p>
1740
- The <strong>name</strong>. This must always be <span class="monospaced">main</span>.
1741
- </p>
1742
- </li>
1743
- <li>
1744
- <p>
1745
- The <strong>address</strong>. For Unix domain sockets, it has the form <span class="monospaced">unix:/path-to-socket</span>. For TCP socket, it has the form <span class="monospaced">tcp://127.0.0.1:PORT</span>.
1746
- </p>
1747
- </li>
1748
- <li>
1749
- <p>
1750
- The <strong>protocol</strong>. This must be either <span class="monospaced">session</span> or <span class="monospaced">http_session</span>.
1751
- </p>
1752
- </li>
1753
- <li>
1754
- <p>
1755
- The maximum number of <strong>concurrent connections</strong> the server supports. The ApplicationPool will ensure that the process never receives more concurrent requests than this number. A value of 0 means that the concurrency is unlimited.
1756
- </p>
1757
- </li>
1758
- </ul></div>
1759
- <div class="paragraph"><p>Here’s an example of what the Node.js loader sends as response:</p></div>
1760
- <div class="listingblock">
1761
- <div class="content monospaced">
1762
- <pre>!&gt; Ready
1763
- !&gt; socket: main;unix:/path-to-generation-dir/backends/node.1234-5677;session;0")
1764
- !&gt;</pre>
1765
- </div>
1766
- </div>
1767
- <div class="paragraph"><p>After reporting readiness, the loader can <a href="#loader_main_loop">enter a main loop and wait for termination</a>.</p></div>
1768
- </div>
1769
- <div class="sect3">
1770
- <span class="anchor_helper" id="loader_error_reporting"></span><h4 data-anchor="loader_error_reporting">4.2.5. Error reporting</h4>
1771
- <div class="paragraph"><p>If something goes wrong in any of the stages, the loader can report an error in two ways:</p></div>
1772
- <div class="olist arabic"><ol class="arabic">
1773
- <li>
1774
- <p>
1775
- Just write the error message to stdout as you normally do, and abort without printing the <span class="monospaced">!&gt; Ready</span> message. The Passenger core will read everything that the loader has written to stdout, and use it as the error message. This error message is considered to be plain text.
1776
- </p>
1777
- </li>
1778
- <li>
1779
- <p>
1780
- Abort after printing a special <span class="monospaced">!&gt; Error</span> message. The loader can signal that the message is HTML. The RequestHandler will format the error message as HTML.
1781
- </p>
1782
- </li>
1783
- </ol></div>
1784
- </div>
1785
- <div class="sect3">
1786
- <span class="anchor_helper" id="loader_main_loop"></span><h4 data-anchor="loader_main_loop">4.2.6. Main loop and termination</h4>
1787
- <div class="paragraph"><p>The loader’s main loop’s job is to wait until a single byte has been received on stdin. As long as the byte has not been received, the loader should not exit, and should keep processing requests. When the byte has been received, the following conditions are guaranteed to be true:</p></div>
1788
- <div class="ulist"><ul>
1789
- <li>
1790
- <p>
1791
- All clients for this particular process have disconnected.
1792
- </p>
1793
- </li>
1794
- <li>
1795
- <p>
1796
- No more clients will be routed to this particular process.
1797
- </p>
1798
- </li>
1799
- </ul></div>
1800
- <div class="paragraph"><p>This guarantee is enforced by the RequestHandler and the ApplicationPool. Thus, the loader doesn’t have to perform any kind of complicated shutdown. It can just exit the process.</p></div>
1801
- <div class="paragraph"><p>If the server was listening on a Unix domain socket file, then the loader doesn’t even have to remove the file. The ApplicationPool already takes care of that.</p></div>
1802
- </div>
1803
- <div class="sect3">
1804
- <span class="anchor_helper" id="_stdout_and_stderr_forwarding"></span><h4 data-anchor="_stdout_and_stderr_forwarding">4.2.7. Stdout and stderr forwarding</h4>
1805
- <div class="paragraph"><p>All lines that the loader writes to stdout, and that are not prefixed with `!&gt; `, are forwarded by the Passenger core to its own stdout. Similarly, everything that the loader writes to stderr, whether prefixed with `!&gt; ` or not, is forwarded by the Passenger core to its own stdout.</p></div>
1806
- <div class="paragraph"><p>While the Spawner is still doing its work, it takes care of this forwarding by itself. Once the Spawner is done, it outsources this work to two PipeWatcher objects, each which spawns a background thread for this purpose.</p></div>
1807
- </div>
1808
- </div>
1809
- <div class="sect2">
1810
- <span class="anchor_helper" id="preloaders"></span><h3 data-anchor="preloaders">4.3. Preloaders</h3>
1811
- <div class="paragraph"><p>Preloaders are a special kind of loaders, used for reducing spawn time and leveraging copy-on-write. You can learn more about this at <a href="https://www.phusionpassenger.com/library/indepth/spawn_methods/">Spawning methods explained</a>.</p></div>
1812
- <div class="paragraph"><p>Preloaders look a lot like loaders, but behave slightly differently. They also use stdin, stderr and stdout to communicate with the Spawner. The protocols are very similar.</p></div>
1813
- <div class="paragraph"><p>A preloader initializes in 4 stages:</p></div>
1814
- <div class="olist arabic"><ol class="arabic">
1815
- <li>
1816
- <p>
1817
- It first goes through a handshake, which is the same as <a href="#loader_handshake">the loader handshake</a>.
1818
- </p>
1819
- </li>
1820
- <li>
1821
- <p>
1822
- It <a href="#application_loading">loads the application</a> just like the loader does.
1823
- </p>
1824
- </li>
1825
- <li>
1826
- <p>
1827
- It sets up a server on which it listens for spawn commands.
1828
- </p>
1829
- </li>
1830
- <li>
1831
- <p>
1832
- It sends a response back to the Spawner. This is similar to how the loader does it, but instead of telling the Spawner where the application listens for requests, it tells the Spawner where the preloader process listens for spawn commands.
1833
- </p>
1834
- </li>
1835
- </ol></div>
1836
- <div class="paragraph"><p>Once initialized, the preloader enters a main loop, in which it keeps handling spawn commands until a signal has been received that says it should terminate.</p></div>
1837
- <div class="paragraph"><p>When a spawn command is received, the preloader forks off a child process (which already has the application loaded) and reports the child process’s PID to the Spawner. It also sets up a communication channel between the Spawner and the child process.</p></div>
1838
- </div>
1839
- <div class="sect2">
1840
- <span class="anchor_helper" id="app_types_registry"></span><h3 data-anchor="app_types_registry">4.4. The AppTypes registry</h3>
1841
- <div class="paragraph"><p>When the web server receives a request, the Phusion Passenger module inside it autodetects the type of application that the request belongs to. It does that by examening the filesystem and checking which one of the startup files exist. For example, if <span class="monospaced">config.ru</span> exists, then it assumes that it’s a Ruby app. Or if <span class="monospaced">app.js</span> exists, then it assumes that it’s a Node.js app. The Phusion Passenger module forwards the inferred application type to the Passenger core.</p></div>
1842
- <div class="paragraph"><p>Given an application type, the associated loader and preloader can be looked up.</p></div>
1843
- <div class="paragraph"><p>Information about the supported application types, startup files, loaders and preloaders are defined in the following places:</p></div>
1844
- <div class="ulist"><ul>
1845
- <li>
1846
- <p>
1847
- The constant <span class="monospaced">appTypeDefinitions</span> in the file <span class="monospaced">src/cxx_supportlib/AppTypes.cpp</span> keeps a list of supported languages. It also specifies the default startup file name belonging to each language.
1848
- </p>
1849
- </li>
1850
- <li>
1851
- <p>
1852
- The method <span class="monospaced">getStartCommand()</span> in the file <span class="monospaced">src/agent/Core/ApplicationPool2/Options.h</span> defines the loaders that should be used for each language.
1853
- </p>
1854
- </li>
1855
- <li>
1856
- <p>
1857
- The method <span class="monospaced">tryCreateSmartSpawner()</span> in the file <span class="monospaced">src/agent/Core/SpawningKit/Factory.h</span> defines the preloaders that should be used for each language.
1858
- </p>
1859
- </li>
1860
- <li>
1861
- <p>
1862
- The method <span class="monospaced">looks_like_app_directory?</span> in the file <span class="monospaced">src/ruby_supportlib/phusion_passenger/standalone/app_finder.rb</span> keeps a list of supported startup files. This is only used within Passenger Standalone.
1863
- </p>
1864
- </li>
1865
- </ul></div>
1866
- </div>
1867
- </div>
1868
- </div>
1869
- <div class="sect1">
1870
- <span class="anchor_helper" id="instance_state_and_communication"></span><h2 data-anchor="instance_state_and_communication">5. Instance state and communication</h2>
1871
- <div class="sectionbody">
1872
- <div class="paragraph"><p>Every time you start Phusion Passenger, you’ve created a new <strong>instance</strong>. Every instance consists of multiple processes that work together (Watchdog, Passenger core, UstRouter, application processes). All those processes have to be able to communicate with each other. Those processes must also <strong>not</strong> communicate with the processes belonging to other instances. For example, if you start Apache+Passenger <strong>and</strong> Nginx+Passenger, then we don’t want the Passenger core that’s started from Apache to use UstRouter that’s started from Nginx.</p></div>
1873
- <div class="paragraph"><p>Clearly, the processes can’t listen on a specific TCP port for communication. Nor can they listen on a fixed Unix domain socket filename.</p></div>
1874
- <div class="paragraph"><p>That is where the <em>instance directory</em> comes in. Every Phusion Passenger instance has its own, unique temporary directory. That directory is removed when the instance halts. The directory contains Unix domain socket files that the processes listen on. Every Phusion Passenger related process knows where its own instance directory is, and thus, knows how to communicate with other processes belonging to the same instance. The instance directory is implemented in <span class="monospaced">src/cxx_supportlib/InstanceDirectory.h</span>.</p></div>
1875
- <div class="paragraph"><p>Administration tools such as <span class="monospaced">passenger-status</span> query information using instance directories. First, they check which instance directories exist on the system. If they find only one, then they query the sockets inside that sole instance directory. Otherwise, they abort with an error and ask the user to specifically select the instance to query.</p></div>
1876
- </div>
1877
- </div>
1878
- <div class="sect1">
1879
- <span class="anchor_helper" id="_about_rack"></span><h2 data-anchor="_about_rack">6. Appendix A: About Rack</h2>
1880
- <div class="sectionbody">
1881
- <div class="paragraph"><p>The de-facto standard interface for Ruby web applications is <a href="http://rack.rubyforge.org/">Rack</a>. Rack specifies an programming interface for web application developers to implement. This interface covers HTTP request and response handling, and is not dependent on any particular application server. The idea is that any Rack-compliant application server can implement the Rack specification and work with all Rack-compliant web applications.</p></div>
1882
- <div class="paragraph"><p><span class="image">
1883
- <img src="images/rack.png" alt="images/rack.png">
1884
- </span></p></div>
1885
- <div class="paragraph"><p>In the distant past, each Ruby web framework had its own interface, so application servers needed to explicitly add support for each web framework. Nowadays application servers just support Rack.</p></div>
1886
- <div class="paragraph"><p><span class="image">
1887
- <img src="images/many_web_framework_protocols.png" alt="images/many_web_framework_protocols.png">
1888
- </span></p></div>
1889
- <div class="paragraph"><p>Ruby on Rails has been fully Rack compliant since version 3.0. Rails 2.3 was partially Rack-compliant while earlier versions were not Rack-compliant at all. Phusion Passenger supports Rack as well as all Rails 1.x and 2.x versions.</p></div>
1890
- </div>
1891
- </div>
1892
- <div class="sect1">
1893
- <span class="anchor_helper" id="_about_apache"></span><h2 data-anchor="_about_apache">7. Appendix B: About Apache</h2>
1894
- <div class="sectionbody">
1895
- <div class="paragraph"><p>The Apache web server has a dynamic module system and a pluggable I/O multiprocessing (the ability to handle more than 1 concurrent HTTP client at the same time) architecture. An Apache module which implements a particular multiprocessing strategy, is called a Multi-Processing Module (MPM). The single-threaded multi-process <a href="http://httpd.apache.org/docs/2.4/mod/prefork.html">prefork MPM</a> had been the default and the most popular one for a long time, but in recent times the hybrid multi-threaded/multi-process <a href="http://httpd.apache.org/docs/2.4/mod/worker.html">worker MPM</a> is becoming increasingly popular because of its better performance and scalability. Furthermore, Apache 2.4 introduced the <a href="http://httpd.apache.org/docs/2.4/mod/event.html">event MPM</a> which is a hybrid evented/multi-threaded/multi-process MPM and offers even more scalability benefits.</p></div>
1896
- <div class="paragraph"><p>The prefork MPM remains in wide use today because it’s the only MPM that works well with mod_php.</p></div>
1897
- <div class="paragraph"><p>The prefork MPM spawns multiple worker child processes. HTTP requests are first accepted by a so-called control process, and then forwarded to one of the worker processes. The next section contains a diagram which shows the prefork MPM’s architecture.</p></div>
1898
- </div>
1899
- </div>
1900
- <div class="sect1">
1901
- <span class="anchor_helper" id="_about_nginx"></span><h2 data-anchor="_about_nginx">8. Appendix C: About Nginx</h2>
1902
- <div class="sectionbody">
1903
- <div class="paragraph"><p>Nginx is a lightweight web server that is becoming increasingly popular. It is known to be smaller, lighter weight and more scalable than Apache thanks to its evented I/O architecture. That said, Nginx is less flexible than Apache. For example it has no dynamic module system: all modules must be statically compiled into Nginx.</p></div>
1904
- </div>
1905
- </div>
1906
- </div>
1907
- <div id="footnotes"><hr></div>
1908
- <div id="footer">
1909
-
1910
- </div>
1911
- <script>/*! jQuery v1.7.1 jquery.com | jquery.org/license */
1912
- (function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function cb(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function ca(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bE.test(a)?d(a,e):ca(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)ca(a+"["+e+"]",b[e],c,d);else d(a,b)}function b_(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function b$(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bT,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bP),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bC(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bx:by,g=0,h=e.length;if(d>0){if(c!=="border")for(;g<h;g++)c||(d-=parseFloat(f.css(a,"padding"+e[g]))||0),c==="margin"?d+=parseFloat(f.css(a,c+e[g]))||0:d-=parseFloat(f.css(a,"border"+e[g]+"Width"))||0;return d+"px"}d=bz(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0;if(c)for(;g<h;g++)d+=parseFloat(f.css(a,"padding"+e[g]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+e[g]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+e[g]))||0);return d+"px"}function bp(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c+(i[c][d].namespace?".":"")+i[c][d].namespace,i[c][d],i[c][d].data)}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?m(g):h==="function"&&(!a.unique||!o.has(g))&&c.push(g)},n=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,l=j||0,j=0,k=c.length;for(;c&&l<k;l++)if(c[l].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}i=!1,c&&(a.once?e===!0?o.disable():c=[]:d&&d.length&&(e=d.shift(),o.fireWith(e[0],e[1])))},o={add:function(){if(c){var a=c.length;m(arguments),i?k=c.length:e&&e!==!0&&(j=a,n(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){i&&f<=k&&(k--,f<=l&&l--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&o.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(i?a.once||d.push([b,c]):(!a.once||!e)&&n(b,c));return this},fire:function(){o.fireWith(this,arguments);return this},fired:function(){return!!e}};return o};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p,q=c.createElement("div"),r=c.documentElement;q.setAttribute("className","t"),q.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="<div "+n+"><div></div></div>"+"<table "+n+" cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="<div style='width:4px;'></div>",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h=null;if(typeof a=="undefined"){if(this.length){h=f.data(this[0]);if(this[0].nodeType===1&&!f._data(this[0],"parsedAttrs")){e=this[0].attributes;for(var i=0,j=e.length;i<j;i++)g=e[i].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),l(this[0],g,h[g]));f._data(this[0],"parsedAttrs",!0)}}return h}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split("."),d[1]=d[1]?"."+d[1]:"";if(c===b){h=this.triggerHandler("getData"+d[1]+"!",[d[0]]),h===b&&this.length&&(h=f.data(this[0],a),h=l(this[0],a,h));return h===b&&d[1]?this.data(d[0]):h}return this.each(function(){var b=f(this),e=[d[0],c];b.triggerHandler("setData"+d[1]+"!",e),f.data(this,a,c),b.triggerHandler("changeData"+d[1]+"!",e)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise()}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h<g;h++)e=d[h],e&&(c=f.propFix[e]||e,f.attr(a,e,""),a.removeAttribute(v?e:c),u.test(e)&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};
1913
- f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=[],j,k,l,m,n,o,p,q,r,s,t;g[0]=c,c.delegateTarget=this;if(e&&!c.target.disabled&&(!c.button||c.type!=="click")){m=f(this),m.context=this.ownerDocument||this;for(l=c.target;l!=this;l=l.parentNode||this){o={},q=[],m[0]=l;for(j=0;j<e;j++)r=d[j],s=r.selector,o[s]===b&&(o[s]=r.quick?H(l,r.quick):m.is(s)),o[s]&&q.push(r);q.length&&i.push({elem:l,matches:q})}}d.length>e&&i.push({elem:this,matches:d.slice(e)});for(j=0;j<i.length&&!c.isPropagationStopped();j++){p=i[j],c.currentTarget=p.elem;for(k=0;k<p.matches.length&&!c.isImmediatePropagationStopped();k++){r=p.matches[k];if(h||!c.namespace&&!r.namespace||c.namespace_re&&c.namespace_re.test(r.namespace))c.data=r.data,c.handleObj=r,n=((f.event.special[r.origType]||{}).handle||r.handler).apply(p.elem,g),n!==b&&(c.result=n,n===!1&&(c.preventDefault(),c.stopPropagation()))}}return c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0)}),d._submit_attached=!0)})},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on.call(this,a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.type+"."+e.namespace:e.type,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.POS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function()
1914
- {for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bp)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bn(k[i]);else bn(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||be.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bq=/alpha\([^)]*\)/i,br=/opacity=([^)]*)/,bs=/([A-Z]|^ms)/g,bt=/^-?\d+(?:px)?$/i,bu=/^-?\d/,bv=/^([\-+])=([\-+.\de]+)/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Left","Right"],by=["Top","Bottom"],bz,bA,bB;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bz(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bv.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bz)return bz(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return bC(a,b,d);f.swap(a,bw,function(){e=bC(a,b,d)});return e}},set:function(a,b){if(!bt.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cv(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cu("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cu("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cv(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cn.test(h)?(o=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),o?(f._data(this,"toggle"+i,o==="show"?"hide":"show"),j[o]()):j[h]()):(k=co.exec(h),l=j.cur(),k?(m=parseFloat(k[2]),n=k[3]||(f.cssNumber[i]?"":"px"),n!=="px"&&(f.style(this,i,(m||1)+n),l=(m||1)/j.cur()*l,f.style(this,i,l+n)),k[1]&&(m=(k[1]==="-="?-1:1)*m+l),j.custom(l,m,n)):j.custom(l,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:cu("show",1),slideUp:cu("hide",1),slideToggle:cu("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cr||cs(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){e.options.hide&&f._data(e.elem,"fxshow"+e.prop)===b&&f._data(e.elem,"fxshow"+e.prop,e.start)},h()&&f.timers.push(h)&&!cp&&(cp=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cr||cs(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cp),cp=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(["width","height"],function(a,b){f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cy(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.support.fixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.support.fixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
1915
- /**
1916
- * jQuery hashchange 1.0.0
1917
- *
1918
- * (based on jquery.history)
1919
- *
1920
- * Copyright (c) 2008 Chris Leishman (chrisleishman.com)
1921
- * Dual licensed under the MIT (MIT-LICENSE.txt)
1922
- * and GPL (GPL-LICENSE.txt) licenses.
1923
- */
1924
- (function($) {
1925
-
1926
- $.fn.extend({
1927
- hashchange: function(callback) { this.bind('hashchange', callback) },
1928
- openOnClick: function(href) {
1929
- if (href === undefined || href.length == 0)
1930
- href = '#';
1931
- return this.click(function(ev) {
1932
- if (href && href.charAt(0) == '#') {
1933
- // execute load in separate call stack
1934
- window.setTimeout(function() { $.locationHash(href) }, 0);
1935
- } else {
1936
- window.location(href);
1937
- }
1938
- ev.stopPropagation();
1939
- return false;
1940
- });
1941
- }
1942
- });
1943
-
1944
- // IE 8 introduces the hashchange event natively - so nothing more to do
1945
- if ($.browser.msie && document.documentMode && document.documentMode >= 8) {
1946
- $.extend({
1947
- locationHash: function(hash) {
1948
- if (!hash) hash = '#';
1949
- else if (hash.charAt(0) != '#') hash = '#' + hash;
1950
- location.hash = hash;
1951
- }
1952
- });
1953
- return;
1954
- }
1955
-
1956
- var curHash;
1957
- // hidden iframe for IE (earlier than 8)
1958
- var iframe;
1959
-
1960
- $.extend({
1961
- locationHash: function(hash) {
1962
- if (curHash === undefined) return;
1963
-
1964
- if (!hash) hash = '#';
1965
- else if (hash.charAt(0) != '#') hash = '#' + hash;
1966
-
1967
- location.hash = hash;
1968
-
1969
- if (curHash == hash) return;
1970
- curHash = hash;
1971
-
1972
- if ($.browser.msie) updateIEFrame(hash);
1973
- $.event.trigger('hashchange');
1974
- }
1975
- });
1976
-
1977
- $(document).ready(function() {
1978
- curHash = location.hash;
1979
- if ($.browser.msie) {
1980
- // stop the callback firing twice during init if no hash present
1981
- if (curHash == '') curHash = '#';
1982
- // add hidden iframe for IE
1983
- iframe = $('<iframe />').hide().get(0);
1984
- $('body').prepend(iframe);
1985
- updateIEFrame(location.hash);
1986
- setInterval(checkHashIE, 100);
1987
- } else {
1988
- setInterval(checkHash, 100);
1989
- }
1990
- });
1991
- $(window).unload(function() { iframe = null });
1992
-
1993
- function checkHash() {
1994
- var hash = location.hash;
1995
- if (hash != curHash) {
1996
- curHash = hash;
1997
- $.event.trigger('hashchange');
1998
- }
1999
- }
2000
-
2001
- if ($.browser.msie) {
2002
- // Attach a live handler for any anchor links
2003
- $('a[href^=#]').live('click', function() {
2004
- var hash = $(this).attr('href');
2005
- // Don't intercept the click if there is an existing anchor on the page
2006
- // that matches this hash
2007
- if ($(hash).length == 0 && $('a[name='+hash.slice(1)+']').length == 0) {
2008
- $.locationHash(hash);
2009
- return false;
2010
- }
2011
- });
2012
- }
2013
-
2014
- function checkHashIE() {
2015
- // On IE, check for location.hash of iframe
2016
- var idoc = iframe.contentDocument || iframe.contentWindow.document;
2017
- var hash = idoc.location.hash;
2018
- if (hash == '') hash = '#';
2019
-
2020
- if (hash != curHash) {
2021
- if (location.hash != hash) location.hash = hash;
2022
- curHash = hash;
2023
- $.event.trigger('hashchange');
2024
- }
2025
- }
2026
-
2027
- function updateIEFrame(hash) {
2028
- if (hash == '#') hash = '';
2029
- var idoc = iframe.contentWindow.document;
2030
- idoc.open();
2031
- idoc.close();
2032
- if (idoc.location.hash != hash) idoc.location.hash = hash;
2033
- }
2034
-
2035
- })(jQuery);
2036
- // IE...
2037
- if (!Date.now) {
2038
- Date.now = function() {
2039
- return new Date().getTime();
2040
- }
2041
- }
2042
-
2043
- var Mizuho = {
2044
- /** Cached DOM elements so that we don't have to re-find them over and over. */
2045
- $document: undefined,
2046
- $window: undefined,
2047
- $mainSections: undefined,
2048
- $sectionHeaders: undefined,
2049
-
2050
- /** Constants */
2051
- MAX_TOC_LEVEL: 3,
2052
-
2053
- sectionHeadersSelector: undefined,
2054
- scrollMemory: {},
2055
- changingHash: false,
2056
- activeHash: undefined,
2057
- /** Whether in single-page or multi-page mode. Either 'single' or 'multi'. */
2058
- mode: 'single',
2059
- /** Whether smooth scrolling is enabled. It is always enabled except right
2060
- * after page load: when the page is scrolled to the section as pointed to
2061
- * by location.hash.
2062
- */
2063
- smoothScrolling: true,
2064
-
2065
- initialize: function() {
2066
- this.sectionHeadersSelector = '';
2067
- for (var i = 0; i < this.MAX_TOC_LEVEL; i++) {
2068
- if (i != 0) {
2069
- this.sectionHeadersSelector += ', ';
2070
- }
2071
- this.sectionHeadersSelector += 'h' + (i + 2);
2072
- }
2073
-
2074
- this.$document = $(document);
2075
- this.$window = $(window);
2076
- this.$mainSections = $('.sect1');
2077
- this.$sectionHeaders = $(this.sectionHeadersSelector, '#content');
2078
- this.$sectionHeaders.sort(function(a, b) {
2079
- var off_a = $(a).offset();
2080
- var off_b = $(b).offset();
2081
- return off_a.top - off_b.top;
2082
- });
2083
-
2084
- if (this.isMobileDevice()) {
2085
- $(document.body).addClass('mobile');
2086
- }
2087
- },
2088
-
2089
-
2090
- /********* Generic utility functions *********/
2091
-
2092
- isMobileDevice: function() {
2093
- return navigator.userAgent.match(
2094
- /(IEMobile|Windows CE|NetFront|PlayStation|PLAYSTATION|like Mac OS X|MIDP|UP\.Browser|Symbian|Nintendo|Android)/
2095
- );
2096
- },
2097
-
2098
- virtualAnimate: function(options) {
2099
- var options = $.extend({
2100
- duration: 1000
2101
- }, options || {});
2102
- var animation_start = Date.now();
2103
- var animation_end = Date.now() + options.duration;
2104
- var interval = animation_end - animation_start;
2105
- this._virtualAnimate_step(animation_start, animation_end, interval, options);
2106
- },
2107
-
2108
- _virtualAnimate_step: function(animation_start, animation_end, interval, options) {
2109
- var self = this;
2110
- var now = new Date();
2111
- var progress = (now - animation_start) / interval;
2112
- if (progress > 1) {
2113
- progress = 1;
2114
- }
2115
- progress = (1 + Math.sin(-Math.PI / 2 + progress * Math.PI)) / 2;
2116
- options.step(progress);
2117
- if (now < animation_end) {
2118
- setTimeout(function() {
2119
- self._virtualAnimate_step(animation_start,
2120
- animation_end, interval, options);
2121
- }, 15);
2122
- } else {
2123
- options.step(1);
2124
- if (options.finish) {
2125
- options.finish();
2126
- }
2127
- }
2128
- },
2129
-
2130
- smoothlyScrollTo: function(top) {
2131
- if (!this.smoothScrolling) {
2132
- return this.setScrollTop(top);
2133
- }
2134
-
2135
- var self = this;
2136
- var $document = this.$document;
2137
- var current = $document.scrollTop();
2138
- this.virtualAnimate({
2139
- duration: 300,
2140
- step: function(x) {
2141
- $document.scrollTop(Math.floor(
2142
- top + (1 - x) * (current - top)
2143
- ));
2144
- },
2145
- finish: function() {
2146
- self.setScrollTop(top);
2147
- }
2148
- });
2149
- },
2150
-
2151
- smoothlyScrollToToc: function() {
2152
- this.smoothlyScrollTo($('#toc').position().top);
2153
- },
2154
-
2155
- scrollToHeader: function(header) {
2156
- this.smoothlyScrollTo($(header).offset().top - 50);
2157
- },
2158
-
2159
- setScrollTop: function(top, element) {
2160
- // Browsers don't always scroll properly so work around
2161
- // this with a few timers.
2162
- var self = this;
2163
- element = element || this.$document;
2164
- element = $(element);
2165
- element.scrollTop(top);
2166
- setTimeout(function() {
2167
- element.scrollTop(top);
2168
- }, 1);
2169
- setTimeout(function() {
2170
- element.scrollTop(top);
2171
- self.$document.trigger('mizuho:updateTopBar');
2172
- }, 20);
2173
- },
2174
-
2175
-
2176
- /********* Mizuho-specific functions *********/
2177
-
2178
- /** Returns the currently displayed section's header DOM element. */
2179
- currentSubsection: function() {
2180
- var $sectionHeaders = this.$sectionHeaders;
2181
- var scrollTop = this.$document.scrollTop();
2182
- var windowHeight = this.$window.height();
2183
- var offset;
2184
-
2185
- var low = 0;
2186
- var high = this.$sectionHeaders.length - 1;
2187
- var mid = 0;
2188
-
2189
- while (low <= high) {
2190
- mid = Math.floor((low + high) / 2);
2191
- offset = $($sectionHeaders[mid]).offset();
2192
-
2193
- if (offset.top >= scrollTop) {
2194
- high = mid - 1;
2195
- } else {
2196
- low = mid + 1;
2197
- }
2198
- }
2199
-
2200
- var $found = $($sectionHeaders[low]);
2201
- if ($found.offset().top > scrollTop + windowHeight) {
2202
- if (low > 0) {
2203
- return $sectionHeaders[low - 1];
2204
- } else {
2205
- return undefined;
2206
- }
2207
- } else {
2208
- return $sectionHeaders[low];
2209
- }
2210
- },
2211
-
2212
- /** Looks up a section's header DOM element corresponding to a hash name. */
2213
- lookupHeader: function(hash) {
2214
- var id = hash.replace(/^#!\//, '#');
2215
- if (id == '') {
2216
- return undefined;
2217
- } else {
2218
- var header = $(id);
2219
- if (header.length == 0) {
2220
- return undefined;
2221
- } else {
2222
- return header;
2223
- }
2224
- }
2225
- }
2226
- };
2227
-
2228
- for (var key in Mizuho) {
2229
- if (typeof(Mizuho[key]) == 'function') {
2230
- Mizuho[key] = $.proxy(Mizuho[key], Mizuho);
2231
- }
2232
- }
2233
- $(document).ready(Mizuho.initialize);
2234
- //$(document).ready(Mizuho.installHashbangLinks);
2235
-
2236
- Mizuho.initializeTopBar = $.proxy(function() {
2237
- var $window = this.$window;
2238
- var $document = this.$document;
2239
- var self = this;
2240
- var $topbar = $('#topbar');
2241
- var $title = $('#header h1');
2242
- var $currentSection = $('#current_section');
2243
- var isMobileDevice = this.isMobileDevice();
2244
- var timerId;
2245
-
2246
- // Create the floating table of contents used in the top bar.
2247
- var $floattoc = $('<div id="floattoc"></div>').html($('#toc').html());
2248
- $floattoc.find('#toctitle').remove();
2249
- $floattoc.find('.comments').remove();
2250
- $floattoc.css('visibility', 'hidden');
2251
- $floattoc.insertAfter($topbar);
2252
- var $floattoclinks = $floattoc.find('a');
2253
- $floattoclinks.each(function() {
2254
- // Firefox changes '#!' to '#%21' so change that back.
2255
- var $this = $(this);
2256
- var href = $this.attr('href');
2257
- if (href.match(/^#%21/)) {
2258
- $this.attr('href', href.replace(/^#%21/, '#!'));
2259
- }
2260
- });
2261
- $floattoclinks.click(function(event) {
2262
- self.internalLinkClicked(this, event);
2263
- });
2264
-
2265
- // Callback for when the user clicks on the Table of Contents
2266
- // button on the top bar.
2267
- function showFloatingToc() {
2268
- var scrollUpdateTimerId;
2269
-
2270
- function reposition() {
2271
- if (isMobileDevice) {
2272
- $floattoc.css({
2273
- top: $currentSection.offset().top +
2274
- $currentSection.innerHeight() +
2275
- 'px',
2276
- height: $window.height() * 0.7 + 'px'
2277
- });
2278
- }
2279
- }
2280
-
2281
- function highlightCurrentTocEntry() {
2282
- var currentSubsection = self.currentSubsection();
2283
- $floattoclinks.removeClass('current');
2284
- if (currentSubsection) {
2285
- var currentSubsectionTitle = $(currentSubsection).text();
2286
- var $link;
2287
-
2288
- $floattoclinks.each(function() {
2289
- if ($(this).text() == currentSubsectionTitle) {
2290
- $link = $(this);
2291
- return false;
2292
- }
2293
- });
2294
- if ($link) {
2295
- $link.addClass('current');
2296
- self.setScrollTop(
2297
- $floattoc.scrollTop() +
2298
- $link.position().top -
2299
- $floattoc.height() * 0.45,
2300
- $floattoc);
2301
- return false;
2302
- }
2303
- }
2304
- }
2305
-
2306
- function hideFloatingToc() {
2307
- $currentSection.removeClass('pressed');
2308
- $floattoc.css('visibility', 'hidden');
2309
- $floattoclinks.unbind('click', hideFloatingToc);
2310
- $document.unbind('mousedown', onMouseDown);
2311
- $document.unbind('touchdown', onMouseDown);
2312
- $document.unbind('mizuho:hideTopBar', hideFloatingToc);
2313
- $window.unbind('scroll', onScroll);
2314
- if (scrollUpdateTimerId !== undefined) {
2315
- clearTimeout(scrollUpdateTimerId);
2316
- scrollUpdateTimerId = undefined;
2317
- }
2318
- }
2319
-
2320
- function onMouseDown(event) {
2321
- if (event.target != $floattoc[0]
2322
- && $(event.target).closest('#floattoc').length == 0) {
2323
- hideFloatingToc();
2324
- }
2325
- }
2326
-
2327
- function onScroll(event) {
2328
- if (scrollUpdateTimerId === undefined) {
2329
- scrollUpdateTimerId = setTimeout(function() {
2330
- scrollUpdateTimerId = undefined;
2331
- reposition();
2332
- highlightCurrentTocEntry();
2333
- }, 100);
2334
- }
2335
- }
2336
-
2337
- // Layout and display floating TOC.
2338
- highlightCurrentTocEntry();
2339
- var origScrollTop = $document.scrollTop();
2340
- var windowWidth = $window.width();
2341
- var maxRight = windowWidth - Math.floor(windowWidth * 0.1);
2342
-
2343
- if ($currentSection.offset().left + $floattoc.outerWidth() > maxRight) {
2344
- $floattoc.css('left', maxRight - $floattoc.outerWidth());
2345
- } else {
2346
- $floattoc.css('left', $currentSection.offset().left + 'px');
2347
- }
2348
- reposition();
2349
- $floattoc.css('visibility', 'visible');
2350
- $currentSection.addClass('pressed');
2351
-
2352
- $floattoclinks.bind('click', hideFloatingToc);
2353
- $document.bind('mousedown', onMouseDown)
2354
- $document.bind('touchdown', onMouseDown);
2355
- $document.bind('mizuho:hideTopBar', hideFloatingToc);
2356
- $window.bind('scroll', onScroll);
2357
- }
2358
-
2359
- // Called whenever the user scrolls. Updates the title of the
2360
- // Table of Contents button in the top bar to the section that
2361
- // the user is currently reading.
2362
- function update() {
2363
- if ($title.offset().top + $title.height() < $document.scrollTop()) {
2364
- if (!$topbar.is(':visible')) {
2365
- $topbar.slideDown(250);
2366
- $document.trigger('mizuho:showTopBar');
2367
- }
2368
- } else {
2369
- if ($topbar.is(':visible')) {
2370
- $topbar.slideUp();
2371
- $document.trigger('mizuho:hideTopBar');
2372
- }
2373
- }
2374
-
2375
- if (isMobileDevice) {
2376
- $topbar.css({
2377
- top: $document.scrollTop() + 'px',
2378
- width: $window.width() -
2379
- parseInt($topbar.css('padding-left')) -
2380
- parseInt($topbar.css('padding-right')) +
2381
- 'px'
2382
- });
2383
- }
2384
-
2385
- var header = self.currentSubsection();
2386
- var name;
2387
- if (header) {
2388
- name = $(header).text();
2389
- } else {
2390
- name = 'Preamble';
2391
- }
2392
- $currentSection.text(name);
2393
- }
2394
-
2395
- function scheduleUpdate() {
2396
- if (timerId !== undefined) {
2397
- return;
2398
- }
2399
- timerId = setTimeout(function() {
2400
- timerId = undefined;
2401
- update();
2402
- }, 100);
2403
- }
2404
-
2405
-
2406
- if (isMobileDevice) {
2407
- // Mobile devices don't support position fixed.
2408
- $topbar.css('position', 'absolute');
2409
- $floattoc.css('position', 'absolute');
2410
- }
2411
-
2412
- $currentSection.click(showFloatingToc);
2413
- $window.scroll(scheduleUpdate);
2414
- $document.bind('mizuho:updateTopBar', update);
2415
- }, Mizuho);
2416
-
2417
- $(document).ready(Mizuho.initializeTopBar);
2418
-
2419
- </script>
2420
- </body>
2421
- </html>