Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

twilio and popcorn.js

  • Loading branch information...
commit 170bf0e904ce9b885bc998b62ab6c1021053898c 0 parents
@coleGillespie authored
Showing with 26,745 additions and 0 deletions.
  1. +52 −0 app.js
  2. +32 −0 css/main.css
  3. +118 −0 html/index.html
  4. +15 −0 js/jquery.qtip.js
  5. +183 −0 js/popcorn.code.js
  6. +1,877 −0 js/popcorn.js
  7. +1 −0  node_modules/.bin/express
  8. +7 −0 node_modules/express/.npmignore
  9. +805 −0 node_modules/express/History.md
  10. +22 −0 node_modules/express/LICENSE
  11. +29 −0 node_modules/express/Makefile
  12. +145 −0 node_modules/express/Readme.md
  13. +416 −0 node_modules/express/bin/express
  14. +2 −0  node_modules/express/index.js
  15. +79 −0 node_modules/express/lib/express.js
  16. +582 −0 node_modules/express/lib/http.js
  17. +52 −0 node_modules/express/lib/https.js
  18. +323 −0 node_modules/express/lib/request.js
  19. +460 −0 node_modules/express/lib/response.js
  20. +53 −0 node_modules/express/lib/router/collection.js
  21. +398 −0 node_modules/express/lib/router/index.js
  22. +70 −0 node_modules/express/lib/router/methods.js
  23. +88 −0 node_modules/express/lib/router/route.js
  24. +152 −0 node_modules/express/lib/utils.js
  25. +460 −0 node_modules/express/lib/view.js
  26. +40 −0 node_modules/express/lib/view/partial.js
  27. +210 −0 node_modules/express/lib/view/view.js
  28. +11 −0 node_modules/express/node_modules/connect/.npmignore
  29. +24 −0 node_modules/express/node_modules/connect/LICENSE
  30. +2 −0  node_modules/express/node_modules/connect/index.js
  31. +81 −0 node_modules/express/node_modules/connect/lib/cache.js
  32. +106 −0 node_modules/express/node_modules/connect/lib/connect.js
  33. +217 −0 node_modules/express/node_modules/connect/lib/http.js
  34. +47 −0 node_modules/express/node_modules/connect/lib/https.js
  35. +46 −0 node_modules/express/node_modules/connect/lib/index.js
  36. +93 −0 node_modules/express/node_modules/connect/lib/middleware/basicAuth.js
  37. +196 −0 node_modules/express/node_modules/connect/lib/middleware/bodyParser.js
  38. +163 −0 node_modules/express/node_modules/connect/lib/middleware/compiler.js
  39. +46 −0 node_modules/express/node_modules/connect/lib/middleware/cookieParser.js
  40. +105 −0 node_modules/express/node_modules/connect/lib/middleware/csrf.js
  41. +222 −0 node_modules/express/node_modules/connect/lib/middleware/directory.js
  42. +100 −0 node_modules/express/node_modules/connect/lib/middleware/errorHandler.js
  43. +76 −0 node_modules/express/node_modules/connect/lib/middleware/favicon.js
  44. +80 −0 node_modules/express/node_modules/connect/lib/middleware/limit.js
  45. +299 −0 node_modules/express/node_modules/connect/lib/middleware/logger.js
  46. +38 −0 node_modules/express/node_modules/connect/lib/middleware/methodOverride.js
  47. +100 −0 node_modules/express/node_modules/connect/lib/middleware/profiler.js
  48. +40 −0 node_modules/express/node_modules/connect/lib/middleware/query.js
  49. +34 −0 node_modules/express/node_modules/connect/lib/middleware/responseTime.js
  50. +379 −0 node_modules/express/node_modules/connect/lib/middleware/router.js
  51. +345 −0 node_modules/express/node_modules/connect/lib/middleware/session.js
  52. +126 −0 node_modules/express/node_modules/connect/lib/middleware/session/cookie.js
  53. +131 −0 node_modules/express/node_modules/connect/lib/middleware/session/memory.js
  54. +137 −0 node_modules/express/node_modules/connect/lib/middleware/session/session.js
  55. +87 −0 node_modules/express/node_modules/connect/lib/middleware/session/store.js
  56. +225 −0 node_modules/express/node_modules/connect/lib/middleware/static.js
  57. +175 −0 node_modules/express/node_modules/connect/lib/middleware/staticCache.js
  58. +44 −0 node_modules/express/node_modules/connect/lib/middleware/vhost.js
  59. +79 −0 node_modules/express/node_modules/connect/lib/patch.js
  60. +75 −0 node_modules/express/node_modules/connect/lib/public/directory.html
  61. +13 −0 node_modules/express/node_modules/connect/lib/public/error.html
  62. BIN  node_modules/express/node_modules/connect/lib/public/favicon.ico
  63. BIN  node_modules/express/node_modules/connect/lib/public/icons/page.png
  64. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_add.png
  65. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_attach.png
  66. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_code.png
  67. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_copy.png
  68. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_delete.png
  69. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_edit.png
  70. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_error.png
  71. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_excel.png
  72. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_find.png
  73. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_gear.png
  74. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_go.png
  75. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_green.png
  76. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_key.png
  77. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_lightning.png
  78. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_link.png
  79. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_paintbrush.png
  80. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_paste.png
  81. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_red.png
  82. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_refresh.png
  83. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_save.png
  84. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white.png
  85. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_acrobat.png
  86. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_actionscript.png
  87. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_add.png
  88. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_c.png
  89. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_camera.png
  90. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_cd.png
  91. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_code.png
  92. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_code_red.png
  93. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_coldfusion.png
  94. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_compressed.png
  95. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_copy.png
  96. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_cplusplus.png
  97. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_csharp.png
  98. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_cup.png
  99. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_database.png
  100. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_delete.png
  101. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_dvd.png
  102. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_edit.png
  103. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_error.png
  104. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_excel.png
  105. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_find.png
  106. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_flash.png
  107. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_freehand.png
  108. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_gear.png
  109. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_get.png
  110. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_go.png
  111. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_h.png
  112. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_horizontal.png
  113. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_key.png
  114. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_lightning.png
  115. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_link.png
  116. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_magnify.png
  117. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_medal.png
  118. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_office.png
  119. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_paint.png
  120. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_paintbrush.png
  121. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_paste.png
  122. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_php.png
  123. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_picture.png
  124. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_powerpoint.png
  125. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_put.png
  126. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_ruby.png
  127. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_stack.png
  128. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_star.png
  129. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_swoosh.png
  130. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_text.png
  131. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_text_width.png
  132. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_tux.png
  133. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_vector.png
  134. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_visualstudio.png
  135. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_width.png
  136. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_word.png
  137. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_world.png
  138. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_wrench.png
  139. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_white_zip.png
  140. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_word.png
  141. BIN  node_modules/express/node_modules/connect/lib/public/icons/page_world.png
  142. +141 −0 node_modules/express/node_modules/connect/lib/public/style.css
  143. +451 −0 node_modules/express/node_modules/connect/lib/utils.js
  144. BIN  node_modules/express/node_modules/connect/node_modules/formidable/..travis.yml.un~
  145. BIN  node_modules/express/node_modules/connect/node_modules/formidable/.Readme.md.un~
  146. +4 −0 node_modules/express/node_modules/connect/node_modules/formidable/.npmignore
  147. BIN  node_modules/express/node_modules/connect/node_modules/formidable/.package.json.un~
  148. +4 −0 node_modules/express/node_modules/connect/node_modules/formidable/.travis.yml
  149. +14 −0 node_modules/express/node_modules/connect/node_modules/formidable/Makefile
  150. +303 −0 node_modules/express/node_modules/connect/node_modules/formidable/Readme.md
  151. +3 −0  node_modules/express/node_modules/connect/node_modules/formidable/TODO
  152. +70 −0 node_modules/express/node_modules/connect/node_modules/formidable/benchmark/bench-multipart-parser.js
  153. +43 −0 node_modules/express/node_modules/connect/node_modules/formidable/example/post.js
  154. +48 −0 node_modules/express/node_modules/connect/node_modules/formidable/example/upload.js
  155. +1 −0  node_modules/express/node_modules/connect/node_modules/formidable/index.js
  156. BIN  node_modules/express/node_modules/connect/node_modules/formidable/lib/.incoming_form.js.un~
  157. +61 −0 node_modules/express/node_modules/connect/node_modules/formidable/lib/file.js
  158. +378 −0 node_modules/express/node_modules/connect/node_modules/formidable/lib/incoming_form.js
  159. +3 −0  node_modules/express/node_modules/connect/node_modules/formidable/lib/index.js
  160. +312 −0 node_modules/express/node_modules/connect/node_modules/formidable/lib/multipart_parser.js
  161. +25 −0 node_modules/express/node_modules/connect/node_modules/formidable/lib/querystring_parser.js
  162. +6 −0 node_modules/express/node_modules/connect/node_modules/formidable/lib/util.js
  163. +22 −0 node_modules/express/node_modules/connect/node_modules/formidable/package.json
  164. BIN  node_modules/express/node_modules/connect/node_modules/formidable/test/.common.js.un~
  165. BIN  node_modules/express/node_modules/connect/node_modules/formidable/test/.run.js.un~
  166. +19 −0 node_modules/express/node_modules/connect/node_modules/formidable/test/common.js
  167. +1 −0  node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/funkyfilename.txt
  168. +1 −0  node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/plain.txt
  169. BIN  ...odules/express/node_modules/connect/node_modules/formidable/test/fixture/http/no-filename/.generic.http.un~
  170. +3 −0  ...es/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/info.md
  171. BIN  node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/.no-filename.js.un~
  172. BIN  ...ules/express/node_modules/connect/node_modules/formidable/test/fixture/js/.special-chars-in-filename.js.un~
  173. +3 −0  node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/no-filename.js
  174. +21 −0 node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/special-chars-in-filename.js
  175. +72 −0 node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/multipart.js
  176. BIN  node_modules/express/node_modules/connect/node_modules/formidable/test/integration/.test-fixtures.js.un~
  177. +89 −0 node_modules/express/node_modules/connect/node_modules/formidable/test/integration/test-fixtures.js
  178. +24 −0 node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/common.js
  179. +80 −0 ...dules/express/node_modules/connect/node_modules/formidable/test/legacy/integration/test-multipart-parser.js
  180. +104 −0 node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-file.js
  181. +726 −0 node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-incoming-form.js
  182. +50 −0 node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-multipart-parser.js
  183. +45 −0 ..._modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-querystring-parser.js
  184. +72 −0 ..._modules/express/node_modules/connect/node_modules/formidable/test/legacy/system/test-multi-video-upload.js
  185. +2 −0  node_modules/express/node_modules/connect/node_modules/formidable/test/run.js
  186. BIN  node_modules/express/node_modules/connect/node_modules/formidable/test/unit/.test-incoming-form.js.un~
  187. +63 −0 node_modules/express/node_modules/connect/node_modules/formidable/test/unit/test-incoming-form.js
  188. +47 −0 node_modules/express/node_modules/connect/node_modules/formidable/tool/record.js
  189. +25 −0 node_modules/express/node_modules/connect/package.json
  190. +19 −0 node_modules/express/node_modules/mime/LICENSE
  191. +50 −0 node_modules/express/node_modules/mime/README.md
  192. +92 −0 node_modules/express/node_modules/mime/mime.js
  193. +22 −0 node_modules/express/node_modules/mime/package.json
  194. +79 −0 node_modules/express/node_modules/mime/test.js
  195. +1,479 −0 node_modules/express/node_modules/mime/types/mime.types
  196. +43 −0 node_modules/express/node_modules/mime/types/node.types
  197. +2 −0  node_modules/express/node_modules/mkdirp/.gitignore.orig
  198. +5 −0 node_modules/express/node_modules/mkdirp/.gitignore.rej
  199. +2 −0  node_modules/express/node_modules/mkdirp/.npmignore
  200. +21 −0 node_modules/express/node_modules/mkdirp/LICENSE
  201. +54 −0 node_modules/express/node_modules/mkdirp/README.markdown
  202. +6 −0 node_modules/express/node_modules/mkdirp/examples/pow.js
  203. +6 −0 node_modules/express/node_modules/mkdirp/examples/pow.js.orig
  204. +19 −0 node_modules/express/node_modules/mkdirp/examples/pow.js.rej
  205. +79 −0 node_modules/express/node_modules/mkdirp/index.js
  206. +23 −0 node_modules/express/node_modules/mkdirp/package.json
  207. +38 −0 node_modules/express/node_modules/mkdirp/test/chmod.js
  208. +37 −0 node_modules/express/node_modules/mkdirp/test/clobber.js
  209. +28 −0 node_modules/express/node_modules/mkdirp/test/mkdirp.js
  210. +32 −0 node_modules/express/node_modules/mkdirp/test/perm.js
  211. +39 −0 node_modules/express/node_modules/mkdirp/test/perm_sync.js
  212. +41 −0 node_modules/express/node_modules/mkdirp/test/race.js
  213. +32 −0 node_modules/express/node_modules/mkdirp/test/rel.js
  214. +27 −0 node_modules/express/node_modules/mkdirp/test/sync.js
  215. +28 −0 node_modules/express/node_modules/mkdirp/test/umask.js
  216. +27 −0 node_modules/express/node_modules/mkdirp/test/umask_sync.js
  217. +6 −0 node_modules/express/node_modules/qs/.gitmodules
  218. +1 −0  node_modules/express/node_modules/qs/.npmignore
  219. +4 −0 node_modules/express/node_modules/qs/.travis.yml
  220. +73 −0 node_modules/express/node_modules/qs/History.md
  221. +5 −0 node_modules/express/node_modules/qs/Makefile
  222. +54 −0 node_modules/express/node_modules/qs/Readme.md
  223. +17 −0 node_modules/express/node_modules/qs/benchmark.js
  224. +51 −0 node_modules/express/node_modules/qs/examples.js
  225. +2 −0  node_modules/express/node_modules/qs/index.js
  226. +264 −0 node_modules/express/node_modules/qs/lib/querystring.js
  227. +16 −0 node_modules/express/node_modules/qs/package.json
  228. +2 −0  node_modules/express/node_modules/qs/test/mocha.opts
  229. +167 −0 node_modules/express/node_modules/qs/test/parse.js
  230. +103 −0 node_modules/express/node_modules/qs/test/stringify.js
  231. +39 −0 node_modules/express/package.json
  232. +35 −0 node_modules/express/testing/foo/app.js
  233. +9 −0 node_modules/express/testing/foo/package.json
  234. +8 −0 node_modules/express/testing/foo/public/stylesheets/style.css
  235. +10 −0 node_modules/express/testing/foo/routes/index.js
  236. +2 −0  node_modules/express/testing/foo/views/index.jade
  237. +6 −0 node_modules/express/testing/foo/views/layout.jade
  238. +43 −0 node_modules/express/testing/index.js
  239. +2,971 −0 node_modules/express/testing/public/test.txt
  240. +1 −0  node_modules/express/testing/views/page.html
  241. +3 −0  node_modules/express/testing/views/page.jade
  242. +1 −0  node_modules/express/testing/views/test.md
  243. +1 −0  node_modules/express/testing/views/user/index.jade
  244. +1 −0  node_modules/express/testing/views/user/list.jade
  245. +55 −0 node_modules/request/LICENSE
  246. +288 −0 node_modules/request/README.md
  247. +103 −0 node_modules/request/forever.js
  248. +874 −0 node_modules/request/main.js
  249. +152 −0 node_modules/request/mimetypes.js
  250. +34 −0 node_modules/request/oauth.js
  251. +15 −0 node_modules/request/package.json
  252. BIN  node_modules/request/tests/googledoodle.png
  253. +37 −0 node_modules/request/tests/run.js
  254. +82 −0 node_modules/request/tests/server.js
  255. +77 −0 node_modules/request/tests/squid.conf
  256. +20 −0 node_modules/request/tests/ssl/ca/ca.cnf
  257. 0  node_modules/request/tests/ssl/ca/ca.crl
  258. +17 −0 node_modules/request/tests/ssl/ca/ca.crt
  259. +13 −0 node_modules/request/tests/ssl/ca/ca.csr
  260. +18 −0 node_modules/request/tests/ssl/ca/ca.key
  261. +1 −0  node_modules/request/tests/ssl/ca/ca.srl
  262. +19 −0 node_modules/request/tests/ssl/ca/server.cnf
  263. +16 −0 node_modules/request/tests/ssl/ca/server.crt
  264. +11 −0 node_modules/request/tests/ssl/ca/server.csr
  265. +28 −0 node_modules/request/tests/ssl/ca/server.js
  266. +9 −0 node_modules/request/tests/ssl/ca/server.key
  267. +16 −0 node_modules/request/tests/ssl/npm-ca.crt
  268. +15 −0 node_modules/request/tests/ssl/test.crt
  269. +15 −0 node_modules/request/tests/ssl/test.key
  270. +95 −0 node_modules/request/tests/test-body.js
  271. +29 −0 node_modules/request/tests/test-cookie.js
  272. +90 −0 node_modules/request/tests/test-cookiejar.js
  273. +68 −0 node_modules/request/tests/test-defaults.js
  274. +37 −0 node_modules/request/tests/test-errors.js
  275. +52 −0 node_modules/request/tests/test-headers.js
  276. +94 −0 node_modules/request/tests/test-httpModule.js
  277. +97 −0 node_modules/request/tests/test-https-strict.js
  278. +86 −0 node_modules/request/tests/test-https.js
  279. +117 −0 node_modules/request/tests/test-oauth.js
  280. +92 −0 node_modules/request/tests/test-params.js
  281. +202 −0 node_modules/request/tests/test-pipes.js
  282. +39 −0 node_modules/request/tests/test-proxy.js
  283. +28 −0 node_modules/request/tests/test-qs.js
  284. +159 −0 node_modules/request/tests/test-redirect.js
  285. +87 −0 node_modules/request/tests/test-timeout.js
  286. +61 −0 node_modules/request/tests/test-tunnel.js
  287. +229 −0 node_modules/request/tunnel.js
  288. +19 −0 node_modules/request/uuid.js
  289. +60 −0 node_modules/request/vendor/cookie/index.js
  290. +72 −0 node_modules/request/vendor/cookie/jar.js
  291. +79 −0 node_modules/tako/README.mkd
  292. +1,479 −0 node_modules/tako/handlebars.js
  293. +782 −0 node_modules/tako/index.js
  294. +76 −0 node_modules/tako/node_modules/filed/README.md
  295. +198 −0 node_modules/tako/node_modules/filed/main.js
  296. +146 −0 node_modules/tako/node_modules/filed/mimetypes.js
  297. +15 −0 node_modules/tako/node_modules/filed/package.json
  298. +47 −0 node_modules/tako/node_modules/filed/rfc822.js
  299. +1 −0  node_modules/tako/node_modules/filed/test/index.html
  300. +20 −0 node_modules/tako/node_modules/filed/test/server.js
Sorry, we could not display the entire diff because too many files (834) changed.
52 app.js
@@ -0,0 +1,52 @@
+var tako = require('tako')
+ , request = require('request')
+ , path = require('path')
+ , twilio = require('twilio').Client
+ , app = tako();
+
+app.route('/js/*').files(path.join(__dirname, 'js'));
+app.route('/css/*').files(path.join(__dirname, 'css'));
+app.route('/html/*').files(path.join(__dirname, 'html'));
+
+app.route('/').html(function (req, resp) {
+ req.pipe(request("http://twilipop.nodejitsu.com/html/index.html")).pipe(resp);
+ //req.pipe(request("http://localhost/html/index.html")).pipe(resp);
+}).methods('GET');
+
+
+
+// Ported example from socket.io docs to show integration
+app.sockets.on('connection', function (socket) {
+
+ socket.on('makeACall', function (o) {
+ makeCall(o.number);
+ })
+
+ function makeCall(number){
+
+ var client = new twilio(
+ 'AC265b70115d9b4f64af3e949e36bba368'
+ , 'd75b8d31d685d8339dc966362dec631d'
+ , 'colegillespie.com/video/helloMonkey.php'
+ );
+
+ var phone = client.getPhoneNumber('+13363106571');
+
+ phone.setup(function() {
+ console.log('setup call')
+ // jourdan +19193230388
+ // me skypez '+13363106571'
+ // brett '+4407534144803'
+ phone.makeCall(number, null, function(call) { });
+
+ });
+
+ }
+})
+
+app.httpServer.listen(80);
+app.httpsServer.listen(443);
+
+
+
+
32 css/main.css
@@ -0,0 +1,32 @@
+*{
+ outline: none;
+}
+body {
+ margin: 0;
+ padding-top: 60px;
+ background: black;
+ color: #333;
+ width:100%;
+ height:100%;
+}
+
+a {
+ color: #FFA500;
+}
+
+.label{
+ width:100px;
+}
+
+#videoContainer{
+ margin: auto;
+ width: 854px;
+ height: 480px;
+ display: none;
+}
+
+#modalBoxClick{
+ margin: auto;
+ width:500px;
+ height:200px;
+}
118 html/index.html
@@ -0,0 +1,118 @@
+<!-- kadewe -->
+<!DOCTYPE HTML>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Popcorn Tako with a side Twilio</title>
+ <link rel="stylesheet" href="css/main.css" media="screen">
+ </head>
+ <body>
+ <div id="modalBoxClick">
+ <h1><a href="#" rel="modal">Click here</a> to enter the tele to make the call to.</h1>
+ </div>
+ <div id="videoContainer">
+ <video id="video" controls>
+ <source src="http://colegillespie.com/video/coldfeet.webm" type='video/webm; codecs="vp8, vorbis"'/>
+ </video>
+ </div>
+ <script src="/socket.io/socket.io.js"></script>
+ <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
+ <script src="/js/jquery.qtip.js"></script>
+ <script src="/js/popcorn.js"></script>
+ <script src="/js/popcorn.code.js"></script>
+ <script>
+ $(document).ready(function(){
+
+ $('#videoContainer').hide();
+ $('a[rel="modal"]:first').qtip({
+ content: {
+ title: {
+ text: 'Modal qTip',
+ button: 'Submit'
+ },
+ text: 'Enter values for the call ( starts at 5 seconds ) <br />' +
+ 'You must include country code like so: <br />' +
+ '+13363106571 ( no spaces ) <br />' +
+ '<span class="label">Phone Number:</span><input id="number" name="searchbox" type="text" value="" > <br />'
+ },
+ position: {
+ target: $(document.body), // Position it via the document body...
+ corner: 'center' // ...at the center of the viewport
+ },
+ show: {
+ when: 'click', // Show it on click
+ solo: true // And hide all other tooltips
+ },
+ hide: false,
+ style: {
+ width: { max: 350 },
+ padding: '14px',
+ border: {
+ width: 9,
+ radius: 9,
+ color: '#666666'
+ },
+ name: 'light'
+ },
+ api: {
+ beforeShow: function(){
+ // Fade in the modal "blanket" using the defined show speed
+ $('#qtip-blanket').fadeIn(this.options.show.effect.length);
+
+ },
+ beforeHide: function(){
+ console.log('beforeHide');
+ // Fade out the modal "blanket" using the defined hide speed
+ initPlayerWithCall($('#number').val(), 5);
+ $('#modalBoxClick').hide();
+ $('#qtip-blanket').fadeOut(this.options.hide.effect.length);
+ }
+ }
+ });
+
+ // Create the modal backdrop on document load so all modal tooltips can use it
+ $('<div id="qtip-blanket">')
+ .css({
+ position: 'absolute',
+ top: $(document).scrollTop(), // Use document scrollTop so it's on-screen even if the window is scrolled
+ left: 0,
+ height: $(document).height(), // Span the full document height...
+ width: '100%', // ...and full width
+
+ opacity: 0.7, // Make it slightly transparent
+ backgroundColor: 'black',
+ zIndex: 5000 // Make sure the zIndex is below 6000 to keep it below tooltips!
+ })
+ .appendTo(document.body) // Append to the document body
+ .hide(); // Hide it initially
+ });
+
+ var socket = io.connect('http://twilipop.nodejitsu.com')
+ , callMade = false;
+
+ function initPlayerWithCall(number, time){
+ $('#videoContainer').show();
+ console.log('init');
+ var p = Popcorn( "#video" ).code({
+ start: time,
+ end: time + 5,
+ onStart: function( options ) {
+ if(!callMade){
+ console.log('makeing the only call to avoid the server going insane');
+ socket.emit('makeACall', {
+ number: number
+ });
+ callMade = true;
+ }
+ },
+ onEnd: function(){
+ console.log('it is finished');
+ }
+ }).play();
+
+ }
+
+
+ </script>
+ </body>
+</html>
15 js/jquery.qtip.js
@@ -0,0 +1,15 @@
+/*
+ * jquery.qtip. The jQuery tooltip plugin
+ *
+ * Copyright (c) 2009 Craig Thompson
+ * http://craigsworks.com
+ *
+ * Licensed under MIT
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ * Launch : February 2009
+ * Version : 1.0.0-rc3
+ * Released: Tuesday 12th May, 2009 - 00:00
+ * Debug: jquery.qtip.debug.js
+ */
+(function(f){f.fn.qtip=function(B,u){var y,t,A,s,x,w,v,z;if(typeof B=="string"){if(typeof f(this).data("qtip")!=="object"){f.fn.qtip.log.error.call(self,1,f.fn.qtip.constants.NO_TOOLTIP_PRESENT,false)}if(B=="api"){return f(this).data("qtip").interfaces[f(this).data("qtip").current]}else{if(B=="interfaces"){return f(this).data("qtip").interfaces}}}else{if(!B){B={}}if(typeof B.content!=="object"||(B.content.jquery&&B.content.length>0)){B.content={text:B.content}}if(typeof B.content.title!=="object"){B.content.title={text:B.content.title}}if(typeof B.position!=="object"){B.position={corner:B.position}}if(typeof B.position.corner!=="object"){B.position.corner={target:B.position.corner,tooltip:B.position.corner}}if(typeof B.show!=="object"){B.show={when:B.show}}if(typeof B.show.when!=="object"){B.show.when={event:B.show.when}}if(typeof B.show.effect!=="object"){B.show.effect={type:B.show.effect}}if(typeof B.hide!=="object"){B.hide={when:B.hide}}if(typeof B.hide.when!=="object"){B.hide.when={event:B.hide.when}}if(typeof B.hide.effect!=="object"){B.hide.effect={type:B.hide.effect}}if(typeof B.style!=="object"){B.style={name:B.style}}B.style=c(B.style);s=f.extend(true,{},f.fn.qtip.defaults,B);s.style=a.call({options:s},s.style);s.user=f.extend(true,{},B)}return f(this).each(function(){if(typeof B=="string"){w=B.toLowerCase();A=f(this).qtip("interfaces");if(typeof A=="object"){if(u===true&&w=="destroy"){while(A.length>0){A[A.length-1].destroy()}}else{if(u!==true){A=[f(this).qtip("api")]}for(y=0;y<A.length;y++){if(w=="destroy"){A[y].destroy()}else{if(A[y].status.rendered===true){if(w=="show"){A[y].show()}else{if(w=="hide"){A[y].hide()}else{if(w=="focus"){A[y].focus()}else{if(w=="disable"){A[y].disable(true)}else{if(w=="enable"){A[y].disable(false)}}}}}}}}}}}else{v=f.extend(true,{},s);v.hide.effect.length=s.hide.effect.length;v.show.effect.length=s.show.effect.length;if(v.position.container===false){v.position.container=f(document.body)}if(v.position.target===false){v.position.target=f(this)}if(v.show.when.target===false){v.show.when.target=f(this)}if(v.hide.when.target===false){v.hide.when.target=f(this)}t=f.fn.qtip.interfaces.length;for(y=0;y<t;y++){if(typeof f.fn.qtip.interfaces[y]=="undefined"){t=y;break}}x=new d(f(this),v,t);f.fn.qtip.interfaces[t]=x;if(typeof f(this).data("qtip")=="object"){if(typeof f(this).attr("qtip")==="undefined"){f(this).data("qtip").current=f(this).data("qtip").interfaces.length}f(this).data("qtip").interfaces.push(x)}else{f(this).data("qtip",{current:0,interfaces:[x]})}if(v.content.prerender===false&&v.show.when.event!==false&&v.show.ready!==true){v.show.when.target.bind(v.show.when.event+".qtip-"+t+"-create",{qtip:t},function(C){z=f.fn.qtip.interfaces[C.data.qtip];z.options.show.when.target.unbind(z.options.show.when.event+".qtip-"+C.data.qtip+"-create");z.cache.mouse={x:C.pageX,y:C.pageY};p.call(z);z.options.show.when.target.trigger(z.options.show.when.event)})}else{x.cache.mouse={x:v.show.when.target.offset().left,y:v.show.when.target.offset().top};p.call(x)}}})};function d(u,t,v){var s=this;s.id=v;s.options=t;s.status={animated:false,rendered:false,disabled:false,focused:false};s.elements={target:u.addClass(s.options.style.classes.target),tooltip:null,wrapper:null,content:null,contentWrapper:null,title:null,button:null,tip:null,bgiframe:null};s.cache={mouse:{},position:{},toggle:0};s.timers={};f.extend(s,s.options.api,{show:function(y){var x,z;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"show")}if(s.elements.tooltip.css("display")!=="none"){return s}s.elements.tooltip.stop(true,false);x=s.beforeShow.call(s,y);if(x===false){return s}function w(){if(s.options.position.type!=="static"){s.focus()}s.onShow.call(s,y);if(f.browser.msie){s.elements.tooltip.get(0).style.removeAttribute("filter")}}s.cache.toggle=1;if(s.options.position.type!=="static"){s.updatePosition(y,(s.options.show.effect.length>0))}if(typeof s.options.show.solo=="object"){z=f(s.options.show.solo)}else{if(s.options.show.solo===true){z=f("div.qtip").not(s.elements.tooltip)}}if(z){z.each(function(){if(f(this).qtip("api").status.rendered===true){f(this).qtip("api").hide()}})}if(typeof s.options.show.effect.type=="function"){s.options.show.effect.type.call(s.elements.tooltip,s.options.show.effect.length);s.elements.tooltip.queue(function(){w();f(this).dequeue()})}else{switch(s.options.show.effect.type.toLowerCase()){case"fade":s.elements.tooltip.fadeIn(s.options.show.effect.length,w);break;case"slide":s.elements.tooltip.slideDown(s.options.show.effect.length,function(){w();if(s.options.position.type!=="static"){s.updatePosition(y,true)}});break;case"grow":s.elements.tooltip.show(s.options.show.effect.length,w);break;default:s.elements.tooltip.show(null,w);break}s.elements.tooltip.addClass(s.options.style.classes.active)}return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_SHOWN,"show")},hide:function(y){var x;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"hide")}else{if(s.elements.tooltip.css("display")==="none"){return s}}clearTimeout(s.timers.show);s.elements.tooltip.stop(true,false);x=s.beforeHide.call(s,y);if(x===false){return s}function w(){s.onHide.call(s,y)}s.cache.toggle=0;if(typeof s.options.hide.effect.type=="function"){s.options.hide.effect.type.call(s.elements.tooltip,s.options.hide.effect.length);s.elements.tooltip.queue(function(){w();f(this).dequeue()})}else{switch(s.options.hide.effect.type.toLowerCase()){case"fade":s.elements.tooltip.fadeOut(s.options.hide.effect.length,w);break;case"slide":s.elements.tooltip.slideUp(s.options.hide.effect.length,w);break;case"grow":s.elements.tooltip.hide(s.options.hide.effect.length,w);break;default:s.elements.tooltip.hide(null,w);break}s.elements.tooltip.removeClass(s.options.style.classes.active)}return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_HIDDEN,"hide")},updatePosition:function(w,x){var C,G,L,J,H,E,y,I,B,D,K,A,F,z;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"updatePosition")}else{if(s.options.position.type=="static"){return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.CANNOT_POSITION_STATIC,"updatePosition")}}G={position:{left:0,top:0},dimensions:{height:0,width:0},corner:s.options.position.corner.target};L={position:s.getPosition(),dimensions:s.getDimensions(),corner:s.options.position.corner.tooltip};if(s.options.position.target!=="mouse"){if(s.options.position.target.get(0).nodeName.toLowerCase()=="area"){J=s.options.position.target.attr("coords").split(",");for(C=0;C<J.length;C++){J[C]=parseInt(J[C])}H=s.options.position.target.parent("map").attr("name");E=f('img[usemap="#'+H+'"]:first').offset();G.position={left:Math.floor(E.left+J[0]),top:Math.floor(E.top+J[1])};switch(s.options.position.target.attr("shape").toLowerCase()){case"rect":G.dimensions={width:Math.ceil(Math.abs(J[2]-J[0])),height:Math.ceil(Math.abs(J[3]-J[1]))};break;case"circle":G.dimensions={width:J[2]+1,height:J[2]+1};break;case"poly":G.dimensions={width:J[0],height:J[1]};for(C=0;C<J.length;C++){if(C%2==0){if(J[C]>G.dimensions.width){G.dimensions.width=J[C]}if(J[C]<J[0]){G.position.left=Math.floor(E.left+J[C])}}else{if(J[C]>G.dimensions.height){G.dimensions.height=J[C]}if(J[C]<J[1]){G.position.top=Math.floor(E.top+J[C])}}}G.dimensions.width=G.dimensions.width-(G.position.left-E.left);G.dimensions.height=G.dimensions.height-(G.position.top-E.top);break;default:return f.fn.qtip.log.error.call(s,4,f.fn.qtip.constants.INVALID_AREA_SHAPE,"updatePosition");break}G.dimensions.width-=2;G.dimensions.height-=2}else{if(s.options.position.target.add(document.body).length===1){G.position={left:f(document).scrollLeft(),top:f(document).scrollTop()};G.dimensions={height:f(window).height(),width:f(window).width()}}else{if(typeof s.options.position.target.attr("qtip")!=="undefined"){G.position=s.options.position.target.qtip("api").cache.position}else{G.position=s.options.position.target.offset()}G.dimensions={height:s.options.position.target.outerHeight(),width:s.options.position.target.outerWidth()}}}y=f.extend({},G.position);if(G.corner.search(/right/i)!==-1){y.left+=G.dimensions.width}if(G.corner.search(/bottom/i)!==-1){y.top+=G.dimensions.height}if(G.corner.search(/((top|bottom)Middle)|center/)!==-1){y.left+=(G.dimensions.width/2)}if(G.corner.search(/((left|right)Middle)|center/)!==-1){y.top+=(G.dimensions.height/2)}}else{G.position=y={left:s.cache.mouse.x,top:s.cache.mouse.y};G.dimensions={height:1,width:1}}if(L.corner.search(/right/i)!==-1){y.left-=L.dimensions.width}if(L.corner.search(/bottom/i)!==-1){y.top-=L.dimensions.height}if(L.corner.search(/((top|bottom)Middle)|center/)!==-1){y.left-=(L.dimensions.width/2)}if(L.corner.search(/((left|right)Middle)|center/)!==-1){y.top-=(L.dimensions.height/2)}I=(f.browser.msie)?1:0;B=(f.browser.msie&&parseInt(f.browser.version.charAt(0))===6)?1:0;if(s.options.style.border.radius>0){if(L.corner.search(/Left/)!==-1){y.left-=s.options.style.border.radius}else{if(L.corner.search(/Right/)!==-1){y.left+=s.options.style.border.radius}}if(L.corner.search(/Top/)!==-1){y.top-=s.options.style.border.radius}else{if(L.corner.search(/Bottom/)!==-1){y.top+=s.options.style.border.radius}}}if(I){if(L.corner.search(/top/)!==-1){y.top-=I}else{if(L.corner.search(/bottom/)!==-1){y.top+=I}}if(L.corner.search(/left/)!==-1){y.left-=I}else{if(L.corner.search(/right/)!==-1){y.left+=I}}if(L.corner.search(/leftMiddle|rightMiddle/)!==-1){y.top-=1}}if(s.options.position.adjust.screen===true){y=o.call(s,y,G,L)}if(s.options.position.target==="mouse"&&s.options.position.adjust.mouse===true){if(s.options.position.adjust.screen===true&&s.elements.tip){K=s.elements.tip.attr("rel")}else{K=s.options.position.corner.tooltip}y.left+=(K.search(/right/i)!==-1)?-6:6;y.top+=(K.search(/bottom/i)!==-1)?-6:6}if(!s.elements.bgiframe&&f.browser.msie&&parseInt(f.browser.version.charAt(0))==6){f("select, object").each(function(){A=f(this).offset();A.bottom=A.top+f(this).height();A.right=A.left+f(this).width();if(y.top+L.dimensions.height>=A.top&&y.left+L.dimensions.width>=A.left){k.call(s)}})}y.left+=s.options.position.adjust.x;y.top+=s.options.position.adjust.y;F=s.getPosition();if(y.left!=F.left||y.top!=F.top){z=s.beforePositionUpdate.call(s,w);if(z===false){return s}s.cache.position=y;if(x===true){s.status.animated=true;s.elements.tooltip.animate(y,200,"swing",function(){s.status.animated=false})}else{s.elements.tooltip.css(y)}s.onPositionUpdate.call(s,w);if(typeof w!=="undefined"&&w.type&&w.type!=="mousemove"){f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_POSITION_UPDATED,"updatePosition")}}return s},updateWidth:function(w){var x;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"updateWidth")}else{if(w&&typeof w!=="number"){return f.fn.qtip.log.error.call(s,2,"newWidth must be of type number","updateWidth")}}x=s.elements.contentWrapper.siblings().add(s.elements.tip).add(s.elements.button);if(!w){if(typeof s.options.style.width.value=="number"){w=s.options.style.width.value}else{s.elements.tooltip.css({width:"auto"});x.hide();if(f.browser.msie){s.elements.wrapper.add(s.elements.contentWrapper.children()).css({zoom:"normal"})}w=s.getDimensions().width+1;if(!s.options.style.width.value){if(w>s.options.style.width.max){w=s.options.style.width.max}if(w<s.options.style.width.min){w=s.options.style.width.min}}}}if(w%2!==0){w-=1}s.elements.tooltip.width(w);x.show();if(s.options.style.border.radius){s.elements.tooltip.find(".qtip-betweenCorners").each(function(y){f(this).width(w-(s.options.style.border.radius*2))})}if(f.browser.msie){s.elements.wrapper.add(s.elements.contentWrapper.children()).css({zoom:"1"});s.elements.wrapper.width(w);if(s.elements.bgiframe){s.elements.bgiframe.width(w).height(s.getDimensions.height)}}return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_WIDTH_UPDATED,"updateWidth")},updateStyle:function(w){var z,A,x,y,B;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"updateStyle")}else{if(typeof w!=="string"||!f.fn.qtip.styles[w]){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.STYLE_NOT_DEFINED,"updateStyle")}}s.options.style=a.call(s,f.fn.qtip.styles[w],s.options.user.style);s.elements.content.css(q(s.options.style));if(s.options.content.title.text!==false){s.elements.title.css(q(s.options.style.title,true))}s.elements.contentWrapper.css({borderColor:s.options.style.border.color});if(s.options.style.tip.corner!==false){if(f("<canvas>").get(0).getContext){z=s.elements.tooltip.find(".qtip-tip canvas:first");x=z.get(0).getContext("2d");x.clearRect(0,0,300,300);y=z.parent("div[rel]:first").attr("rel");B=b(y,s.options.style.tip.size.width,s.options.style.tip.size.height);h.call(s,z,B,s.options.style.tip.color||s.options.style.border.color)}else{if(f.browser.msie){z=s.elements.tooltip.find('.qtip-tip [nodeName="shape"]');z.attr("fillcolor",s.options.style.tip.color||s.options.style.border.color)}}}if(s.options.style.border.radius>0){s.elements.tooltip.find(".qtip-betweenCorners").css({backgroundColor:s.options.style.border.color});if(f("<canvas>").get(0).getContext){A=g(s.options.style.border.radius);s.elements.tooltip.find(".qtip-wrapper canvas").each(function(){x=f(this).get(0).getContext("2d");x.clearRect(0,0,300,300);y=f(this).parent("div[rel]:first").attr("rel");r.call(s,f(this),A[y],s.options.style.border.radius,s.options.style.border.color)})}else{if(f.browser.msie){s.elements.tooltip.find('.qtip-wrapper [nodeName="arc"]').each(function(){f(this).attr("fillcolor",s.options.style.border.color)})}}}return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_STYLE_UPDATED,"updateStyle")},updateContent:function(A,y){var z,x,w;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"updateContent")}else{if(!A){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.NO_CONTENT_PROVIDED,"updateContent")}}z=s.beforeContentUpdate.call(s,A);if(typeof z=="string"){A=z}else{if(z===false){return}}if(f.browser.msie){s.elements.contentWrapper.children().css({zoom:"normal"})}if(A.jquery&&A.length>0){A.clone(true).appendTo(s.elements.content).show()}else{s.elements.content.html(A)}x=s.elements.content.find("img[complete=false]");if(x.length>0){w=0;x.each(function(C){f('<img src="'+f(this).attr("src")+'" />').load(function(){if(++w==x.length){B()}})})}else{B()}function B(){s.updateWidth();if(y!==false){if(s.options.position.type!=="static"){s.updatePosition(s.elements.tooltip.is(":visible"),true)}if(s.options.style.tip.corner!==false){n.call(s)}}}s.onContentUpdate.call(s);return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_CONTENT_UPDATED,"loadContent")},loadContent:function(w,z,A){var y;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"loadContent")}y=s.beforeContentLoad.call(s);if(y===false){return s}if(A=="post"){f.post(w,z,x)}else{f.get(w,z,x)}function x(B){s.onContentLoad.call(s);f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_CONTENT_LOADED,"loadContent");s.updateContent(B)}return s},updateTitle:function(w){if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"updateTitle")}else{if(!w){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.NO_CONTENT_PROVIDED,"updateTitle")}}returned=s.beforeTitleUpdate.call(s);if(returned===false){return s}if(s.elements.button){s.elements.button=s.elements.button.clone(true)}s.elements.title.html(w);if(s.elements.button){s.elements.title.prepend(s.elements.button)}s.onTitleUpdate.call(s);return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_TITLE_UPDATED,"updateTitle")},focus:function(A){var y,x,w,z;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"focus")}else{if(s.options.position.type=="static"){return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.CANNOT_FOCUS_STATIC,"focus")}}y=parseInt(s.elements.tooltip.css("z-index"));x=6000+f("div.qtip[qtip]").length-1;if(!s.status.focused&&y!==x){z=s.beforeFocus.call(s,A);if(z===false){return s}f("div.qtip[qtip]").not(s.elements.tooltip).each(function(){if(f(this).qtip("api").status.rendered===true){w=parseInt(f(this).css("z-index"));if(typeof w=="number"&&w>-1){f(this).css({zIndex:parseInt(f(this).css("z-index"))-1})}f(this).qtip("api").status.focused=false}});s.elements.tooltip.css({zIndex:x});s.status.focused=true;s.onFocus.call(s,A);f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_FOCUSED,"focus")}return s},disable:function(w){if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"disable")}if(w){if(!s.status.disabled){s.status.disabled=true;f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_DISABLED,"disable")}else{f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.TOOLTIP_ALREADY_DISABLED,"disable")}}else{if(s.status.disabled){s.status.disabled=false;f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_ENABLED,"disable")}else{f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.TOOLTIP_ALREADY_ENABLED,"disable")}}return s},destroy:function(){var w,x,y;x=s.beforeDestroy.call(s);if(x===false){return s}if(s.status.rendered){s.options.show.when.target.unbind("mousemove.qtip",s.updatePosition);s.options.show.when.target.unbind("mouseout.qtip",s.hide);s.options.show.when.target.unbind(s.options.show.when.event+".qtip");s.options.hide.when.target.unbind(s.options.hide.when.event+".qtip");s.elements.tooltip.unbind(s.options.hide.when.event+".qtip");s.elements.tooltip.unbind("mouseover.qtip",s.focus);s.elements.tooltip.remove()}else{s.options.show.when.target.unbind(s.options.show.when.event+".qtip-create")}if(typeof s.elements.target.data("qtip")=="object"){y=s.elements.target.data("qtip").interfaces;if(typeof y=="object"&&y.length>0){for(w=0;w<y.length-1;w++){if(y[w].id==s.id){y.splice(w,1)}}}}delete f.fn.qtip.interfaces[s.id];if(typeof y=="object"&&y.length>0){s.elements.target.data("qtip").current=y.length-1}else{s.elements.target.removeData("qtip")}s.onDestroy.call(s);f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_DESTROYED,"destroy");return s.elements.target},getPosition:function(){var w,x;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"getPosition")}w=(s.elements.tooltip.css("display")!=="none")?false:true;if(w){s.elements.tooltip.css({visiblity:"hidden"}).show()}x=s.elements.tooltip.offset();if(w){s.elements.tooltip.css({visiblity:"visible"}).hide()}return x},getDimensions:function(){var w,x;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"getDimensions")}w=(!s.elements.tooltip.is(":visible"))?true:false;if(w){s.elements.tooltip.css({visiblity:"hidden"}).show()}x={height:s.elements.tooltip.outerHeight(),width:s.elements.tooltip.outerWidth()};if(w){s.elements.tooltip.css({visiblity:"visible"}).hide()}return x}})}function p(){var s,w,u,t,v,y,x;s=this;s.beforeRender.call(s);s.status.rendered=true;s.elements.tooltip='<div qtip="'+s.id+'" class="qtip '+(s.options.style.classes.tooltip||s.options.style)+'"style="display:none; -moz-border-radius:0; -webkit-border-radius:0; border-radius:0;position:'+s.options.position.type+';"> <div class="qtip-wrapper" style="position:relative; overflow:hidden; text-align:left;"> <div class="qtip-contentWrapper" style="overflow:hidden;"> <div class="qtip-content '+s.options.style.classes.content+'"></div></div></div></div>';s.elements.tooltip=f(s.elements.tooltip);s.elements.tooltip.appendTo(s.options.position.container);s.elements.tooltip.data("qtip",{current:0,interfaces:[s]});s.elements.wrapper=s.elements.tooltip.children("div:first");s.elements.contentWrapper=s.elements.wrapper.children("div:first").css({background:s.options.style.background});s.elements.content=s.elements.contentWrapper.children("div:first").css(q(s.options.style));if(f.browser.msie){s.elements.wrapper.add(s.elements.content).css({zoom:1})}if(s.options.hide.when.event=="unfocus"){s.elements.tooltip.attr("unfocus",true)}if(typeof s.options.style.width.value=="number"){s.updateWidth()}if(f("<canvas>").get(0).getContext||f.browser.msie){if(s.options.style.border.radius>0){m.call(s)}else{s.elements.contentWrapper.css({border:s.options.style.border.width+"px solid "+s.options.style.border.color})}if(s.options.style.tip.corner!==false){e.call(s)}}else{s.elements.contentWrapper.css({border:s.options.style.border.width+"px solid "+s.options.style.border.color});s.options.style.border.radius=0;s.options.style.tip.corner=false;f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.CANVAS_VML_NOT_SUPPORTED,"render")}if((typeof s.options.content.text=="string"&&s.options.content.text.length>0)||(s.options.content.text.jquery&&s.options.content.text.length>0)){u=s.options.content.text}else{if(typeof s.elements.target.attr("title")=="string"&&s.elements.target.attr("title").length>0){u=s.elements.target.attr("title").replace("\\n","<br />");s.elements.target.attr("title","")}else{if(typeof s.elements.target.attr("alt")=="string"&&s.elements.target.attr("alt").length>0){u=s.elements.target.attr("alt").replace("\\n","<br />");s.elements.target.attr("alt","")}else{u=" ";f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.NO_VALID_CONTENT,"render")}}}if(s.options.content.title.text!==false){j.call(s)}s.updateContent(u);l.call(s);if(s.options.show.ready===true){s.show()}if(s.options.content.url!==false){t=s.options.content.url;v=s.options.content.data;y=s.options.content.method||"get";s.loadContent(t,v,y)}s.onRender.call(s);f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_RENDERED,"render")}function m(){var F,z,t,B,x,E,u,G,D,y,w,C,A,s,v;F=this;F.elements.wrapper.find(".qtip-borderBottom, .qtip-borderTop").remove();t=F.options.style.border.width;B=F.options.style.border.radius;x=F.options.style.border.color||F.options.style.tip.color;E=g(B);u={};for(z in E){u[z]='<div rel="'+z+'" style="'+((z.search(/Left/)!==-1)?"left":"right")+":0; position:absolute; height:"+B+"px; width:"+B+'px; overflow:hidden; line-height:0.1px; font-size:1px">';if(f("<canvas>").get(0).getContext){u[z]+='<canvas height="'+B+'" width="'+B+'" style="vertical-align: top"></canvas>'}else{if(f.browser.msie){G=B*2+3;u[z]+='<v:arc stroked="false" fillcolor="'+x+'" startangle="'+E[z][0]+'" endangle="'+E[z][1]+'" style="width:'+G+"px; height:"+G+"px; margin-top:"+((z.search(/bottom/)!==-1)?-2:-1)+"px; margin-left:"+((z.search(/Right/)!==-1)?E[z][2]-3.5:-1)+'px; vertical-align:top; display:inline-block; behavior:url(#default#VML)"></v:arc>'}}u[z]+="</div>"}D=F.getDimensions().width-(Math.max(t,B)*2);y='<div class="qtip-betweenCorners" style="height:'+B+"px; width:"+D+"px; overflow:hidden; background-color:"+x+'; line-height:0.1px; font-size:1px;">';w='<div class="qtip-borderTop" dir="ltr" style="height:'+B+"px; margin-left:"+B+'px; line-height:0.1px; font-size:1px; padding:0;">'+u.topLeft+u.topRight+y;F.elements.wrapper.prepend(w);C='<div class="qtip-borderBottom" dir="ltr" style="height:'+B+"px; margin-left:"+B+'px; line-height:0.1px; font-size:1px; padding:0;">'+u.bottomLeft+u.bottomRight+y;F.elements.wrapper.append(C);if(f("<canvas>").get(0).getContext){F.elements.wrapper.find("canvas").each(function(){A=E[f(this).parent("[rel]:first").attr("rel")];r.call(F,f(this),A,B,x)})}else{if(f.browser.msie){F.elements.tooltip.append('<v:image style="behavior:url(#default#VML);"></v:image>')}}s=Math.max(B,(B+(t-B)));v=Math.max(t-B,0);F.elements.contentWrapper.css({border:"0px solid "+x,borderWidth:v+"px "+s+"px"})}function r(u,w,s,t){var v=u.get(0).getContext("2d");v.fillStyle=t;v.beginPath();v.arc(w[0],w[1],s,0,Math.PI*2,false);v.fill()}function e(v){var t,s,x,u,w;t=this;if(t.elements.tip!==null){t.elements.tip.remove()}s=t.options.style.tip.color||t.options.style.border.color;if(t.options.style.tip.corner===false){return}else{if(!v){v=t.options.style.tip.corner}}x=b(v,t.options.style.tip.size.width,t.options.style.tip.size.height);t.elements.tip='<div class="'+t.options.style.classes.tip+'" dir="ltr" rel="'+v+'" style="position:absolute; height:'+t.options.style.tip.size.height+"px; width:"+t.options.style.tip.size.width+'px; margin:0 auto; line-height:0.1px; font-size:1px;">';if(f("<canvas>").get(0).getContext){t.elements.tip+='<canvas height="'+t.options.style.tip.size.height+'" width="'+t.options.style.tip.size.width+'"></canvas>'}else{if(f.browser.msie){u=t.options.style.tip.size.width+","+t.options.style.tip.size.height;w="m"+x[0][0]+","+x[0][1];w+=" l"+x[1][0]+","+x[1][1];w+=" "+x[2][0]+","+x[2][1];w+=" xe";t.elements.tip+='<v:shape fillcolor="'+s+'" stroked="false" filled="true" path="'+w+'" coordsize="'+u+'" style="width:'+t.options.style.tip.size.width+"px; height:"+t.options.style.tip.size.height+"px; line-height:0.1px; display:inline-block; behavior:url(#default#VML); vertical-align:"+((v.search(/top/)!==-1)?"bottom":"top")+'"></v:shape>';t.elements.tip+='<v:image style="behavior:url(#default#VML);"></v:image>';t.elements.contentWrapper.css("position","relative")}}t.elements.tooltip.prepend(t.elements.tip+"</div>");t.elements.tip=t.elements.tooltip.find("."+t.options.style.classes.tip).eq(0);if(f("<canvas>").get(0).getContext){h.call(t,t.elements.tip.find("canvas:first"),x,s)}if(v.search(/top/)!==-1&&f.browser.msie&&parseInt(f.browser.version.charAt(0))===6){t.elements.tip.css({marginTop:-4})}n.call(t,v)}function h(t,v,s){var u=t.get(0).getContext("2d");u.fillStyle=s;u.beginPath();u.moveTo(v[0][0],v[0][1]);u.lineTo(v[1][0],v[1][1]);u.lineTo(v[2][0],v[2][1]);u.fill()}function n(u){var t,w,s,x,v;t=this;if(t.options.style.tip.corner===false||!t.elements.tip){return}if(!u){u=t.elements.tip.attr("rel")}w=positionAdjust=(f.browser.msie)?1:0;t.elements.tip.css(u.match(/left|right|top|bottom/)[0],0);if(u.search(/top|bottom/)!==-1){if(f.browser.msie){if(parseInt(f.browser.version.charAt(0))===6){positionAdjust=(u.search(/top/)!==-1)?-3:1}else{positionAdjust=(u.search(/top/)!==-1)?1:2}}if(u.search(/Middle/)!==-1){t.elements.tip.css({left:"50%",marginLeft:-(t.options.style.tip.size.width/2)})}else{if(u.search(/Left/)!==-1){t.elements.tip.css({left:t.options.style.border.radius-w})}else{if(u.search(/Right/)!==-1){t.elements.tip.css({right:t.options.style.border.radius+w})}}}if(u.search(/top/)!==-1){t.elements.tip.css({top:-positionAdjust})}else{t.elements.tip.css({bottom:positionAdjust})}}else{if(u.search(/left|right/)!==-1){if(f.browser.msie){positionAdjust=(parseInt(f.browser.version.charAt(0))===6)?1:((u.search(/left/)!==-1)?1:2)}if(u.search(/Middle/)!==-1){t.elements.tip.css({top:"50%",marginTop:-(t.options.style.tip.size.height/2)})}else{if(u.search(/Top/)!==-1){t.elements.tip.css({top:t.options.style.border.radius-w})}else{if(u.search(/Bottom/)!==-1){t.elements.tip.css({bottom:t.options.style.border.radius+w})}}}if(u.search(/left/)!==-1){t.elements.tip.css({left:-positionAdjust})}else{t.elements.tip.css({right:positionAdjust})}}}s="padding-"+u.match(/left|right|top|bottom/)[0];x=t.options.style.tip.size[(s.search(/left|right/)!==-1)?"width":"height"];t.elements.tooltip.css("padding",0);t.elements.tooltip.css(s,x);if(f.browser.msie&&parseInt(f.browser.version.charAt(0))==6){v=parseInt(t.elements.tip.css("margin-top"))||0;v+=parseInt(t.elements.content.css("margin-top"))||0;t.elements.tip.css({marginTop:v})}}function j(){var s=this;if(s.elements.title!==null){s.elements.title.remove()}s.elements.title=f('<div class="'+s.options.style.classes.title+'">').css(q(s.options.style.title,true)).css({zoom:(f.browser.msie)?1:0}).prependTo(s.elements.contentWrapper);if(s.options.content.title.text){s.updateTitle.call(s,s.options.content.title.text)}if(s.options.content.title.button!==false&&typeof s.options.content.title.button=="string"){s.elements.button=f('<a class="'+s.options.style.classes.button+'" style="float:right; position: relative"></a>').css(q(s.options.style.button,true)).html(s.options.content.title.button).prependTo(s.elements.title).click(function(t){if(!s.status.disabled){s.hide(t)}})}}function l(){var t,v,u,s;t=this;v=t.options.show.when.target;u=t.options.hide.when.target;if(t.options.hide.fixed){u=u.add(t.elements.tooltip)}if(t.options.hide.when.event=="inactive"){s=["click","dblclick","mousedown","mouseup","mousemove","mouseout","mouseenter","mouseleave","mouseover"];function y(z){if(t.status.disabled===true){return}clearTimeout(t.timers.inactive);t.timers.inactive=setTimeout(function(){f(s).each(function(){u.unbind(this+".qtip-inactive");t.elements.content.unbind(this+".qtip-inactive")});t.hide(z)},t.options.hide.delay)}}else{if(t.options.hide.fixed===true){t.elements.tooltip.bind("mouseover.qtip",function(){if(t.status.disabled===true){return}clearTimeout(t.timers.hide)})}}function x(z){if(t.status.disabled===true){return}if(t.options.hide.when.event=="inactive"){f(s).each(function(){u.bind(this+".qtip-inactive",y);t.elements.content.bind(this+".qtip-inactive",y)});y()}clearTimeout(t.timers.show);clearTimeout(t.timers.hide);t.timers.show=setTimeout(function(){t.show(z)},t.options.show.delay)}function w(z){if(t.status.disabled===true){return}if(t.options.hide.fixed===true&&t.options.hide.when.event.search(/mouse(out|leave)/i)!==-1&&f(z.relatedTarget).parents("div.qtip[qtip]").length>0){z.stopPropagation();z.preventDefault();clearTimeout(t.timers.hide);return false}clearTimeout(t.timers.show);clearTimeout(t.timers.hide);t.elements.tooltip.stop(true,true);t.timers.hide=setTimeout(function(){t.hide(z)},t.options.hide.delay)}if((t.options.show.when.target.add(t.options.hide.when.target).length===1&&t.options.show.when.event==t.options.hide.when.event&&t.options.hide.when.event!=="inactive")||t.options.hide.when.event=="unfocus"){t.cache.toggle=0;v.bind(t.options.show.when.event+".qtip",function(z){if(t.cache.toggle==0){x(z)}else{w(z)}})}else{v.bind(t.options.show.when.event+".qtip",x);if(t.options.hide.when.event!=="inactive"){u.bind(t.options.hide.when.event+".qtip",w)}}if(t.options.position.type.search(/(fixed|absolute)/)!==-1){t.elements.tooltip.bind("mouseover.qtip",t.focus)}if(t.options.position.target==="mouse"&&t.options.position.type!=="static"){v.bind("mousemove.qtip",function(z){t.cache.mouse={x:z.pageX,y:z.pageY};if(t.status.disabled===false&&t.options.position.adjust.mouse===true&&t.options.position.type!=="static"&&t.elements.tooltip.css("display")!=="none"){t.updatePosition(z)}})}}function o(u,v,A){var z,s,x,y,t,w;z=this;if(A.corner=="center"){return v.position}s=f.extend({},u);y={x:false,y:false};t={left:(s.left<f.fn.qtip.cache.screen.scroll.left),right:(s.left+A.dimensions.width+2>=f.fn.qtip.cache.screen.width+f.fn.qtip.cache.screen.scroll.left),top:(s.top<f.fn.qtip.cache.screen.scroll.top),bottom:(s.top+A.dimensions.height+2>=f.fn.qtip.cache.screen.height+f.fn.qtip.cache.screen.scroll.top)};x={left:(t.left&&(A.corner.search(/right/i)!=-1||(A.corner.search(/right/i)==-1&&!t.right))),right:(t.right&&(A.corner.search(/left/i)!=-1||(A.corner.search(/left/i)==-1&&!t.left))),top:(t.top&&A.corner.search(/top/i)==-1),bottom:(t.bottom&&A.corner.search(/bottom/i)==-1)};if(x.left){if(z.options.position.target!=="mouse"){s.left=v.position.left+v.dimensions.width}else{s.left=z.cache.mouse.x}y.x="Left"}else{if(x.right){if(z.options.position.target!=="mouse"){s.left=v.position.left-A.dimensions.width}else{s.left=z.cache.mouse.x-A.dimensions.width}y.x="Right"}}if(x.top){if(z.options.position.target!=="mouse"){s.top=v.position.top+v.dimensions.height}else{s.top=z.cache.mouse.y}y.y="top"}else{if(x.bottom){if(z.options.position.target!=="mouse"){s.top=v.position.top-A.dimensions.height}else{s.top=z.cache.mouse.y-A.dimensions.height}y.y="bottom"}}if(s.left<0){s.left=u.left;y.x=false}if(s.top<0){s.top=u.top;y.y=false}if(z.options.style.tip.corner!==false){s.corner=new String(A.corner);if(y.x!==false){s.corner=s.corner.replace(/Left|Right|Middle/,y.x)}if(y.y!==false){s.corner=s.corner.replace(/top|bottom/,y.y)}if(s.corner!==z.elements.tip.attr("rel")){e.call(z,s.corner)}}return s}function q(u,t){var v,s;v=f.extend(true,{},u);for(s in v){if(t===true&&s.search(/(tip|classes)/i)!==-1){delete v[s]}else{if(!t&&s.search(/(width|border|tip|title|classes|user)/i)!==-1){delete v[s]}}}return v}function c(s){if(typeof s.tip!=="object"){s.tip={corner:s.tip}}if(typeof s.tip.size!=="object"){s.tip.size={width:s.tip.size,height:s.tip.size}}if(typeof s.border!=="object"){s.border={width:s.border}}if(typeof s.width!=="object"){s.width={value:s.width}}if(typeof s.width.max=="string"){s.width.max=parseInt(s.width.max.replace(/([0-9]+)/i,"$1"))}if(typeof s.width.min=="string"){s.width.min=parseInt(s.width.min.replace(/([0-9]+)/i,"$1"))}if(typeof s.tip.size.x=="number"){s.tip.size.width=s.tip.size.x;delete s.tip.size.x}if(typeof s.tip.size.y=="number"){s.tip.size.height=s.tip.size.y;delete s.tip.size.y}return s}function a(){var s,t,u,x,v,w;s=this;u=[true,{}];for(t=0;t<arguments.length;t++){u.push(arguments[t])}x=[f.extend.apply(f,u)];while(typeof x[0].name=="string"){x.unshift(c(f.fn.qtip.styles[x[0].name]))}x.unshift(true,{classes:{tooltip:"qtip-"+(arguments[0].name||"defaults")}},f.fn.qtip.styles.defaults);v=f.extend.apply(f,x);w=(f.browser.msie)?1:0;v.tip.size.width+=w;v.tip.size.height+=w;if(v.tip.size.width%2>0){v.tip.size.width+=1}if(v.tip.size.height%2>0){v.tip.size.height+=1}if(v.tip.corner===true){v.tip.corner=(s.options.position.corner.tooltip==="center")?false:s.options.position.corner.tooltip}return v}function b(v,u,t){var s={bottomRight:[[0,0],[u,t],[u,0]],bottomLeft:[[0,0],[u,0],[0,t]],topRight:[[0,t],[u,0],[u,t]],topLeft:[[0,0],[0,t],[u,t]],topMiddle:[[0,t],[u/2,0],[u,t]],bottomMiddle:[[0,0],[u,0],[u/2,t]],rightMiddle:[[0,0],[u,t/2],[0,t]],leftMiddle:[[u,0],[u,t],[0,t/2]]};s.leftTop=s.bottomRight;s.rightTop=s.bottomLeft;s.leftBottom=s.topRight;s.rightBottom=s.topLeft;return s[v]}function g(s){var t;if(f("<canvas>").get(0).getContext){t={topLeft:[s,s],topRight:[0,s],bottomLeft:[s,0],bottomRight:[0,0]}}else{if(f.browser.msie){t={topLeft:[-90,90,0],topRight:[-90,90,-s],bottomLeft:[90,270,0],bottomRight:[90,270,-s]}}}return t}function k(){var s,t,u;s=this;u=s.getDimensions();t='<iframe class="qtip-bgiframe" frameborder="0" tabindex="-1" src="javascript:false" style="display:block; position:absolute; z-index:-1; filter:alpha(opacity=\'0\'); border: 1px solid red; height:'+u.height+"px; width:"+u.width+'px" />';s.elements.bgiframe=s.elements.wrapper.prepend(t).children(".qtip-bgiframe:first")}f(document).ready(function(){f.fn.qtip.cache={screen:{scroll:{left:f(window).scrollLeft(),top:f(window).scrollTop()},width:f(window).width(),height:f(window).height()}};var s;f(window).bind("resize scroll",function(t){clearTimeout(s);s=setTimeout(function(){if(t.type==="scroll"){f.fn.qtip.cache.screen.scroll={left:f(window).scrollLeft(),top:f(window).scrollTop()}}else{f.fn.qtip.cache.screen.width=f(window).width();f.fn.qtip.cache.screen.height=f(window).height()}for(i=0;i<f.fn.qtip.interfaces.length;i++){var u=f.fn.qtip.interfaces[i];if(u.status.rendered===true&&(u.options.position.type!=="static"||u.options.position.adjust.scroll&&t.type==="scroll"||u.options.position.adjust.resize&&t.type==="resize")){u.updatePosition(t,true)}}},100)});f(document).bind("mousedown.qtip",function(t){if(f(t.target).parents("div.qtip").length===0){f(".qtip[unfocus]").each(function(){var u=f(this).qtip("api");if(f(this).is(":visible")&&!u.status.disabled&&f(t.target).add(u.elements.target).length>1){u.hide(t)}})}})});f.fn.qtip.interfaces=[];f.fn.qtip.log={error:function(){return this}};f.fn.qtip.constants={};f.fn.qtip.defaults={content:{prerender:false,text:false,url:false,data:null,title:{text:false,button:false}},position:{target:false,corner:{target:"bottomRight",tooltip:"topLeft"},adjust:{x:0,y:0,mouse:true,screen:false,scroll:true,resize:true},type:"absolute",container:false},show:{when:{target:false,event:"mouseover"},effect:{type:"fade",length:100},delay:140,solo:false,ready:false},hide:{when:{target:false,event:"mouseout"},effect:{type:"fade",length:100},delay:0,fixed:false},api:{beforeRender:function(){},onRender:function(){},beforePositionUpdate:function(){},onPositionUpdate:function(){},beforeShow:function(){},onShow:function(){},beforeHide:function(){},onHide:function(){},beforeContentUpdate:function(){},onContentUpdate:function(){},beforeContentLoad:function(){},onContentLoad:function(){},beforeTitleUpdate:function(){},onTitleUpdate:function(){},beforeDestroy:function(){},onDestroy:function(){},beforeFocus:function(){},onFocus:function(){}}};f.fn.qtip.styles={defaults:{background:"white",color:"#111",overflow:"hidden",textAlign:"left",width:{min:0,max:250},padding:"5px 9px",border:{width:1,radius:0,color:"#d3d3d3"},tip:{corner:false,color:false,size:{width:13,height:13},opacity:1},title:{background:"#e1e1e1",fontWeight:"bold",padding:"7px 12px"},button:{cursor:"pointer"},classes:{target:"",tip:"qtip-tip",title:"qtip-title",button:"qtip-button",content:"qtip-content",active:"qtip-active"}},cream:{border:{width:3,radius:0,color:"#F9E98E"},title:{background:"#F0DE7D",color:"#A27D35"},background:"#FBF7AA",color:"#A27D35",classes:{tooltip:"qtip-cream"}},light:{border:{width:3,radius:0,color:"#E2E2E2"},title:{background:"#f1f1f1",color:"#454545"},background:"white",color:"#454545",classes:{tooltip:"qtip-light"}},dark:{border:{width:3,radius:0,color:"#303030"},title:{background:"#404040",color:"#f3f3f3"},background:"#505050",color:"#f3f3f3",classes:{tooltip:"qtip-dark"}},red:{border:{width:3,radius:0,color:"#CE6F6F"},title:{background:"#f28279",color:"#9C2F2F"},background:"#F79992",color:"#9C2F2F",classes:{tooltip:"qtip-red"}},green:{border:{width:3,radius:0,color:"#A9DB66"},title:{background:"#b9db8c",color:"#58792E"},background:"#CDE6AC",color:"#58792E",classes:{tooltip:"qtip-green"}},blue:{border:{width:3,radius:0,color:"#ADD9ED"},title:{background:"#D0E9F5",color:"#5E99BD"},background:"#E5F6FE",color:"#4D9FBF",classes:{tooltip:"qtip-blue"}}}})(jQuery);
183 js/popcorn.code.js
@@ -0,0 +1,183 @@
+// PLUGIN: Code
+
+(function ( Popcorn ) {
+
+ /**
+ * Code Popcorn Plug-in
+ *
+ * Adds the ability to run arbitrary code (JavaScript functions) according to video timing.
+ *
+ * @param {Object} options
+ *
+ * Required parameters: start, end, template, data, and target.
+ * Optional parameter: static.
+ *
+ * start: the time in seconds when the mustache template should be rendered
+ * in the target div.
+ *
+ * end: the time in seconds when the rendered mustache template should be
+ * removed from the target div.
+ *
+ * onStart: the function to be run when the start time is reached.
+ *
+ * onFrame: [optional] a function to be run on each paint call
+ * (e.g., called ~60 times per second) between the start and end times.
+ *
+ * onEnd: [optional] a function to be run when the end time is reached.
+ *
+ * Example:
+ var p = Popcorn('#video')
+
+ // onStart function only
+ .code({
+ start: 1,
+ end: 4,
+ onStart: function( options ) {
+ // called on start
+ }
+ })
+
+ // onStart + onEnd only
+ .code({
+ start: 6,
+ end: 8,
+ onStart: function( options ) {
+ // called on start
+ },
+ onEnd: function ( options ) {
+ // called on end
+ }
+ })
+
+ // onStart, onEnd, onFrame
+ .code({
+ start: 10,
+ end: 14,
+ onStart: function( options ) {
+ // called on start
+ },
+ onFrame: function ( options ) {
+ // called on every paint frame between start and end.
+ // uses mozRequestAnimationFrame, webkitRequestAnimationFrame,
+ // or setTimeout with 16ms window.
+ },
+ onEnd: function ( options ) {
+ // called on end
+ }
+ });
+ *
+ */
+
+ Popcorn.plugin( "code" , function( options ) {
+ var running = false;
+
+ // Setup a proper frame interval function (60fps), favouring paint events.
+ var step = (function() {
+
+ var buildFrameRunner = function( runner ) {
+ return function( f, options ) {
+
+ var _f = function() {
+ running && f();
+ running && runner( _f );
+ };
+
+ _f();
+ };
+ };
+
+ // Figure out which level of browser support we have for this
+ if ( window.webkitRequestAnimationFrame ) {
+ return buildFrameRunner( window.webkitRequestAnimationFrame );
+ } else if ( window.mozRequestAnimationFrame ) {
+ return buildFrameRunner( window.mozRequestAnimationFrame );
+ } else {
+ return buildFrameRunner( function( f ) {
+ window.setTimeout( f, 16 );
+ });
+ }
+
+ })();
+
+ if ( !options.onStart || typeof options.onStart !== "function" ) {
+
+ if ( Popcorn.plugin.debug ) {
+ throw new Error( "Popcorn Code Plugin Error: onStart must be a function." );
+ }
+ options.onStart = Popcorn.nop;
+ }
+
+ if ( options.onEnd && typeof options.onEnd !== "function" ) {
+
+ if ( Popcorn.plugin.debug ) {
+ throw new Error( "Popcorn Code Plugin Error: onEnd must be a function." );
+ }
+ options.onEnd = undefined;
+ }
+
+ if ( options.onFrame && typeof options.onFrame !== "function" ) {
+
+ if ( Popcorn.plugin.debug ) {
+ throw new Error( "Popcorn Code Plugin Error: onFrame must be a function." );
+ }
+ options.onFrame = undefined;
+ }
+
+ return {
+ start: function( event, options ) {
+ options.onStart( options );
+
+ if ( options.onFrame ) {
+ running = true;
+ step( options.onFrame, options );
+ }
+ },
+
+ end: function( event, options ) {
+ if ( options.onFrame ) {
+ running = false;
+ }
+
+ if ( options.onEnd ) {
+ options.onEnd( options );
+ }
+ }
+ };
+ },
+ {
+ about: {
+ name: "Popcorn Code Plugin",
+ version: "0.1",
+ author: "David Humphrey (@humphd)",
+ website: "http://vocamus.net/dave"
+ },
+ options: {
+ start: {
+ elem: "input",
+ type: "text",
+ label: "In"
+ },
+ end: {
+ elem: "input",
+ type: "text",
+ label: "Out"
+ },
+ onStart: {
+ elem: "input",
+ type: "function",
+ label: "onStart"
+ },
+ onFrame: {
+ elem: "input",
+ type: "function",
+ label: "onFrame",
+ optional: true
+ },
+ onEnd: {
+ elem: "input",
+ type: "function",
+ label: "onEnd"
+ }
+ }
+ });
+})( Popcorn );
1,877 js/popcorn.js
@@ -0,0 +1,1877 @@
+(function(global, document) {
+
+ // Popcorn.js does not support archaic browsers
+ if ( !document.addEventListener ) {
+ global.Popcorn = {
+ isSupported: false
+ };
+
+ var methods = ( "removeInstance addInstance getInstanceById removeInstanceById " +
+ "forEach extend effects error guid sizeOf isArray nop position disable enable destroy" +
+ "addTrackEvent removeTrackEvent getTrackEvents getTrackEvent getLastTrackEventId " +
+ "timeUpdate plugin removePlugin compose effect xhr getJSONP getScript" ).split(/\s+/);
+
+ while ( methods.length ) {
+ global.Popcorn[ methods.shift() ] = function() {};
+ }
+ return;
+ }
+
+ var
+
+ AP = Array.prototype,
+ OP = Object.prototype,
+
+ forEach = AP.forEach,
+ slice = AP.slice,
+ hasOwn = OP.hasOwnProperty,
+ toString = OP.toString,
+
+ // Copy global Popcorn (may not exist)
+ _Popcorn = global.Popcorn,
+
+ // Ready fn cache
+ readyStack = [],
+ readyBound = false,
+ readyFired = false,
+
+ // Non-public internal data object
+ internal = {
+ events: {
+ hash: {},
+ apis: {}
+ }
+ },
+
+ // Non-public `requestAnimFrame`
+ // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
+ requestAnimFrame = (function(){
+ return global.requestAnimationFrame ||
+ global.webkitRequestAnimationFrame ||
+ global.mozRequestAnimationFrame ||
+ global.oRequestAnimationFrame ||
+ global.msRequestAnimationFrame ||
+ function( callback, element ) {
+ global.setTimeout( callback, 16 );
+ };
+ }()),
+
+ // Non-public `getKeys`, return an object's keys as an array
+ getKeys = function( obj ) {
+ return Object.keys ? Object.keys( obj ) : (function( obj ) {
+ var item,
+ list = [];
+
+ for ( item in obj ) {
+ if ( hasOwn.call( obj, item ) ) {
+ list.push( item );
+ }
+ }
+ return list;
+ })( obj );
+ },
+
+ // Declare constructor
+ // Returns an instance object.
+ Popcorn = function( entity, options ) {
+ // Return new Popcorn object
+ return new Popcorn.p.init( entity, options || null );
+ };
+
+ // Popcorn API version, automatically inserted via build system.
+ Popcorn.version = "@VERSION";
+
+ // Boolean flag allowing a client to determine if Popcorn can be supported
+ Popcorn.isSupported = true;
+
+ // Instance caching
+ Popcorn.instances = [];
+
+ // Declare a shortcut (Popcorn.p) to and a definition of
+ // the new prototype for our Popcorn constructor
+ Popcorn.p = Popcorn.prototype = {
+
+ init: function( entity, options ) {
+
+ var matches,
+ self = this;
+
+ // Supports Popcorn(function () { /../ })
+ // Originally proposed by Daniel Brooks
+
+ if ( typeof entity === "function" ) {
+
+ // If document ready has already fired
+ if ( document.readyState === "complete" ) {
+
+ entity( document, Popcorn );
+
+ return;
+ }
+ // Add `entity` fn to ready stack
+ readyStack.push( entity );
+
+ // This process should happen once per page load
+ if ( !readyBound ) {
+
+ // set readyBound flag
+ readyBound = true;
+
+ var DOMContentLoaded = function() {
+
+ readyFired = true;
+
+ // Remove global DOM ready listener
+ document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+
+ // Execute all ready function in the stack
+ for ( var i = 0, readyStackLength = readyStack.length; i < readyStackLength; i++ ) {
+
+ readyStack[ i ].call( document, Popcorn );
+
+ }
+ // GC readyStack
+ readyStack = null;
+ };
+
+ // Register global DOM ready listener
+ document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+ }
+
+ return;
+ }
+
+ if ( typeof entity === "string" ) {
+ try {
+ matches = document.querySelector( entity );
+ } catch( e ) {
+ throw new Error( "Popcorn.js Error: Invalid media element selector: " + entity );
+ }
+ }
+
+ // Get media element by id or object reference
+ this.media = matches || entity;
+
+ // Create an audio or video element property reference
+ this[ ( this.media.nodeName && this.media.nodeName.toLowerCase() ) || "video" ] = this.media;
+
+ // Register new instance
+ Popcorn.instances.push( this );
+
+ this.options = options || {};
+
+ this.isDestroyed = false;
+
+ this.data = {
+
+ // data structure of all
+ running: {
+ cue: []
+ },
+
+ // Executed by either timeupdate event or in rAF loop
+ timeUpdate: Popcorn.nop,
+
+ // Allows disabling a plugin per instance
+ disabled: {},
+
+ // Stores DOM event queues by type
+ events: {},
+
+ // Stores Special event hooks data
+ hooks: {},
+
+ // Store track event history data
+ history: [],
+
+ // Stores ad-hoc state related data]
+ state: {
+ volume: this.media.volume
+ },
+
+ // Store track event object references by trackId
+ trackRefs: {},
+
+ // Playback track event queues
+ trackEvents: {
+ byStart: [{
+
+ start: -1,
+ end: -1
+ }],
+ byEnd: [{
+ start: -1,
+ end: -1
+ }],
+ animating: [],
+ startIndex: 0,
+ endIndex: 0,
+ previousUpdateTime: -1
+ }
+ };
+
+ // function to fire when video is ready
+ var isReady = function() {
+
+ // chrome bug: http://code.google.com/p/chromium/issues/detail?id=119598
+ // it is possible the video's time is less than 0
+ // this has the potential to call track events more than once, when they should not
+ // start: 0, end: 1 will start, end, start again, when it should just start
+ // just setting it to 0 if it is below 0 fixes this issue
+ if ( self.media.currentTime < 0 ) {
+
+ self.media.currentTime = 0;
+ }
+
+ self.media.removeEventListener( "loadeddata", isReady, false );
+
+ var duration, videoDurationPlus,
+ runningPlugins, runningPlugin, rpLength, rpNatives;
+
+ // Adding padding to the front and end of the arrays
+ // this is so we do not fall off either end
+ duration = self.media.duration;
+
+ // Check for no duration info (NaN)
+ videoDurationPlus = duration != duration ? Number.MAX_VALUE : duration + 1;
+
+ Popcorn.addTrackEvent( self, {
+ start: videoDurationPlus,
+ end: videoDurationPlus
+ });
+
+ if ( self.options.frameAnimation ) {
+
+ // if Popcorn is created with frameAnimation option set to true,
+ // requestAnimFrame is used instead of "timeupdate" media event.
+ // This is for greater frame time accuracy, theoretically up to
+ // 60 frames per second as opposed to ~4 ( ~every 15-250ms)
+ self.data.timeUpdate = function () {
+
+ Popcorn.timeUpdate( self, {} );
+
+ // fire frame for each enabled active plugin of every type
+ Popcorn.forEach( Popcorn.manifest, function( key, val ) {
+
+ runningPlugins = self.data.running[ val ];
+
+ // ensure there are running plugins on this type on this instance
+ if ( runningPlugins ) {
+
+ rpLength = runningPlugins.length;
+ for ( var i = 0; i < rpLength; i++ ) {
+
+ runningPlugin = runningPlugins[ i ];
+ rpNatives = runningPlugin._natives;
+ rpNatives && rpNatives.frame &&
+ rpNatives.frame.call( self, {}, runningPlugin, self.currentTime() );
+ }
+ }
+ });
+
+ self.emit( "timeupdate" );
+
+ !self.isDestroyed && requestAnimFrame( self.data.timeUpdate );
+ };
+
+ !self.isDestroyed && requestAnimFrame( self.data.timeUpdate );
+
+ } else {
+
+ self.data.timeUpdate = function( event ) {
+ Popcorn.timeUpdate( self, event );
+ };
+
+ if ( !self.isDestroyed ) {
+ self.media.addEventListener( "timeupdate", self.data.timeUpdate, false );
+ }
+ }
+ };
+
+ if ( self.media.readyState >= 2 ) {
+
+ isReady();
+ } else {
+
+ self.media.addEventListener( "loadeddata", isReady, false );
+ }
+
+ return this;
+ }
+ };
+
+ // Extend constructor prototype to instance prototype
+ // Allows chaining methods to instances
+ Popcorn.p.init.prototype = Popcorn.p;
+
+ Popcorn.forEach = function( obj, fn, context ) {
+
+ if ( !obj || !fn ) {
+ return {};
+ }
+
+ context = context || this;
+
+ var key, len;
+
+ // Use native whenever possible
+ if ( forEach && obj.forEach === forEach ) {
+ return obj.forEach( fn, context );
+ }
+
+ if ( toString.call( obj ) === "[object NodeList]" ) {
+ for ( key = 0, len = obj.length; key < len; key++ ) {
+ fn.call( context, obj[ key ], key, obj );
+ }
+ return obj;
+ }
+
+ for ( key in obj ) {
+ if ( hasOwn.call( obj, key ) ) {
+ fn.call( context, obj[ key ], key, obj );
+ }
+ }
+ return obj;
+ };
+
+ Popcorn.extend = function( obj ) {
+ var dest = obj, src = slice.call( arguments, 1 );
+
+ Popcorn.forEach( src, function( copy ) {
+ for ( var prop in copy ) {
+ dest[ prop ] = copy[ prop ];
+ }
+ });
+
+ return dest;
+ };
+
+
+ // A Few reusable utils, memoized onto Popcorn
+ Popcorn.extend( Popcorn, {
+ noConflict: function( deep ) {
+
+ if ( deep ) {
+ global.Popcorn = _Popcorn;
+ }
+
+ return Popcorn;
+ },
+ error: function( msg ) {
+ throw new Error( msg );
+ },
+ guid: function( prefix ) {
+ Popcorn.guid.counter++;
+ return ( prefix ? prefix : "" ) + ( +new Date() + Popcorn.guid.counter );
+ },
+ sizeOf: function( obj ) {
+ var size = 0;
+
+ for ( var prop in obj ) {
+ size++;
+ }
+
+ return size;
+ },
+ isArray: Array.isArray || function( array ) {
+ return toString.call( array ) === "[object Array]";
+ },
+
+ nop: function() {},
+
+ position: function( elem ) {
+
+ var clientRect = elem.getBoundingClientRect(),
+ bounds = {},
+ doc = elem.ownerDocument,
+ docElem = document.documentElement,
+ body = document.body,
+ clientTop, clientLeft, scrollTop, scrollLeft, top, left;
+
+ // Determine correct clientTop/Left
+ clientTop = docElem.clientTop || body.clientTop || 0;
+ clientLeft = docElem.clientLeft || body.clientLeft || 0;
+
+ // Determine correct scrollTop/Left
+ scrollTop = ( global.pageYOffset && docElem.scrollTop || body.scrollTop );
+ scrollLeft = ( global.pageXOffset && docElem.scrollLeft || body.scrollLeft );
+
+ // Temp top/left
+ top = Math.ceil( clientRect.top + scrollTop - clientTop );
+ left = Math.ceil( clientRect.left + scrollLeft - clientLeft );
+
+ for ( var p in clientRect ) {
+ bounds[ p ] = Math.round( clientRect[ p ] );
+ }
+
+ return Popcorn.extend({}, bounds, { top: top, left: left });
+ },
+
+ disable: function( instance, plugin ) {
+
+ if ( !instance.data.disabled[ plugin ] ) {
+
+ instance.data.disabled[ plugin ] = true;
+
+ for ( var i = instance.data.running[ plugin ].length - 1, event; i >= 0; i-- ) {
+
+ event = instance.data.running[ plugin ][ i ];
+ event._natives.end.call( instance, null, event );
+ }
+ }
+
+ return instance;
+ },
+ enable: function( instance, plugin ) {
+
+ if ( instance.data.disabled[ plugin ] ) {
+
+ instance.data.disabled[ plugin ] = false;
+
+ for ( var i = instance.data.running[ plugin ].length - 1, event; i >= 0; i-- ) {
+
+ event = instance.data.running[ plugin ][ i ];
+ event._natives.start.call( instance, null, event );
+ }
+ }
+
+ return instance;
+ },
+ destroy: function( instance ) {
+ var events = instance.data.events,
+ singleEvent, item, fn;
+
+ // Iterate through all events and remove them
+ for ( item in events ) {
+ singleEvent = events[ item ];
+ for ( fn in singleEvent ) {
+ delete singleEvent[ fn ];
+ }
+ events[ item ] = null;
+ }
+
+ if ( !instance.isDestroyed ) {
+ instance.data.timeUpdate && instance.media.removeEventListener( "timeupdate", instance.data.timeUpdate, false );
+ instance.isDestroyed = true;
+ }
+ }
+ });
+
+ // Memoized GUID Counter
+ Popcorn.guid.counter = 1;
+
+ // Factory to implement getters, setters and controllers
+ // as Popcorn instance methods. The IIFE will create and return
+ // an object with defined methods
+ Popcorn.extend(Popcorn.p, (function() {
+
+ var methods = "load play pause currentTime playbackRate volume duration preload playbackRate " +
+ "autoplay loop controls muted buffered readyState seeking paused played seekable ended",
+ ret = {};
+
+
+ // Build methods, store in object that is returned and passed to extend
+ Popcorn.forEach( methods.split( /\s+/g ), function( name ) {
+
+ ret[ name ] = function( arg ) {
+
+ if ( typeof this.media[ name ] === "function" ) {
+
+ // Support for shorthanded play(n)/pause(n) jump to currentTime
+ // If arg is not null or undefined and called by one of the
+ // allowed shorthandable methods, then set the currentTime
+ // Supports time as seconds or SMPTE
+ if ( arg != null && /play|pause/.test( name ) ) {
+ this.media.currentTime = Popcorn.util.toSeconds( arg );
+ }
+
+ this.media[ name ]();
+
+ return this;
+ }
+
+
+ if ( arg != null ) {
+
+ this.media[ name ] = arg;
+
+ return this;
+ }
+
+ return this.media[ name ];
+ };
+ });
+
+ return ret;
+
+ })()
+ );
+
+ Popcorn.forEach( "enable disable".split(" "), function( method ) {
+ Popcorn.p[ method ] = function( plugin ) {
+ return Popcorn[ method ]( this, plugin );
+ };
+ });
+
+ Popcorn.extend(Popcorn.p, {
+
+ // Rounded currentTime
+ roundTime: function() {
+ return -~this.media.currentTime;
+ },
+
+ // Attach an event to a single point in time
+ exec: function( time, fn ) {
+
+ // Creating a one second track event with an empty end
+ Popcorn.addTrackEvent( this, {
+ start: time,
+ end: time + 1,
+ _running: false,
+ _natives: {
+ start: fn || Popcorn.nop,
+ end: Popcorn.nop,
+ type: "cue"
+ }
+ });
+
+ return this;
+ },
+
+ // Mute the calling media, optionally toggle
+ mute: function( toggle ) {
+
+ var event = toggle == null || toggle === true ? "muted" : "unmuted";
+
+ // If `toggle` is explicitly `false`,
+ // unmute the media and restore the volume level
+ if ( event === "unmuted" ) {
+ this.media.muted = false;
+ this.media.volume = this.data.state.volume;
+ }
+
+ // If `toggle` is either null or undefined,
+ // save the current volume and mute the media element
+ if ( event === "muted" ) {
+ this.data.state.volume = this.media.volume;
+ this.media.muted = true;
+ }
+
+ // Trigger either muted|unmuted event
+ this.emit( event );
+
+ return this;
+ },
+
+ // Convenience method, unmute the calling media
+ unmute: function( toggle ) {
+
+ return this.mute( toggle == null ? false : !toggle );
+ },
+
+ // Get the client bounding box of an instance element
+ position: function() {
+ return Popcorn.position( this.media );
+ },
+
+ // Toggle a plugin's playback behaviour (on or off) per instance
+ toggle: function( plugin ) {
+ return Popcorn[ this.data.disabled[ plugin ] ? "enable" : "disable" ]( this, plugin );
+ },
+
+ // Set default values for plugin options objects per instance
+ defaults: function( plugin, defaults ) {
+
+ // If an array of default configurations is provided,
+ // iterate and apply each to this instance
+ if ( Popcorn.isArray( plugin ) ) {
+
+ Popcorn.forEach( plugin, function( obj ) {
+ for ( var name in obj ) {
+ this.defaults( name, obj[ name ] );
+ }
+ }, this );
+
+ return this;
+ }
+
+ if ( !this.options.defaults ) {
+ this.options.defaults = {};
+ }
+
+ if ( !this.options.defaults[ plugin ] ) {
+ this.options.defaults[ plugin ] = {};
+ }
+
+ Popcorn.extend( this.options.defaults[ plugin ], defaults );
+
+ return this;
+ }
+ });
+
+ Popcorn.Events = {
+ UIEvents: "blur focus focusin focusout load resize scroll unload",
+ MouseEvents: "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave click dblclick",
+ Events: "loadstart progress suspend emptied stalled play pause " +
+ "loadedmetadata loadeddata waiting playing canplay canplaythrough " +
+ "seeking seeked timeupdate ended ratechange durationchange volumechange"
+ };
+
+ Popcorn.Events.Natives = Popcorn.Events.UIEvents + " " +
+ Popcorn.Events.MouseEvents + " " +
+ Popcorn.Events.Events;
+
+ internal.events.apiTypes = [ "UIEvents", "MouseEvents", "Events" ];
+
+ // Privately compile events table at load time
+ (function( events, data ) {
+
+ var apis = internal.events.apiTypes,
+ eventsList = events.Natives.split( /\s+/g ),
+ idx = 0, len = eventsList.length, prop;
+
+ for( ; idx < len; idx++ ) {
+ data.hash[ eventsList[idx] ] = true;
+ }
+
+ apis.forEach(function( val, idx ) {
+
+ data.apis[ val ] = {};
+
+ var apiEvents = events[ val ].split( /\s+/g ),
+ len = apiEvents.length,
+ k = 0;
+
+ for ( ; k < len; k++ ) {
+ data.apis[ val ][ apiEvents[ k ] ] = true;
+ }
+ });
+ })( Popcorn.Events, internal.events );
+
+ Popcorn.events = {
+
+ isNative: function( type ) {
+ return !!internal.events.hash[ type ];
+ },
+ getInterface: function( type ) {
+
+ if ( !Popcorn.events.isNative( type ) ) {
+ return false;
+ }
+
+ var eventApi = internal.events,
+ apis = eventApi.apiTypes,
+ apihash = eventApi.apis,
+ idx = 0, len = apis.length, api, tmp;
+
+ for ( ; idx < len; idx++ ) {
+ tmp = apis[ idx ];
+
+ if ( apihash[ tmp ][ type ] ) {
+ api = tmp;
+ break;
+ }
+ }
+ return api;
+ },
+ // Compile all native events to single array
+ all: Popcorn.Events.Natives.split( /\s+/g ),
+ // Defines all Event handling static functions
+ fn: {
+ trigger: function( type, data ) {
+
+ var eventInterface, evt;
+ // setup checks for custom event system
+ if ( this.data.events[ type ] && Popcorn.sizeOf( this.data.events[ type ] ) ) {
+
+ eventInterface = Popcorn.events.getInterface( type );
+
+ if ( eventInterface ) {
+
+ evt = document.createEvent( eventInterface );
+ evt.initEvent( type, true, true, global, 1 );
+
+ this.media.dispatchEvent( evt );
+
+ return this;
+ }
+
+ // Custom events
+ Popcorn.forEach( this.data.events[ type ], function( obj, key ) {
+
+ obj.call( this, data );
+
+ }, this );
+
+ }
+
+ return this;
+ },
+ listen: function( type, fn ) {
+
+ var self = this,
+ hasEvents = true,
+ eventHook = Popcorn.events.hooks[ type ],
+ origType = type,
+ tmp;
+
+ if ( !this.data.events[ type ] ) {
+ this.data.events[ type ] = {};
+ hasEvents = false;
+ }
+
+ // Check and setup event hooks
+ if ( eventHook ) {
+
+ // Execute hook add method if defined
+ if ( eventHook.add ) {
+ eventHook.add.call( this, {}, fn );
+ }
+
+ // Reassign event type to our piggyback event type if defined
+ if ( eventHook.bind ) {
+ type = eventHook.bind;
+ }
+
+ // Reassign handler if defined
+ if ( eventHook.handler ) {
+ tmp = fn;
+
+ fn = function wrapper( event ) {
+ eventHook.handler.call( self, event, tmp );
+ };
+ }
+
+ // assume the piggy back event is registered
+ hasEvents = true;
+
+ // Setup event registry entry
+ if ( !this.data.events[ type ] ) {
+ this.data.events[ type ] = {};
+ // Toggle if the previous assumption was untrue
+ hasEvents = false;
+ }
+ }
+
+ // Register event and handler
+ this.data.events[ type ][ fn.name || ( fn.toString() + Popcorn.guid() ) ] = fn;
+
+ // only attach one event of any type
+ if ( !hasEvents && Popcorn.events.all.indexOf( type ) > -1 ) {
+
+ this.media.addEventListener( type, function( event ) {
+
+ Popcorn.forEach( self.data.events[ type ], function( obj, key ) {
+ if ( typeof obj === "function" ) {
+ obj.call( self, event );
+ }
+ });
+
+ }, false);
+ }
+ return this;
+ },
+ unlisten: function( type, fn ) {
+
+ if ( this.data.events[ type ] && this.data.events[ type ][ fn ] ) {
+
+ delete this.data.events[ type ][ fn ];
+
+ return this;
+ }
+
+ this.data.events[ type ] = null;
+
+ return this;
+ }
+ },
+ hooks: {
+ canplayall: {
+ bind: "canplaythrough",
+ add: function( event, callback ) {
+
+ var state = false;
+
+ if ( this.media.readyState ) {
+
+ callback.call( this, event );
+
+ state = true;
+ }
+
+ this.data.hooks.canplayall = {
+ fired: state
+ };
+ },
+ // declare special handling instructions
+ handler: function canplayall( event, callback ) {
+
+ if ( !this.data.hooks.canplayall.fired ) {
+ // trigger original user callback once
+ callback.call( this, event );
+
+ this.data.hooks.canplayall.fired = true;
+ }
+ }
+ }
+ }
+ };
+
+ // Extend Popcorn.events.fns (listen, unlisten, trigger) to all Popcorn instances
+ // Extend aliases (on, off, emit)
+ Popcorn.forEach( [ [ "trigger", "emit" ], [ "listen", "on" ], [ "unlisten", "off" ] ], function( key ) {
+ Popcorn.p[ key[ 0 ] ] = Popcorn.p[ key[ 1 ] ] = Popcorn.events.fn[ key[ 0 ] ];
+ });
+
+ // Internal Only - Adds track events to the instance object
+ Popcorn.addTrackEvent = function( obj, track ) {
+
+ // Determine if this track has default options set for it
+ // If so, apply them to the track object
+ if ( track && track._natives && track._natives.type &&
+ ( obj.options.defaults && obj.options.defaults[ track._natives.type ] ) ) {
+
+ track = Popcorn.extend( {}, obj.options.defaults[ track._natives.type ], track );
+ }
+
+ if ( track._natives ) {
+ // Supports user defined track event id
+ track._id = !track.id ? Popcorn.guid( track._natives.type ) : track.id;
+
+ // Push track event ids into the history
+ obj.data.history.push( track._id );
+ }
+
+ track.start = Popcorn.util.toSeconds( track.start, obj.options.framerate );
+ track.end = Popcorn.util.toSeconds( track.end, obj.options.framerate );
+
+ // Store this definition in an array sorted by times
+ var byStart = obj.data.trackEvents.byStart,
+ byEnd = obj.data.trackEvents.byEnd,
+ startIndex, endIndex;
+
+ for ( startIndex = byStart.length - 1; startIndex >= 0; startIndex-- ) {
+
+ if ( track.start >= byStart[ startIndex ].start ) {
+ byStart.splice( startIndex + 1, 0, track );
+ break;
+ }
+ }
+
+ for ( endIndex = byEnd.length - 1; endIndex >= 0; endIndex-- ) {
+
+ if ( track.end > byEnd[ endIndex ].end ) {
+ byEnd.splice( endIndex + 1, 0, track );
+ break;
+ }
+ }
+
+ // Display track event immediately if it's enabled and current
+ if ( track.end > obj.media.currentTime &&
+ track.start <= obj.media.currentTime ) {
+
+ track._running = true;
+ obj.data.running[ track._natives.type ].push( track );
+
+ if ( !obj.data.disabled[ track._natives.type ] ) {
+
+ track._natives.start.call( obj, null, track );
+ }
+ }
+
+ // update startIndex and endIndex
+ if ( startIndex <= obj.data.trackEvents.startIndex &&
+ track.start <= obj.data.trackEvents.previousUpdateTime ) {
+
+ obj.data.trackEvents.startIndex++;
+ }
+
+ if ( endIndex <= obj.data.trackEvents.endIndex &&
+ track.end < obj.data.trackEvents.previousUpdateTime ) {
+
+ obj.data.trackEvents.endIndex++;
+ }
+
+ this.timeUpdate( obj, null, true );
+
+ // Store references to user added trackevents in ref table
+ if ( track._id ) {
+ Popcorn.addTrackEvent.ref( obj, track );
+ }
+ };
+
+ // Internal Only - Adds track event references to the instance object's trackRefs hash table
+ Popcorn.addTrackEvent.ref = function( obj, track ) {
+ obj.data.trackRefs[ track._id ] = track;
+
+ return obj;
+ };
+
+ Popcorn.removeTrackEvent = function( obj, removeId ) {
+
+ var start, end, animate,
+ historyLen = obj.data.history.length,
+ length = obj.data.trackEvents.byStart.length,
+ index = 0,
+ indexWasAt = 0,
+ byStart = [],
+ byEnd = [],
+ animating = [],
+ history = [];
+
+ while ( --length > -1 ) {
+ start = obj.data.trackEvents.byStart[ index ];
+ end = obj.data.trackEvents.byEnd[ index ];
+
+ // Padding events will not have _id properties.
+ // These should be safely pushed onto the front and back of the
+ // track event array
+ if ( !start._id ) {
+ byStart.push( start );
+ byEnd.push( end );
+ }
+
+ // Filter for user track events (vs system track events)
+ if ( start._id ) {
+
+ // If not a matching start event for removal
+ if ( start._id !== removeId ) {
+ byStart.push( start );
+ }
+
+ // If not a matching end event for removal
+ if ( end._id !== removeId ) {
+ byEnd.push( end );
+ }
+
+ // If the _id is matched, capture the current index
+ if ( start._id === removeId ) {
+ indexWasAt = index;
+
+ // If a _teardown function was defined,
+ // enforce for track event removals
+ if ( start._natives._teardown ) {
+ start._natives._teardown.call( obj, start );
+ }
+ }
+ }
+ // Increment the track index
+ index++;
+ }
+
+ // Reset length to be used by the condition below to determine
+ // if animating track events should also be filtered for removal.
+ // Reset index below to be used by the reverse while as an
+ // incrementing counter
+ length = obj.data.trackEvents.animating.length;
+ index = 0;
+
+ if ( length ) {
+ while ( --length > -1 ) {
+ animate = obj.data.trackEvents.animating[ index ];
+
+ // Padding events will not have _id properties.
+ // These should be safely pushed onto the front and back of the
+ // track event array
+ if ( !animate._id ) {
+ animating.push( animate );
+ }
+
+ // If not a matching animate event for removal
+ if ( animate._id && animate._id !== removeId ) {
+ animating.push( animate );
+ }
+ // Increment the track index
+ index++;
+ }
+ }
+
+ // Update
+ if ( indexWasAt <= obj.data.trackEvents.startIndex ) {
+ obj.data.trackEvents.startIndex--;
+ }
+
+ if ( indexWasAt <= obj.data.trackEvents.endIndex ) {
+ obj.data.trackEvents.endIndex--;
+ }
+
+ obj.data.trackEvents.byStart = byStart;
+ obj.data.trackEvents.byEnd = byEnd;
+ obj.data.trackEvents.animating = animating;
+
+ for ( var i = 0; i < historyLen; i++ ) {
+ if ( obj.data.history[ i ] !== removeId ) {
+ history.push( obj.data.history[ i ] );
+ }
+ }
+
+ // Update ordered history array
+ obj.data.history = history;
+
+ // Update track event references
+ Popcorn.removeTrackEvent.ref( obj, removeId );
+ };
+
+ // Internal Only - Removes track event references from instance object's trackRefs hash table
+ Popcorn.removeTrackEvent.ref = function( obj, removeId ) {
+ delete obj.data.trackRefs[ removeId ];
+
+ return obj;
+ };
+
+ // Return an array of track events bound to this instance object
+ Popcorn.getTrackEvents = function( obj ) {
+
+ var trackevents = [],
+ refs = obj.data.trackEvents.byStart,
+ length = refs.length,
+ idx = 0,
+ ref;
+
+ for ( ; idx < length; idx++ ) {
+ ref = refs[ idx ];
+ // Return only user attributed track event references
+ if ( ref._id ) {
+ trackevents.push( ref );
+ }
+ }
+
+ return trackevents;
+ };
+
+ // Internal Only - Returns an instance object's trackRefs hash table
+ Popcorn.getTrackEvents.ref = function( obj ) {
+ return obj.data.trackRefs;
+ };
+
+ // Return a single track event bound to this instance object
+ Popcorn.getTrackEvent = function( obj, trackId ) {
+ return obj.data.trackRefs[ trackId ];
+ };
+
+ // Internal Only - Returns an instance object's track reference by track id
+ Popcorn.getTrackEvent.ref = function( obj, trackId ) {
+ return obj.data.trackRefs[ trackId ];
+ };
+
+ Popcorn.getLastTrackEventId = function( obj ) {
+ return obj.data.history[ obj.data.history.length - 1 ];
+ };
+
+ Popcorn.timeUpdate = function( obj, event ) {
+
+ var currentTime = obj.media.currentTime,
+ previousTime = obj.data.trackEvents.previousUpdateTime,
+ tracks = obj.data.trackEvents,
+ end = tracks.endIndex,
+ start = tracks.startIndex,
+ byStartLen = tracks.byStart.length,
+ byEndLen = tracks.byEnd.length,
+ registryByName = Popcorn.registryByName,
+ trackstart = "trackstart",
+ trackend = "trackend",
+
+ byEnd, byStart, byAnimate, natives, type, runningPlugins;
+
+ // Playbar advancing
+ if ( previousTime <= currentTime ) {
+
+ while ( tracks.byEnd[ end ] && tracks.byEnd[ end ].end <= currentTime ) {
+
+ byEnd = tracks.byEnd[ end ];
+ natives = byEnd._natives;
+ type = natives && natives.type;
+
+ // If plugin does not exist on this instance, remove it
+ if ( !natives ||
+ ( !!registryByName[ type ] ||
+ !!obj[ type ] ) ) {
+
+ if ( byEnd._running === true ) {
+
+ byEnd._running = false;
+ runningPlugins = obj.data.running[ type ];
+ runningPlugins.splice( runningPlugins.indexOf( byEnd ), 1 );
+
+ if ( !obj.data.disabled[ type ] ) {
+
+ natives.end.call( obj, event, byEnd );
+
+ obj.emit( trackend,
+ Popcorn.extend({}, byEnd, {
+ plugin: type,
+ type: trackend
+ })
+ );
+ }
+ }
+
+ end++;
+ } else {
+ // remove track event
+ Popcorn.removeTrackEvent( obj, byEnd._id );
+ return;
+ }
+ }
+
+ while ( tracks.byStart[ start ] && tracks.byStart[ start ].start <= currentTime ) {
+
+ byStart = tracks.byStart[ start ];
+ natives = byStart._natives;
+ type = natives && natives.type;
+
+ // If plugin does not exist on this instance, remove it
+ if ( !natives ||
+ ( !!registryByName[ type ] ||
+ !!obj[ type ] ) ) {
+
+ if ( byStart.end > currentTime &&
+ byStart._running === false ) {
+
+ byStart._running = true;
+ obj.data.running[ type ].push( byStart );
+
+ if ( !obj.data.disabled[ type ] ) {
+
+ natives.start.call( obj, event, byStart );
+
+ obj.emit( trackstart,
+ Popcorn.extend({}, byStart, {
+ plugin: type,
+ type: trackstart
+ })
+ );
+ }
+ }
+ start++;
+ } else {
+ // remove track event
+ Popcorn.removeTrackEvent( obj, byStart._id );
+ return;
+ }
+ }
+
+ // Playbar receding
+ } else if ( previousTime > currentTime ) {
+
+ while ( tracks.byStart[ start ] && tracks.byStart[ start ].start > currentTime ) {
+
+ byStart = tracks.byStart[ start ];
+ natives = byStart._natives;
+ type = natives && natives.type;
+
+ // if plugin does not exist on this instance, remove it
+ if ( !natives ||
+ ( !!registryByName[ type ] ||
+ !!obj[ type ] ) ) {
+
+ if ( byStart._running === true ) {
+
+ byStart._running = false;
+ runningPlugins = obj.data.running[ type ];
+ runningPlugins.splice( runningPlugins.indexOf( byStart ), 1 );
+
+ if ( !obj.data.disabled[ type ] ) {
+
+ natives.end.call( obj, event, byStart );
+
+ obj.emit( trackend,
+ Popcorn.extend({}, byEnd, {
+ plugin: type,
+ type: trackend
+ })
+ );
+ }
+ }
+ start--;
+ } else {
+ // remove track event
+ Popcorn.removeTrackEvent( obj, byStart._id );
+ return;
+ }
+ }
+
+ while ( tracks.byEnd[ end ] && tracks.byEnd[ end ].end > currentTime ) {
+
+ byEnd = tracks.byEnd[ end ];
+ natives = byEnd._natives;
+ type = natives && natives.type;
+
+ // if plugin does not exist on this instance, remove it
+ if ( !natives ||
+ ( !!registryByName[ type ] ||
+ !!obj[ type ] ) ) {
+
+ if ( byEnd.start <= currentTime &&
+ byEnd._running === false ) {
+
+ byEnd._running = true;
+ obj.data.running[ type ].push( byEnd );
+
+ if ( !obj.data.disabled[ type ] ) {
+
+ natives.start.call( obj, event, byEnd );
+
+ obj.emit( trackstart,
+ Popcorn.extend({}, byStart, {
+ plugin: type,
+ type: trackstart
+ })
+ );
+ }
+ }
+ end--;
+ } else {
+ // remove track event
+ Popcorn.removeTrackEvent( obj, byEnd._id );
+ return;
+ }
+ }
+ }
+
+ tracks.endIndex = end;
+ tracks.startIndex = start;
+ tracks.previousUpdateTime = currentTime;
+
+ //enforce index integrity if trackRemoved
+ tracks.byStart.length < byStartLen && tracks.startIndex--;
+ tracks.byEnd.length < byEndLen && tracks.endIndex--;
+
+ };
+
+ // Map and Extend TrackEvent functions to all Popcorn instances
+ Popcorn.extend( Popcorn.p, {
+
+ getTrackEvents: function() {
+ return Popcorn.getTrackEvents.call( null, this );
+ },
+
+ getTrackEvent: function( id ) {
+ return Popcorn.getTrackEvent.call( null, this, id );
+ },
+
+ getLastTrackEventId: function() {
+ return Popcorn.getLastTrackEventId.call( null, this );
+ },
+
+ removeTrackEvent: function( id ) {
+
+ Popcorn.removeTrackEvent.call( null, this, id );
+ return this;
+ },
+
+ removePlugin: function( name ) {
+ Popcorn.removePlugin.call( null, this, name );
+ return this;
+ },
+
+ timeUpdate: function( event ) {
+ Popcorn.timeUpdate.call( null, this, event );
+ return this;
+ },
+
+ destroy: function() {
+ Popcorn.destroy.call( null, this );
+ return this;
+ }
+ });
+
+ // Plugin manifests
+ Popcorn.manifest = {};
+ // Plugins are registered
+ Popcorn.registry = [];
+ Popcorn.registryByName = {};
+ // An interface for extending Popcorn
+ // with plugin functionality
+ Popcorn.plugin = function( name, definition, manifest ) {
+
+ if ( Popcorn.protect.natives.indexOf( name.toLowerCase() ) >= 0 ) {
+ Popcorn.error( "'" + name + "' is a protected function name" );
+ return;
+ }
+
+ // Provides some sugar, but ultimately extends
+ // the definition into Popcorn.p
+ var reserved = [ "start", "end" ],
+ plugin = {},
+ setup,
+ isfn = typeof definition === "function",
+ methods = [ "_setup", "_teardown", "start", "end", "frame" ];
+
+ // combines calls of two function calls into one
+ var combineFn = function( first, second ) {
+
+ first = first || Popcorn.nop;
+ second = second || Popcorn.nop;
+
+ return function() {
+ first.apply( this, arguments );
+ second.apply( this, arguments );
+ };
+ };
+
+ // If `manifest` arg is undefined, check for manifest within the `definition` object
+ // If no `definition.manifest`, an empty object is a sufficient fallback
+ Popcorn.manifest[ name ] = manifest = manifest || definition.manifest || {};
+
+ // apply safe, and empty default functions
+ methods.forEach(function( method ) {
+ definition[ method ] = safeTry( definition[ method ] || Popcorn.nop, name );
+ });
+
+ var pluginFn = function( setup, options ) {
+
+ if ( !options ) {
+ return this;
+ }
+
+ // Storing the plugin natives
+ var natives = options._natives = {},
+ compose = "",
+ originalOpts, manifestOpts;
+
+ Popcorn.extend( natives, setup );
+
+ options._natives.type = name;
+ options._running = false;
+
+ natives.start = natives.start || natives[ "in" ];
+ natives.end = natives.end || natives[ "out" ];
+
+ // extend teardown to always call end if running
+ natives._teardown = combineFn(function() {
+
+ var args = slice.call( arguments ),
+ runningPlugins = this.data.running[ natives.type ];
+
+ // end function signature is not the same as teardown,
+ // put null on the front of arguments for the event parameter
+ args.unshift( null );
+
+ // only call end if event is running
+ args[ 1 ]._running &&
+ runningPlugins.splice( runningPlugins.indexOf( options ), 1 ) &&
+ natives.end.apply( this, args );
+ }, natives._teardown );
+
+ // default to an empty string if no effect exists
+ // split string into an array of effects
+ options.compose = options.compose && options.compose.split( " " ) || [];
+ options.effect = options.effect && options.effect.split( " " ) || [];
+
+ // join the two arrays together
+ options.compose = options.compose.concat( options.effect );
+
+ options.compose.forEach(function( composeOption ) {
+
+ // if the requested compose is garbage, throw it away
+ compose = Popcorn.compositions[ composeOption ] || {};
+
+ // extends previous functions with compose function
+ methods.forEach(function( method ) {
+ natives[ method ] = combineFn( natives[ method ], compose[ method ] );
+ });
+ });
+
+ // Ensure a manifest object, an empty object is a sufficient fallback
+ options._natives.manifest = manifest;
+
+ // Checks for expected properties
+ if ( !( "start" in options ) ) {
+ options.start = options[ "in" ] || 0;
+ }
+
+ if ( !options.end && options.end !== 0 ) {
+ options.end = options[ "out" ] || Number.MAX_VALUE;
+ }
+
+ // Use hasOwn to detect non-inherited toString, since all
+ // objects will receive a toString - its otherwise undetectable
+ if ( !hasOwn.call( options, "toString" ) ) {
+ options.toString = function() {
+ var props = [
+ "start: " + options.start,
+ "end: " + options.end,
+ "id: " + (options.id || options._id)
+ ];
+
+ // Matches null and undefined, allows: false, 0, "" and truthy
+ if ( options.target != null ) {
+ props.push( "target: " + options.target );
+ }
+
+ return name + " ( " + props.join(", ") + " )";
+ };
+ }
+
+ // Resolves 239, 241, 242
+ if ( !options.target ) {
+
+ // Sometimes the manifest may be missing entirely
+ // or it has an options object that doesn't have a `target` property
+ manifestOpts = "options" in manifest && manifest.options;
+
+ options.target = manifestOpts && "target" in manifestOpts && manifestOpts.target;
+ }
+
+ // Trigger _setup method if exists
+ options._natives._setup && options._natives._setup.call( this, options );
+
+ // Create new track event for this instance
+ Popcorn.addTrackEvent( this, Popcorn.extend( options, options ) );
+
+ // Future support for plugin event definitions
+ // for all of the native events
+ Popcorn.forEach( setup, function( callback, type ) {
+
+ if ( type !== "type" ) {
+
+ if ( reserved.indexOf( type ) === -1 ) {
+
+ this.on( type, callback );
+ }
+ }
+
+ }, this );
+
+ return this;
+ };
+
+ // Extend Popcorn.p with new named definition
+ // Assign new named definition
+ Popcorn.p[ name ] = plugin[ name ] = function( options ) {
+
+ this.data.running[ name ] = this.data.running[ name ] || [];
+
+ // Merge with defaults if they exist, make sure per call is prioritized
+ var defaults = ( this.options.defaults && this.options.defaults[ name ] ) || {},
+ mergedSetupOpts = Popcorn.extend( {}, defaults, options );
+
+ return pluginFn.call( this, isfn ? definition.call( this, mergedSetupOpts ) : definition,
+ mergedSetupOpts );
+ };
+
+ // Push into the registry
+ var entry = {
+ fn: plugin[ name ],
+ definition: definition,
+ base: definition,
+ parents: [],
+ name: name
+ };
+ Popcorn.registry.push(
+ Popcorn.extend( plugin, entry, {
+ type: name
+ })
+ );
+ Popcorn.registryByName[ name ] = entry;
+
+ return plugin;
+ };
+
+ // Storage for plugin function errors
+ Popcorn.plugin.errors = [];
+
+ // Returns wrapped plugin function
+ function safeTry( fn, pluginName ) {
+ return function() {
+
+ // When Popcorn.plugin.debug is true, do not suppress errors
+ if ( Popcorn.plugin.debug ) {
+ return fn.apply( this, arguments );
+ }
+
+ try {
+ return fn.apply( this, arguments );
+ } catch ( ex ) {
+
+ // Push plugin function errors into logging queue
+ Popcorn.plugin.errors.push({
+ plugin: pluginName,
+ thrown: ex,
+ source: fn.toString()
+ });
+
+ // Trigger an error that the instance can listen for
+ // and react to
+ this.emit( "error", Popcorn.plugin.errors );
+ }
+ };
+ }
+
+ // Debug-mode flag for plugin development
+ Popcorn.plugin.debug = false;
+
+ // removePlugin( type ) removes all tracks of that from all instances of popcorn
+ // removePlugin( obj, type ) removes all tracks of type from obj, where obj is a single instance of popcorn
+ Popcorn.removePlugin = function( obj, name ) {
+
+ // Check if we are removing plugin from an instance or from all of Popcorn
+ if ( !name ) {
+
+ // Fix the order
+ name = obj;
+ obj = Popcorn.p;
+
+ if ( Popcorn.protect.natives.indexOf( name.toLowerCase() ) >= 0 ) {
+ Popcorn.error( "'" + name + "' is a protected function name" );
+ return;
+ }
+
+ var registryLen = Popcorn.registry.length,
+ registryIdx;
+
+ // remove plugin reference from registry
+ for ( registryIdx = 0; registryIdx < registryLen; registryIdx++ ) {
+ if ( Popcorn.registry[ registryIdx ].name === name ) {
+ Popcorn.registry.splice( registryIdx, 1 );
+ delete Popcorn.registryByName[ name ];
+ delete Popcorn.manifest[ name ];
+
+ // delete the plugin
+ delete obj[ name ];
+
+ // plugin found and removed, stop checking, we are done
+ return;
+ }
+ }
+
+ }
+
+ var byStart = obj.data.trackEvents.byStart,
+ byEnd = obj.data.trackEvents.byEnd,
+ animating = obj.data.trackEvents.animating,
+ idx, sl;
+
+ // remove all trackEvents
+ for ( idx = 0, sl = byStart.length; idx < sl; idx++ ) {
+
+ if ( byStart[ idx ] && byStart[ idx ]._natives && byStart[ idx ]._natives.type === name ) {
+
+ byStart[ idx ]._natives._teardown && byStart[ idx ]._natives._teardown.call( obj, byStart[ idx ] );
+
+ byStart.splice( idx, 1 );
+
+ // update for loop if something removed, but keep checking
+ idx--; sl--;
+ if ( obj.data.trackEvents.startIndex <= idx ) {
+ obj.data.trackEvents.startIndex--;
+ obj.data.trackEvents.endIndex--;
+ }
+ }
+
+ // clean any remaining references in the end index
+ // we do this seperate from the above check because they might not be in the same order
+ if ( byEnd[ idx ] && byEnd[ idx ]._natives && byEnd[ idx ]._natives.type === name ) {
+
+ byEnd.splice( idx, 1 );
+ }
+ }
+
+ //remove all animating events
+ for ( idx = 0, sl = animating.length; idx < sl; idx++ ) {
+
+ if ( animating[ idx ] && animating[ idx ]._natives && animating[ idx ]._natives.type === name ) {
+
+ animating.splice( idx, 1 );
+
+ // update for loop if something removed, but keep checking
+ idx--; sl--;
+ }
+ }
+
+ };
+
+ Popcorn.compositions = {};
+
+ // Plugin inheritance
+ Popcorn.compose = function( name, definition, manifest ) {
+
+ // If `manifest` arg is undefined, check for manifest within the `definition` object
+ // If no `definition.manifest`, an empty object is a sufficient fallback
+ Popcorn.manifest[ name ] = manifest = manifest || definition.manifest || {};
+
+ // register the effect by name
+ Popcorn.compositions[ name ] = definition;
+ };
+
+ Popcorn.plugin.effect = Popcorn.effect = Popcorn.compose;
+
+ // Cache references to reused RegExps
+ var rparams = /\?/,
+ // XHR Setup object
+ setup = {
+ url: "",
+ data: "",
+ dataType: "",
+ success: Popcorn.nop,
+ type: "GET",
+ async: true,
+ xhr: function() {
+ return new global.XMLHttpRequest();
+ }
+ };
+
+ Popcorn.xhr = function( options ) {
+
+ options.dataType = options.dataType && options.dataType.toLowerCase() || null;
+
+ if ( options.dataType &&
+ ( options.dataType === "jsonp" || options.dataType === "script" ) ) {
+
+ Popcorn.xhr.getJSONP(
+ options.url,
+ options.success,
+ options.dataType === "script"
+ );
+ return;
+ }
+
+ var settings = Popcorn.extend( {}, setup, options );
+
+ // Create new XMLHttpRequest object
+ settings.ajax = settings.xhr();
+
+ if ( settings.ajax ) {
+
+ if ( settings.type === "GET" && settings.data ) {
+
+ // append query string