EmbedPress – Embed Google Docs, YouTube, Maps, Vimeo, Wistia Videos & Upload PDF, PPT in Gutenberg & Elementor - Version 1.0.0

Version Description

Download this release

Release Info

Developer pressshack
Plugin Icon wp plugin EmbedPress – Embed Google Docs, YouTube, Maps, Vimeo, Wistia Videos & Upload PDF, PPT in Gutenberg & Elementor
Version 1.0.0
Comparing to
See all releases

Version 1.0.0

Files changed (262) hide show
  1. EmbedPress/AutoLoader.php +200 -0
  2. EmbedPress/Disabler.php +125 -0
  3. EmbedPress/Ends/Back/Handler.php +114 -0
  4. EmbedPress/Ends/Back/Settings.php +225 -0
  5. EmbedPress/Ends/Back/index.html +9 -0
  6. EmbedPress/Ends/Front/Handler.php +39 -0
  7. EmbedPress/Ends/Front/index.html +9 -0
  8. EmbedPress/Ends/Handler.php +65 -0
  9. EmbedPress/Ends/index.html +9 -0
  10. EmbedPress/Loader.php +126 -0
  11. EmbedPress/Plugin.php +225 -0
  12. EmbedPress/Providers/GoogleDocs.php +117 -0
  13. EmbedPress/Providers/GoogleMaps.php +63 -0
  14. EmbedPress/Providers/index.html +9 -0
  15. EmbedPress/Shortcode.php +367 -0
  16. EmbedPress/index.html +9 -0
  17. PROVIDERS.md +69 -0
  18. assets/bootstrap.config.json +400 -0
  19. assets/css/embedpress.css +85 -0
  20. assets/css/font.css +94 -0
  21. assets/css/index.html +9 -0
  22. assets/css/preview.css +144 -0
  23. assets/css/vendor/bootstrap/bootstrap.css +2733 -0
  24. assets/css/vendor/bootstrap/bootstrap.min.css +14 -0
  25. assets/css/vendor/bootstrap/index.html +9 -0
  26. assets/css/vendor/index.html +9 -0
  27. assets/fonts/embedpress.eot +0 -0
  28. assets/fonts/embedpress.svg +1 -0
  29. assets/fonts/embedpress.ttf +0 -0
  30. assets/fonts/embedpress.woff +0 -0
  31. assets/fonts/index.html +9 -0
  32. assets/index.html +9 -0
  33. assets/js/index.html +9 -0
  34. assets/js/preview.js +1625 -0
  35. assets/js/vendor/bootbox.min.js +6 -0
  36. assets/js/vendor/bootstrap/bootstrap.js +418 -0
  37. assets/js/vendor/bootstrap/bootstrap.min.js +11 -0
  38. assets/js/vendor/bootstrap/index.html +9 -0
  39. assets/js/vendor/index.html +9 -0
  40. autoloader.php +24 -0
  41. changelog.txt +5 -0
  42. embedpress.php +41 -0
  43. includes.php +54 -0
  44. index.html +9 -0
  45. library/autoload.php +7 -0
  46. library/composer/ClassLoader.php +413 -0
  47. library/composer/LICENSE +21 -0
  48. library/composer/autoload_classmap.php +9 -0
  49. library/composer/autoload_namespaces.php +10 -0
  50. library/composer/autoload_psr4.php +9 -0
  51. library/composer/autoload_real.php +50 -0
  52. library/composer/index.html +9 -0
  53. library/composer/installed.json +57 -0
  54. library/index.html +9 -0
  55. library/ostraining/embera/LICENSE +20 -0
  56. library/ostraining/embera/Lib/Embera/Adapters/Service.php +192 -0
  57. library/ostraining/embera/Lib/Embera/Autoload.php +22 -0
  58. library/ostraining/embera/Lib/Embera/Embera.php +258 -0
  59. library/ostraining/embera/Lib/Embera/FakeResponse.php +83 -0
  60. library/ostraining/embera/Lib/Embera/Formatter.php +157 -0
  61. library/ostraining/embera/Lib/Embera/HttpRequest.php +165 -0
  62. library/ostraining/embera/Lib/Embera/Oembed.php +95 -0
  63. library/ostraining/embera/Lib/Embera/Providers.php +284 -0
  64. library/ostraining/embera/Lib/Embera/Providers/AmCharts.php +61 -0
  65. library/ostraining/embera/Lib/Embera/Providers/Animatron.php +36 -0
  66. library/ostraining/embera/Lib/Embera/Providers/Animoto.php +36 -0
  67. library/ostraining/embera/Lib/Embera/Providers/AolOn.php +68 -0
  68. library/ostraining/embera/Lib/Embera/Providers/AppNet.php +36 -0
  69. library/ostraining/embera/Lib/Embera/Providers/AudioSnaps.php +53 -0
  70. library/ostraining/embera/Lib/Embera/Providers/Bambuser.php +80 -0
  71. library/ostraining/embera/Lib/Embera/Providers/BlipTV.php +31 -0
  72. library/ostraining/embera/Lib/Embera/Providers/Cacoo.php +58 -0
  73. library/ostraining/embera/Lib/Embera/Providers/Chartblocks.php +46 -0
  74. library/ostraining/embera/Lib/Embera/Providers/Chirbit.php +53 -0
  75. library/ostraining/embera/Lib/Embera/Providers/CircuitLab.php +56 -0
  76. library/ostraining/embera/Lib/Embera/Providers/Clyp.php +58 -0
  77. library/ostraining/embera/Lib/Embera/Providers/Codepoints.php +50 -0
  78. library/ostraining/embera/Lib/Embera/Providers/CollegeHumor.php +55 -0
  79. library/ostraining/embera/Lib/Embera/Providers/Coub.php +49 -0
  80. library/ostraining/embera/Lib/Embera/Providers/CrowdRanking.php +52 -0
  81. library/ostraining/embera/Lib/Embera/Providers/DailyMile.php +32 -0
  82. library/ostraining/embera/Lib/Embera/Providers/DailyMotion.php +62 -0
  83. library/ostraining/embera/Lib/Embera/Providers/Deviantart.php +50 -0
  84. library/ostraining/embera/Lib/Embera/Providers/Dipity.php +53 -0
  85. library/ostraining/embera/Lib/Embera/Providers/DotSub.php +55 -0
  86. library/ostraining/embera/Lib/Embera/Providers/Edocr.php +36 -0
  87. library/ostraining/embera/Lib/Embera/Providers/EgliseInfo.php +31 -0
  88. library/ostraining/embera/Lib/Embera/Providers/Facebook.php +134 -0
  89. library/ostraining/embera/Lib/Embera/Providers/Flickr.php +53 -0
  90. library/ostraining/embera/Lib/Embera/Providers/FunnyOrDie.php +61 -0
  91. library/ostraining/embera/Lib/Embera/Providers/GeographCI.php +33 -0
  92. library/ostraining/embera/Lib/Embera/Providers/GeographDe.php +33 -0
  93. library/ostraining/embera/Lib/Embera/Providers/GeographUk.php +33 -0
  94. library/ostraining/embera/Lib/Embera/Providers/GettyImages.php +48 -0
  95. library/ostraining/embera/Lib/Embera/Providers/Gfycat.php +51 -0
  96. library/ostraining/embera/Lib/Embera/Providers/GithubGist.php +69 -0
  97. library/ostraining/embera/Lib/Embera/Providers/Gmep.php +51 -0
  98. library/ostraining/embera/Lib/Embera/Providers/Hq23.php +46 -0
  99. library/ostraining/embera/Lib/Embera/Providers/Huffduffer.php +31 -0
  100. library/ostraining/embera/Lib/Embera/Providers/Hulu.php +41 -0
  101. library/ostraining/embera/Lib/Embera/Providers/IFTTT.php +47 -0
  102. library/ostraining/embera/Lib/Embera/Providers/IFixIt.php +44 -0
  103. library/ostraining/embera/Lib/Embera/Providers/Infogram.php +38 -0
  104. library/ostraining/embera/Lib/Embera/Providers/Instagram.php +48 -0
  105. library/ostraining/embera/Lib/Embera/Providers/Issuu.php +49 -0
  106. library/ostraining/embera/Lib/Embera/Providers/Kickstarter.php +46 -0
  107. library/ostraining/embera/Lib/Embera/Providers/LearningApps.php +32 -0
  108. library/ostraining/embera/Lib/Embera/Providers/Meetup.php +35 -0
  109. library/ostraining/embera/Lib/Embera/Providers/MixCloud.php +35 -0
  110. library/ostraining/embera/Lib/Embera/Providers/MobyPicture.php +50 -0
  111. library/ostraining/embera/Lib/Embera/Providers/NFB.php +65 -0
  112. library/ostraining/embera/Lib/Embera/Providers/Officemix.php +48 -0
  113. library/ostraining/embera/Lib/Embera/Providers/OfficialFM.php +57 -0
  114. library/ostraining/embera/Lib/Embera/Providers/Oumy.php +48 -0
  115. library/ostraining/embera/Lib/Embera/Providers/Pastery.php +31 -0
  116. library/ostraining/embera/Lib/Embera/Providers/PollDaddy.php +66 -0
  117. library/ostraining/embera/Lib/Embera/Providers/PollEveryWhere.php +48 -0
  118. library/ostraining/embera/Lib/Embera/Providers/Portfolium.php +35 -0
  119. library/ostraining/embera/Lib/Embera/Providers/Rapidengage.php +37 -0
  120. library/ostraining/embera/Lib/Embera/Providers/Rdio.php +34 -0
  121. library/ostraining/embera/Lib/Embera/Providers/ReleaseWire.php +42 -0
  122. library/ostraining/embera/Lib/Embera/Providers/RepubHub.php +30 -0
  123. library/ostraining/embera/Lib/Embera/Providers/Reverbnation.php +59 -0
  124. library/ostraining/embera/Lib/Embera/Providers/Revision3.php +34 -0
  125. library/ostraining/embera/Lib/Embera/Providers/Roomshare.php +34 -0
  126. library/ostraining/embera/Lib/Embera/Providers/Rutube.php +52 -0
  127. library/ostraining/embera/Lib/Embera/Providers/Sapo.php +45 -0
  128. library/ostraining/embera/Lib/Embera/Providers/Screenr.php +48 -0
  129. library/ostraining/embera/Lib/Embera/Providers/Scribd.php +58 -0
  130. library/ostraining/embera/Lib/Embera/Providers/ShortNote.php +49 -0
  131. library/ostraining/embera/Lib/Embera/Providers/Shoudio.php +35 -0
  132. library/ostraining/embera/Lib/Embera/Providers/Showtheway.php +34 -0
  133. library/ostraining/embera/Lib/Embera/Providers/Silk.php +51 -0
  134. library/ostraining/embera/Lib/Embera/Providers/Sketchfab.php +77 -0
  135. library/ostraining/embera/Lib/Embera/Providers/SlideShare.php +35 -0
  136. library/ostraining/embera/Lib/Embera/Providers/SoundCloud.php +34 -0
  137. library/ostraining/embera/Lib/Embera/Providers/Speakerdeck.php +31 -0
  138. library/ostraining/embera/Lib/Embera/Providers/Spotify.php +66 -0
  139. library/ostraining/embera/Lib/Embera/Providers/Sway.php +50 -0
  140. library/ostraining/embera/Lib/Embera/Providers/Ted.php +43 -0
  141. library/ostraining/embera/Lib/Embera/Providers/TheySaidSo.php +49 -0
  142. library/ostraining/embera/Lib/Embera/Providers/Twitter.php +40 -0
  143. library/ostraining/embera/Lib/Embera/Providers/Ustream.php +36 -0
  144. library/ostraining/embera/Lib/Embera/Providers/Verse.php +49 -0
  145. library/ostraining/embera/Lib/Embera/Providers/Viddler.php +53 -0
  146. library/ostraining/embera/Lib/Embera/Providers/VideoFork.php +59 -0
  147. library/ostraining/embera/Lib/Embera/Providers/VideoJug.php +32 -0
  148. library/ostraining/embera/Lib/Embera/Providers/Vimeo.php +56 -0
  149. library/ostraining/embera/Lib/Embera/Providers/Vine.php +48 -0
  150. library/ostraining/embera/Lib/Embera/Providers/WordpressTV.php +30 -0
  151. library/ostraining/embera/Lib/Embera/Providers/YFrog.php +43 -0
  152. library/ostraining/embera/Lib/Embera/Providers/Yandex.php +37 -0
  153. library/ostraining/embera/Lib/Embera/Providers/Youtube.php +52 -0
  154. library/ostraining/embera/Lib/Embera/Url.php +121 -0
  155. library/ostraining/embera/PROVIDERS.md +95 -0
  156. library/ostraining/embera/README.md +363 -0
  157. library/ostraining/embera/Tests/Autoload.php +49 -0
  158. library/ostraining/embera/Tests/TestEmbera.php +241 -0
  159. library/ostraining/embera/Tests/TestFakeResponse.php +101 -0
  160. library/ostraining/embera/Tests/TestFormatter.php +122 -0
  161. library/ostraining/embera/Tests/TestHttpRequest.php +169 -0
  162. library/ostraining/embera/Tests/TestOembed.php +75 -0
  163. library/ostraining/embera/Tests/TestProviders.php +237 -0
  164. library/ostraining/embera/Tests/TestServiceAmCharts.php +48 -0
  165. library/ostraining/embera/Tests/TestServiceAnimatron.php +37 -0
  166. library/ostraining/embera/Tests/TestServiceAnimoto.php +40 -0
  167. library/ostraining/embera/Tests/TestServiceAolOn.php +50 -0
  168. library/ostraining/embera/Tests/TestServiceAppNet.php +35 -0
  169. library/ostraining/embera/Tests/TestServiceAudioSnaps.php +44 -0
  170. library/ostraining/embera/Tests/TestServiceBambuser.php +47 -0
  171. library/ostraining/embera/Tests/TestServiceBlipTv.php +38 -0
  172. library/ostraining/embera/Tests/TestServiceCacoo.php +50 -0
  173. library/ostraining/embera/Tests/TestServiceChartblocks.php +40 -0
  174. library/ostraining/embera/Tests/TestServiceChirbit.php +45 -0
  175. library/ostraining/embera/Tests/TestServiceCircuitLab.php +48 -0
  176. library/ostraining/embera/Tests/TestServiceClyp.php +34 -0
  177. library/ostraining/embera/Tests/TestServiceCodepoints.php +38 -0
  178. library/ostraining/embera/Tests/TestServiceCollegeHumor.php +42 -0
  179. library/ostraining/embera/Tests/TestServiceCoub.php +48 -0
  180. library/ostraining/embera/Tests/TestServiceCrowdRanking.php +49 -0
  181. library/ostraining/embera/Tests/TestServiceDailyMile.php +37 -0
  182. library/ostraining/embera/Tests/TestServiceDailyMotion.php +57 -0
  183. library/ostraining/embera/Tests/TestServiceDeviantart.php +40 -0
  184. library/ostraining/embera/Tests/TestServiceDipity.php +44 -0
  185. library/ostraining/embera/Tests/TestServiceDotSub.php +48 -0
  186. library/ostraining/embera/Tests/TestServiceEdocr.php +41 -0
  187. library/ostraining/embera/Tests/TestServiceEgliseInfo.php +29 -0
  188. library/ostraining/embera/Tests/TestServiceFacebook.php +55 -0
  189. library/ostraining/embera/Tests/TestServiceFlickr.php +47 -0
  190. library/ostraining/embera/Tests/TestServiceFunnyOrDie.php +49 -0
  191. library/ostraining/embera/Tests/TestServiceGeographCI.php +36 -0
  192. library/ostraining/embera/Tests/TestServiceGeographDe.php +36 -0
  193. library/ostraining/embera/Tests/TestServiceGeographUk.php +37 -0
  194. library/ostraining/embera/Tests/TestServiceGettyImages.php +42 -0
  195. library/ostraining/embera/Tests/TestServiceGfycat.php +42 -0
  196. library/ostraining/embera/Tests/TestServiceGithubGist.php +51 -0
  197. library/ostraining/embera/Tests/TestServiceGmep.php +43 -0
  198. library/ostraining/embera/Tests/TestServiceHq23.php +35 -0
  199. library/ostraining/embera/Tests/TestServiceHuffduffer.php +37 -0
  200. library/ostraining/embera/Tests/TestServiceHulu.php +44 -0
  201. library/ostraining/embera/Tests/TestServiceIFTTT.php +38 -0
  202. library/ostraining/embera/Tests/TestServiceIFixIt.php +40 -0
  203. library/ostraining/embera/Tests/TestServiceInfogram.php +36 -0
  204. library/ostraining/embera/Tests/TestServiceInstagram.php +41 -0
  205. library/ostraining/embera/Tests/TestServiceIssuu.php +29 -0
  206. library/ostraining/embera/Tests/TestServiceIssuuFakeResponse.php +34 -0
  207. library/ostraining/embera/Tests/TestServiceKickstarter.php +60 -0
  208. library/ostraining/embera/Tests/TestServiceLearningApps.php +34 -0
  209. library/ostraining/embera/Tests/TestServiceMeetup.php +40 -0
  210. library/ostraining/embera/Tests/TestServiceMixCloud.php +40 -0
  211. library/ostraining/embera/Tests/TestServiceMobyPicture.php +39 -0
  212. library/ostraining/embera/Tests/TestServiceNFB.php +45 -0
  213. library/ostraining/embera/Tests/TestServiceOfficeMix.php +37 -0
  214. library/ostraining/embera/Tests/TestServiceOfficialFM.php +46 -0
  215. library/ostraining/embera/Tests/TestServiceOumy.php +39 -0
  216. library/ostraining/embera/Tests/TestServicePastery.php +33 -0
  217. library/ostraining/embera/Tests/TestServicePollDaddy.php +48 -0
  218. library/ostraining/embera/Tests/TestServicePollEverywhere.php +33 -0
  219. library/ostraining/embera/Tests/TestServicePortfolium.php +39 -0
  220. library/ostraining/embera/Tests/TestServiceRapidengage.php +33 -0
  221. library/ostraining/embera/Tests/TestServiceRdio.php +38 -0
  222. library/ostraining/embera/Tests/TestServiceReleaseWire.php +41 -0
  223. library/ostraining/embera/Tests/TestServiceRepubHub.php +32 -0
  224. library/ostraining/embera/Tests/TestServiceReverbnation.php +38 -0
  225. library/ostraining/embera/Tests/TestServiceRevision3.php +45 -0
  226. library/ostraining/embera/Tests/TestServiceRoomshare.php +34 -0
  227. library/ostraining/embera/Tests/TestServiceRutube.php +33 -0
  228. library/ostraining/embera/Tests/TestServiceSapo.php +43 -0
  229. library/ostraining/embera/Tests/TestServiceScreenr.php +40 -0
  230. library/ostraining/embera/Tests/TestServiceScribd.php +41 -0
  231. library/ostraining/embera/Tests/TestServiceShortNote.php +38 -0
  232. library/ostraining/embera/Tests/TestServiceShoudio.php +44 -0
  233. library/ostraining/embera/Tests/TestServiceShowTheWay.php +35 -0
  234. library/ostraining/embera/Tests/TestServiceSilk.php +41 -0
  235. library/ostraining/embera/Tests/TestServiceSketchfab.php +60 -0
  236. library/ostraining/embera/Tests/TestServiceSlideshare.php +39 -0
  237. library/ostraining/embera/Tests/TestServiceSoundCloud.php +42 -0
  238. library/ostraining/embera/Tests/TestServiceSpeakerDeck.php +36 -0
  239. library/ostraining/embera/Tests/TestServiceSpotify.php +50 -0
  240. library/ostraining/embera/Tests/TestServiceSway.php +36 -0
  241. library/ostraining/embera/Tests/TestServiceTed.php +39 -0
  242. library/ostraining/embera/Tests/TestServiceTheySaidSo.php +40 -0
  243. library/ostraining/embera/Tests/TestServiceTwitter.php +43 -0
  244. library/ostraining/embera/Tests/TestServiceUstream.php +41 -0
  245. library/ostraining/embera/Tests/TestServiceVerse.php +36 -0
  246. library/ostraining/embera/Tests/TestServiceViddler.php +47 -0
  247. library/ostraining/embera/Tests/TestServiceVideoFork.php +41 -0
  248. library/ostraining/embera/Tests/TestServiceVideoJug.php +36 -0
  249. library/ostraining/embera/Tests/TestServiceVimeo.php +52 -0
  250. library/ostraining/embera/Tests/TestServiceVine.php +43 -0
  251. library/ostraining/embera/Tests/TestServiceWordpressTV.php +35 -0
  252. library/ostraining/embera/Tests/TestServiceYFrog.php +46 -0
  253. library/ostraining/embera/Tests/TestServiceYandex.php +33 -0
  254. library/ostraining/embera/Tests/TestServiceYoutube.php +55 -0
  255. library/ostraining/embera/Tests/TestUrl.php +154 -0
  256. library/ostraining/embera/composer.json +22 -0
  257. library/ostraining/embera/phpdoc.xml +22 -0
  258. library/ostraining/embera/phpunit.full-urls.xml +26 -0
  259. library/ostraining/embera/phpunit.xml +23 -0
  260. library/ostraining/index.html +9 -0
  261. providers.php +20 -0
  262. readme.txt +57 -0
EmbedPress/AutoLoader.php ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EmbedPress;
3
+
4
+ (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
5
+
6
+ /**
7
+ * Entity responsible for autoloading classes using the PSR-4 pattern.
8
+ *
9
+ * @package EmbedPress
10
+ * @author PressShack <help@pressshack.com>
11
+ * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
12
+ * @license GPLv2 or later
13
+ * @since 1.0
14
+ */
15
+ class AutoLoader
16
+ {
17
+ /**
18
+ * Associative array where the key is a namespace prefix and the value
19
+ * is an array of base directories for classes in that namespace.
20
+ *
21
+ * @var array
22
+ */
23
+ protected static $prefixes = array();
24
+
25
+ /**
26
+ * Associative array of prefixes for loading specialized camelCase classes
27
+ * where Uppercase letters in the class name indicate directory structure
28
+ *
29
+ * @var array
30
+ */
31
+ protected static $camelPrefixes = array();
32
+
33
+ /**
34
+ * @var AutoLoader
35
+ */
36
+ protected static $instance = null;
37
+
38
+ protected static function registerLoader($method)
39
+ {
40
+ if (static::$instance === null) {
41
+ static::$instance = new static();
42
+ }
43
+
44
+ spl_autoload_register(array(static::$instance, $method));
45
+ }
46
+
47
+ /**
48
+ * Register a psr4 namespace
49
+ *
50
+ * @param string $prefix The namespace prefix.
51
+ * @param string $baseDir A base directory for class files in the
52
+ * namespace.
53
+ * @param bool $prepend If true, prepend the base directory to the stack
54
+ * instead of appending it; this causes it to be searched first rather
55
+ * than last.
56
+ *
57
+ * @return void
58
+ */
59
+ public static function register($prefix = null, $baseDir = null, $prepend = false)
60
+ {
61
+ if ($prefix === null || $baseDir === null) {
62
+ // Recognize old-style instantiations for backward compatibility
63
+ return;
64
+ }
65
+
66
+ if (count(self::$prefixes) == 0) {
67
+ // Register function on first call
68
+ static::registerLoader('loadClass');
69
+ }
70
+
71
+ // normalize namespace prefix
72
+ $prefix = trim($prefix, '\\') . '\\';
73
+
74
+ // normalize the base directory with a trailing separator
75
+ $baseDir = rtrim($baseDir, '\\/') . '/';
76
+
77
+ // initialise the namespace prefix array
78
+ if (empty(self::$prefixes[$prefix])) {
79
+ self::$prefixes[$prefix] = array();
80
+ }
81
+
82
+ // retain the base directory for the namespace prefix
83
+ if ($prepend) {
84
+ array_unshift(self::$prefixes[$prefix], $baseDir);
85
+ } else {
86
+ array_push(self::$prefixes[$prefix], $baseDir);
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Loads the class file for a given class name.
92
+ *
93
+ * @param string $class The fully-qualified class name.
94
+ *
95
+ * @return null|string The mapped file name on success, or boolean false on failure.
96
+ */
97
+ protected function loadClass($class)
98
+ {
99
+ $prefixes = explode('\\', $class);
100
+ $className = '';
101
+ while ($prefixes) {
102
+ $className = array_pop($prefixes) . $className;
103
+ $prefix = join('\\', $prefixes) . '\\';
104
+
105
+ if ($filePath = $this->loadMappedFile($prefix, $className)) {
106
+ return $filePath;
107
+ }
108
+ $className = '\\' . $className;
109
+ }
110
+
111
+ // never found a mapped file
112
+ return false;
113
+ }
114
+
115
+ /**
116
+ * Load the mapped file for a namespace prefix and class.
117
+ *
118
+ * @param string $prefix The namespace prefix.
119
+ * @param string $className The relative class name.
120
+ *
121
+ * @return bool|string false if no mapped file can be loaded | path that was loaded
122
+ */
123
+ protected function loadMappedFile($prefix, $className)
124
+ {
125
+ // are there any base directories for this namespace prefix?
126
+ if (isset(self::$prefixes[$prefix]) === false) {
127
+ return false;
128
+ }
129
+
130
+ // look through base directories for this namespace prefix
131
+ foreach (self::$prefixes[$prefix] as $baseDir) {
132
+ $path = $baseDir . str_replace('\\', '/', $className) . '.php';
133
+
134
+ if (is_file($path)) {
135
+ require_once $path;
136
+ return $path;
137
+ }
138
+ }
139
+
140
+ // never found it
141
+ return false;
142
+ }
143
+
144
+ /**
145
+ * Register a base directory for classes organized using camelCase.
146
+ * Class names beginning with the prefix will be automatically loaded
147
+ * if there is a matching file in the directory tree starting with $baseDir.
148
+ * File names and directory names are all expected to be lower case.
149
+ *
150
+ * @param string $prefix
151
+ * @param string $baseDir
152
+ *
153
+ * @return void
154
+ * @throws \Exception
155
+ */
156
+ public static function registerCamelBase($prefix, $baseDir)
157
+ {
158
+ if (!is_dir($baseDir)) {
159
+ throw new \Exception("Cannot register '{$prefix}'. The requested base directory does not exist!'");
160
+ }
161
+
162
+ if (count(self::$camelPrefixes) == 0) {
163
+ // Register function on first call
164
+ static::registerLoader('loadCamelClass');
165
+ }
166
+
167
+ if (empty(self::$camelPrefixes[$prefix])) {
168
+ self::$camelPrefixes[$prefix] = $baseDir;
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Autoload a class using the camelCase structure
174
+ *
175
+ * @param string $class
176
+ *
177
+ * @return bool|string
178
+ */
179
+ protected function loadCamelClass($class)
180
+ {
181
+ if (!class_exists($class)) {
182
+ foreach (self::$camelPrefixes as $prefix => $baseDir) {
183
+ if (strpos($class, $prefix) === 0) {
184
+ $parts = preg_split('/(?<=[a-z])(?=[A-Z])/x', substr($class, strlen($prefix)));
185
+
186
+ $file = strtolower(join('/', $parts));
187
+ $filePath = $baseDir . '/' . $file . '.php';
188
+
189
+ if (is_file($filePath)) {
190
+ require_once $filePath;
191
+ return $filePath;
192
+ }
193
+ }
194
+ }
195
+ }
196
+
197
+ // No file found
198
+ return false;
199
+ }
200
+ }
EmbedPress/Disabler.php ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EmbedPress;
3
+
4
+ use \EmbedPress\Shortcode;
5
+
6
+ (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
7
+
8
+ /**
9
+ * Entity responsible for replace the WordPress default embed-related shortcodes with the EmbedPress one.
10
+ *
11
+ * @package EmbedPress
12
+ * @author PressShack <help@pressshack.com>
13
+ * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
14
+ * @license GPLv2 or later
15
+ * @since 1.0
16
+ */
17
+ class Disabler
18
+ {
19
+ /**
20
+ * Method that replaces the embed shortcodes.
21
+ *
22
+ * @since 1.0
23
+ */
24
+ public function run()
25
+ {
26
+ self::disableNativeEmbedHooks();
27
+
28
+ Shortcode::register();
29
+ }
30
+
31
+ /**
32
+ * Disable all actions/filters related to the embed. This is required to make sure our "shortcode" overrides the WordPress one.
33
+ *
34
+ * @since 1.0
35
+ * @static
36
+ */
37
+ protected static function disableNativeEmbedHooks()
38
+ {
39
+ global $wp, $wp_embed;
40
+
41
+ // Remove the embed query var.
42
+ $wp->public_query_vars = array_diff($wp->public_query_vars, array("embed"));
43
+
44
+ // Remove the REST API endpoint.
45
+ remove_action('rest_api_init', 'wp_oembed_register_route');
46
+
47
+ // Turn off oEmbed auto discovery.
48
+ add_filter('embed_oembed_discover', '__return_false');
49
+
50
+ // Don't filter oEmbed results.
51
+ remove_filter('oembed_dataparse', 'wp_filter_oembed_result', 10);
52
+
53
+ // Remove oEmbed discovery links.
54
+ remove_action('wp_head', 'wp_oembed_add_discovery_links');
55
+
56
+ // Remove oEmbed-specific JavaScript from the front-end and back-end.
57
+ remove_action('wp_head', 'wp_oembed_add_host_js');
58
+
59
+ // Disable all TinyMCE plugins embed-related.
60
+ add_filter('tiny_mce_plugins', array('\EmbedPress\Disabler', 'disableDefaultEmbedTinyMCERelatedPlugins'));
61
+
62
+ remove_action('rest_api_init', 'wp_oembed_register_route');
63
+
64
+ // Remove embed-related scripts from the queue
65
+ remove_action('embed_head', 'enqueue_embed_scripts');
66
+ remove_action('embed_head', 'wp_print_head_scripts');
67
+
68
+ add_filter('load_default_embeds', false);
69
+
70
+ wp_embed_unregister_handler("video");
71
+ wp_embed_unregister_handler("youtube_embed_url");
72
+ wp_embed_unregister_handler("googlevideo");
73
+
74
+ // Remove all embeds rewrite rules.
75
+ add_filter('rewrite_rules_array', array('\EmbedPress\Disabler', 'disableDefaultEmbedRewriteRules'));
76
+
77
+ // Disable the method that determines if default embed handlers should be loaded.
78
+ add_filter('wp_maybe_load_embeds', '__return_false');
79
+
80
+ // Disable the method that transform any URL from content to {@link WP_Embed::shortcode()}.
81
+ remove_filter('the_content', array($wp_embed, 'run_shortcode'), 8);
82
+ remove_filter('the_content', array($wp_embed, 'autoembed'), 8);
83
+
84
+ // Remove {@link WP_Embed::shortcode()} from execution.
85
+ remove_shortcode(EMBEDPRESS_SHORTCODE);
86
+
87
+ wp_deregister_script('wp-embed');
88
+ }
89
+
90
+ /**
91
+ * Remove all rewrite rules related to embeds.
92
+ *
93
+ * @since 1.0
94
+ *
95
+ * @param array $rules WordPress rewrite rules.
96
+ * @return array
97
+ */
98
+ public static function disableDefaultEmbedRewriteRules($rules)
99
+ {
100
+ if (count($rules) > 0) {
101
+ foreach ($rules as $rule => $rewrite) {
102
+ if (strpos($rewrite, 'embed=true') !== false) {
103
+ unset($rules[$rule]);
104
+ }
105
+ }
106
+ }
107
+
108
+ return $rules;
109
+ }
110
+
111
+ /**
112
+ * Disable all TinyMCE plugins related to the embed.
113
+ *
114
+ * @since 1.0
115
+ * @static
116
+ *
117
+ * @param array $plugins An array containing enabled plugins.
118
+ */
119
+ public static function disableDefaultEmbedTinyMCERelatedPlugins($plugins)
120
+ {
121
+ $blackListedPlugins = array("wpembed", "wpview");
122
+
123
+ return array_diff($plugins, $blackListedPlugins);
124
+ }
125
+ }
EmbedPress/Ends/Back/Handler.php ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EmbedPress\Ends\Back;
3
+
4
+ use \EmbedPress\Ends\Handler as EndHandlerAbstract;
5
+ use \EmbedPress\Shortcode;
6
+ use \EmbedPress\Plugin;
7
+ use \Embera\Embera;
8
+
9
+ (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
10
+
11
+ /**
12
+ * The admin-facing functionality of the plugin.
13
+ * Defines the plugin name, version, and enqueue the admin-specific stylesheets and scripts.
14
+ *
15
+ * @package EmbedPress
16
+ * @subpackage EmbedPress/Ends/Back
17
+ * @author PressShack <help@pressshack.com>
18
+ * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
19
+ * @license GPLv2 or later
20
+ * @since 1.0
21
+ */
22
+ class Handler extends EndHandlerAbstract
23
+ {
24
+ /**
25
+ * Method that register all scripts for the admin area.
26
+ *
27
+ * @since 1.0
28
+ */
29
+ public function enqueueScripts()
30
+ {
31
+ $plgSettings = Plugin::getSettings();
32
+
33
+ wp_enqueue_script("bootbox-bootstrap", EMBEDPRESS_URL_ASSETS .'js/vendor/bootstrap/bootstrap.min.js', array('jquery'), $this->pluginVersion, true);
34
+ wp_enqueue_script("bootbox", EMBEDPRESS_URL_ASSETS .'js/vendor/bootbox.min.js', array('jquery', 'bootbox-bootstrap'), $this->pluginVersion, true);
35
+ wp_enqueue_script($this->pluginName, EMBEDPRESS_URL_ASSETS .'js/preview.js', array('jquery', 'bootbox'), $this->pluginVersion, true);
36
+ wp_localize_script($this->pluginName, '$data', array(
37
+ 'previewSettings' => array(
38
+ 'juriRoot' => get_site_url() .'/',
39
+ 'versionUID' => $this->pluginVersion,
40
+ 'debug' => true
41
+ ),
42
+ 'EMBEDPRESS_SHORTCODE' => EMBEDPRESS_SHORTCODE,
43
+ 'EMBEDPRESS_URL_ASSETS' => EMBEDPRESS_URL_ASSETS,
44
+ 'displayPreviewBox' => $plgSettings->displayPreviewBox
45
+ ));
46
+ }
47
+
48
+ /**
49
+ * Method that register all stylesheets for the admin area.
50
+ *
51
+ * @since 1.0
52
+ */
53
+ public function enqueueStyles()
54
+ {
55
+ global $wp_scripts;
56
+
57
+ wp_enqueue_style('bootbox-bootstrap', EMBEDPRESS_URL_ASSETS .'css/vendor/bootstrap/bootstrap.min.css');
58
+ wp_enqueue_style($this->pluginName, EMBEDPRESS_URL_ASSETS .'css/preview.css');
59
+ }
60
+
61
+ /**
62
+ * Method that receive a string via AJAX and return the decoded-shortcoded-version of that string.
63
+ *
64
+ * @since 1.0
65
+ */
66
+ public function doShortcodeReceivedViaAjax()
67
+ {
68
+ $response = array(
69
+ 'data' => array(
70
+ 'content' => Shortcode::parseContent(@$_POST['subject'], true)
71
+ )
72
+ );
73
+
74
+ header('Content-Type:application/json;charset=UTF-8');
75
+ echo json_encode($response);
76
+
77
+ exit();
78
+ }
79
+
80
+ /**
81
+ * Method that receive an url via AJAX and return the info about that url/embed.
82
+ *
83
+ * @since 1.0
84
+ */
85
+ public function getUrlInfoViaAjax()
86
+ {
87
+ $response = array(
88
+ 'url' => trim(@$_GET['url']),
89
+ 'canBeResponsive' => false
90
+ );
91
+
92
+ if (!!strlen($response['url'])) {
93
+ $embera = new Embera();
94
+
95
+ $additionalServiceProviders = Plugin::getAdditionalServiceProviders();
96
+ if (!empty($additionalServiceProviders)) {
97
+ foreach ($additionalServiceProviders as $serviceProviderClassName => $serviceProviderUrls) {
98
+ Shortcode::addServiceProvider($serviceProviderClassName, $serviceProviderUrls, $embera);
99
+ }
100
+ }
101
+
102
+ $urlInfo = $embera->getUrlInfo($response['url']);
103
+ if (isset($urlInfo[$response['url']])) {
104
+ $urlInfo = (object)$urlInfo[$response['url']];
105
+ $response['canBeResponsive'] = Plugin::canServiceProviderBeResponsive($urlInfo->provider_alias);
106
+ }
107
+ }
108
+
109
+ header('Content-Type:application/json;charset=UTF-8');
110
+ echo json_encode($response);
111
+
112
+ exit();
113
+ }
114
+ }
EmbedPress/Ends/Back/Settings.php ADDED
@@ -0,0 +1,225 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EmbedPress\Ends\Back;
3
+
4
+ use \EmbedPress\Plugin;
5
+
6
+ (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
7
+
8
+ /**
9
+ * Entity that handles the plugin's settings page.
10
+ *
11
+ * @package EmbedPress
12
+ * @subpackage EmbedPress/Ends/Back
13
+ * @author PressShack <help@pressshack.com>
14
+ * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
15
+ * @license GPLv2 or later
16
+ * @since 1.0
17
+ */
18
+ class Settings
19
+ {
20
+ /**
21
+ * This class namespace.
22
+ *
23
+ * @since 1.0
24
+ * @access private
25
+ * @static
26
+ *
27
+ * @var string $namespace
28
+ */
29
+ private static $namespace = '\EmbedPress\Ends\Back\Settings';
30
+
31
+ /**
32
+ * The plugin's unique identifier.
33
+ *
34
+ * @since 1.0
35
+ * @access private
36
+ * @static
37
+ *
38
+ * @var string $identifier
39
+ */
40
+ private static $identifier = "plg_embedpress";
41
+
42
+ /**
43
+ * Unique identifier to the plugin's admin settings section.
44
+ *
45
+ * @since 1.0
46
+ * @access private
47
+ * @static
48
+ *
49
+ * @var string $sectionAdminIdentifier
50
+ */
51
+ private static $sectionAdminIdentifier = "embedpress_options_admin";
52
+
53
+ /**
54
+ * Unique identifier to the plugin's general settings section.
55
+ *
56
+ * @since 1.0
57
+ * @access private
58
+ * @static
59
+ *
60
+ * @var string $sectionGroupIdentifier The name of the plugin.
61
+ */
62
+ private static $sectionGroupIdentifier = "embedpress_options";
63
+
64
+ /**
65
+ * Map to all settings.
66
+ *
67
+ * @since 1.0
68
+ * @access private
69
+ * @static
70
+ *
71
+ * @var string $fieldMap
72
+ */
73
+ private static $fieldMap = array(
74
+ 'enablePluginInAdmin' => array(
75
+ 'label' => "Enable EmbedPress in the admin area",
76
+ 'section' => "admin"
77
+ ),
78
+ 'displayPreviewBox' => array(
79
+ 'label' => "Display Preview Box inside editor",
80
+ 'section' => "admin"
81
+ )
82
+ );
83
+
84
+ /**
85
+ * Class constructor. This prevents the class being directly instantiated.
86
+ *
87
+ * @since 1.0
88
+ */
89
+ public function __construct()
90
+ {}
91
+
92
+ /**
93
+ * This prevents the class being cloned.
94
+ *
95
+ * @since 1.0
96
+ */
97
+ public function __clone()
98
+ {}
99
+
100
+ /**
101
+ * Method that adds an sub-item for EmbedPress to the WordPress Settings menu.
102
+ *
103
+ * @since 1.0
104
+ * @static
105
+ */
106
+ public static function registerMenuItem()
107
+ {
108
+ add_options_page('EmbedPress Settings', 'EmbedPress', 'manage_options', 'embedpress', array(self::$namespace, 'renderForm'));
109
+ }
110
+
111
+ /**
112
+ * Method that configures the EmbedPress settings page.
113
+ *
114
+ * @since 1.0
115
+ * @static
116
+ */
117
+ public static function registerActions()
118
+ {
119
+ register_setting(self::$sectionGroupIdentifier, self::$sectionGroupIdentifier, array(self::$namespace, "validateForm"));
120
+
121
+ add_settings_section(self::$sectionAdminIdentifier, 'Admin Section Settings', array(self::$namespace, 'renderHelpText'), self::$identifier);
122
+
123
+ foreach (self::$fieldMap as $fieldName => $field) {
124
+ add_settings_field($fieldName, $field['label'], array(self::$namespace, "renderField_{$fieldName}"), self::$identifier, self::${"section". ucfirst($field['section']) ."Identifier"});
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Method that render the settings's form.
130
+ *
131
+ * @since 1.0
132
+ * @static
133
+ */
134
+ public static function renderForm()
135
+ {
136
+ ?>
137
+ <div>
138
+ <h2>EmbedPress Settings Page</h2>
139
+ <form action="options.php" method="POST">
140
+ <?php settings_fields(self::$sectionGroupIdentifier); ?>
141
+ <?php do_settings_sections(self::$identifier); ?>
142
+
143
+ <input name="Submit" type="submit" value="Save changes" />
144
+ </form>
145
+ </div>
146
+ <?php
147
+ }
148
+
149
+ /**
150
+ * Method that validates the form data.
151
+ *
152
+ * @since 1.0
153
+ * @static
154
+ *
155
+ * @param mixed $freshData Data received from the form.
156
+ *
157
+ * @return array
158
+ */
159
+ public static function validateForm($freshData)
160
+ {
161
+ $data = array(
162
+ 'displayPreviewBox' => (bool)$freshData['displayPreviewBox'],
163
+ 'enablePluginInAdmin' => (bool)$freshData['enablePluginInAdmin']
164
+ );
165
+
166
+ return $data;
167
+ }
168
+
169
+ /**
170
+ * Method that prints help info for the form.
171
+ *
172
+ * @since 1.0
173
+ * @static
174
+ *
175
+ * @return string
176
+ */
177
+ public static function renderHelpText()
178
+ {
179
+ return "";
180
+ }
181
+
182
+ /**
183
+ * Method that renders the displayPreviewBox input.
184
+ *
185
+ * @since 1.0
186
+ * @static
187
+ */
188
+ public static function renderField_displayPreviewBox()
189
+ {
190
+ $fieldName = "displayPreviewBox";
191
+
192
+ $options = get_option(self::$sectionGroupIdentifier);
193
+
194
+ $activeOptions = Plugin::getSettings();
195
+ if (isset($activeOptions->enablePluginInAdmin) && (bool)$activeOptions->enablePluginInAdmin === false) {
196
+ $options[$fieldName] = false;
197
+ } else {
198
+ $options[$fieldName] = !isset($options[$fieldName]) ? true : (bool)$options[$fieldName];
199
+ }
200
+ unset($activeOptions);
201
+
202
+ echo '<label><input type="radio" id="'. $fieldName .'_0" name="'. self::$sectionGroupIdentifier .'['. $fieldName .']" value="0" '. (!$options[$fieldName] ? "checked" : "") .' /> No</label>';
203
+ echo "&nbsp;&nbsp;";
204
+ echo '<label><input type="radio" id="'. $fieldName .'_1" name="'. self::$sectionGroupIdentifier .'['. $fieldName .']" value="1" '. ($options[$fieldName] ? "checked" : "") .' /> Yes</label>';
205
+ }
206
+
207
+ /**
208
+ * Method that renders the enablePluginInAdmin input.
209
+ *
210
+ * @since 1.0
211
+ * @static
212
+ */
213
+ public static function renderField_enablePluginInAdmin()
214
+ {
215
+ $fieldName = "enablePluginInAdmin";
216
+
217
+ $options = get_option(self::$sectionGroupIdentifier);
218
+
219
+ $options[$fieldName] = !isset($options[$fieldName]) ? true : (bool)$options[$fieldName];
220
+
221
+ echo '<label><input type="radio" id="'. $fieldName .'_0" name="'. self::$sectionGroupIdentifier .'['. $fieldName .']" value="0" '. (!$options[$fieldName] ? "checked" : "") .' /> No</label>';
222
+ echo "&nbsp;&nbsp;";
223
+ echo '<label><input type="radio" id="'. $fieldName .'_1" name="'. self::$sectionGroupIdentifier .'['. $fieldName .']" value="1" '. ($options[$fieldName] ? "checked" : "") .' /> Yes</label>';
224
+ }
225
+ }
EmbedPress/Ends/Back/index.html ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>403 Forbidden</title>
5
+ </head>
6
+ <body>
7
+ <p>Directory access is forbidden.</p>
8
+ </body>
9
+ </html>
EmbedPress/Ends/Front/Handler.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EmbedPress\Ends\Front;
3
+
4
+ use \EmbedPress\Ends\Handler as EndHandlerAbstract;
5
+
6
+ (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
7
+
8
+ /**
9
+ * The public-facing functionality of the plugin.
10
+ * Defines the plugin name, version, and enqueue the public-specific stylesheets and scripts.
11
+ *
12
+ * @package EmbedPress
13
+ * @subpackage EmbedPress/Ends/Front
14
+ * @author PressShack <help@pressshack.com>
15
+ * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
16
+ * @license GPLv2 or later
17
+ * @since 1.0
18
+ */
19
+ class Handler extends EndHandlerAbstract
20
+ {
21
+ /**
22
+ * Method that register all scripts for the admin area.
23
+ *
24
+ * @since 1.0
25
+ */
26
+ public function enqueueScripts()
27
+ {}
28
+
29
+ /**
30
+ * Method that register all stylesheets for the public area.
31
+ *
32
+ * @since 1.0
33
+ */
34
+ public function enqueueStyles()
35
+ {
36
+ wp_enqueue_style(EMBEDPRESS_NAME, EMBEDPRESS_URL_ASSETS .'css/embedpress.css');
37
+
38
+ }
39
+ }
EmbedPress/Ends/Front/index.html ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>403 Forbidden</title>
5
+ </head>
6
+ <body>
7
+ <p>Directory access is forbidden.</p>
8
+ </body>
9
+ </html>
EmbedPress/Ends/Handler.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EmbedPress\Ends;
3
+
4
+ (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
5
+
6
+ /**
7
+ * Modeling class to handle the plugin in different environments. I.e: public area/admin area.
8
+ *
9
+ * @package EmbedPress
10
+ * @subpackage EmbedPress/Ends
11
+ * @author PressShack <help@pressshack.com>
12
+ * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
13
+ * @license GPLv2 or later
14
+ * @since 1.0
15
+ */
16
+ abstract class Handler
17
+ {
18
+ /**
19
+ * The name of the plugin.
20
+ *
21
+ * @since 1.0
22
+ * @access private
23
+ *
24
+ * @var string $pluginName The name of the plugin.
25
+ */
26
+ protected $pluginName;
27
+
28
+ /**
29
+ * The version of the plugin.
30
+ *
31
+ * @since 1.0
32
+ * @access private
33
+ *
34
+ * @var string $pluginVersion The version of the plugin.
35
+ */
36
+ protected $pluginVersion;
37
+
38
+ /**
39
+ * Initialize the class and set its properties.
40
+ *
41
+ * @since 1.0
42
+ *
43
+ * @param string $pluginName - The name of the plugin.
44
+ * @param string $pluginVersion - The version of the plugin.
45
+ */
46
+ public function __construct($pluginName, $pluginVersion)
47
+ {
48
+ $this->pluginName = $pluginName;
49
+ $this->pluginVersion = $pluginVersion;
50
+ }
51
+
52
+ /**
53
+ * Method that register all scripts for the admin area.
54
+ *
55
+ * @since 1.0
56
+ */
57
+ abstract public function enqueueScripts();
58
+
59
+ /**
60
+ * Method that register all stylesheets for the admin area.
61
+ *
62
+ * @since 1.0
63
+ */
64
+ abstract public function enqueueStyles();
65
+ }
EmbedPress/Ends/index.html ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>403 Forbidden</title>
5
+ </head>
6
+ <body>
7
+ <p>Directory access is forbidden.</p>
8
+ </body>
9
+ </html>
EmbedPress/Loader.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EmbedPress;
3
+
4
+ (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
5
+
6
+ /**
7
+ * Entity responsible for maintaining and registering all hooks that power the plugin.
8
+ *
9
+ * @package EmbedPress
10
+ * @author PressShack <help@pressshack.com>
11
+ * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
12
+ * @license GPLv2 or later
13
+ * @since 1.0
14
+ */
15
+ class Loader
16
+ {
17
+ /**
18
+ * The array of actions registered with WordPress.
19
+ *
20
+ * @since 1.0
21
+ * @access protected
22
+ *
23
+ * @var array $actions The actions registered with WordPress to fire when the plugin loads.
24
+ */
25
+ protected $actions;
26
+
27
+ /**
28
+ * The array of filters registered with WordPress.
29
+ *
30
+ * @since 1.0
31
+ * @access protected
32
+ *
33
+ * @var array $filters The filters registered with WordPress to fire when the plugin loads.
34
+ */
35
+ protected $filters;
36
+
37
+ /**
38
+ * Initialize the collections used to maintain the actions and filters.
39
+ *
40
+ * @since 1.0
41
+ */
42
+ public function __construct()
43
+ {
44
+ $this->actions = array();
45
+ $this->filters = array();
46
+ }
47
+
48
+ /**
49
+ * Add a new action to the collection to be registered with WordPress.
50
+ *
51
+ * @since 1.0
52
+ *
53
+ * @param string $hook The name of the WordPress action that is being registered.
54
+ * @param object $component A reference to the instance of the object on which the action is defined.
55
+ * @param string $callback The name of the function definition on the $component.
56
+ * @param int $priority Optional. he priority at which the function should be fired. Default is 10.
57
+ * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1.
58
+ */
59
+ public function add_action($hook, $component, $callback, $priority = 10, $accepted_args = 1)
60
+ {
61
+ $this->actions = $this->add($this->actions, $hook, $component, $callback, $priority, $accepted_args);
62
+ }
63
+
64
+ /**
65
+ * Add a new filter to the collection to be registered with WordPress.
66
+ *
67
+ * @since 1.0
68
+ *
69
+ * @param string $hook The name of the WordPress filter that is being registered.
70
+ * @param object $component A reference to the instance of the object on which the filter is defined.
71
+ * @param string $callback The name of the function definition on the $component.
72
+ * @param int $priority Optional. he priority at which the function should be fired. Default is 10.
73
+ * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1.
74
+ */
75
+ public function add_filter($hook, $component, $callback, $priority = 10, $accepted_args = 1)
76
+ {
77
+ $this->filters = $this->add($this->filters, $hook, $component, $callback, $priority, $accepted_args);
78
+ }
79
+
80
+ /**
81
+ * Method that is used to register the actions and hooks into a single collection.
82
+ *
83
+ * @since 1.0
84
+ * @access private
85
+ *
86
+ * @param array $hooks The collection of hooks that is being registered (that is, actions or filters).
87
+ * @param string $hook The name of the WordPress filter that is being registered.
88
+ * @param object $component A reference to the instance of the object on which the filter is defined.
89
+ * @param string $callback The name of the function definition on the $component.
90
+ * @param int $priority The priority at which the function should be fired.
91
+ * @param int $accepted_args The number of arguments that should be passed to the $callback.
92
+ * @return array The collection of actions and filters registered with WordPress.
93
+ */
94
+ private function add($hooks, $hook, $component, $callback, $priority, $accepted_args)
95
+ {
96
+ $hooks[] = array(
97
+ 'hook' => $hook,
98
+ 'component' => $component,
99
+ 'callback' => $callback,
100
+ 'priority' => $priority,
101
+ 'accepted_args' => $accepted_args
102
+ );
103
+
104
+ return $hooks;
105
+ }
106
+
107
+ /**
108
+ * Register all required filters and actions with WordPress.
109
+ *
110
+ * @since 1.0
111
+ */
112
+ public function run()
113
+ {
114
+ foreach ($this->filters as $hook) {
115
+ add_filter($hook['hook'], array(
116
+ $hook['component'], $hook['callback']
117
+ ), $hook['priority'], $hook['accepted_args']);
118
+ }
119
+
120
+ foreach ($this->actions as $hook) {
121
+ add_action($hook['hook'], array(
122
+ $hook['component'], $hook['callback']
123
+ ), $hook['priority'], $hook['accepted_args']);
124
+ }
125
+ }
126
+ }
EmbedPress/Plugin.php ADDED
@@ -0,0 +1,225 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EmbedPress;
3
+
4
+ use \EmbedPress\Loader;
5
+ use \EmbedPress\Ends\Back\Handler as EndHandlerAdmin;
6
+ use \EmbedPress\Ends\Front\Handler as EndHandlerPublic;
7
+
8
+ (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
9
+
10
+ /**
11
+ * Entity that glues together all pieces that the plugin is made of.
12
+ *
13
+ * @package EmbedPress
14
+ * @author PressShack <help@pressshack.com>
15
+ * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
16
+ * @license GPLv2 or later
17
+ * @since 1.0
18
+ */
19
+ class Plugin
20
+ {
21
+ /**
22
+ * The name of the plugin.
23
+ *
24
+ * @since 1.0
25
+ * @access protected
26
+ *
27
+ * @var string $pluginName The name of the plugin.
28
+ */
29
+ protected $pluginName;
30
+
31
+ /**
32
+ * The version of the plugin.
33
+ *
34
+ * @since 1.0
35
+ * @access protected
36
+ *
37
+ * @var string $pluginVersion The version of the plugin.
38
+ */
39
+ protected $pluginVersion;
40
+
41
+ /**
42
+ * An instance of the plugin loader.
43
+ *
44
+ * @since 1.0
45
+ * @access protected
46
+ *
47
+ * @var \EmbedPress\Loader $pluginVersion The version of the plugin.
48
+ */
49
+ protected $loaderInstance;
50
+
51
+ /**
52
+ * Initialize the plugin and set its properties.
53
+ *
54
+ * @since 1.0
55
+ */
56
+ public function __construct()
57
+ {
58
+ $this->pluginName = EMBEDPRESS_PLG_NAME;
59
+ $this->pluginVersion = EMBEDPRESS_PLG_VERSION;
60
+
61
+ $this->loaderInstance = new Loader();
62
+ }
63
+
64
+ /**
65
+ * Method that retrieves the plugin name.
66
+ *
67
+ * @since 1.0
68
+ *
69
+ * @return string
70
+ */
71
+ public function getPluginName()
72
+ {
73
+ return $this->pluginName;
74
+ }
75
+
76
+ /**
77
+ * Method that retrieves the plugin version.
78
+ *
79
+ * @since 1.0
80
+ *
81
+ * @return string
82
+ */
83
+ public function getPluginVersion()
84
+ {
85
+ return $this->pluginVersion;
86
+ }
87
+
88
+ /**
89
+ * Method that retrieves the loader instance.
90
+ *
91
+ * @since 1.0
92
+ *
93
+ * @return \EmbedPress\Loader
94
+ */
95
+ public function getLoader()
96
+ {
97
+ return $this->loaderInstance;
98
+ }
99
+
100
+ /**
101
+ * Method responsible to connect all required hooks in order to make the plugin work.
102
+ *
103
+ * @since 1.0
104
+ */
105
+ public function initialize()
106
+ {
107
+ global $wp_actions;
108
+
109
+ if (is_admin()) {
110
+ $plgSettings = self::getSettings();
111
+
112
+ $settingsClassNamespace = '\EmbedPress\Ends\Back\Settings';
113
+ add_action('admin_menu', array($settingsClassNamespace, 'registerMenuItem'));
114
+ add_action('admin_init', array($settingsClassNamespace, 'registerActions'));
115
+ unset($settingsClassNamespace);
116
+
117
+ if ($plgSettings->enablePluginInAdmin) {
118
+ add_action('init', array('\EmbedPress\Disabler', 'run'), 1);
119
+
120
+ $plgHandlerAdminInstance = new EndHandlerAdmin($this->getPluginName(), $this->getPluginVersion());
121
+
122
+ $enqueueScriptsHookName = "admin_enqueue_scripts";
123
+ $this->loaderInstance->add_action($enqueueScriptsHookName, $plgHandlerAdminInstance, 'enqueueScripts');
124
+ $this->loaderInstance->add_action($enqueueScriptsHookName, $plgHandlerAdminInstance, 'enqueueStyles');
125
+
126
+ $onAjaxCallbackName = "doShortcodeReceivedViaAjax";
127
+ $this->loaderInstance->add_action('wp_ajax_embedpress_do_ajax_request', $plgHandlerAdminInstance, $onAjaxCallbackName);
128
+ $this->loaderInstance->add_action('wp_ajax_nopriv_embedpress_do_ajax_request', $plgHandlerAdminInstance, $onAjaxCallbackName);
129
+
130
+ $this->loaderInstance->add_action('wp_ajax_embedpress_get_embed_url_info', $plgHandlerAdminInstance, "getUrlInfoViaAjax");
131
+
132
+ unset($onAjaxCallbackName, $enqueueScriptsHookName, $plgHandlerAdminInstance);
133
+ }
134
+ } else {
135
+ add_action('init', array('\EmbedPress\Disabler', 'run'), 1);
136
+
137
+ $plgHandlerPublicInstance = new EndHandlerPublic($this->getPluginName(), $this->getPluginVersion());
138
+
139
+ $enqueueScriptsHookName = "wp_enqueue_scripts";
140
+ $this->loaderInstance->add_action($enqueueScriptsHookName, $plgHandlerPublicInstance, 'enqueueScripts');
141
+ $this->loaderInstance->add_action($enqueueScriptsHookName, $plgHandlerPublicInstance, 'enqueueStyles');
142
+
143
+ unset($enqueueScriptsHookName, $plgHandlerPublicInstance);
144
+ }
145
+
146
+ $this->loaderInstance->run();
147
+ }
148
+
149
+ /**
150
+ * Callback called right after the plugin has been activated.
151
+ *
152
+ * @since 1.0
153
+ */
154
+ public static function onPluginActivationCallback()
155
+ {
156
+ add_filter('rewrite_rules_array', array('\EmbedPress\Disabler', 'disableDefaultEmbedRewriteRules'));
157
+ flush_rewrite_rules();
158
+ }
159
+
160
+ /**
161
+ * Callback called right after the plugin has been deactivated.
162
+ *
163
+ * @since 1.0
164
+ */
165
+ public static function onPluginDeactivationCallback()
166
+ {
167
+ remove_filter('rewrite_rules_array', array('\EmbedPress\Disabler', 'disableDefaultEmbedRewriteRules'));
168
+ flush_rewrite_rules();
169
+ }
170
+
171
+ /**
172
+ * Method that retrieves all additional service providers defined in the ~<plugin_root_path>/providers.php file.
173
+ *
174
+ * @since 1.0
175
+ *
176
+ * @return array
177
+ */
178
+ public static function getAdditionalServiceProviders()
179
+ {
180
+ $additionalProvidersFilePath = EMBEDPRESS_PATH_BASE .'providers.php';
181
+ if (file_exists($additionalProvidersFilePath)) {
182
+ include $additionalProvidersFilePath;
183
+
184
+ if (isset($additionalServiceProviders)) {
185
+ return $additionalServiceProviders;
186
+ }
187
+ }
188
+
189
+ return array();
190
+ }
191
+
192
+ /**
193
+ * Method that checks if an embed of a given service provider can be responsive.
194
+ *
195
+ * @since 1.0
196
+ *
197
+ * @return boolean
198
+ */
199
+ public static function canServiceProviderBeResponsive($serviceProviderAlias)
200
+ {
201
+ return in_array($serviceProviderAlias, array("dailymotion", "kickstarter", "rutube", "ted", "vimeo", "youtube", "ustream", "google-docs", "animatron", "amcharts", "on-aol-com", "animoto", "videojug"));
202
+ }
203
+
204
+ /**
205
+ * Method that retrieves the plugin settings defined by the user.
206
+ *
207
+ * @since 1.0
208
+ *
209
+ * @return object
210
+ */
211
+ public static function getSettings()
212
+ {
213
+ $settings = get_option("embedpress_options");
214
+
215
+ if (!isset($settings['displayPreviewBox'])) {
216
+ $settings['displayPreviewBox'] = true;
217
+ }
218
+
219
+ if (!isset($settings['enablePluginInAdmin'])) {
220
+ $settings['enablePluginInAdmin'] = true;
221
+ }
222
+
223
+ return (object)$settings;
224
+ }
225
+ }
EmbedPress/Providers/GoogleDocs.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EmbedPress\Providers;
3
+
4
+ use \Embera\Adapters\Service as EmberaService;
5
+
6
+ (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
7
+
8
+ /**
9
+ * Entity responsible to support GoogleDocs embeds.
10
+ *
11
+ * @package EmbedPress
12
+ * @subpackage EmbedPress/Providers
13
+ * @author PressShack <help@pressshack.com>
14
+ * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
15
+ * @license GPLv2 or later
16
+ * @since 1.0
17
+ */
18
+ class GoogleDocs extends EmberaService
19
+ {
20
+ /**
21
+ * Method that verifies if the embed URL belongs to GoogleDocs.
22
+ *
23
+ * @since 1.0
24
+ *
25
+ * @return boolean
26
+ */
27
+ public function validateUrl()
28
+ {
29
+ return preg_match('~http[s]?:\/\/((?:www\.)?docs\.google\.com\/(?:document|presentation|spreadsheets|forms|drawings)\/[a-z0-9\/\?=_\-\.\,&%\$#\@\!\+]*)~i', $this->url);
30
+ }
31
+
32
+ /**
33
+ * This method fakes an Oembed response.
34
+ *
35
+ * @since 1.0
36
+ *
37
+ * @return array
38
+ */
39
+ public function fakeResponse()
40
+ {
41
+ $iframeSrc = html_entity_decode($this->url);
42
+
43
+ // Check the type of document
44
+ preg_match('~google\.com/(document|presentation|spreadsheets|forms|drawings)/~i', $iframeSrc, $matches);
45
+ $type = $matches[1];
46
+
47
+ switch ($type) {
48
+ case 'document':
49
+ // Check if the url still doesn't have the embedded param, and add if needed
50
+ if (!preg_match('~([?&])embedded=true~i', $iframeSrc, $matches)) {
51
+ if (substr_count($iframeSrc, '?')) {
52
+ $iframeSrc .= '&embedded=true';
53
+ } else {
54
+ $iframeSrc .= '?embedded=true';
55
+ }
56
+ }
57
+ break;
58
+
59
+ case 'presentation':
60
+ // Convert the /pub to /embed if needed
61
+ if (preg_match('~/pub\?~i', $iframeSrc)) {
62
+ $iframeSrc = str_replace('/pub?', '/embed?', $iframeSrc);
63
+ }
64
+ break;
65
+
66
+ case 'spreadsheets':
67
+ if (substr_count($iframeSrc, '?')) {
68
+ $query = explode('?', $iframeSrc);
69
+ $query = $query[1];
70
+ $query = explode('&', $query);
71
+
72
+ if (!empty($query)) {
73
+ $hasWidgetParam = false;
74
+ $hasHeadersParam = false;
75
+
76
+ foreach ($query as $param) {
77
+ if (substr_count($param, 'widget=')) {
78
+ $hasWidgetParam = true;
79
+ } elseif (substr_count($param, 'headers=')) {
80
+ $hasHeadersParam = true;
81
+ }
82
+ }
83
+
84
+ if (!$hasWidgetParam) {
85
+ $iframeSrc .= '&widget=true';
86
+ }
87
+
88
+ if (!$hasHeadersParam) {
89
+ $iframeSrc .= '&headers=false';
90
+ }
91
+ }
92
+ } else {
93
+ $iframeSrc .= '?widget=true&headers=false';
94
+ }
95
+ break;
96
+
97
+ case 'forms':
98
+ case 'drawings':
99
+ break;
100
+ }
101
+
102
+ if ($type !== 'drawings') {
103
+ $html = '<iframe src="' . $iframeSrc . '" frameborder="0" width="600" height="450" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>';
104
+ } else {
105
+ $html = '<img src="' . $iframeSrc . '" width="960" height="720" />';
106
+ }
107
+
108
+ return array(
109
+ 'type' => 'rich',
110
+ 'provider_name' => 'Google Docs',
111
+ 'provider_url' => 'http://docs.google.com',
112
+ 'title' => 'Unknown title',
113
+ 'html' => $html,
114
+ 'wrapper_class' => 'ose-google-docs-' . $type
115
+ );
116
+ }
117
+ }
EmbedPress/Providers/GoogleMaps.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EmbedPress\Providers;
3
+
4
+ use \Embera\Adapters\Service as EmberaService;
5
+
6
+ (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
7
+
8
+ /**
9
+ * Entity responsible to support GoogleMaps embeds.
10
+ *
11
+ * @package EmbedPress
12
+ * @subpackage EmbedPress/Providers
13
+ * @author PressShack <help@pressshack.com>
14
+ * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
15
+ * @license GPLv2 or later
16
+ * @since 1.0
17
+ */
18
+ class GoogleMaps extends EmberaService
19
+ {
20
+ /**
21
+ * Method that verifies if the embed URL belongs to GoogleMaps.
22
+ *
23
+ * @since 1.0
24
+ *
25
+ * @return boolean
26
+ */
27
+ public function validateUrl()
28
+ {
29
+ return preg_match('~http[s]?:\/\/((?:www\.)?google\.com(\.[a-z]{2})?|(?:www\.)?maps\.google\.com(\.[a-z]{2})?)\/maps[/?][a-z0-9\/%,+\-_=!:@\.&*\$#?\']*~i', $this->url);
30
+ }
31
+
32
+ /**
33
+ * This method fakes an Oembed response.
34
+ *
35
+ * @since 1.0
36
+ *
37
+ * @return array
38
+ */
39
+ public function fakeResponse()
40
+ {
41
+ $iframeSrc = '';
42
+
43
+ // Check if the url is already converted to the embed format
44
+ if (preg_match('~(maps/embed|output=embed)~i', $this->url)) {
45
+ $iframeSrc = $this->url;
46
+ } else {
47
+ // Extract coordinates and zoom from the url
48
+ if (preg_match('~@(-?[0-9\.]+,-?[0-9\.]+).+,([0-9\.]+z)~i', $this->url, $matches)) {
49
+ $iframeSrc = 'http://maps.google.com/maps?hl=en&ie=UTF8&ll=' . $matches[1] . '&spn=' . $matches[1] . '&t=m&z=' . round($matches[2]) . '&output=embed';
50
+ } else {
51
+ return array();
52
+ }
53
+ }
54
+
55
+ return array(
56
+ 'type' => 'rich',
57
+ 'provider_name' => 'Google Maps',
58
+ 'provider_url' => 'http://maps.google.com',
59
+ 'title' => 'Unknown title',
60
+ 'html' => '<iframe width="600" height="450" src="' . $iframeSrc . '" frameborder="0"></iframe>',
61
+ );
62
+ }
63
+ }
EmbedPress/Providers/index.html ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>403 Forbidden</title>
5
+ </head>
6
+ <body>
7
+ <p>Directory access is forbidden.</p>
8
+ </body>
9
+ </html>
EmbedPress/Shortcode.php ADDED
@@ -0,0 +1,367 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EmbedPress;
3
+
4
+ use \EmbedPress\Plugin;
5
+ use \Embera\Embera;
6
+ use \Embera\Formatter;
7
+
8
+ (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
9
+
10
+ /**
11
+ * Entity responsible to handle the plugin's shortcode events and behaviors.
12
+ *
13
+ * @package EmbedPress
14
+ * @author PressShack <help@pressshack.com>
15
+ * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
16
+ * @license GPLv2 or later
17
+ * @since 1.0
18
+ */
19
+ class Shortcode
20
+ {
21
+ /**
22
+ * The WP_oEmbed class instance.
23
+ *
24
+ * @since 1.0
25
+ * @access private
26
+ *
27
+ * @var string $oEmbedInstance
28
+ */
29
+ private static $oEmbedInstance = null;
30
+
31
+ /**
32
+ * Register the plugin's shortcode into WordPress.
33
+ *
34
+ * @since 1.0
35
+ * @static
36
+ */
37
+ public static function register()
38
+ {
39
+ // Register the new shortcode for embeds.
40
+ add_shortcode(EMBEDPRESS_SHORTCODE, array('\\EmbedPress\\Shortcode', 'do_shortcode'), 1);
41
+ }
42
+
43
+ /**
44
+ * Method that converts the plugin shortcoded-string into its complex content.
45
+ *
46
+ * @since 1.0
47
+ * @static
48
+ *
49
+ * @param array $attributes @TODO
50
+ * @param string $subject The given string
51
+ * @return string
52
+ */
53
+ public static function do_shortcode($attributes = array(), $subject = null)
54
+ {
55
+ $decodedSubject = self::parseContent($subject, true, $attributes);
56
+
57
+ return $decodedSubject;
58
+ }
59
+
60
+ /**
61
+ * Replace a given content with its embeded HTML code.
62
+ *
63
+ * @since 1.0
64
+ * @static
65
+ *
66
+ * @param string The raw content that will be replaced.
67
+ * @param boolean Optional. If true, new lines at the end of the embeded code are stripped.
68
+ * @return string
69
+ */
70
+ public static function parseContent($subject, $stripNewLine = false, $customAttributes = array())
71
+ {
72
+ if (!empty($subject)) {
73
+ if (empty($customAttributes)) {
74
+ $customAttributes = self::parseContentAttributesFromString($subject);
75
+ }
76
+
77
+ $content = preg_replace('/(\['. EMBEDPRESS_SHORTCODE .'(?:\]|.+?\])|\[\/'. EMBEDPRESS_SHORTCODE .'\])/i', "", $subject);
78
+
79
+ // Check if the WP_oEmbed class is loaded
80
+ if (!self::$oEmbedInstance) {
81
+ require_once ABSPATH .'wp-includes/class-oembed.php';
82
+
83
+ self::$oEmbedInstance = _wp_oembed_get_object();
84
+ }
85
+
86
+ $emberaInstanceSettings = array(
87
+ 'params' => array()
88
+ );
89
+
90
+ $attributes = self::parseContentAttributes($customAttributes);
91
+ if (isset($attributes['width']) || isset($attributes['height'])) {
92
+ if (isset($attributes['width'])) {
93
+ $emberaInstanceSettings['params']['width'] = $attributes['width'];
94
+ unset($attributes['width']);
95
+ }
96
+
97
+ if (isset($attributes['height'])) {
98
+ $emberaInstanceSettings['params']['height'] = $attributes['height'];
99
+ unset($attributes['height']);
100
+ }
101
+ }
102
+
103
+ // Identify what service provider the shortcode's link belongs to
104
+ $serviceProvider = self::$oEmbedInstance->get_provider($content);
105
+
106
+ // Gather info about the shortcode's link
107
+ $urlData = self::$oEmbedInstance->fetch($serviceProvider, $content, $attributes);
108
+
109
+ // Transform all shortcode attributes into html form. I.e.: {foo: "joe"} -> foo="joe"
110
+ $attributesHtml = array();
111
+ foreach ($attributes as $attrName => $attrValue) {
112
+ $attributesHtml[] = $attrName .'="'. $attrValue .'"';
113
+ }
114
+
115
+ // Define the EmbedPress html template where the generated embed will be injected in
116
+ $embedTemplate = '<div '. implode(' ', $attributesHtml) .'>{html}</div>';
117
+
118
+ // Try to generate the embed using WP API
119
+ $parsedContent = self::$oEmbedInstance->get_html($content, $attributes);
120
+ if (!$parsedContent) {
121
+ // If the embed couldn't be generated, we'll try to use Embera's API
122
+ $emberaInstance = new Embera($emberaInstanceSettings);
123
+ // Add support to the user's custom service providers
124
+ $additionalServiceProviders = Plugin::getAdditionalServiceProviders();
125
+ if (!empty($additionalServiceProviders)) {
126
+ foreach ($additionalServiceProviders as $serviceProviderClassName => $serviceProviderUrls) {
127
+ self::addServiceProvider($serviceProviderClassName, $serviceProviderUrls, $emberaInstance);
128
+ }
129
+
130
+ unset($serviceProviderUrls, $serviceProviderClassName);
131
+ }
132
+
133
+ // Register the html template
134
+ $emberaFormaterInstance = new Formatter($emberaInstance, true);
135
+ $emberaFormaterInstance->setTemplate($embedTemplate);
136
+
137
+ // Try to generate the embed using Embera API
138
+ $parsedContent = $emberaFormaterInstance->transform($content);
139
+
140
+ unset($emberaFormaterInstance, $additionalServiceProviders, $emberaInstance);
141
+ } else {
142
+ // Inject the generated code inside the html template
143
+ $parsedContent = str_replace('{html}', $parsedContent, $embedTemplate);
144
+
145
+ // Replace all single quotes to double quotes. I.e: foo='joe' -> foo="joe"
146
+ $parsedContent = str_replace("'", '"', $parsedContent);
147
+
148
+ // Replace the flag `{provider_alias}` which is used by Embera with the "ose-<serviceProviderAlias>". I.e: YouTube -> "ose-youtube"
149
+ $parsedContent = preg_replace('/((?:ose-)?\{provider_alias\})/i', "ose-". strtolower($urlData->provider_name), $parsedContent);
150
+ }
151
+
152
+ unset($embedTemplate, $urlData, $serviceProvider);
153
+
154
+ // This assure that the iframe has the same dimensions the user wants to
155
+ if (isset($emberaInstanceSettings['params']['width']) || isset($emberaInstanceSettings['params']['height'])) {
156
+ if (isset($emberaInstanceSettings['params']['width']) && isset($emberaInstanceSettings['params']['height'])) {
157
+ $customWidth = (int)$emberaInstanceSettings['params']['width'];
158
+ $customHeight = (int)$emberaInstanceSettings['params']['height'];
159
+ } else {
160
+ preg_match_all('/\<iframe\s+width="(\d+)"\s+height="(\d+)"/i', $parsedContent, $matches);
161
+ $iframeWidth = (int)$matches[1][0];
162
+ $iframeHeight = (int)$matches[2][0];
163
+ $iframeRatio = ceil($iframeWidth / $iframeHeight);
164
+
165
+ if (isset($emberaInstanceSettings['params']['width'])) {
166
+ $customWidth = (int)$emberaInstanceSettings['params']['width'];
167
+ $customHeight = ceil($customWidth / $iframeRatio);
168
+ } else {
169
+ $customHeight = (int)$emberaInstanceSettings['params']['height'];
170
+ $customWidth = $iframeRatio * $customHeight;
171
+ }
172
+
173
+ unset($iframeRatio, $iframeHeight, $iframeWidth, $matches);
174
+ }
175
+
176
+ $parsedContent = preg_replace('/\s+width\=\"(\d+)\"/i', ' width="'. $customWidth .'"', $parsedContent);
177
+ $parsedContent = preg_replace('/\s+height\=\"(\d+)\"/i', ' height="'. $customHeight .'"', $parsedContent);
178
+ }
179
+
180
+ if ($stripNewLine) {
181
+ $parsedContent = preg_replace('/\n/', '', $parsedContent);
182
+ }
183
+
184
+ if (!empty($parsedContent)) {
185
+ return $parsedContent;
186
+ }
187
+ }
188
+
189
+ return $subject;
190
+ }
191
+
192
+ /**
193
+ * Method that adds support to a given new service provider (SP).
194
+ *
195
+ * @since 1.0
196
+ * @static
197
+ *
198
+ * @param string $className The new SP class name.
199
+ * @param string $reference The new SP reference name.
200
+ * @param \Embera\Embera $emberaInstance The embera's instance where the SP will be registered in.
201
+ *
202
+ * @return boolean
203
+ */
204
+ public static function addServiceProvider($className, $reference, &$emberaInstance)
205
+ {
206
+ if (empty($className) || empty($reference)) {
207
+ return false;
208
+ }
209
+
210
+ if (is_string($reference)) {
211
+ $emberaInstance->addProvider($reference, EMBEDPRESS_NAMESPACE ."\\Providers\\{$className}");
212
+ } else if (is_array($reference)) {
213
+ foreach ($reference as $serviceProviderUrl) {
214
+ self::addServiceProvider($className, $serviceProviderUrl, $emberaInstance);
215
+ }
216
+ } else {
217
+ return false;
218
+ }
219
+ }
220
+
221
+ /**
222
+ * Method that retrieves all custom parameters from a shortcoded string.
223
+ *
224
+ * @since 1.0
225
+ * @static
226
+ *
227
+ * @param string $subject The given shortcoded string.
228
+ *
229
+ * @return array
230
+ */
231
+ public static function parseContentAttributesFromString($subject)
232
+ {
233
+ $customAttributes = array();
234
+ if (preg_match('/\[embed\s*(.*?)\]/i', stripslashes($subject), $m)) {
235
+ if (preg_match_all('/(\!?\w+-?\w*)(?:="(.+?)")?/i', stripslashes($m[1]), $matches)) {
236
+ $attributes = $matches[1];
237
+ $attrValues = $matches[2];
238
+
239
+ foreach ($attributes as $attrIndex => $attrName) {
240
+ $customAttributes[$attrName] = $attrValues[$attrIndex];
241
+ }
242
+ }
243
+ }
244
+
245
+ return $customAttributes;
246
+ }
247
+
248
+ /**
249
+ * Method that parses and adds the "data-" prefix to the given custom shortcode attributes.
250
+ *
251
+ * @since 1.0
252
+ * @static
253
+ *
254
+ * @param array $attributes The array containing the embed attributes.
255
+ *
256
+ * @return array
257
+ */
258
+ private static function parseContentAttributes(array $customAttributes)
259
+ {
260
+ $attributes = array(
261
+ 'class' => array("embedpress-wrapper")
262
+ );
263
+
264
+ $embedShouldBeResponsive = true;
265
+ $embedShouldHaveCustomDimensions = false;
266
+ if (!empty($customAttributes)) {
267
+ if (isset($customAttributes['class'])) {
268
+ if (!empty($customAttributes['class'])) {
269
+ $customAttributes['class'] = explode(' ', $customAttributes['class']);
270
+
271
+ $attributes['class'] = array_merge($attributes['class'], $customAttributes['class']);
272
+ }
273
+
274
+ unset($customAttributes['class']);
275
+ }
276
+
277
+ if (isset($customAttributes['width'])) {
278
+ if (!empty($customAttributes['width'])) {
279
+ $attributes['width'] = (int)$customAttributes['width'];
280
+ $embedShouldHaveCustomDimensions = true;
281
+ }
282
+ }
283
+
284
+ if (isset($customAttributes['height'])) {
285
+ if (!empty($customAttributes['height'])) {
286
+ $attributes['height'] = (int)$customAttributes['height'];
287
+ $embedShouldHaveCustomDimensions = true;
288
+ }
289
+ }
290
+
291
+ if (!empty($customAttributes)) {
292
+ $attrNameDefaultPrefix = "data-";
293
+ foreach ($customAttributes as $attrName => $attrValue) {
294
+ if (is_numeric($attrName)) {
295
+ $attrName = $attrValue;
296
+ $attrValue = "";
297
+ }
298
+
299
+ $attrName = str_replace($attrNameDefaultPrefix, "", $attrName);
300
+
301
+ if (!strlen($attrValue)) {
302
+ if ($attrName[0] === "!") {
303
+ $attrValue = "false";
304
+ $attrName = substr($attrName, 1);
305
+ } else {
306
+ $attrValue = "true";
307
+ }
308
+ }
309
+
310
+ $attributes[$attrNameDefaultPrefix . $attrName] = $attrValue;
311
+ }
312
+ }
313
+
314
+ // Check if there's any "responsive" parameter
315
+ $responsiveAttributes = array("responsive", "data-responsive");
316
+ foreach ($responsiveAttributes as $responsiveAttr) {
317
+ if (isset($attributes[$responsiveAttr])) {
318
+ if (!strlen($attributes[$responsiveAttr])) { // If the parameter is passed but have no value, it will be true by default
319
+ $embedShouldBeResponsive = true;
320
+ } else {
321
+ $embedShouldBeResponsive = !self::valueIsFalse($attributes[$responsiveAttr]);
322
+ }
323
+
324
+ break;
325
+ }
326
+ }
327
+ unset($responsiveAttr, $responsiveAttributes);
328
+ }
329
+
330
+ if ($embedShouldBeResponsive && !$embedShouldHaveCustomDimensions) {
331
+ $attributes['class'][] = 'ose-{provider_alias} responsive';
332
+ } else {
333
+ $attributes['data-responsive'] = "false";
334
+ }
335
+
336
+ $attributes['class'] = implode(' ', array_unique(array_filter($attributes['class'])));
337
+
338
+ return $attributes;
339
+ }
340
+
341
+ /**
342
+ * Method that checks if a given value is/can be identified as (bool)false.
343
+ *
344
+ * @since 1.0
345
+ * @static
346
+ *
347
+ * @param mixed $subject The value to be checked.
348
+ *
349
+ * @return boolean
350
+ */
351
+ public static function valueIsFalse($subject)
352
+ {
353
+ $subject = strtolower(trim((string)$subject));
354
+ switch ($subject) {
355
+ case "0":
356
+ case "false":
357
+ case "off":
358
+ case "no":
359
+ case "n":
360
+ case "nil":
361
+ case "null":
362
+ return true;
363
+ default:
364
+ return false;
365
+ }
366
+ }
367
+ }
EmbedPress/index.html ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>403 Forbidden</title>
5
+ </head>
6
+ <body>
7
+ <p>Directory access is forbidden.</p>
8
+ </body>
9
+ </html>
PROVIDERS.md ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Supported Sites
2
+ ===============
3
+ This is the complete list of supported providers.
4
+ Sites marked with an `*` allow offline html embedding.
5
+
6
+ - [23hq](http://23hq.com)
7
+ - [AmCharts](http://live.amcharts.com)
8
+ - [Animoto](http://animoto.com)
9
+ - * [Aol On](http://on.aol.com) (which is also [5min.com](http://5min.com))
10
+ - * [AudioSnaps](http://audiosnaps.com/)
11
+ - * [Bambuser](http://bambuser.com)
12
+ - * [Cacoo](http://cacoo.com)
13
+ - * [ChartBlocks](http://chartblocks.com)
14
+ - * [Chirbit](http://chirb.it)
15
+ - [Clyp](http://clyp.it)
16
+ - * [CircuitLab](https://www.circuitlab.com)
17
+ - * [CollegeHumor](http://www.collegehumor.com)
18
+ - * [Coub](http://coub.com)
19
+ - * [Crowd Ranking](http://crowdranking.com)
20
+ - [Daily Mile](http://dailymile.com)
21
+ - * [DailyMotion](http://www.dailymotion.com/)
22
+ - [Deviantart](http://deviantart.com)
23
+ - * [Dipity](http://dipity.com)
24
+ - * [Dotsub](http://dotsub.com)
25
+ - [Edocr](http://edocr.com)
26
+ - [EgliseInfo](http://egliseinfo.catholique.fr)
27
+ - [Flickr](http://flickr.com)
28
+ - * [Funny Or Die](http://www.funnyordie.com)
29
+ - [GettyImages](http://www.gettyimages.com)
30
+ - * [Github Gist](https://gist.github.com)
31
+ - * [Google Docs](http://docs.google.com)
32
+ - * [Google Maps](http://google.com/maps)
33
+ - [HuffDuffer](http://huffduffer.com)
34
+ - [Hulu](http://www.hulu.com)
35
+ - * [IFTTT](http://ifttt.com)
36
+ - [Infogram](https://infogr.am)
37
+ - [Instagram](http://instagram.com)
38
+ - * [Issuu](https://issuu.com) (Offline response available only when the url has the `e` parameter)
39
+ - * [Kickstarter](http://www.kickstarter.com)
40
+ - [Meetup](http://meetup.com)
41
+ - [MixCloud](http://mixcloud.com)
42
+ - [MobyPicture](http://mobypicture.com)
43
+ - * [NFB](http://www.nfb.ca)
44
+ - * [OfficialFM](http://official.fm)
45
+ - [Porfolium](https://portfolium.com)
46
+ - [Rapidengage](https://rapidengage.com/)
47
+ - [Rdio](http://rdio.com)
48
+ - [Release Wire](http://releasewire.com)
49
+ - [Reverbnation](https://www.reverbnation.com)
50
+ - [Roomshare](http://roomshare.jp)
51
+ - * [Sapo Videos](http://videos.sapo.pt)
52
+ - * [Scribd](http://www.scribd.com)
53
+ - * [ShortNote](https://www.shortnote.jp)
54
+ - * [Rutube](https://rutube.ru)
55
+ - [Shoudio](http://shoudio.com)
56
+ - * [Sketchfab](http://sketchfab.com)
57
+ - [SlideShare](http://www.slideshare.net)
58
+ - [SoundCloud](http://soundcloud.com)
59
+ - [SpeakerDeck](https://speackerdeck.com)
60
+ - * [Spotify](http://spotify.com)
61
+ - * [Ted](http://ted.com)
62
+ - [Twitter](https://twitter.com)
63
+ - [Ustream](http://ustream.tv)
64
+ - * [Viddler](http://www.viddler.com)
65
+ - [VideoJug](http://www.videojug.com)
66
+ - * [Vimeo](http://vimeo.com/)
67
+ - * [Vine](http://vine.co/)
68
+ - * [Youtube](http://www.youtube.com/)
69
+ - [Facebook](https://www.facebook.com)
assets/bootstrap.config.json ADDED
@@ -0,0 +1,400 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "vars": {
3
+ "@gray-base": "#000",
4
+ "@gray-darker": "lighten(@gray-base, 13.5%)",
5
+ "@gray-dark": "lighten(@gray-base, 20%)",
6
+ "@gray": "lighten(@gray-base, 33.5%)",
7
+ "@gray-light": "lighten(@gray-base, 46.7%)",
8
+ "@gray-lighter": "lighten(@gray-base, 93.5%)",
9
+ "@brand-primary": "darken(#428bca, 6.5%)",
10
+ "@brand-success": "#5cb85c",
11
+ "@brand-info": "#5bc0de",
12
+ "@brand-warning": "#f0ad4e",
13
+ "@brand-danger": "#d9534f",
14
+ "@body-bg": "transparent",
15
+ "@text-color": "@gray-dark",
16
+ "@link-color": "@brand-primary",
17
+ "@link-hover-color": "darken(@link-color, 15%)",
18
+ "@link-hover-decoration": "underline",
19
+ "@font-family-sans-serif": "\"Helvetica Neue\", Helvetica, Arial, sans-serif",
20
+ "@font-family-serif": "Georgia, \"Times New Roman\", Times, serif",
21
+ "@font-family-monospace": "Menlo, Monaco, Consolas, \"Courier New\", monospace",
22
+ "@font-family-base": "@font-family-sans-serif",
23
+ "@font-size-base": "14px",
24
+ "@font-size-large": "ceil((@font-size-base * 1.25))",
25
+ "@font-size-small": "ceil((@font-size-base * 0.85))",
26
+ "@font-size-h1": "floor((@font-size-base * 2.6))",
27
+ "@font-size-h2": "floor((@font-size-base * 2.15))",
28
+ "@font-size-h3": "ceil((@font-size-base * 1.7))",
29
+ "@font-size-h4": "ceil((@font-size-base * 1.25))",
30
+ "@font-size-h5": "@font-size-base",
31
+ "@font-size-h6": "ceil((@font-size-base * 0.85))",
32
+ "@line-height-base": "1.428571429",
33
+ "@line-height-computed": "floor((@font-size-base * @line-height-base))",
34
+ "@headings-font-family": "inherit",
35
+ "@headings-font-weight": "500",
36
+ "@headings-line-height": "1.1",
37
+ "@headings-color": "inherit",
38
+ "@icon-font-path": "\"../fonts/\"",
39
+ "@icon-font-name": "\"glyphicons-halflings-regular\"",
40
+ "@icon-font-svg-id": "\"glyphicons_halflingsregular\"",
41
+ "@padding-base-vertical": "6px",
42
+ "@padding-base-horizontal": "12px",
43
+ "@padding-large-vertical": "10px",
44
+ "@padding-large-horizontal": "16px",
45
+ "@padding-small-vertical": "5px",
46
+ "@padding-small-horizontal": "10px",
47
+ "@padding-xs-vertical": "1px",
48
+ "@padding-xs-horizontal": "5px",
49
+ "@line-height-large": "1.3333333",
50
+ "@line-height-small": "1.5",
51
+ "@border-radius-base": "4px",
52
+ "@border-radius-large": "6px",
53
+ "@border-radius-small": "3px",
54
+ "@component-active-color": "#fff",
55
+ "@component-active-bg": "@brand-primary",
56
+ "@caret-width-base": "4px",
57
+ "@caret-width-large": "5px",
58
+ "@table-cell-padding": "8px",
59
+ "@table-condensed-cell-padding": "5px",
60
+ "@table-bg": "transparent",
61
+ "@table-bg-accent": "#f9f9f9",
62
+ "@table-bg-hover": "#f5f5f5",
63
+ "@table-bg-active": "@table-bg-hover",
64
+ "@table-border-color": "#ddd",
65
+ "@btn-font-weight": "normal",
66
+ "@btn-default-color": "#333",
67
+ "@btn-default-bg": "#fff",
68
+ "@btn-default-border": "#ccc",
69
+ "@btn-primary-color": "#fff",
70
+ "@btn-primary-bg": "@brand-primary",
71
+ "@btn-primary-border": "darken(@btn-primary-bg, 5%)",
72
+ "@btn-success-color": "#fff",
73
+ "@btn-success-bg": "@brand-success",
74
+ "@btn-success-border": "darken(@btn-success-bg, 5%)",
75
+ "@btn-info-color": "#fff",
76
+ "@btn-info-bg": "@brand-info",
77
+ "@btn-info-border": "darken(@btn-info-bg, 5%)",
78
+ "@btn-warning-color": "#fff",
79
+ "@btn-warning-bg": "@brand-warning",
80
+ "@btn-warning-border": "darken(@btn-warning-bg, 5%)",
81
+ "@btn-danger-color": "#fff",
82
+ "@btn-danger-bg": "@brand-danger",
83
+ "@btn-danger-border": "darken(@btn-danger-bg, 5%)",
84
+ "@btn-link-disabled-color": "@gray-light",
85
+ "@btn-border-radius-base": "@border-radius-base",
86
+ "@btn-border-radius-large": "@border-radius-large",
87
+ "@btn-border-radius-small": "@border-radius-small",
88
+ "@input-bg": "#fff",
89
+ "@input-bg-disabled": "@gray-lighter",
90
+ "@input-color": "@gray",
91
+ "@input-border": "#ccc",
92
+ "@input-border-radius": "@border-radius-base",
93
+ "@input-border-radius-large": "@border-radius-large",
94
+ "@input-border-radius-small": "@border-radius-small",
95
+ "@input-border-focus": "#66afe9",
96
+ "@input-color-placeholder": "#999",
97
+ "@input-height-base": "(@line-height-computed + (@padding-base-vertical * 2) + 2)",
98
+ "@input-height-large": "(ceil(@font-size-large * @line-height-large) + (@padding-large-vertical * 2) + 2)",
99
+ "@input-height-small": "(floor(@font-size-small * @line-height-small) + (@padding-small-vertical * 2) + 2)",
100
+ "@form-group-margin-bottom": "15px",
101
+ "@legend-color": "@gray-dark",
102
+ "@legend-border-color": "#e5e5e5",
103
+ "@input-group-addon-bg": "@gray-lighter",
104
+ "@input-group-addon-border-color": "@input-border",
105
+ "@cursor-disabled": "not-allowed",
106
+ "@dropdown-bg": "#fff",
107
+ "@dropdown-border": "rgba(0,0,0,.15)",
108
+ "@dropdown-fallback-border": "#ccc",
109
+ "@dropdown-divider-bg": "#e5e5e5",
110
+ "@dropdown-link-color": "@gray-dark",
111
+ "@dropdown-link-hover-color": "darken(@gray-dark, 5%)",
112
+ "@dropdown-link-hover-bg": "#f5f5f5",
113
+ "@dropdown-link-active-color": "@component-active-color",
114
+ "@dropdown-link-active-bg": "@component-active-bg",
115
+ "@dropdown-link-disabled-color": "@gray-light",
116
+ "@dropdown-header-color": "@gray-light",
117
+ "@dropdown-caret-color": "#000",
118
+ "@screen-xs": "480px",
119
+ "@screen-xs-min": "@screen-xs",
120
+ "@screen-phone": "@screen-xs-min",
121
+ "@screen-sm": "768px",
122
+ "@screen-sm-min": "@screen-sm",
123
+ "@screen-tablet": "@screen-sm-min",
124
+ "@screen-md": "992px",
125
+ "@screen-md-min": "@screen-md",
126
+ "@screen-desktop": "@screen-md-min",
127
+ "@screen-lg": "1200px",
128
+ "@screen-lg-min": "@screen-lg",
129
+ "@screen-lg-desktop": "@screen-lg-min",
130
+ "@screen-xs-max": "(@screen-sm-min - 1)",
131
+ "@screen-sm-max": "(@screen-md-min - 1)",
132
+ "@screen-md-max": "(@screen-lg-min - 1)",
133
+ "@grid-columns": "12",
134
+ "@grid-gutter-width": "30px",
135
+ "@grid-float-breakpoint": "@screen-sm-min",
136
+ "@grid-float-breakpoint-max": "(@grid-float-breakpoint - 1)",
137
+ "@container-tablet": "(720px + @grid-gutter-width)",
138
+ "@container-sm": "@container-tablet",
139
+ "@container-desktop": "(940px + @grid-gutter-width)",
140
+ "@container-md": "@container-desktop",
141
+ "@container-large-desktop": "(1140px + @grid-gutter-width)",
142
+ "@container-lg": "@container-large-desktop",
143
+ "@navbar-height": "50px",
144
+ "@navbar-margin-bottom": "@line-height-computed",
145
+ "@navbar-border-radius": "@border-radius-base",
146
+ "@navbar-padding-horizontal": "floor((@grid-gutter-width / 2))",
147
+ "@navbar-padding-vertical": "((@navbar-height - @line-height-computed) / 2)",
148
+ "@navbar-collapse-max-height": "340px",
149
+ "@navbar-default-color": "#777",
150
+ "@navbar-default-bg": "#f8f8f8",
151
+ "@navbar-default-border": "darken(@navbar-default-bg, 6.5%)",
152
+ "@navbar-default-link-color": "#777",
153
+ "@navbar-default-link-hover-color": "#333",
154
+ "@navbar-default-link-hover-bg": "transparent",
155
+ "@navbar-default-link-active-color": "#555",
156
+ "@navbar-default-link-active-bg": "darken(@navbar-default-bg, 6.5%)",
157
+ "@navbar-default-link-disabled-color": "#ccc",
158
+ "@navbar-default-link-disabled-bg": "transparent",
159
+ "@navbar-default-brand-color": "@navbar-default-link-color",
160
+ "@navbar-default-brand-hover-color": "darken(@navbar-default-brand-color, 10%)",
161
+ "@navbar-default-brand-hover-bg": "transparent",
162
+ "@navbar-default-toggle-hover-bg": "#ddd",
163
+ "@navbar-default-toggle-icon-bar-bg": "#888",
164
+ "@navbar-default-toggle-border-color": "#ddd",
165
+ "@navbar-inverse-color": "lighten(@gray-light, 15%)",
166
+ "@navbar-inverse-bg": "#222",
167
+ "@navbar-inverse-border": "darken(@navbar-inverse-bg, 10%)",
168
+ "@navbar-inverse-link-color": "lighten(@gray-light, 15%)",
169
+ "@navbar-inverse-link-hover-color": "#fff",
170
+ "@navbar-inverse-link-hover-bg": "transparent",
171
+ "@navbar-inverse-link-active-color": "@navbar-inverse-link-hover-color",
172
+ "@navbar-inverse-link-active-bg": "darken(@navbar-inverse-bg, 10%)",
173
+ "@navbar-inverse-link-disabled-color": "#444",
174
+ "@navbar-inverse-link-disabled-bg": "transparent",
175
+ "@navbar-inverse-brand-color": "@navbar-inverse-link-color",
176
+ "@navbar-inverse-brand-hover-color": "#fff",
177
+ "@navbar-inverse-brand-hover-bg": "transparent",
178
+ "@navbar-inverse-toggle-hover-bg": "#333",
179
+ "@navbar-inverse-toggle-icon-bar-bg": "#fff",
180
+ "@navbar-inverse-toggle-border-color": "#333",
181
+ "@nav-link-padding": "10px 15px",
182
+ "@nav-link-hover-bg": "@gray-lighter",
183
+ "@nav-disabled-link-color": "@gray-light",
184
+ "@nav-disabled-link-hover-color": "@gray-light",
185
+ "@nav-tabs-border-color": "#ddd",
186
+ "@nav-tabs-link-hover-border-color": "@gray-lighter",
187
+ "@nav-tabs-active-link-hover-bg": "@body-bg",
188
+ "@nav-tabs-active-link-hover-color": "@gray",
189
+ "@nav-tabs-active-link-hover-border-color": "#ddd",
190
+ "@nav-tabs-justified-link-border-color": "#ddd",
191
+ "@nav-tabs-justified-active-link-border-color": "@body-bg",
192
+ "@nav-pills-border-radius": "@border-radius-base",
193
+ "@nav-pills-active-link-hover-bg": "@component-active-bg",
194
+ "@nav-pills-active-link-hover-color": "@component-active-color",
195
+ "@pagination-color": "@link-color",
196
+ "@pagination-bg": "#fff",
197
+ "@pagination-border": "#ddd",
198
+ "@pagination-hover-color": "@link-hover-color",
199
+ "@pagination-hover-bg": "@gray-lighter",
200
+ "@pagination-hover-border": "#ddd",
201
+ "@pagination-active-color": "#fff",
202
+ "@pagination-active-bg": "@brand-primary",
203
+ "@pagination-active-border": "@brand-primary",
204
+ "@pagination-disabled-color": "@gray-light",
205
+ "@pagination-disabled-bg": "#fff",
206
+ "@pagination-disabled-border": "#ddd",
207
+ "@pager-bg": "@pagination-bg",
208
+ "@pager-border": "@pagination-border",
209
+ "@pager-border-radius": "15px",
210
+ "@pager-hover-bg": "@pagination-hover-bg",
211
+ "@pager-active-bg": "@pagination-active-bg",
212
+ "@pager-active-color": "@pagination-active-color",
213
+ "@pager-disabled-color": "@pagination-disabled-color",
214
+ "@jumbotron-padding": "30px",
215
+ "@jumbotron-color": "inherit",
216
+ "@jumbotron-bg": "@gray-lighter",
217
+ "@jumbotron-heading-color": "inherit",
218
+ "@jumbotron-font-size": "ceil((@font-size-base * 1.5))",
219
+ "@jumbotron-heading-font-size": "ceil((@font-size-base * 4.5))",
220
+ "@state-success-text": "#3c763d",
221
+ "@state-success-bg": "#dff0d8",
222
+ "@state-success-border": "darken(spin(@state-success-bg, -10), 5%)",
223
+ "@state-info-text": "#31708f",
224
+ "@state-info-bg": "#d9edf7",
225
+ "@state-info-border": "darken(spin(@state-info-bg, -10), 7%)",
226
+ "@state-warning-text": "#8a6d3b",
227
+ "@state-warning-bg": "#fcf8e3",
228
+ "@state-warning-border": "darken(spin(@state-warning-bg, -10), 5%)",
229
+ "@state-danger-text": "#a94442",
230
+ "@state-danger-bg": "#f2dede",
231
+ "@state-danger-border": "darken(spin(@state-danger-bg, -10), 5%)",
232
+ "@tooltip-max-width": "200px",
233
+ "@tooltip-color": "#fff",
234
+ "@tooltip-bg": "#000",
235
+ "@tooltip-opacity": ".9",
236
+ "@tooltip-arrow-width": "5px",
237
+ "@tooltip-arrow-color": "@tooltip-bg",
238
+ "@popover-bg": "#fff",
239
+ "@popover-max-width": "276px",
240
+ "@popover-border-color": "rgba(0,0,0,.2)",
241
+ "@popover-fallback-border-color": "#ccc",
242
+ "@popover-title-bg": "darken(@popover-bg, 3%)",
243
+ "@popover-arrow-width": "10px",
244
+ "@popover-arrow-color": "@popover-bg",
245
+ "@popover-arrow-outer-width": "(@popover-arrow-width + 1)",
246
+ "@popover-arrow-outer-color": "fadein(@popover-border-color, 5%)",
247
+ "@popover-arrow-outer-fallback-color": "darken(@popover-fallback-border-color, 20%)",
248
+ "@label-default-bg": "@gray-light",
249
+ "@label-primary-bg": "@brand-primary",
250
+ "@label-success-bg": "@brand-success",
251
+ "@label-info-bg": "@brand-info",
252
+ "@label-warning-bg": "@brand-warning",
253
+ "@label-danger-bg": "@brand-danger",
254
+ "@label-color": "#fff",
255
+ "@label-link-hover-color": "#fff",
256
+ "@modal-inner-padding": "15px",
257
+ "@modal-title-padding": "15px",
258
+ "@modal-title-line-height": "@line-height-base",
259
+ "@modal-content-bg": "#fff",
260
+ "@modal-content-border-color": "rgba(0,0,0,.2)",
261
+ "@modal-content-fallback-border-color": "#999",
262
+ "@modal-backdrop-bg": "#000",
263
+ "@modal-backdrop-opacity": ".5",
264
+ "@modal-header-border-color": "#e5e5e5",
265
+ "@modal-footer-border-color": "@modal-header-border-color",
266
+ "@modal-lg": "900px",
267
+ "@modal-md": "600px",
268
+ "@modal-sm": "300px",
269
+ "@alert-padding": "15px",
270
+ "@alert-border-radius": "@border-radius-base",
271
+ "@alert-link-font-weight": "bold",
272
+ "@alert-success-bg": "@state-success-bg",
273
+ "@alert-success-text": "@state-success-text",
274
+ "@alert-success-border": "@state-success-border",
275
+ "@alert-info-bg": "@state-info-bg",
276
+ "@alert-info-text": "@state-info-text",
277
+ "@alert-info-border": "@state-info-border",
278
+ "@alert-warning-bg": "@state-warning-bg",
279
+ "@alert-warning-text": "@state-warning-text",
280
+ "@alert-warning-border": "@state-warning-border",
281
+ "@alert-danger-bg": "@state-danger-bg",
282
+ "@alert-danger-text": "@state-danger-text",
283
+ "@alert-danger-border": "@state-danger-border",
284
+ "@progress-bg": "#f5f5f5",
285
+ "@progress-bar-color": "#fff",
286
+ "@progress-border-radius": "@border-radius-base",
287
+ "@progress-bar-bg": "@brand-primary",
288
+ "@progress-bar-success-bg": "@brand-success",
289
+ "@progress-bar-warning-bg": "@brand-warning",
290
+ "@progress-bar-danger-bg": "@brand-danger",
291
+ "@progress-bar-info-bg": "@brand-info",
292
+ "@list-group-bg": "#fff",
293
+ "@list-group-border": "#ddd",
294
+ "@list-group-border-radius": "@border-radius-base",
295
+ "@list-group-hover-bg": "#f5f5f5",
296
+ "@list-group-active-color": "@component-active-color",
297
+ "@list-group-active-bg": "@component-active-bg",
298
+ "@list-group-active-border": "@list-group-active-bg",
299
+ "@list-group-active-text-color": "lighten(@list-group-active-bg, 40%)",
300
+ "@list-group-disabled-color": "@gray-light",
301
+ "@list-group-disabled-bg": "@gray-lighter",
302
+ "@list-group-disabled-text-color": "@list-group-disabled-color",
303
+ "@list-group-link-color": "#555",
304
+ "@list-group-link-hover-color": "@list-group-link-color",
305
+ "@list-group-link-heading-color": "#333",
306
+ "@panel-bg": "#fff",
307
+ "@panel-body-padding": "15px",
308
+ "@panel-heading-padding": "10px 15px",
309
+ "@panel-footer-padding": "@panel-heading-padding",
310
+ "@panel-border-radius": "@border-radius-base",
311
+ "@panel-inner-border": "#ddd",
312
+ "@panel-footer-bg": "#f5f5f5",
313
+ "@panel-default-text": "@gray-dark",
314
+ "@panel-default-border": "#ddd",
315
+ "@panel-default-heading-bg": "#f5f5f5",
316
+ "@panel-primary-text": "#fff",
317
+ "@panel-primary-border": "@brand-primary",
318
+ "@panel-primary-heading-bg": "@brand-primary",
319
+ "@panel-success-text": "@state-success-text",
320
+ "@panel-success-border": "@state-success-border",
321
+ "@panel-success-heading-bg": "@state-success-bg",
322
+ "@panel-info-text": "@state-info-text",
323
+ "@panel-info-border": "@state-info-border",
324
+ "@panel-info-heading-bg": "@state-info-bg",
325
+ "@panel-warning-text": "@state-warning-text",
326
+ "@panel-warning-border": "@state-warning-border",
327
+ "@panel-warning-heading-bg": "@state-warning-bg",
328
+ "@panel-danger-text": "@state-danger-text",
329
+ "@panel-danger-border": "@state-danger-border",
330
+ "@panel-danger-heading-bg": "@state-danger-bg",
331
+ "@thumbnail-padding": "4px",
332
+ "@thumbnail-bg": "@body-bg",
333
+ "@thumbnail-border": "#ddd",
334
+ "@thumbnail-border-radius": "@border-radius-base",
335
+ "@thumbnail-caption-color": "@text-color",
336
+ "@thumbnail-caption-padding": "9px",
337
+ "@well-bg": "#f5f5f5",
338
+ "@well-border": "darken(@well-bg, 7%)",
339
+ "@badge-color": "#fff",
340
+ "@badge-link-hover-color": "#fff",
341
+ "@badge-bg": "@gray-light",
342
+ "@badge-active-color": "@link-color",
343
+ "@badge-active-bg": "#fff",
344
+ "@badge-font-weight": "bold",
345
+ "@badge-line-height": "1",
346
+ "@badge-border-radius": "10px",
347
+ "@breadcrumb-padding-vertical": "8px",
348
+ "@breadcrumb-padding-horizontal": "15px",
349
+ "@breadcrumb-bg": "#f5f5f5",
350
+ "@breadcrumb-color": "#ccc",
351
+ "@breadcrumb-active-color": "@gray-light",
352
+ "@breadcrumb-separator": "\"/\"",
353
+ "@carousel-text-shadow": "0 1px 2px rgba(0,0,0,.6)",
354
+ "@carousel-control-color": "#fff",
355
+ "@carousel-control-width": "15%",
356
+ "@carousel-control-opacity": ".5",
357
+ "@carousel-control-font-size": "20px",
358
+ "@carousel-indicator-active-bg": "#fff",
359
+ "@carousel-indicator-border-color": "#fff",
360
+ "@carousel-caption-color": "#fff",
361
+ "@close-font-weight": "bold",
362
+ "@close-color": "#000",
363
+ "@close-text-shadow": "0 1px 0 #fff",
364
+ "@code-color": "#c7254e",
365
+ "@code-bg": "#f9f2f4",
366
+ "@kbd-color": "#fff",
367
+ "@kbd-bg": "#333",
368
+ "@pre-bg": "#f5f5f5",
369
+ "@pre-color": "@gray-dark",
370
+ "@pre-border-color": "#ccc",
371
+ "@pre-scrollable-max-height": "340px",
372
+ "@component-offset-horizontal": "180px",
373
+ "@text-muted": "@gray-light",
374
+ "@abbr-border-color": "@gray-light",
375
+ "@headings-small-color": "@gray-light",
376
+ "@blockquote-small-color": "@gray-light",
377
+ "@blockquote-font-size": "(@font-size-base * 1.25)",
378
+ "@blockquote-border-color": "@gray-lighter",
379
+ "@page-header-border-color": "@gray-lighter",
380
+ "@dl-horizontal-offset": "@component-offset-horizontal",
381
+ "@dl-horizontal-breakpoint": "@grid-float-breakpoint",
382
+ "@hr-border": "@gray-lighter"
383
+ },
384
+ "css": [
385
+ "grid.less",
386
+ "forms.less",
387
+ "buttons.less",
388
+ "responsive-utilities.less",
389
+ "button-groups.less",
390
+ "input-groups.less",
391
+ "close.less",
392
+ "component-animations.less",
393
+ "modals.less"
394
+ ],
395
+ "js": [
396
+ "modal.js",
397
+ "transition.js"
398
+ ],
399
+ "customizerUrl": "http://getbootstrap.com/customize/?id=f9591b2f58105c5fa28db0e6eba864bd"
400
+ }
assets/css/embedpress.css ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * @package EmbedPress
3
+ * @author PressShack <help@pressshack.com>
4
+ * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
5
+ * @license GPLv2 or later
6
+ * @since 1.0
7
+ */
8
+
9
+ .ose-dailymotion.responsive,
10
+ .ose-kickstarter.responsive,
11
+ .ose-rutube.responsive,
12
+ .ose-ted.responsive,
13
+ .ose-vimeo.responsive,
14
+ .ose-youtube.responsive,
15
+ .ose-ustream.responsive,
16
+ .ose-google-docs.responsive,
17
+ .ose-animatron.responsive,
18
+ .ose-amcharts.responsive,
19
+ .ose-on-aol-com.responsive,
20
+ .ose-animoto.responsive,
21
+ .ose-videojug.responsive {
22
+ overflow: hidden;
23
+ position: relative;
24
+ height: 0;
25
+ }
26
+
27
+ .ose-dailymotion.responsive iframe,
28
+ .ose-kickstarter.responsive iframe,
29
+ .ose-rutube.responsive iframe,
30
+ .ose-ted.responsive iframe,
31
+ .ose-vimeo.responsive iframe,
32
+ .ose-vine.responsive iframe,
33
+ .ose-youtube.responsive iframe,
34
+ .ose-ustream.responsive iframe,
35
+ .ose-google-docs.responsive iframe,
36
+ .ose-animatron.responsive iframe,
37
+ .ose-amcharts.responsive iframe,
38
+ .ose-on-aol-com.responsive iframe,
39
+ .ose-animoto.responsive iframe,
40
+ .ose-videojug.responsive iframe {
41
+ left: 0;
42
+ top: 0;
43
+ height: 100%;
44
+ width: 100%;
45
+ position: absolute;
46
+ }
47
+
48
+ /* 16:9 aspect ratio */
49
+ .ose-dailymotion.responsive,
50
+ .ose-kickstarter.responsive,
51
+ .ose-rutube.responsive,
52
+ .ose-ted.responsive,
53
+ .ose-vimeo.responsive,
54
+ .ose-youtube.responsive,
55
+ .ose-animatron.responsive,
56
+ .ose-amcharts.responsive,
57
+ .ose-on-aol-com.responsive,
58
+ .ose-animoto.responsive,
59
+ .ose-videojug.responsive {
60
+ padding-bottom: 56.25%;
61
+ }
62
+
63
+ /* 1:1 aspect ratio */
64
+ .ose-vine.responsive {
65
+ padding-bottom: 100%;
66
+ }
67
+
68
+ /* Mixed aspect ratio */
69
+ .ose-ustream.responsive {
70
+ padding-bottom: 63.3%;
71
+ }
72
+
73
+ .ose-google-docs.responsive {
74
+ padding-bottom: 62.6%;
75
+ }
76
+
77
+ .ose-google-docs.ose-google-docs-drawings.responsive {
78
+ padding-bottom: 74.5%;
79
+ }
80
+
81
+ .ose-google-docs.ose-google-docs-document.responsive,
82
+ .ose-google-docs.ose-google-docs-forms.responsive,
83
+ .ose-google-docs.ose-google-docs-spreadsheets.responsive {
84
+ padding-bottom: 142%;
85
+ }
assets/css/font.css ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * @package EmbedPress
3
+ * @author PressShack <help@pressshack.com>
4
+ * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
5
+ * @license GPLv2 or later
6
+ * @since 1.0
7
+ */
8
+
9
+ @font-face {
10
+ font-family: 'EmbedPress';
11
+ src: url('../fonts/embedpress.eot?80956116');
12
+ src: url('../fonts/embedpress.eot?80956116#iefix') format('embedded-opentype'),
13
+ url('../fonts/embedpress.woff?80956116') format('woff'),
14
+ url('../fonts/embedpress.ttf?80956116') format('truetype'),
15
+ url('../fonts/embedpress.svg?80956116#embedpress') format('svg');
16
+ font-weight: normal;
17
+ font-style: normal;
18
+ }
19
+ /* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
20
+ /* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
21
+ /*
22
+ @media screen and (-webkit-min-device-pixel-ratio:0) {
23
+ @font-face {
24
+ font-family: 'embedpress';
25
+ src: url('../font/embedpress.svg?80956116#embedpress') format('svg');
26
+ }
27
+ }
28
+ */
29
+
30
+ [class^="embedpress-icon-"]:before, [class*=" embedpress-icon-"]:before {
31
+ font-family: "EmbedPress";
32
+ font-style: normal;
33
+ font-weight: normal;
34
+ speak: none;
35
+
36
+ display: inline-block;
37
+ text-decoration: inherit;
38
+ width: 1em;
39
+ margin-right: .2em;
40
+ text-align: center;
41
+ /* opacity: .8; */
42
+
43
+ /* For safety - reset parent styles, that can break glyph codes*/
44
+ font-variant: normal;
45
+ text-transform: none;
46
+
47
+ /* fix buttons height, for twitter bootstrap */
48
+ line-height: 1em;
49
+
50
+ /* Animation center compensation - margins should be symmetric */
51
+ /* remove if not needed */
52
+ margin-left: .2em;
53
+
54
+ /* you can be more comfortable with increased icons size */
55
+ /* font-size: 120%; */
56
+
57
+ /* Font smoothing. That was taken from TWBS */
58
+ -webkit-font-smoothing: antialiased;
59
+ -moz-osx-font-smoothing: grayscale;
60
+
61
+ /* Uncomment for 3D effect */
62
+ /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
63
+ }
64
+
65
+ .embedpress-icon-pencil:before {content:'\0041';}
66
+ .embedpress-icon-gear:before{content:'\0042';}
67
+ .embedpress-icon-x:before{content:'\0043';}
68
+
69
+ .embedpress-icon-reload {
70
+ -webkit-animation: embedpress-spin 2s infinite linear;
71
+ animation: embedpress-spin 2s infinite linear;
72
+ }
73
+ .embedpress-icon-reload:before{content:'\0044';}
74
+
75
+ @-webkit-keyframes embedpress-spin {
76
+ 0% {
77
+ -webkit-transform: rotate(0deg);
78
+ transform: rotate(0deg);
79
+ }
80
+ 100% {
81
+ -webkit-transform: rotate(359deg);
82
+ transform: rotate(359deg);
83
+ }
84
+ }
85
+ @keyframes embedpress-spin {
86
+ 0% {
87
+ -webkit-transform: rotate(0deg);
88
+ transform: rotate(0deg);
89
+ }
90
+ 100% {
91
+ -webkit-transform: rotate(359deg);
92
+ transform: rotate(359deg);
93
+ }
94
+ }
assets/css/index.html ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>403 Forbidden</title>
5
+ </head>
6
+ <body>
7
+ <p>Directory access is forbidden.</p>
8
+ </body>
9
+ </html>
assets/css/preview.css ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * @package EmbedPress
3
+ * @author PressShack <help@pressshack.com>
4
+ * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
5
+ * @license GPLv2 or later
6
+ * @since 1.0
7
+ */
8
+
9
+ .embedpress_wrapper {
10
+ position: relative;
11
+ padding: 1px;
12
+ overflow: hidden;
13
+ text-overflow: ellipsis;
14
+ white-space: nowrap;
15
+ }
16
+
17
+ .embedpress_wrapper.dynamic-width {
18
+ display: inline-block;
19
+ }
20
+
21
+ .embedpress_wrapper .loader-indicator {
22
+ width: 100%;
23
+ height: 100%;
24
+ position: absolute;
25
+ top: 0;
26
+ left: 0;
27
+ background-color: rgba(255, 255, 255, .7);
28
+ display: flex;
29
+ justify-content: center;
30
+ align-items: center;
31
+ z-index: 9999999;
32
+ pointer-events: none;
33
+ opacity: 0;
34
+ -webkit-transition: all 250ms ease-in;
35
+ -moz-transition: all 250ms ease-in;
36
+ -o-transition: all 250ms ease-in;
37
+ transition: all 250ms ease-in;
38
+ }
39
+
40
+ .embedpress_wrapper .loader-indicator.is-loading {
41
+ -webkit-transition: all 500ms ease-out;
42
+ -moz-transition: all 500ms ease-out;
43
+ -o-transition: all 500ms ease-out;
44
+ transition: all 500ms ease-out;
45
+ opacity: 1;
46
+ }
47
+
48
+ .embedpress_controller_panel {
49
+ display: inline-block;
50
+ position: absolute;
51
+ padding: 8px;
52
+ margin-left: -45px;
53
+ width: 62px;
54
+ top: 1px;
55
+ left: 50%;
56
+ background: #075c97;
57
+ border: 1px solid rgba(207, 235, 255, 0.8);
58
+ -webkit-box-shadow: 0px 10px 44px -5px rgba(0,0,0,0.66);
59
+ -moz-box-shadow: 0px 10px 44px -5px rgba(0,0,0,0.66);
60
+ box-shadow: 0px 10px 44px -5px rgba(0,0,0,0.66);
61
+ z-index: 999999;
62
+ }
63
+
64
+ .embedpress_controller_panel div.embedpress_controller_button {
65
+ color: #fff;
66
+ margin: 0 5px;
67
+ font-size: 15px;
68
+ cursor: pointer;
69
+ display: inline-block;
70
+ width: 20px;
71
+ }
72
+
73
+ .embedpress_controller_panel div.embedpress_controller_button:hover {
74
+ text-decoration: none;
75
+ color: #ccc;
76
+ }
77
+
78
+ .embedpress_controller_panel.hidden {
79
+ visibility: hidden;
80
+ }
81
+
82
+ .embedpress_wrapper.embedpress_placeholder {
83
+ display: block;
84
+ padding: 10px;
85
+ background: #cbC5e3;
86
+ border: 1px solid #427F7f;
87
+ height: 120px;
88
+ width: 450px;
89
+ text-align: center;
90
+ box-sizing: border-box;
91
+ color: #000;
92
+ }
93
+
94
+ .embedpress_wrapper.embedpress_placeholder:before {
95
+ content: attr(data-loading-text);
96
+ display: block;
97
+ margin-top: 30px;
98
+ margin-bottom: 7px;
99
+ font-weight: bold;
100
+ }
101
+
102
+ .embedpress_wrapper.embedpress_placeholder:after {
103
+ content: attr(data-url);
104
+ overflow: hidden;
105
+ text-overflow: ellipsis;
106
+ white-space: nowrap;
107
+ font-style: italic;
108
+ font-size: 11px;
109
+ }
110
+
111
+ .embedpress_wrapper img {
112
+ max-width: 100%;
113
+ width: auto \9;
114
+ height: auto;
115
+ vertical-align: middle;
116
+ border: 0;
117
+ }
118
+
119
+ .modal {
120
+ text-align: center;
121
+ }
122
+
123
+ @media screen and (min-width: 768px) {
124
+ .modal:before {
125
+ display: inline-block;
126
+ vertical-align: middle;
127
+ content: " ";
128
+ height: 100%;
129
+ }
130
+ }
131
+
132
+ .modal-dialog {
133
+ display: inline-block;
134
+ text-align: left;
135
+ vertical-align: middle;
136
+ }
137
+
138
+ span.hidden {
139
+ display: none;
140
+ }
141
+
142
+ .bootbox.modal {
143
+ z-index: 100002;
144
+ }
assets/css/vendor/bootstrap/bootstrap.css ADDED
@@ -0,0 +1,2733 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Bootstrap v3.3.5 (http://getbootstrap.com)
3
+ * Copyright 2011-2016 Twitter, Inc.
4
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5
+ */
6
+
7
+ /*!
8
+ * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=f9591b2f58105c5fa28db0e6eba864bd)
9
+ * Config saved to config.json and https://gist.github.com/f9591b2f58105c5fa28db0e6eba864bd
10
+ */
11
+ /*!
12
+ * Bootstrap v3.3.6 (http://getbootstrap.com)
13
+ * Copyright 2011-2015 Twitter, Inc.
14
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
15
+ */
16
+ /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
17
+ html {
18
+ font-family: sans-serif;
19
+ -ms-text-size-adjust: 100%;
20
+ -webkit-text-size-adjust: 100%;
21
+ }
22
+ body {
23
+ margin: 0;
24
+ }
25
+ article,
26
+ aside,
27
+ details,
28
+ figcaption,
29
+ figure,
30
+ footer,
31
+ header,
32
+ hgroup,
33
+ main,
34
+ menu,
35
+ nav,
36
+ section,
37
+ summary {
38
+ display: block;
39
+ }
40
+ audio,
41
+ canvas,
42
+ progress,
43
+ video {
44
+ display: inline-block;
45
+ vertical-align: baseline;
46
+ }
47
+ audio:not([controls]) {
48
+ display: none;
49
+ height: 0;
50
+ }
51
+ [hidden],
52
+ template {
53
+ display: none;
54
+ }
55
+ a {
56
+ background-color: transparent;
57
+ }
58
+ a:active,
59
+ a:hover {
60
+ outline: 0;
61
+ }
62
+ abbr[title] {
63
+ border-bottom: 1px dotted;
64
+ }
65
+ b,
66
+ strong {
67
+ font-weight: bold;
68
+ }
69
+ dfn {
70
+ font-style: italic;
71
+ }
72
+ h1 {
73
+ font-size: 2em;
74
+ margin: 0.67em 0;
75
+ }
76
+ mark {
77
+ background: #ff0;
78
+ color: #000;
79
+ }
80
+ small {
81
+ font-size: 80%;
82
+ }
83
+ sub,
84
+ sup {
85
+ font-size: 75%;
86
+ line-height: 0;
87
+ position: relative;
88
+ vertical-align: baseline;
89
+ }
90
+ sup {
91
+ top: -0.5em;
92
+ }
93
+ sub {
94
+ bottom: -0.25em;
95
+ }
96
+ img {
97
+ border: 0;
98
+ }
99
+ svg:not(:root) {
100
+ overflow: hidden;
101
+ }
102
+ figure {
103
+ margin: 1em 40px;
104
+ }
105
+ hr {
106
+ -webkit-box-sizing: content-box;
107
+ -moz-box-sizing: content-box;
108
+ box-sizing: content-box;
109
+ height: 0;
110
+ }
111
+ pre {
112
+ overflow: auto;
113
+ }
114
+ code,
115
+ kbd,
116
+ pre,
117
+ samp {
118
+ font-family: monospace, monospace;
119
+ font-size: 1em;
120
+ }
121
+ button,
122
+ input,
123
+ optgroup,
124
+ select,
125
+ textarea {
126
+ color: inherit;
127
+ font: inherit;
128
+ margin: 0;
129
+ }
130
+ button {
131
+ overflow: visible;
132
+ }
133
+ button,
134
+ select {
135
+ text-transform: none;
136
+ }
137
+ button,
138
+ html input[type="button"],
139
+ input[type="reset"],
140
+ input[type="submit"] {
141
+ -webkit-appearance: button;
142
+ cursor: pointer;
143
+ }
144
+ button[disabled],
145
+ html input[disabled] {
146
+ cursor: default;
147
+ }
148
+ button::-moz-focus-inner,
149
+ input::-moz-focus-inner {
150
+ border: 0;
151
+ padding: 0;
152
+ }
153
+ input {
154
+ line-height: normal;
155
+ }
156
+ input[type="checkbox"],
157
+ input[type="radio"] {
158
+ -webkit-box-sizing: border-box;
159
+ -moz-box-sizing: border-box;
160
+ box-sizing: border-box;
161
+ padding: 0;
162
+ }
163
+ input[type="number"]::-webkit-inner-spin-button,
164
+ input[type="number"]::-webkit-outer-spin-button {
165
+ height: auto;
166
+ }
167
+ input[type="search"] {
168
+ -webkit-appearance: textfield;
169
+ -webkit-box-sizing: content-box;
170
+ -moz-box-sizing: content-box;
171
+ box-sizing: content-box;
172
+ }
173
+ input[type="search"]::-webkit-search-cancel-button,
174
+ input[type="search"]::-webkit-search-decoration {
175
+ -webkit-appearance: none;
176
+ }
177
+ fieldset {
178
+ border: 1px solid #c0c0c0;
179
+ margin: 0 2px;
180
+ padding: 0.35em 0.625em 0.75em;
181
+ }
182
+ legend {
183
+ border: 0;
184
+ padding: 0;
185
+ }
186
+ textarea {
187
+ overflow: auto;
188
+ }
189
+ optgroup {
190
+ font-weight: bold;
191
+ }
192
+ table {
193
+ border-collapse: collapse;
194
+ border-spacing: 0;
195
+ }
196
+ td,
197
+ th {
198
+ padding: 0;
199
+ }
200
+ * {
201
+ -webkit-box-sizing: border-box;
202
+ -moz-box-sizing: border-box;
203
+ box-sizing: border-box;
204
+ }
205
+ *:before,
206
+ *:after {
207
+ -webkit-box-sizing: border-box;
208
+ -moz-box-sizing: border-box;
209
+ box-sizing: border-box;
210
+ }
211
+ html {
212
+ font-size: 10px;
213
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
214
+ }
215
+ body {
216
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
217
+ font-size: 14px;
218
+ line-height: 1.42857143;
219
+ color: #333333;
220
+ background-color: transparent;
221
+ }
222
+ input,
223
+ button,
224
+ select,
225
+ textarea {
226
+ font-family: inherit;
227
+ font-size: inherit;
228
+ line-height: inherit;
229
+ }
230
+ a {
231
+ color: #337ab7;
232
+ text-decoration: none;
233
+ }
234
+ a:hover,
235
+ a:focus {
236
+ color: #23527c;
237
+ text-decoration: underline;
238
+ }
239
+ a:focus {
240
+ outline: thin dotted;
241
+ outline: 5px auto -webkit-focus-ring-color;
242
+ outline-offset: -2px;
243
+ }
244
+ figure {
245
+ margin: 0;
246
+ }
247
+ img {
248
+ vertical-align: middle;
249
+ }
250
+ .img-responsive {
251
+ display: block;
252
+ max-width: 100%;
253
+ height: auto;
254
+ }
255
+ .img-rounded {
256
+ border-radius: 6px;
257
+ }
258
+ .img-thumbnail {
259
+ padding: 4px;
260
+ line-height: 1.42857143;
261
+ background-color: transparent;
262
+ border: 1px solid #dddddd;
263
+ border-radius: 4px;
264
+ -webkit-transition: all 0.2s ease-in-out;
265
+ -o-transition: all 0.2s ease-in-out;
266
+ transition: all 0.2s ease-in-out;
267
+ display: inline-block;
268
+ max-width: 100%;
269
+ height: auto;
270
+ }
271
+ .img-circle {
272
+ border-radius: 50%;
273
+ }
274
+ hr {
275
+ margin-top: 20px;
276
+ margin-bottom: 20px;
277
+ border: 0;
278
+ border-top: 1px solid #eeeeee;
279
+ }
280
+ .sr-only {
281
+ position: absolute;
282
+ width: 1px;
283
+ height: 1px;
284
+ margin: -1px;
285
+ padding: 0;
286
+ overflow: hidden;
287
+ clip: rect(0, 0, 0, 0);
288
+ border: 0;
289
+ }
290
+ .sr-only-focusable:active,
291
+ .sr-only-focusable:focus {
292
+ position: static;
293
+ width: auto;
294
+ height: auto;
295
+ margin: 0;
296
+ overflow: visible;
297
+ clip: auto;
298
+ }
299
+ [role="button"] {
300
+ cursor: pointer;
301
+ }
302
+ .container {
303
+ margin-right: auto;
304
+ margin-left: auto;
305
+ padding-left: 15px;
306
+ padding-right: 15px;
307
+ }
308
+ @media (min-width: 768px) {
309
+ .container {
310
+ width: 750px;
311
+ }
312
+ }
313
+ @media (min-width: 992px) {
314
+ .container {
315
+ width: 970px;
316
+ }
317
+ }
318
+ @media (min-width: 1200px) {
319
+ .container {
320
+ width: 1170px;
321
+ }
322
+ }
323
+ .container-fluid {
324
+ margin-right: auto;
325
+ margin-left: auto;
326
+ padding-left: 15px;
327
+ padding-right: 15px;
328
+ }
329
+ .row {
330
+ margin-left: -15px;
331
+ margin-right: -15px;
332
+ }
333
+ .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
334
+ position: relative;
335
+ min-height: 1px;
336
+ padding-left: 15px;
337
+ padding-right: 15px;
338
+ }
339
+ .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
340
+ float: left;
341
+ }
342
+ .col-xs-12 {
343
+ width: 100%;
344
+ }
345
+ .col-xs-11 {
346
+ width: 91.66666667%;
347
+ }
348
+ .col-xs-10 {
349
+ width: 83.33333333%;
350
+ }
351
+ .col-xs-9 {
352
+ width: 75%;
353
+ }
354
+ .col-xs-8 {
355
+ width: 66.66666667%;
356
+ }
357
+ .col-xs-7 {
358
+ width: 58.33333333%;
359
+ }
360
+ .col-xs-6 {
361
+ width: 50%;
362
+ }
363
+ .col-xs-5 {
364
+ width: 41.66666667%;
365
+ }
366
+ .col-xs-4 {
367
+ width: 33.33333333%;
368
+ }
369
+ .col-xs-3 {
370
+ width: 25%;
371
+ }
372
+ .col-xs-2 {
373
+ width: 16.66666667%;
374
+ }
375
+ .col-xs-1 {
376
+ width: 8.33333333%;
377
+ }
378
+ .col-xs-pull-12 {
379
+ right: 100%;
380
+ }
381
+ .col-xs-pull-11 {
382
+ right: 91.66666667%;
383
+ }
384
+ .col-xs-pull-10 {
385
+ right: 83.33333333%;
386
+ }
387
+ .col-xs-pull-9 {
388
+ right: 75%;
389
+ }
390
+ .col-xs-pull-8 {
391
+ right: 66.66666667%;
392
+ }
393
+ .col-xs-pull-7 {
394
+ right: 58.33333333%;
395
+ }
396
+ .col-xs-pull-6 {
397
+ right: 50%;
398
+ }
399
+ .col-xs-pull-5 {
400
+ right: 41.66666667%;
401
+ }
402
+ .col-xs-pull-4 {
403
+ right: 33.33333333%;
404
+ }
405
+ .col-xs-pull-3 {
406
+ right: 25%;
407
+ }
408
+ .col-xs-pull-2 {
409
+ right: 16.66666667%;
410
+ }
411
+ .col-xs-pull-1 {
412
+ right: 8.33333333%;
413
+ }
414
+ .col-xs-pull-0 {
415
+ right: auto;
416
+ }
417
+ .col-xs-push-12 {
418
+ left: 100%;
419
+ }
420
+ .col-xs-push-11 {
421
+ left: 91.66666667%;
422
+ }
423
+ .col-xs-push-10 {
424
+ left: 83.33333333%;
425
+ }
426
+ .col-xs-push-9 {
427
+ left: 75%;
428
+ }
429
+ .col-xs-push-8 {
430
+ left: 66.66666667%;
431
+ }
432
+ .col-xs-push-7 {
433
+ left: 58.33333333%;
434
+ }
435
+ .col-xs-push-6 {
436
+ left: 50%;
437
+ }
438
+ .col-xs-push-5 {
439
+ left: 41.66666667%;
440
+ }
441
+ .col-xs-push-4 {
442
+ left: 33.33333333%;
443
+ }
444
+ .col-xs-push-3 {
445
+ left: 25%;
446
+ }
447
+ .col-xs-push-2 {
448
+ left: 16.66666667%;
449
+ }
450
+ .col-xs-push-1 {
451
+ left: 8.33333333%;
452
+ }
453
+ .col-xs-push-0 {
454
+ left: auto;
455
+ }
456
+ .col-xs-offset-12 {
457
+ margin-left: 100%;
458
+ }
459
+ .col-xs-offset-11 {
460
+ margin-left: 91.66666667%;
461
+ }
462
+ .col-xs-offset-10 {
463
+ margin-left: 83.33333333%;
464
+ }
465
+ .col-xs-offset-9 {
466
+ margin-left: 75%;
467
+ }
468
+ .col-xs-offset-8 {
469
+ margin-left: 66.66666667%;
470
+ }
471
+ .col-xs-offset-7 {
472
+ margin-left: 58.33333333%;
473
+ }
474
+ .col-xs-offset-6 {
475
+ margin-left: 50%;
476
+ }
477
+ .col-xs-offset-5 {
478
+ margin-left: 41.66666667%;
479
+ }
480
+ .col-xs-offset-4 {
481
+ margin-left: 33.33333333%;
482
+ }
483
+ .col-xs-offset-3 {
484
+ margin-left: 25%;
485
+ }
486
+ .col-xs-offset-2 {
487
+ margin-left: 16.66666667%;
488
+ }
489
+ .col-xs-offset-1 {
490
+ margin-left: 8.33333333%;
491
+ }
492
+ .col-xs-offset-0 {
493
+ margin-left: 0%;
494
+ }
495
+ @media (min-width: 768px) {
496
+ .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
497
+ float: left;
498
+ }
499
+ .col-sm-12 {
500
+ width: 100%;
501
+ }
502
+ .col-sm-11 {
503
+ width: 91.66666667%;
504
+ }
505
+ .col-sm-10 {
506
+ width: 83.33333333%;
507
+ }
508
+ .col-sm-9 {
509
+ width: 75%;
510
+ }
511
+ .col-sm-8 {
512
+ width: 66.66666667%;
513
+ }
514
+ .col-sm-7 {
515
+ width: 58.33333333%;
516
+ }
517
+ .col-sm-6 {
518
+ width: 50%;
519
+ }
520
+ .col-sm-5 {
521
+ width: 41.66666667%;
522
+ }
523
+ .col-sm-4 {
524
+ width: 33.33333333%;
525
+ }
526
+ .col-sm-3 {
527
+ width: 25%;
528
+ }
529
+ .col-sm-2 {
530
+ width: 16.66666667%;
531
+ }
532
+ .col-sm-1 {
533
+ width: 8.33333333%;
534
+ }
535
+ .col-sm-pull-12 {
536
+ right: 100%;
537
+ }
538
+ .col-sm-pull-11 {
539
+ right: 91.66666667%;
540
+ }
541
+ .col-sm-pull-10 {
542
+ right: 83.33333333%;
543
+ }
544
+ .col-sm-pull-9 {
545
+ right: 75%;
546
+ }
547
+ .col-sm-pull-8 {
548
+ right: 66.66666667%;
549
+ }
550
+ .col-sm-pull-7 {
551
+ right: 58.33333333%;
552
+ }
553
+ .col-sm-pull-6 {
554
+ right: 50%;
555
+ }
556
+ .col-sm-pull-5 {
557
+ right: 41.66666667%;
558
+ }
559
+ .col-sm-pull-4 {
560
+ right: 33.33333333%;
561
+ }
562
+ .col-sm-pull-3 {
563
+ right: 25%;
564
+ }
565
+ .col-sm-pull-2 {
566
+ right: 16.66666667%;
567
+ }
568
+ .col-sm-pull-1 {
569
+ right: 8.33333333%;
570
+ }
571
+ .col-sm-pull-0 {
572
+ right: auto;
573
+ }
574
+ .col-sm-push-12 {
575
+ left: 100%;
576
+ }
577
+ .col-sm-push-11 {
578
+ left: 91.66666667%;
579
+ }
580
+ .col-sm-push-10 {
581
+ left: 83.33333333%;
582
+ }
583
+ .col-sm-push-9 {
584
+ left: 75%;
585
+ }
586
+ .col-sm-push-8 {
587
+ left: 66.66666667%;
588
+ }
589
+ .col-sm-push-7 {
590
+ left: 58.33333333%;
591
+ }
592
+ .col-sm-push-6 {
593
+ left: 50%;
594
+ }
595
+ .col-sm-push-5 {
596
+ left: 41.66666667%;
597
+ }
598
+ .col-sm-push-4 {
599
+ left: 33.33333333%;
600
+ }
601
+ .col-sm-push-3 {
602
+ left: 25%;
603
+ }
604
+ .col-sm-push-2 {
605
+ left: 16.66666667%;
606
+ }
607
+ .col-sm-push-1 {
608
+ left: 8.33333333%;
609
+ }
610
+ .col-sm-push-0 {
611
+ left: auto;
612
+ }
613
+ .col-sm-offset-12 {
614
+ margin-left: 100%;
615
+ }
616
+ .col-sm-offset-11 {
617
+ margin-left: 91.66666667%;
618
+ }
619
+ .col-sm-offset-10 {
620
+ margin-left: 83.33333333%;
621
+ }
622
+ .col-sm-offset-9 {
623
+ margin-left: 75%;
624
+ }
625
+ .col-sm-offset-8 {
626
+ margin-left: 66.66666667%;
627
+ }
628
+ .col-sm-offset-7 {
629
+ margin-left: 58.33333333%;
630
+ }
631
+ .col-sm-offset-6 {
632
+ margin-left: 50%;
633
+ }
634
+ .col-sm-offset-5 {
635
+ margin-left: 41.66666667%;
636
+ }
637
+ .col-sm-offset-4 {
638
+ margin-left: 33.33333333%;
639
+ }
640
+ .col-sm-offset-3 {
641
+ margin-left: 25%;
642
+ }
643
+ .col-sm-offset-2 {
644
+ margin-left: 16.66666667%;
645
+ }
646
+ .col-sm-offset-1 {
647
+ margin-left: 8.33333333%;
648
+ }
649
+ .col-sm-offset-0 {
650
+ margin-left: 0%;
651
+ }
652
+ }
653
+ @media (min-width: 992px) {
654
+ .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
655
+ float: left;
656
+ }
657
+ .col-md-12 {
658
+ width: 100%;
659
+ }
660
+ .col-md-11 {
661
+ width: 91.66666667%;
662
+ }
663
+ .col-md-10 {
664
+ width: 83.33333333%;
665
+ }
666
+ .col-md-9 {
667
+ width: 75%;
668
+ }
669
+ .col-md-8 {
670
+ width: 66.66666667%;
671
+ }
672
+ .col-md-7 {
673
+ width: 58.33333333%;
674
+ }
675
+ .col-md-6 {
676
+ width: 50%;
677
+ }
678
+ .col-md-5 {
679
+ width: 41.66666667%;
680
+ }
681
+ .col-md-4 {
682
+ width: 33.33333333%;
683
+ }
684
+ .col-md-3 {
685
+ width: 25%;
686
+ }
687
+ .col-md-2 {
688
+ width: 16.66666667%;
689
+ }
690
+ .col-md-1 {
691
+ width: 8.33333333%;
692
+ }
693
+ .col-md-pull-12 {
694
+ right: 100%;
695
+ }
696
+ .col-md-pull-11 {
697
+ right: 91.66666667%;
698
+ }
699
+ .col-md-pull-10 {
700
+ right: 83.33333333%;
701
+ }
702
+ .col-md-pull-9 {
703
+ right: 75%;
704
+ }
705
+ .col-md-pull-8 {
706
+ right: 66.66666667%;
707
+ }
708
+ .col-md-pull-7 {
709
+ right: 58.33333333%;
710
+ }
711
+ .col-md-pull-6 {
712
+ right: 50%;
713
+ }
714
+ .col-md-pull-5 {
715
+ right: 41.66666667%;
716
+ }
717
+ .col-md-pull-4 {
718
+ right: 33.33333333%;
719
+ }
720
+ .col-md-pull-3 {
721
+ right: 25%;
722
+ }
723
+ .col-md-pull-2 {
724
+ right: 16.66666667%;
725
+ }
726
+ .col-md-pull-1 {
727
+ right: 8.33333333%;
728
+ }
729
+ .col-md-pull-0 {
730
+ right: auto;
731
+ }
732
+ .col-md-push-12 {
733
+ left: 100%;
734
+ }
735
+ .col-md-push-11 {
736
+ left: 91.66666667%;
737
+ }
738
+ .col-md-push-10 {
739
+ left: 83.33333333%;
740
+ }
741
+ .col-md-push-9 {
742
+ left: 75%;
743
+ }
744
+ .col-md-push-8 {
745
+ left: 66.66666667%;
746
+ }
747
+ .col-md-push-7 {
748
+ left: 58.33333333%;
749
+ }
750
+ .col-md-push-6 {
751
+ left: 50%;
752
+ }
753
+ .col-md-push-5 {
754
+ left: 41.66666667%;
755
+ }
756
+ .col-md-push-4 {
757
+ left: 33.33333333%;
758
+ }
759
+ .col-md-push-3 {
760
+ left: 25%;
761
+ }
762
+ .col-md-push-2 {
763
+ left: 16.66666667%;
764
+ }
765
+ .col-md-push-1 {
766
+ left: 8.33333333%;
767
+ }
768
+ .col-md-push-0 {
769
+ left: auto;
770
+ }
771
+ .col-md-offset-12 {
772
+ margin-left: 100%;
773
+ }
774
+ .col-md-offset-11 {
775
+ margin-left: 91.66666667%;
776
+ }
777
+ .col-md-offset-10 {
778
+ margin-left: 83.33333333%;
779
+ }
780
+ .col-md-offset-9 {
781
+ margin-left: 75%;
782
+ }
783
+ .col-md-offset-8 {
784
+ margin-left: 66.66666667%;
785
+ }
786
+ .col-md-offset-7 {
787
+ margin-left: 58.33333333%;
788
+ }
789
+ .col-md-offset-6 {
790
+ margin-left: 50%;
791
+ }
792
+ .col-md-offset-5 {
793
+ margin-left: 41.66666667%;
794
+ }
795
+ .col-md-offset-4 {
796
+ margin-left: 33.33333333%;
797
+ }
798
+ .col-md-offset-3 {
799
+ margin-left: 25%;
800
+ }
801
+ .col-md-offset-2 {
802
+ margin-left: 16.66666667%;
803
+ }
804
+ .col-md-offset-1 {
805
+ margin-left: 8.33333333%;
806
+ }
807
+ .col-md-offset-0 {
808
+ margin-left: 0%;
809
+ }
810
+ }
811
+ @media (min-width: 1200px) {
812
+ .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
813
+ float: left;
814
+ }
815
+ .col-lg-12 {
816
+ width: 100%;
817
+ }
818
+ .col-lg-11 {
819
+ width: 91.66666667%;
820
+ }
821
+ .col-lg-10 {
822
+ width: 83.33333333%;
823
+ }
824
+ .col-lg-9 {
825
+ width: 75%;
826
+ }
827
+ .col-lg-8 {
828
+ width: 66.66666667%;
829
+ }
830
+ .col-lg-7 {
831
+ width: 58.33333333%;
832
+ }
833
+ .col-lg-6 {
834
+ width: 50%;
835
+ }
836
+ .col-lg-5 {
837
+ width: 41.66666667%;
838
+ }
839
+ .col-lg-4 {
840
+ width: 33.33333333%;
841
+ }
842
+ .col-lg-3 {
843
+ width: 25%;
844
+ }
845
+ .col-lg-2 {
846
+ width: 16.66666667%;
847
+ }
848
+ .col-lg-1 {
849
+ width: 8.33333333%;
850
+ }
851
+ .col-lg-pull-12 {
852
+ right: 100%;
853
+ }
854
+ .col-lg-pull-11 {
855
+ right: 91.66666667%;
856
+ }
857
+ .col-lg-pull-10 {
858
+ right: 83.33333333%;
859
+ }
860
+ .col-lg-pull-9 {
861
+ right: 75%;
862
+ }
863
+ .col-lg-pull-8 {
864
+ right: 66.66666667%;
865
+ }
866
+ .col-lg-pull-7 {
867
+ right: 58.33333333%;
868
+ }
869
+ .col-lg-pull-6 {
870
+ right: 50%;
871
+ }
872
+ .col-lg-pull-5 {
873
+ right: 41.66666667%;
874
+ }
875
+ .col-lg-pull-4 {
876
+ right: 33.33333333%;
877
+ }
878
+ .col-lg-pull-3 {
879
+ right: 25%;
880
+ }
881
+ .col-lg-pull-2 {
882
+ right: 16.66666667%;
883
+ }
884
+ .col-lg-pull-1 {
885
+ right: 8.33333333%;
886
+ }
887
+ .col-lg-pull-0 {
888
+ right: auto;
889
+ }
890
+ .col-lg-push-12 {
891
+ left: 100%;
892
+ }
893
+ .col-lg-push-11 {
894
+ left: 91.66666667%;
895
+ }
896
+ .col-lg-push-10 {
897
+ left: 83.33333333%;
898
+ }
899
+ .col-lg-push-9 {
900
+ left: 75%;
901
+ }
902
+ .col-lg-push-8 {
903
+ left: 66.66666667%;
904
+ }
905
+ .col-lg-push-7 {
906
+ left: 58.33333333%;
907
+ }
908
+ .col-lg-push-6 {
909
+ left: 50%;
910
+ }
911
+ .col-lg-push-5 {
912
+ left: 41.66666667%;
913
+ }
914
+ .col-lg-push-4 {
915
+ left: 33.33333333%;
916
+ }
917
+ .col-lg-push-3 {
918
+ left: 25%;
919
+ }
920
+ .col-lg-push-2 {
921
+ left: 16.66666667%;
922
+ }
923
+ .col-lg-push-1 {
924
+ left: 8.33333333%;
925
+ }
926
+ .col-lg-push-0 {
927
+ left: auto;
928
+ }
929
+ .col-lg-offset-12 {
930
+ margin-left: 100%;
931
+ }
932
+ .col-lg-offset-11 {
933
+ margin-left: 91.66666667%;
934
+ }
935
+ .col-lg-offset-10 {
936
+ margin-left: 83.33333333%;
937
+ }
938
+ .col-lg-offset-9 {
939
+ margin-left: 75%;
940
+ }
941
+ .col-lg-offset-8 {
942
+ margin-left: 66.66666667%;
943
+ }
944
+ .col-lg-offset-7 {
945
+ margin-left: 58.33333333%;
946
+ }
947
+ .col-lg-offset-6 {
948
+ margin-left: 50%;
949
+ }
950
+ .col-lg-offset-5 {
951
+ margin-left: 41.66666667%;
952
+ }
953
+ .col-lg-offset-4 {
954
+ margin-left: 33.33333333%;
955
+ }
956
+ .col-lg-offset-3 {
957
+ margin-left: 25%;
958
+ }
959
+ .col-lg-offset-2 {
960
+ margin-left: 16.66666667%;
961
+ }
962
+ .col-lg-offset-1 {
963
+ margin-left: 8.33333333%;
964
+ }
965
+ .col-lg-offset-0 {
966
+ margin-left: 0%;
967
+ }
968
+ }
969
+ fieldset {
970
+ padding: 0;
971
+ margin: 0;
972
+ border: 0;
973
+ min-width: 0;
974
+ }
975
+ legend {
976
+ display: block;
977
+ width: 100%;
978
+ padding: 0;
979
+ margin-bottom: 20px;
980
+ font-size: 21px;
981
+ line-height: inherit;
982
+ color: #333333;
983
+ border: 0;
984
+ border-bottom: 1px solid #e5e5e5;
985
+ }
986
+ label {
987
+ display: inline-block;
988
+ max-width: 100%;
989
+ margin-bottom: 5px;
990
+ font-weight: bold;
991
+ }
992
+ input[type="search"] {
993
+ -webkit-box-sizing: border-box;
994
+ -moz-box-sizing: border-box;
995
+ box-sizing: border-box;
996
+ }
997
+ input[type="radio"],
998
+ input[type="checkbox"] {
999
+ margin: 4px 0 0;
1000
+ margin-top: 1px \9;
1001
+ line-height: normal;
1002
+ }
1003
+ input[type="file"] {
1004
+ display: block;
1005
+ }
1006
+ input[type="range"] {
1007
+ display: block;
1008
+ width: 100%;
1009
+ }
1010
+ select[multiple],
1011
+ select[size] {
1012
+ height: auto;
1013
+ }
1014
+ input[type="file"]:focus,
1015
+ input[type="radio"]:focus,
1016
+ input[type="checkbox"]:focus {
1017
+ outline: thin dotted;
1018
+ outline: 5px auto -webkit-focus-ring-color;
1019
+ outline-offset: -2px;
1020
+ }
1021
+ output {
1022
+ display: block;
1023
+ padding-top: 7px;
1024
+ font-size: 14px;
1025
+ line-height: 1.42857143;
1026
+ color: #555555;
1027
+ }
1028
+ .form-control {
1029
+ display: block;
1030
+ width: 100%;
1031
+ height: 34px;
1032
+ padding: 6px 12px;
1033
+ font-size: 14px;
1034
+ line-height: 1.42857143;
1035
+ color: #555555;
1036
+ background-color: #ffffff;
1037
+ background-image: none;
1038
+ border: 1px solid #cccccc;
1039
+ border-radius: 4px;
1040
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
1041
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
1042
+ -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
1043
+ -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
1044
+ transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
1045
+ }
1046
+ .form-control:focus {
1047
+ border-color: #66afe9;
1048
+ outline: 0;
1049
+ -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
1050
+ box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
1051
+ }
1052
+ .form-control::-moz-placeholder {
1053
+ color: #999999;
1054
+ opacity: 1;
1055
+ }
1056
+ .form-control:-ms-input-placeholder {
1057
+ color: #999999;
1058
+ }
1059
+ .form-control::-webkit-input-placeholder {
1060
+ color: #999999;
1061
+ }
1062
+ .form-control::-ms-expand {
1063
+ border: 0;
1064
+ background-color: transparent;
1065
+ }
1066
+ .form-control[disabled],
1067
+ .form-control[readonly],
1068
+ fieldset[disabled] .form-control {
1069
+ background-color: #eeeeee;
1070
+ opacity: 1;
1071
+ }
1072
+ .form-control[disabled],
1073
+ fieldset[disabled] .form-control {
1074
+ cursor: not-allowed;
1075
+ }
1076
+ textarea.form-control {
1077
+ height: auto;
1078
+ }
1079
+ input[type="search"] {
1080
+ -webkit-appearance: none;
1081
+ }
1082
+ @media screen and (-webkit-min-device-pixel-ratio: 0) {
1083
+ input[type="date"].form-control,
1084
+ input[type="time"].form-control,
1085
+ input[type="datetime-local"].form-control,
1086
+ input[type="month"].form-control {
1087
+ line-height: 34px;
1088
+ }
1089
+ input[type="date"].input-sm,
1090
+ input[type="time"].input-sm,
1091
+ input[type="datetime-local"].input-sm,
1092
+ input[type="month"].input-sm,
1093
+ .input-group-sm input[type="date"],
1094
+ .input-group-sm input[type="time"],
1095
+ .input-group-sm input[type="datetime-local"],
1096
+ .input-group-sm input[type="month"] {
1097
+ line-height: 30px;
1098
+ }
1099
+ input[type="date"].input-lg,
1100
+ input[type="time"].input-lg,
1101
+ input[type="datetime-local"].input-lg,
1102
+ input[type="month"].input-lg,
1103
+ .input-group-lg input[type="date"],
1104
+ .input-group-lg input[type="time"],
1105
+ .input-group-lg input[type="datetime-local"],
1106
+ .input-group-lg input[type="month"] {
1107
+ line-height: 46px;
1108
+ }
1109
+ }
1110
+ .form-group {
1111
+ margin-bottom: 15px;
1112
+ }
1113
+ .radio,
1114
+ .checkbox {
1115
+ position: relative;
1116
+ display: block;
1117
+ margin-top: 10px;
1118
+ margin-bottom: 10px;
1119
+ }
1120
+ .radio label,
1121
+ .checkbox label {
1122
+ min-height: 20px;
1123
+ padding-left: 20px;
1124
+ margin-bottom: 0;
1125
+ font-weight: normal;
1126
+ cursor: pointer;
1127
+ }
1128
+ .radio input[type="radio"],
1129
+ .radio-inline input[type="radio"],
1130
+ .checkbox input[type="checkbox"],
1131
+ .checkbox-inline input[type="checkbox"] {
1132
+ position: absolute;
1133
+ margin-left: -20px;
1134
+ margin-top: 4px \9;
1135
+ }
1136
+ .radio + .radio,
1137
+ .checkbox + .checkbox {
1138
+ margin-top: -5px;
1139
+ }
1140
+ .radio-inline,
1141
+ .checkbox-inline {
1142
+ position: relative;
1143
+ display: inline-block;
1144
+ padding-left: 20px;
1145
+ margin-bottom: 0;
1146
+ vertical-align: middle;
1147
+ font-weight: normal;
1148
+ cursor: pointer;
1149
+ }
1150
+ .radio-inline + .radio-inline,
1151
+ .checkbox-inline + .checkbox-inline {
1152
+ margin-top: 0;
1153
+ margin-left: 10px;
1154
+ }
1155
+ input[type="radio"][disabled],
1156
+ input[type="checkbox"][disabled],
1157
+ input[type="radio"].disabled,
1158
+ input[type="checkbox"].disabled,
1159
+ fieldset[disabled] input[type="radio"],
1160
+ fieldset[disabled] input[type="checkbox"] {
1161
+ cursor: not-allowed;
1162
+ }
1163
+ .radio-inline.disabled,
1164
+ .checkbox-inline.disabled,
1165
+ fieldset[disabled] .radio-inline,
1166
+ fieldset[disabled] .checkbox-inline {
1167
+ cursor: not-allowed;
1168
+ }
1169
+ .radio.disabled label,
1170
+ .checkbox.disabled label,
1171
+ fieldset[disabled] .radio label,
1172
+ fieldset[disabled] .checkbox label {
1173
+ cursor: not-allowed;
1174
+ }
1175
+ .form-control-static {
1176
+ padding-top: 7px;
1177
+ padding-bottom: 7px;
1178
+ margin-bottom: 0;
1179
+ min-height: 34px;
1180
+ }
1181
+ .form-control-static.input-lg,
1182
+ .form-control-static.input-sm {
1183
+ padding-left: 0;
1184
+ padding-right: 0;
1185
+ }
1186
+ .input-sm {
1187
+ height: 30px;
1188
+ padding: 5px 10px;
1189
+ font-size: 12px;
1190
+ line-height: 1.5;
1191
+ border-radius: 3px;
1192
+ }
1193
+ select.input-sm {
1194
+ height: 30px;
1195
+ line-height: 30px;
1196
+ }
1197
+ textarea.input-sm,
1198
+ select[multiple].input-sm {
1199
+ height: auto;
1200
+ }
1201
+ .form-group-sm .form-control {
1202
+ height: 30px;
1203
+ padding: 5px 10px;
1204
+ font-size: 12px;
1205
+ line-height: 1.5;
1206
+ border-radius: 3px;
1207
+ }
1208
+ .form-group-sm select.form-control {
1209
+ height: 30px;
1210
+ line-height: 30px;
1211
+ }
1212
+ .form-group-sm textarea.form-control,
1213
+ .form-group-sm select[multiple].form-control {
1214
+ height: auto;
1215
+ }
1216
+ .form-group-sm .form-control-static {
1217
+ height: 30px;
1218
+ min-height: 32px;
1219
+ padding: 6px 10px;
1220
+ font-size: 12px;
1221
+ line-height: 1.5;
1222
+ }
1223
+ .input-lg {
1224
+ height: 46px;
1225
+ padding: 10px 16px;
1226
+ font-size: 18px;
1227
+ line-height: 1.3333333;
1228
+ border-radius: 6px;
1229
+ }
1230
+ select.input-lg {
1231
+ height: 46px;
1232
+ line-height: 46px;
1233
+ }
1234
+ textarea.input-lg,
1235
+ select[multiple].input-lg {
1236
+ height: auto;
1237
+ }
1238
+ .form-group-lg .form-control {
1239
+ height: 46px;
1240
+ padding: 10px 16px;
1241
+ font-size: 18px;
1242
+ line-height: 1.3333333;
1243
+ border-radius: 6px;
1244
+ }
1245
+ .form-group-lg select.form-control {
1246
+ height: 46px;
1247
+ line-height: 46px;
1248
+ }
1249
+ .form-group-lg textarea.form-control,
1250
+ .form-group-lg select[multiple].form-control {
1251
+ height: auto;
1252
+ }
1253
+ .form-group-lg .form-control-static {
1254
+ height: 46px;
1255
+ min-height: 38px;
1256
+ padding: 11px 16px;
1257
+ font-size: 18px;
1258
+ line-height: 1.3333333;
1259
+ }
1260
+ .has-feedback {
1261
+ position: relative;
1262
+ }
1263
+ .has-feedback .form-control {
1264
+ padding-right: 42.5px;
1265
+ }
1266
+ .form-control-feedback {
1267
+ position: absolute;
1268
+ top: 0;
1269
+ right: 0;
1270
+ z-index: 2;
1271
+ display: block;
1272
+ width: 34px;
1273
+ height: 34px;
1274
+ line-height: 34px;
1275
+ text-align: center;
1276
+ pointer-events: none;
1277
+ }
1278
+ .input-lg + .form-control-feedback,
1279
+ .input-group-lg + .form-control-feedback,
1280
+ .form-group-lg .form-control + .form-control-feedback {
1281
+ width: 46px;
1282
+ height: 46px;
1283
+ line-height: 46px;
1284
+ }
1285
+ .input-sm + .form-control-feedback,
1286
+ .input-group-sm + .form-control-feedback,
1287
+ .form-group-sm .form-control + .form-control-feedback {
1288
+ width: 30px;
1289
+ height: 30px;
1290
+ line-height: 30px;
1291
+ }
1292
+ .has-success .help-block,
1293
+ .has-success .control-label,
1294
+ .has-success .radio,
1295
+ .has-success .checkbox,
1296
+ .has-success .radio-inline,
1297
+ .has-success .checkbox-inline,
1298
+ .has-success.radio label,
1299
+ .has-success.checkbox label,
1300
+ .has-success.radio-inline label,
1301
+ .has-success.checkbox-inline label {
1302
+ color: #3c763d;
1303
+ }
1304
+ .has-success .form-control {
1305
+ border-color: #3c763d;
1306
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
1307
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
1308
+ }
1309
+ .has-success .form-control:focus {
1310
+ border-color: #2b542c;
1311
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
1312
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
1313
+ }
1314
+ .has-success .input-group-addon {
1315
+ color: #3c763d;
1316
+ border-color: #3c763d;
1317
+ background-color: #dff0d8;
1318
+ }
1319
+ .has-success .form-control-feedback {
1320
+ color: #3c763d;
1321
+ }
1322
+ .has-warning .help-block,
1323
+ .has-warning .control-label,
1324
+ .has-warning .radio,
1325
+ .has-warning .checkbox,
1326
+ .has-warning .radio-inline,
1327
+ .has-warning .checkbox-inline,
1328
+ .has-warning.radio label,
1329
+ .has-warning.checkbox label,
1330
+ .has-warning.radio-inline label,
1331
+ .has-warning.checkbox-inline label {
1332
+ color: #8a6d3b;
1333
+ }
1334
+ .has-warning .form-control {
1335
+ border-color: #8a6d3b;
1336
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
1337
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
1338
+ }
1339
+ .has-warning .form-control:focus {
1340
+ border-color: #66512c;
1341
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
1342
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
1343
+ }
1344
+ .has-warning .input-group-addon {
1345
+ color: #8a6d3b;
1346
+ border-color: #8a6d3b;
1347
+ background-color: #fcf8e3;
1348
+ }
1349
+ .has-warning .form-control-feedback {
1350
+ color: #8a6d3b;
1351
+ }
1352
+ .has-error .help-block,
1353
+ .has-error .control-label,
1354
+ .has-error .radio,
1355
+ .has-error .checkbox,
1356
+ .has-error .radio-inline,
1357
+ .has-error .checkbox-inline,
1358
+ .has-error.radio label,
1359
+ .has-error.checkbox label,
1360
+ .has-error.radio-inline label,
1361
+ .has-error.checkbox-inline label {
1362
+ color: #a94442;
1363
+ }
1364
+ .has-error .form-control {
1365
+ border-color: #a94442;
1366
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
1367
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
1368
+ }
1369
+ .has-error .form-control:focus {
1370
+ border-color: #843534;
1371
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
1372
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
1373
+ }
1374
+ .has-error .input-group-addon {
1375
+ color: #a94442;
1376
+ border-color: #a94442;
1377
+ background-color: #f2dede;
1378
+ }
1379
+ .has-error .form-control-feedback {
1380
+ color: #a94442;
1381
+ }
1382
+ .has-feedback label ~ .form-control-feedback {
1383
+ top: 25px;
1384
+ }
1385
+ .has-feedback label.sr-only ~ .form-control-feedback {
1386
+ top: 0;
1387
+ }
1388
+ .help-block {
1389
+ display: block;
1390
+ margin-top: 5px;
1391
+ margin-bottom: 10px;
1392
+ color: #737373;
1393
+ }
1394
+ @media (min-width: 768px) {
1395
+ .form-inline .form-group {
1396
+ display: inline-block;
1397
+ margin-bottom: 0;
1398
+ vertical-align: middle;
1399
+ }
1400
+ .form-inline .form-control {
1401
+ display: inline-block;
1402
+ width: auto;
1403
+ vertical-align: middle;
1404
+ }
1405
+ .form-inline .form-control-static {
1406
+ display: inline-block;
1407
+ }
1408
+ .form-inline .input-group {
1409
+ display: inline-table;
1410
+ vertical-align: middle;
1411
+ }
1412
+ .form-inline .input-group .input-group-addon,
1413
+ .form-inline .input-group .input-group-btn,
1414
+ .form-inline .input-group .form-control {
1415
+ width: auto;
1416
+ }
1417
+ .form-inline .input-group > .form-control {
1418
+ width: 100%;
1419
+ }
1420
+ .form-inline .control-label {
1421
+ margin-bottom: 0;
1422
+ vertical-align: middle;
1423
+ }
1424
+ .form-inline .radio,
1425
+ .form-inline .checkbox {
1426
+ display: inline-block;
1427
+ margin-top: 0;
1428
+ margin-bottom: 0;
1429
+ vertical-align: middle;
1430
+ }
1431
+ .form-inline .radio label,
1432
+ .form-inline .checkbox label {
1433
+ padding-left: 0;
1434
+ }
1435
+ .form-inline .radio input[type="radio"],
1436
+ .form-inline .checkbox input[type="checkbox"] {
1437
+ position: relative;
1438
+ margin-left: 0;
1439
+ }
1440
+ .form-inline .has-feedback .form-control-feedback {
1441
+ top: 0;
1442
+ }
1443
+ }
1444
+ .form-horizontal .radio,
1445
+ .form-horizontal .checkbox,
1446
+ .form-horizontal .radio-inline,
1447
+ .form-horizontal .checkbox-inline {
1448
+ margin-top: 0;
1449
+ margin-bottom: 0;
1450
+ padding-top: 7px;
1451
+ }
1452
+ .form-horizontal .radio,
1453
+ .form-horizontal .checkbox {
1454
+ min-height: 27px;
1455
+ }
1456
+ .form-horizontal .form-group {
1457
+ margin-left: -15px;
1458
+ margin-right: -15px;
1459
+ }
1460
+ @media (min-width: 768px) {
1461
+ .form-horizontal .control-label {
1462
+ text-align: right;
1463
+ margin-bottom: 0;
1464
+ padding-top: 7px;
1465
+ }
1466
+ }
1467
+ .form-horizontal .has-feedback .form-control-feedback {
1468
+ right: 15px;
1469
+ }
1470
+ @media (min-width: 768px) {
1471
+ .form-horizontal .form-group-lg .control-label {
1472
+ padding-top: 11px;
1473
+ font-size: 18px;
1474
+ }
1475
+ }
1476
+ @media (min-width: 768px) {
1477
+ .form-horizontal .form-group-sm .control-label {
1478
+ padding-top: 6px;
1479
+ font-size: 12px;
1480
+ }
1481
+ }
1482
+ .btn {
1483
+ display: inline-block;
1484
+ margin-bottom: 0;
1485
+ font-weight: normal;
1486
+ text-align: center;
1487
+ vertical-align: middle;
1488
+ -ms-touch-action: manipulation;
1489
+ touch-action: manipulation;
1490
+ cursor: pointer;
1491
+ background-image: none;
1492
+ border: 1px solid transparent;
1493
+ white-space: nowrap;
1494
+ padding: 6px 12px;
1495
+ font-size: 14px;
1496
+ line-height: 1.42857143;
1497
+ border-radius: 4px;
1498
+ -webkit-user-select: none;
1499
+ -moz-user-select: none;
1500
+ -ms-user-select: none;
1501
+ user-select: none;
1502
+ }
1503
+ .btn:focus,
1504
+ .btn:active:focus,
1505
+ .btn.active:focus,
1506
+ .btn.focus,
1507
+ .btn:active.focus,
1508
+ .btn.active.focus {
1509
+ outline: thin dotted;
1510
+ outline: 5px auto -webkit-focus-ring-color;
1511
+ outline-offset: -2px;
1512
+ }
1513
+ .btn:hover,
1514
+ .btn:focus,
1515
+ .btn.focus {
1516
+ color: #333333;
1517
+ text-decoration: none;
1518
+ }
1519
+ .btn:active,
1520
+ .btn.active {
1521
+ outline: 0;
1522
+ background-image: none;
1523
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
1524
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
1525
+ }
1526
+ .btn.disabled,
1527
+ .btn[disabled],
1528
+ fieldset[disabled] .btn {
1529
+ cursor: not-allowed;
1530
+ opacity: 0.65;
1531
+ filter: alpha(opacity=65);
1532
+ -webkit-box-shadow: none;
1533
+ box-shadow: none;
1534
+ }
1535
+ a.btn.disabled,
1536
+ fieldset[disabled] a.btn {
1537
+ pointer-events: none;
1538
+ }
1539
+ .btn-default {
1540
+ color: #333333;
1541
+ background-color: #ffffff;
1542
+ border-color: #cccccc;
1543
+ }
1544
+ .btn-default:focus,
1545
+ .btn-default.focus {
1546
+ color: #333333;
1547
+ background-color: #e6e6e6;
1548
+ border-color: #8c8c8c;
1549
+ }
1550
+ .btn-default:hover {
1551
+ color: #333333;
1552
+ background-color: #e6e6e6;
1553
+ border-color: #adadad;
1554
+ }
1555
+ .btn-default:active,
1556
+ .btn-default.active,
1557
+ .open > .dropdown-toggle.btn-default {
1558
+ color: #333333;
1559
+ background-color: #e6e6e6;
1560
+ border-color: #adadad;
1561
+ }
1562
+ .btn-default:active:hover,
1563
+ .btn-default.active:hover,
1564
+ .open > .dropdown-toggle.btn-default:hover,
1565
+ .btn-default:active:focus,
1566
+ .btn-default.active:focus,
1567
+ .open > .dropdown-toggle.btn-default:focus,
1568
+ .btn-default:active.focus,
1569
+ .btn-default.active.focus,
1570
+ .open > .dropdown-toggle.btn-default.focus {
1571
+ color: #333333;
1572
+ background-color: #d4d4d4;
1573
+ border-color: #8c8c8c;
1574
+ }
1575
+ .btn-default:active,
1576
+ .btn-default.active,
1577
+ .open > .dropdown-toggle.btn-default {
1578
+ background-image: none;
1579
+ }
1580
+ .btn-default.disabled:hover,
1581
+ .btn-default[disabled]:hover,
1582
+ fieldset[disabled] .btn-default:hover,
1583
+ .btn-default.disabled:focus,
1584
+ .btn-default[disabled]:focus,
1585
+ fieldset[disabled] .btn-default:focus,
1586
+ .btn-default.disabled.focus,
1587
+ .btn-default[disabled].focus,
1588
+ fieldset[disabled] .btn-default.focus {
1589
+ background-color: #ffffff;
1590
+ border-color: #cccccc;
1591
+ }
1592
+ .btn-default .badge {
1593
+ color: #ffffff;
1594
+ background-color: #333333;
1595
+ }
1596
+ .btn-primary {
1597
+ color: #ffffff;
1598
+ background-color: #337ab7;
1599
+ border-color: #2e6da4;
1600
+ }
1601
+ .btn-primary:focus,
1602
+ .btn-primary.focus {
1603
+ color: #ffffff;
1604
+ background-color: #286090;
1605
+ border-color: #122b40;
1606
+ }
1607
+ .btn-primary:hover {
1608
+ color: #ffffff;
1609
+ background-color: #286090;
1610
+ border-color: #204d74;
1611
+ }
1612
+ .btn-primary:active,
1613
+ .btn-primary.active,
1614
+ .open > .dropdown-toggle.btn-primary {
1615
+ color: #ffffff;
1616
+ background-color: #286090;
1617
+ border-color: #204d74;
1618
+ }
1619
+ .btn-primary:active:hover,
1620
+ .btn-primary.active:hover,
1621
+ .open > .dropdown-toggle.btn-primary:hover,
1622
+ .btn-primary:active:focus,
1623
+ .btn-primary.active:focus,
1624
+ .open > .dropdown-toggle.btn-primary:focus,
1625
+ .btn-primary:active.focus,
1626
+ .btn-primary.active.focus,
1627
+ .open > .dropdown-toggle.btn-primary.focus {
1628
+ color: #ffffff;
1629
+ background-color: #204d74;
1630
+ border-color: #122b40;
1631
+ }
1632
+ .btn-primary:active,
1633
+ .btn-primary.active,
1634
+ .open > .dropdown-toggle.btn-primary {
1635
+ background-image: none;
1636
+ }
1637
+ .btn-primary.disabled:hover,
1638
+ .btn-primary[disabled]:hover,
1639
+ fieldset[disabled] .btn-primary:hover,
1640
+ .btn-primary.disabled:focus,
1641
+ .btn-primary[disabled]:focus,
1642
+ fieldset[disabled] .btn-primary:focus,
1643
+ .btn-primary.disabled.focus,
1644
+ .btn-primary[disabled].focus,
1645
+ fieldset[disabled] .btn-primary.focus {
1646
+ background-color: #337ab7;
1647
+ border-color: #2e6da4;
1648
+ }
1649
+ .btn-primary .badge {
1650
+ color: #337ab7;
1651
+ background-color: #ffffff;
1652
+ }
1653
+ .btn-success {
1654
+ color: #ffffff;
1655
+ background-color: #5cb85c;
1656
+ border-color: #4cae4c;
1657
+ }
1658
+ .btn-success:focus,
1659
+ .btn-success.focus {
1660
+ color: #ffffff;
1661
+ background-color: #449d44;
1662
+ border-color: #255625;
1663
+ }
1664
+ .btn-success:hover {
1665
+ color: #ffffff;
1666
+ background-color: #449d44;
1667
+ border-color: #398439;
1668
+ }
1669
+ .btn-success:active,
1670
+ .btn-success.active,
1671
+ .open > .dropdown-toggle.btn-success {
1672
+ color: #ffffff;
1673
+ background-color: #449d44;
1674
+ border-color: #398439;
1675
+ }
1676
+ .btn-success:active:hover,
1677
+ .btn-success.active:hover,
1678
+ .open > .dropdown-toggle.btn-success:hover,
1679
+ .btn-success:active:focus,
1680
+ .btn-success.active:focus,
1681
+ .open > .dropdown-toggle.btn-success:focus,
1682
+ .btn-success:active.focus,
1683
+ .btn-success.active.focus,
1684
+ .open > .dropdown-toggle.btn-success.focus {
1685
+ color: #ffffff;
1686
+ background-color: #398439;
1687
+ border-color: #255625;
1688
+ }
1689
+ .btn-success:active,
1690
+ .btn-success.active,
1691
+ .open > .dropdown-toggle.btn-success {
1692
+ background-image: none;
1693
+ }
1694
+ .btn-success.disabled:hover,
1695
+ .btn-success[disabled]:hover,
1696
+ fieldset[disabled] .btn-success:hover,
1697
+ .btn-success.disabled:focus,
1698
+ .btn-success[disabled]:focus,
1699
+ fieldset[disabled] .btn-success:focus,
1700
+ .btn-success.disabled.focus,
1701
+ .btn-success[disabled].focus,
1702
+ fieldset[disabled] .btn-success.focus {
1703
+ background-color: #5cb85c;
1704
+ border-color: #4cae4c;
1705
+ }
1706
+ .btn-success .badge {
1707
+ color: #5cb85c;
1708
+ background-color: #ffffff;
1709
+ }
1710
+ .btn-info {
1711
+ color: #ffffff;
1712
+ background-color: #5bc0de;
1713
+ border-color: #46b8da;
1714
+ }
1715
+ .btn-info:focus,
1716
+ .btn-info.focus {
1717
+ color: #ffffff;
1718
+ background-color: #31b0d5;
1719
+ border-color: #1b6d85;
1720
+ }
1721
+ .btn-info:hover {
1722
+ color: #ffffff;
1723
+ background-color: #31b0d5;
1724
+ border-color: #269abc;
1725
+ }
1726
+ .btn-info:active,
1727
+ .btn-info.active,
1728
+ .open > .dropdown-toggle.btn-info {
1729
+ color: #ffffff;
1730
+ background-color: #31b0d5;
1731
+ border-color: #269abc;
1732
+ }
1733
+ .btn-info:active:hover,
1734
+ .btn-info.active:hover,
1735
+ .open > .dropdown-toggle.btn-info:hover,
1736
+ .btn-info:active:focus,
1737
+ .btn-info.active:focus,
1738
+ .open > .dropdown-toggle.btn-info:focus,
1739
+ .btn-info:active.focus,
1740
+ .btn-info.active.focus,
1741
+ .open > .dropdown-toggle.btn-info.focus {
1742
+ color: #ffffff;
1743
+ background-color: #269abc;
1744
+ border-color: #1b6d85;
1745
+ }
1746
+ .btn-info:active,
1747
+ .btn-info.active,
1748
+ .open > .dropdown-toggle.btn-info {
1749
+ background-image: none;
1750
+ }
1751
+ .btn-info.disabled:hover,
1752
+ .btn-info[disabled]:hover,
1753
+ fieldset[disabled] .btn-info:hover,
1754
+ .btn-info.disabled:focus,
1755
+ .btn-info[disabled]:focus,
1756
+ fieldset[disabled] .btn-info:focus,
1757
+ .btn-info.disabled.focus,
1758
+ .btn-info[disabled].focus,
1759
+ fieldset[disabled] .btn-info.focus {
1760
+ background-color: #5bc0de;
1761
+ border-color: #46b8da;
1762
+ }
1763
+ .btn-info .badge {
1764
+ color: #5bc0de;
1765
+ background-color: #ffffff;
1766
+ }
1767
+ .btn-warning {
1768
+ color: #ffffff;
1769
+ background-color: #f0ad4e;
1770
+ border-color: #eea236;
1771
+ }
1772
+ .btn-warning:focus,
1773
+ .btn-warning.focus {
1774
+ color: #ffffff;
1775
+ background-color: #ec971f;
1776
+ border-color: #985f0d;
1777
+ }
1778
+ .btn-warning:hover {
1779
+ color: #ffffff;
1780
+ background-color: #ec971f;
1781
+ border-color: #d58512;
1782
+ }
1783
+ .btn-warning:active,
1784
+ .btn-warning.active,
1785
+ .open > .dropdown-toggle.btn-warning {
1786
+ color: #ffffff;
1787
+ background-color: #ec971f;
1788
+ border-color: #d58512;
1789
+ }
1790
+ .btn-warning:active:hover,
1791
+ .btn-warning.active:hover,
1792
+ .open > .dropdown-toggle.btn-warning:hover,
1793
+ .btn-warning:active:focus,
1794
+ .btn-warning.active:focus,
1795
+ .open > .dropdown-toggle.btn-warning:focus,
1796
+ .btn-warning:active.focus,
1797
+ .btn-warning.active.focus,
1798
+ .open > .dropdown-toggle.btn-warning.focus {
1799
+ color: #ffffff;
1800
+ background-color: #d58512;
1801
+ border-color: #985f0d;
1802
+ }
1803
+ .btn-warning:active,
1804
+ .btn-warning.active,
1805
+ .open > .dropdown-toggle.btn-warning {
1806
+ background-image: none;
1807
+ }
1808
+ .btn-warning.disabled:hover,
1809
+ .btn-warning[disabled]:hover,
1810
+ fieldset[disabled] .btn-warning:hover,
1811
+ .btn-warning.disabled:focus,
1812
+ .btn-warning[disabled]:focus,
1813
+ fieldset[disabled] .btn-warning:focus,
1814
+ .btn-warning.disabled.focus,
1815
+ .btn-warning[disabled].focus,
1816
+ fieldset[disabled] .btn-warning.focus {
1817
+ background-color: #f0ad4e;
1818
+ border-color: #eea236;
1819
+ }
1820
+ .btn-warning .badge {
1821
+ color: #f0ad4e;
1822
+ background-color: #ffffff;
1823
+ }
1824
+ .btn-danger {
1825
+ color: #ffffff;
1826
+ background-color: #d9534f;
1827
+ border-color: #d43f3a;
1828
+ }
1829
+ .btn-danger:focus,
1830
+ .btn-danger.focus {
1831
+ color: #ffffff;
1832
+ background-color: #c9302c;
1833
+ border-color: #761c19;
1834
+ }
1835
+ .btn-danger:hover {
1836
+ color: #ffffff;
1837
+ background-color: #c9302c;
1838
+ border-color: #ac2925;
1839
+ }
1840
+ .btn-danger:active,
1841
+ .btn-danger.active,
1842
+ .open > .dropdown-toggle.btn-danger {
1843
+ color: #ffffff;
1844
+ background-color: #c9302c;
1845
+ border-color: #ac2925;
1846
+ }
1847
+ .btn-danger:active:hover,
1848
+ .btn-danger.active:hover,
1849
+ .open > .dropdown-toggle.btn-danger:hover,
1850
+ .btn-danger:active:focus,
1851
+ .btn-danger.active:focus,
1852
+ .open > .dropdown-toggle.btn-danger:focus,
1853
+ .btn-danger:active.focus,
1854
+ .btn-danger.active.focus,
1855
+ .open > .dropdown-toggle.btn-danger.focus {
1856
+ color: #ffffff;
1857
+ background-color: #ac2925;
1858
+ border-color: #761c19;
1859
+ }
1860
+ .btn-danger:active,
1861
+ .btn-danger.active,
1862
+ .open > .dropdown-toggle.btn-danger {
1863
+ background-image: none;
1864
+ }
1865
+ .btn-danger.disabled:hover,
1866
+ .btn-danger[disabled]:hover,
1867
+ fieldset[disabled] .btn-danger:hover,
1868
+ .btn-danger.disabled:focus,
1869
+ .btn-danger[disabled]:focus,
1870
+ fieldset[disabled] .btn-danger:focus,
1871
+ .btn-danger.disabled.focus,
1872
+ .btn-danger[disabled].focus,
1873
+ fieldset[disabled] .btn-danger.focus {
1874
+ background-color: #d9534f;
1875
+ border-color: #d43f3a;
1876
+ }
1877
+ .btn-danger .badge {
1878
+ color: #d9534f;
1879
+ background-color: #ffffff;
1880
+ }
1881
+ .btn-link {
1882
+ color: #337ab7;
1883
+ font-weight: normal;
1884
+ border-radius: 0;
1885
+ }
1886
+ .btn-link,
1887
+ .btn-link:active,
1888
+ .btn-link.active,
1889
+ .btn-link[disabled],
1890
+ fieldset[disabled] .btn-link {
1891
+ background-color: transparent;
1892
+ -webkit-box-shadow: none;
1893
+ box-shadow: none;
1894
+ }
1895
+ .btn-link,
1896
+ .btn-link:hover,
1897
+ .btn-link:focus,
1898
+ .btn-link:active {
1899
+ border-color: transparent;
1900
+ }
1901
+ .btn-link:hover,
1902
+ .btn-link:focus {
1903
+ color: #23527c;
1904
+ text-decoration: underline;
1905
+ background-color: transparent;
1906
+ }
1907
+ .btn-link[disabled]:hover,
1908
+ fieldset[disabled] .btn-link:hover,
1909
+ .btn-link[disabled]:focus,
1910
+ fieldset[disabled] .btn-link:focus {
1911
+ color: #777777;
1912
+ text-decoration: none;
1913
+ }
1914
+ .btn-lg,
1915
+ .btn-group-lg > .btn {
1916
+ padding: 10px 16px;
1917
+ font-size: 18px;
1918
+ line-height: 1.3333333;
1919
+ border-radius: 6px;
1920
+ }
1921
+ .btn-sm,
1922
+ .btn-group-sm > .btn {
1923
+ padding: 5px 10px;
1924
+ font-size: 12px;
1925
+ line-height: 1.5;
1926
+ border-radius: 3px;
1927
+ }
1928
+ .btn-xs,
1929
+ .btn-group-xs > .btn {
1930
+ padding: 1px 5px;
1931
+ font-size: 12px;
1932
+ line-height: 1.5;
1933
+ border-radius: 3px;
1934
+ }
1935
+ .btn-block {
1936
+ display: block;
1937
+ width: 100%;
1938
+ }
1939
+ .btn-block + .btn-block {
1940
+ margin-top: 5px;
1941
+ }
1942
+ input[type="submit"].btn-block,
1943
+ input[type="reset"].btn-block,
1944
+ input[type="button"].btn-block {
1945
+ width: 100%;
1946
+ }
1947
+ .fade {
1948
+ opacity: 0;
1949
+ -webkit-transition: opacity 0.15s linear;
1950
+ -o-transition: opacity 0.15s linear;
1951
+ transition: opacity 0.15s linear;
1952
+ }
1953
+ .fade.in {
1954
+ opacity: 1;
1955
+ }
1956
+ .collapse {
1957
+ display: none;
1958
+ }
1959
+ .collapse.in {
1960
+ display: block;
1961
+ }
1962
+ tr.collapse.in {
1963
+ display: table-row;
1964
+ }
1965
+ tbody.collapse.in {
1966
+ display: table-row-group;
1967
+ }
1968
+ .collapsing {
1969
+ position: relative;
1970
+ height: 0;
1971
+ overflow: hidden;
1972
+ -webkit-transition-property: height, visibility;
1973
+ -o-transition-property: height, visibility;
1974
+ transition-property: height, visibility;
1975
+ -webkit-transition-duration: 0.35s;
1976
+ -o-transition-duration: 0.35s;
1977
+ transition-duration: 0.35s;
1978
+ -webkit-transition-timing-function: ease;
1979
+ -o-transition-timing-function: ease;
1980
+ transition-timing-function: ease;
1981
+ }
1982
+ .btn-group,
1983
+ .btn-group-vertical {
1984
+ position: relative;
1985
+ display: inline-block;
1986
+ vertical-align: middle;
1987
+ }
1988
+ .btn-group > .btn,
1989
+ .btn-group-vertical > .btn {
1990
+ position: relative;
1991
+ float: left;
1992
+ }
1993
+ .btn-group > .btn:hover,
1994
+ .btn-group-vertical > .btn:hover,
1995
+ .btn-group > .btn:focus,
1996
+ .btn-group-vertical > .btn:focus,
1997
+ .btn-group > .btn:active,
1998
+ .btn-group-vertical > .btn:active,
1999
+ .btn-group > .btn.active,
2000
+ .btn-group-vertical > .btn.active {
2001
+ z-index: 2;
2002
+ }
2003
+ .btn-group .btn + .btn,
2004
+ .btn-group .btn + .btn-group,
2005
+ .btn-group .btn-group + .btn,
2006
+ .btn-group .btn-group + .btn-group {
2007
+ margin-left: -1px;
2008
+ }
2009
+ .btn-toolbar {
2010
+ margin-left: -5px;
2011
+ }
2012
+ .btn-toolbar .btn,
2013
+ .btn-toolbar .btn-group,
2014
+ .btn-toolbar .input-group {
2015
+ float: left;
2016
+ }
2017
+ .btn-toolbar > .btn,
2018
+ .btn-toolbar > .btn-group,
2019
+ .btn-toolbar > .input-group {
2020
+ margin-left: 5px;
2021
+ }
2022
+ .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
2023
+ border-radius: 0;
2024
+ }
2025
+ .btn-group > .btn:first-child {
2026
+ margin-left: 0;
2027
+ }
2028
+ .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
2029
+ border-bottom-right-radius: 0;
2030
+ border-top-right-radius: 0;
2031
+ }
2032
+ .btn-group > .btn:last-child:not(:first-child),
2033
+ .btn-group > .dropdown-toggle:not(:first-child) {
2034
+ border-bottom-left-radius: 0;
2035
+ border-top-left-radius: 0;
2036
+ }
2037
+ .btn-group > .btn-group {
2038
+ float: left;
2039
+ }
2040
+ .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
2041
+ border-radius: 0;
2042
+ }
2043
+ .btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
2044
+ .btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
2045
+ border-bottom-right-radius: 0;
2046
+ border-top-right-radius: 0;
2047
+ }
2048
+ .btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
2049
+ border-bottom-left-radius: 0;
2050
+ border-top-left-radius: 0;
2051
+ }
2052
+ .btn-group .dropdown-toggle:active,
2053
+ .btn-group.open .dropdown-toggle {
2054
+ outline: 0;
2055
+ }
2056
+ .btn-group > .btn + .dropdown-toggle {
2057
+ padding-left: 8px;
2058
+ padding-right: 8px;
2059
+ }
2060
+ .btn-group > .btn-lg + .dropdown-toggle {
2061
+ padding-left: 12px;
2062
+ padding-right: 12px;
2063
+ }
2064
+ .btn-group.open .dropdown-toggle {
2065
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
2066
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
2067
+ }
2068
+ .btn-group.open .dropdown-toggle.btn-link {
2069
+ -webkit-box-shadow: none;
2070
+ box-shadow: none;
2071
+ }
2072
+ .btn .caret {
2073
+ margin-left: 0;
2074
+ }
2075
+ .btn-lg .caret {
2076
+ border-width: 5px 5px 0;
2077
+ border-bottom-width: 0;
2078
+ }
2079
+ .dropup .btn-lg .caret {
2080
+ border-width: 0 5px 5px;
2081
+ }
2082
+ .btn-group-vertical > .btn,
2083
+ .btn-group-vertical > .btn-group,
2084
+ .btn-group-vertical > .btn-group > .btn {
2085
+ display: block;
2086
+ float: none;
2087
+ width: 100%;
2088
+ max-width: 100%;
2089
+ }
2090
+ .btn-group-vertical > .btn-group > .btn {
2091
+ float: none;
2092
+ }
2093
+ .btn-group-vertical > .btn + .btn,
2094
+ .btn-group-vertical > .btn + .btn-group,
2095
+ .btn-group-vertical > .btn-group + .btn,
2096
+ .btn-group-vertical > .btn-group + .btn-group {
2097
+ margin-top: -1px;
2098
+ margin-left: 0;
2099
+ }
2100
+ .btn-group-vertical > .btn:not(:first-child):not(:last-child) {
2101
+ border-radius: 0;
2102
+ }
2103
+ .btn-group-vertical > .btn:first-child:not(:last-child) {
2104
+ border-top-right-radius: 4px;
2105
+ border-top-left-radius: 4px;
2106
+ border-bottom-right-radius: 0;
2107
+ border-bottom-left-radius: 0;
2108
+ }
2109
+ .btn-group-vertical > .btn:last-child:not(:first-child) {
2110
+ border-top-right-radius: 0;
2111
+ border-top-left-radius: 0;
2112
+ border-bottom-right-radius: 4px;
2113
+ border-bottom-left-radius: 4px;
2114
+ }
2115
+ .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
2116
+ border-radius: 0;
2117
+ }
2118
+ .btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
2119
+ .btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
2120
+ border-bottom-right-radius: 0;
2121
+ border-bottom-left-radius: 0;
2122
+ }
2123
+ .btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
2124
+ border-top-right-radius: 0;
2125
+ border-top-left-radius: 0;
2126
+ }
2127
+ .btn-group-justified {
2128
+ display: table;
2129
+ width: 100%;
2130
+ table-layout: fixed;
2131
+ border-collapse: separate;
2132
+ }
2133
+ .btn-group-justified > .btn,
2134
+ .btn-group-justified > .btn-group {
2135
+ float: none;
2136
+ display: table-cell;
2137
+ width: 1%;
2138
+ }
2139
+ .btn-group-justified > .btn-group .btn {
2140
+ width: 100%;
2141
+ }
2142
+ .btn-group-justified > .btn-group .dropdown-menu {
2143
+ left: auto;
2144
+ }
2145
+ [data-toggle="buttons"] > .btn input[type="radio"],
2146
+ [data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
2147
+ [data-toggle="buttons"] > .btn input[type="checkbox"],
2148
+ [data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
2149
+ position: absolute;
2150
+ clip: rect(0, 0, 0, 0);
2151
+ pointer-events: none;
2152
+ }
2153
+ .input-group {
2154
+ position: relative;
2155
+ display: table;
2156
+ border-collapse: separate;
2157
+ }
2158
+ .input-group[class*="col-"] {
2159
+ float: none;
2160
+ padding-left: 0;
2161
+ padding-right: 0;
2162
+ }
2163
+ .input-group .form-control {
2164
+ position: relative;
2165
+ z-index: 2;
2166
+ float: left;
2167
+ width: 100%;
2168
+ margin-bottom: 0;
2169
+ }
2170
+ .input-group .form-control:focus {
2171
+ z-index: 3;
2172
+ }
2173
+ .input-group-lg > .form-control,
2174
+ .input-group-lg > .input-group-addon,
2175
+ .input-group-lg > .input-group-btn > .btn {
2176
+ height: 46px;
2177
+ padding: 10px 16px;
2178
+ font-size: 18px;
2179
+ line-height: 1.3333333;
2180
+ border-radius: 6px;
2181
+ }
2182
+ select.input-group-lg > .form-control,
2183
+ select.input-group-lg > .input-group-addon,
2184
+ select.input-group-lg > .input-group-btn > .btn {
2185
+ height: 46px;
2186
+ line-height: 46px;
2187
+ }
2188
+ textarea.input-group-lg > .form-control,
2189
+ textarea.input-group-lg > .input-group-addon,
2190
+ textarea.input-group-lg > .input-group-btn > .btn,
2191
+ select[multiple].input-group-lg > .form-control,
2192
+ select[multiple].input-group-lg > .input-group-addon,
2193
+ select[multiple].input-group-lg > .input-group-btn > .btn {
2194
+ height: auto;
2195
+ }
2196
+ .input-group-sm > .form-control,
2197
+ .input-group-sm > .input-group-addon,
2198
+ .input-group-sm > .input-group-btn > .btn {
2199
+ height: 30px;
2200
+ padding: 5px 10px;
2201
+ font-size: 12px;
2202
+ line-height: 1.5;
2203
+ border-radius: 3px;
2204
+ }
2205
+ select.input-group-sm > .form-control,
2206
+ select.input-group-sm > .input-group-addon,
2207
+ select.input-group-sm > .input-group-btn > .btn {
2208
+ height: 30px;
2209
+ line-height: 30px;
2210
+ }
2211
+ textarea.input-group-sm > .form-control,
2212
+ textarea.input-group-sm > .input-group-addon,
2213
+ textarea.input-group-sm > .input-group-btn > .btn,
2214
+ select[multiple].input-group-sm > .form-control,
2215
+ select[multiple].input-group-sm > .input-group-addon,
2216
+ select[multiple].input-group-sm > .input-group-btn > .btn {
2217
+ height: auto;
2218
+ }
2219
+ .input-group-addon,
2220
+ .input-group-btn,
2221
+ .input-group .form-control {
2222
+ display: table-cell;
2223
+ }
2224
+ .input-group-addon:not(:first-child):not(:last-child),
2225
+ .input-group-btn:not(:first-child):not(:last-child),
2226
+ .input-group .form-control:not(:first-child):not(:last-child) {
2227
+ border-radius: 0;
2228
+ }
2229
+ .input-group-addon,
2230
+ .input-group-btn {
2231
+ width: 1%;
2232
+ white-space: nowrap;
2233
+ vertical-align: middle;
2234
+ }
2235
+ .input-group-addon {
2236
+ padding: 6px 12px;
2237
+ font-size: 14px;
2238
+ font-weight: normal;
2239
+ line-height: 1;
2240
+ color: #555555;
2241
+ text-align: center;
2242
+ background-color: #eeeeee;
2243
+ border: 1px solid #cccccc;
2244
+ border-radius: 4px;
2245
+ }
2246
+ .input-group-addon.input-sm {
2247
+ padding: 5px 10px;
2248
+ font-size: 12px;
2249
+ border-radius: 3px;
2250
+ }
2251
+ .input-group-addon.input-lg {
2252
+ padding: 10px 16px;
2253
+ font-size: 18px;
2254
+ border-radius: 6px;
2255
+ }
2256
+ .input-group-addon input[type="radio"],
2257
+ .input-group-addon input[type="checkbox"] {
2258
+ margin-top: 0;
2259
+ }
2260
+ .input-group .form-control:first-child,
2261
+ .input-group-addon:first-child,
2262
+ .input-group-btn:first-child > .btn,
2263
+ .input-group-btn:first-child > .btn-group > .btn,
2264
+ .input-group-btn:first-child > .dropdown-toggle,
2265
+ .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
2266
+ .input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
2267
+ border-bottom-right-radius: 0;
2268
+ border-top-right-radius: 0;
2269
+ }
2270
+ .input-group-addon:first-child {
2271
+ border-right: 0;
2272
+ }
2273
+ .input-group .form-control:last-child,
2274
+ .input-group-addon:last-child,
2275
+ .input-group-btn:last-child > .btn,
2276
+ .input-group-btn:last-child > .btn-group > .btn,
2277
+ .input-group-btn:last-child > .dropdown-toggle,
2278
+ .input-group-btn:first-child > .btn:not(:first-child),
2279
+ .input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
2280
+ border-bottom-left-radius: 0;
2281
+ border-top-left-radius: 0;
2282
+ }
2283
+ .input-group-addon:last-child {
2284
+ border-left: 0;
2285
+ }
2286
+ .input-group-btn {
2287
+ position: relative;
2288
+ font-size: 0;
2289
+ white-space: nowrap;
2290
+ }
2291
+ .input-group-btn > .btn {
2292
+ position: relative;
2293
+ }
2294
+ .input-group-btn > .btn + .btn {
2295
+ margin-left: -1px;
2296
+ }
2297
+ .input-group-btn > .btn:hover,
2298
+ .input-group-btn > .btn:focus,
2299
+ .input-group-btn > .btn:active {
2300
+ z-index: 2;
2301
+ }
2302
+ .input-group-btn:first-child > .btn,
2303
+ .input-group-btn:first-child > .btn-group {
2304
+ margin-right: -1px;
2305
+ }
2306
+ .input-group-btn:last-child > .btn,
2307
+ .input-group-btn:last-child > .btn-group {
2308
+ z-index: 2;
2309
+ margin-left: -1px;
2310
+ }
2311
+ .close {
2312
+ float: right;
2313
+ font-size: 21px;
2314
+ font-weight: bold;
2315
+ line-height: 1;
2316
+ color: #000000;
2317
+ text-shadow: 0 1px 0 #ffffff;
2318
+ opacity: 0.2;
2319
+ filter: alpha(opacity=20);
2320
+ }
2321
+ .close:hover,
2322
+ .close:focus {
2323
+ color: #000000;
2324
+ text-decoration: none;
2325
+ cursor: pointer;
2326
+ opacity: 0.5;
2327
+ filter: alpha(opacity=50);
2328
+ }
2329
+ button.close {
2330
+ padding: 0;
2331
+ cursor: pointer;
2332
+ background: transparent;
2333
+ border: 0;
2334
+ -webkit-appearance: none;
2335
+ }
2336
+ .modal-open {
2337
+ overflow: hidden;
2338
+ }
2339
+ .modal {
2340
+ display: none;
2341
+ overflow: hidden;
2342
+ position: fixed;
2343
+ top: 0;
2344
+ right: 0;
2345
+ bottom: 0;
2346
+ left: 0;
2347
+ z-index: 1050;
2348
+ -webkit-overflow-scrolling: touch;
2349
+ outline: 0;
2350
+ }
2351
+ .modal.fade .modal-dialog {
2352
+ -webkit-transform: translate(0, -25%);
2353
+ -ms-transform: translate(0, -25%);
2354
+ -o-transform: translate(0, -25%);
2355
+ transform: translate(0, -25%);
2356
+ -webkit-transition: -webkit-transform 0.3s ease-out;
2357
+ -o-transition: -o-transform 0.3s ease-out;
2358
+ transition: transform 0.3s ease-out;
2359
+ }
2360
+ .modal.in .modal-dialog {
2361
+ -webkit-transform: translate(0, 0);
2362
+ -ms-transform: translate(0, 0);
2363
+ -o-transform: translate(0, 0);
2364
+ transform: translate(0, 0);
2365
+ }
2366
+ .modal-open .modal {
2367
+ overflow-x: hidden;
2368
+ overflow-y: auto;
2369
+ }
2370
+ .modal-dialog {
2371
+ position: relative;
2372
+ width: auto;
2373
+ margin: 10px;
2374
+ }
2375
+ .modal-content {
2376
+ position: relative;
2377
+ background-color: #ffffff;
2378
+ border: 1px solid #999999;
2379
+ border: 1px solid rgba(0, 0, 0, 0.2);
2380
+ border-radius: 6px;
2381
+ -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
2382
+ box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
2383
+ -webkit-background-clip: padding-box;
2384
+ background-clip: padding-box;
2385
+ outline: 0;
2386
+ }
2387
+ .modal-backdrop {
2388
+ position: fixed;
2389
+ top: 0;
2390
+ right: 0;
2391
+ bottom: 0;
2392
+ left: 0;
2393
+ z-index: 1040;
2394
+ background-color: #000000;
2395
+ }
2396
+ .modal-backdrop.fade {
2397
+ opacity: 0;
2398
+ filter: alpha(opacity=0);
2399
+ }
2400
+ .modal-backdrop.in {
2401
+ opacity: 0.5;
2402
+ filter: alpha(opacity=50);
2403
+ }
2404
+ .modal-header {
2405
+ padding: 15px;
2406
+ border-bottom: 1px solid #e5e5e5;
2407
+ }
2408
+ .modal-header .close {
2409
+ margin-top: -2px;
2410
+ }
2411
+ .modal-title {
2412
+ margin: 0;
2413
+ line-height: 1.42857143;
2414
+ }
2415
+ .modal-body {
2416
+ position: relative;
2417
+ padding: 15px;
2418
+ }
2419
+ .modal-footer {
2420
+ padding: 15px;
2421
+ text-align: right;
2422
+ border-top: 1px solid #e5e5e5;
2423
+ }
2424
+ .modal-footer .btn + .btn {
2425
+ margin-left: 5px;
2426
+ margin-bottom: 0;
2427
+ }
2428
+ .modal-footer .btn-group .btn + .btn {
2429
+ margin-left: -1px;
2430
+ }
2431
+ .modal-footer .btn-block + .btn-block {
2432
+ margin-left: 0;
2433
+ }
2434
+ .modal-scrollbar-measure {
2435
+ position: absolute;
2436
+ top: -9999px;
2437
+ width: 50px;
2438
+ height: 50px;
2439
+ overflow: scroll;
2440
+ }
2441
+ @media (min-width: 768px) {
2442
+ .modal-dialog {
2443
+ width: 600px;
2444
+ margin: 30px auto;
2445
+ }
2446
+ .modal-content {
2447
+ -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
2448
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
2449
+ }
2450
+ .modal-sm {
2451
+ width: 300px;
2452
+ }
2453
+ }
2454
+ @media (min-width: 992px) {
2455
+ .modal-lg {
2456
+ width: 900px;
2457
+ }
2458
+ }
2459
+ .clearfix:before,
2460
+ .clearfix:after,
2461
+ .container:before,
2462
+ .container:after,
2463
+ .container-fluid:before,
2464
+ .container-fluid:after,
2465
+ .row:before,
2466
+ .row:after,
2467
+ .form-horizontal .form-group:before,
2468
+ .form-horizontal .form-group:after,
2469
+ .btn-toolbar:before,
2470
+ .btn-toolbar:after,
2471
+ .btn-group-vertical > .btn-group:before,
2472
+ .btn-group-vertical > .btn-group:after,
2473
+ .modal-header:before,
2474
+ .modal-header:after,
2475
+ .modal-footer:before,
2476
+ .modal-footer:after {
2477
+ content: " ";
2478
+ display: table;
2479
+ }
2480
+ .clearfix:after,
2481
+ .container:after,
2482
+ .container-fluid:after,
2483
+ .row:after,
2484
+ .form-horizontal .form-group:after,
2485
+ .btn-toolbar:after,
2486
+ .btn-group-vertical > .btn-group:after,
2487
+ .modal-header:after,
2488
+ .modal-footer:after {
2489
+ clear: both;
2490
+ }
2491
+ .center-block {
2492
+ display: block;
2493
+ margin-left: auto;
2494
+ margin-right: auto;
2495
+ }
2496
+ .pull-right {
2497
+ float: right !important;
2498
+ }
2499
+ .pull-left {
2500
+ float: left !important;
2501
+ }
2502
+ .hide {
2503
+ display: none !important;
2504
+ }
2505
+ .show {
2506
+ display: block !important;
2507
+ }
2508
+ .invisible {
2509
+ visibility: hidden;
2510
+ }
2511
+ .text-hide {
2512
+ font: 0/0 a;
2513
+ color: transparent;
2514
+ text-shadow: none;
2515
+ background-color: transparent;
2516
+ border: 0;
2517
+ }
2518
+ .hidden {
2519
+ display: none !important;
2520
+ }
2521
+ .affix {
2522
+ position: fixed;
2523
+ }
2524
+ @-ms-viewport {
2525
+ width: device-width;
2526
+ }
2527
+ .visible-xs,
2528
+ .visible-sm,
2529
+ .visible-md,
2530
+ .visible-lg {
2531
+ display: none !important;
2532
+ }
2533
+ .visible-xs-block,
2534
+ .visible-xs-inline,
2535
+ .visible-xs-inline-block,
2536
+ .visible-sm-block,
2537
+ .visible-sm-inline,
2538
+ .visible-sm-inline-block,
2539
+ .visible-md-block,
2540
+ .visible-md-inline,
2541
+ .visible-md-inline-block,
2542
+ .visible-lg-block,
2543
+ .visible-lg-inline,
2544
+ .visible-lg-inline-block {
2545
+ display: none !important;
2546
+ }
2547
+ @media (max-width: 767px) {
2548
+ .visible-xs {
2549
+ display: block !important;
2550
+ }
2551
+ table.visible-xs {
2552
+ display: table !important;
2553
+ }
2554
+ tr.visible-xs {
2555
+ display: table-row !important;
2556
+ }
2557
+ th.visible-xs,
2558
+ td.visible-xs {
2559
+ display: table-cell !important;
2560
+ }
2561
+ }
2562
+ @media (max-width: 767px) {
2563
+ .visible-xs-block {
2564
+ display: block !important;
2565
+ }
2566
+ }
2567
+ @media (max-width: 767px) {
2568
+ .visible-xs-inline {
2569
+ display: inline !important;
2570
+ }
2571
+ }
2572
+ @media (max-width: 767px) {
2573
+ .visible-xs-inline-block {
2574
+ display: inline-block !important;
2575
+ }
2576
+ }
2577
+ @media (min-width: 768px) and (max-width: 991px) {
2578
+ .visible-sm {
2579
+ display: block !important;
2580
+ }
2581
+ table.visible-sm {
2582
+ display: table !important;
2583
+ }
2584
+ tr.visible-sm {
2585
+ display: table-row !important;
2586
+ }
2587
+ th.visible-sm,
2588
+ td.visible-sm {
2589
+ display: table-cell !important;
2590
+ }
2591
+ }
2592
+ @media (min-width: 768px) and (max-width: 991px) {
2593
+ .visible-sm-block {
2594
+ display: block !important;
2595
+ }
2596
+ }
2597
+ @media (min-width: 768px) and (max-width: 991px) {
2598
+ .visible-sm-inline {
2599
+ display: inline !important;
2600
+ }
2601
+ }
2602
+ @media (min-width: 768px) and (max-width: 991px) {
2603
+ .visible-sm-inline-block {
2604
+ display: inline-block !important;
2605
+ }
2606
+ }
2607
+ @media (min-width: 992px) and (max-width: 1199px) {
2608
+ .visible-md {
2609
+ display: block !important;
2610
+ }
2611
+ table.visible-md {
2612
+ display: table !important;
2613
+ }
2614
+ tr.visible-md {
2615
+ display: table-row !important;
2616
+ }
2617
+ th.visible-md,
2618
+ td.visible-md {
2619
+ display: table-cell !important;
2620
+ }
2621
+ }
2622
+ @media (min-width: 992px) and (max-width: 1199px) {
2623
+ .visible-md-block {
2624
+ display: block !important;
2625
+ }
2626
+ }
2627
+ @media (min-width: 992px) and (max-width: 1199px) {
2628
+ .visible-md-inline {
2629
+ display: inline !important;
2630
+ }
2631
+ }
2632
+ @media (min-width: 992px) and (max-width: 1199px) {
2633
+ .visible-md-inline-block {
2634
+ display: inline-block !important;
2635
+ }
2636
+ }
2637
+ @media (min-width: 1200px) {
2638
+ .visible-lg {
2639
+ display: block !important;
2640
+ }
2641
+ table.visible-lg {
2642
+ display: table !important;
2643
+ }
2644
+ tr.visible-lg {
2645
+ display: table-row !important;
2646
+ }
2647
+ th.visible-lg,
2648
+ td.visible-lg {
2649
+ display: table-cell !important;
2650
+ }
2651
+ }
2652
+ @media (min-width: 1200px) {
2653
+ .visible-lg-block {
2654
+ display: block !important;
2655
+ }
2656
+ }
2657
+ @media (min-width: 1200px) {
2658
+ .visible-lg-inline {
2659
+ display: inline !important;
2660
+ }
2661
+ }
2662
+ @media (min-width: 1200px) {
2663
+ .visible-lg-inline-block {
2664
+ display: inline-block !important;
2665
+ }
2666
+ }
2667
+ @media (max-width: 767px) {
2668
+ .hidden-xs {
2669
+ display: none !important;
2670
+ }
2671
+ }
2672
+ @media (min-width: 768px) and (max-width: 991px) {
2673
+ .hidden-sm {
2674
+ display: none !important;
2675
+ }
2676
+ }
2677
+ @media (min-width: 992px) and (max-width: 1199px) {
2678
+ .hidden-md {
2679
+ display: none !important;
2680
+ }
2681
+ }
2682
+ @media (min-width: 1200px) {
2683
+ .hidden-lg {
2684
+ display: none !important;
2685
+ }
2686
+ }
2687
+ .visible-print {
2688
+ display: none !important;
2689
+ }
2690
+ @media print {
2691
+ .visible-print {
2692
+ display: block !important;
2693
+ }
2694
+ table.visible-print {
2695
+ display: table !important;
2696
+ }
2697
+ tr.visible-print {
2698
+ display: table-row !important;
2699
+ }
2700
+ th.visible-print,
2701
+ td.visible-print {
2702
+ display: table-cell !important;
2703
+ }
2704
+ }
2705
+ .visible-print-block {
2706
+ display: none !important;
2707
+ }
2708
+ @media print {
2709
+ .visible-print-block {
2710
+ display: block !important;
2711
+ }
2712
+ }
2713
+ .visible-print-inline {
2714
+ display: none !important;
2715
+ }
2716
+ @media print {
2717
+ .visible-print-inline {
2718
+ display: inline !important;
2719
+ }
2720
+ }
2721
+ .visible-print-inline-block {
2722
+ display: none !important;
2723
+ }
2724
+ @media print {
2725
+ .visible-print-inline-block {
2726
+ display: inline-block !important;
2727
+ }
2728
+ }
2729
+ @media print {
2730
+ .hidden-print {
2731
+ display: none !important;
2732
+ }
2733
+ }
assets/css/vendor/bootstrap/bootstrap.min.css ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Bootstrap v3.3.5 (http://getbootstrap.com)
3
+ * Copyright 2011-2016 Twitter, Inc.
4
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5
+ */
6
+
7
+ /*!
8
+ * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=f9591b2f58105c5fa28db0e6eba864bd)
9
+ * Config saved to config.json and https://gist.github.com/f9591b2f58105c5fa28db0e6eba864bd
10
+ *//*!
11
+ * Bootstrap v3.3.6 (http://getbootstrap.com)
12
+ * Copyright 2011-2015 Twitter, Inc.
13
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
14
+ *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:transparent}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:hover,a:focus{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:transparent;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role="button"]{cursor:pointer}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}input[type="range"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{border:0;background-color:transparent}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type="date"].form-control,input[type="time"].form-control,input[type="datetime-local"].form-control,input[type="month"].form-control{line-height:34px}input[type="date"].input-sm,input[type="time"].input-sm,input[type="datetime-local"].input-sm,input[type="month"].input-sm,.input-group-sm input[type="date"],.input-group-sm input[type="time"],.input-group-sm input[type="datetime-local"],.input-group-sm input[type="month"]{line-height:30px}input[type="date"].input-lg,input[type="time"].input-lg,input[type="datetime-local"].input-lg,input[type="month"].input-lg,.input-group-lg input[type="date"],.input-group-lg input[type="time"],.input-group-lg input[type="datetime-local"],.input-group-lg input[type="month"]{line-height:46px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:absolute;margin-left:-20px;margin-top:4px \9}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"].disabled,input[type="checkbox"].disabled,fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0;min-height:34px}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm textarea.form-control,.form-group-sm select[multiple].form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg textarea.form-control,.form-group-lg select[multiple].form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback,.input-group-lg+.form-control-feedback,.form-group-lg .form-control+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback,.input-group-sm+.form-control-feedback,.form-group-sm .form-control+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:7px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:focus,.btn-default.focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active:hover,.btn-default.active:hover,.open>.dropdown-toggle.btn-default:hover,.btn-default:active:focus,.btn-default.active:focus,.open>.dropdown-toggle.btn-default:focus,.btn-default:active.focus,.btn-default.active.focus,.open>.dropdown-toggle.btn-default.focus{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary:focus,.btn-primary.focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active:hover,.btn-primary.active:hover,.open>.dropdown-toggle.btn-primary:hover,.btn-primary:active:focus,.btn-primary.active:focus,.open>.dropdown-toggle.btn-primary:focus,.btn-primary:active.focus,.btn-primary.active.focus,.open>.dropdown-toggle.btn-primary.focus{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:focus,.btn-success.focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active:hover,.btn-success.active:hover,.open>.dropdown-toggle.btn-success:hover,.btn-success:active:focus,.btn-success.active:focus,.open>.dropdown-toggle.btn-success:focus,.btn-success:active.focus,.btn-success.active.focus,.open>.dropdown-toggle.btn-success.focus{color:#fff;background-color:#398439;border-color:#255625}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:focus,.btn-info.focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active:hover,.btn-info.active:hover,.open>.dropdown-toggle.btn-info:hover,.btn-info:active:focus,.btn-info.active:focus,.open>.dropdown-toggle.btn-info:focus,.btn-info:active.focus,.btn-info.active.focus,.open>.dropdown-toggle.btn-info.focus{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:focus,.btn-warning.focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active:hover,.btn-warning.active:hover,.open>.dropdown-toggle.btn-warning:hover,.btn-warning:active:focus,.btn-warning.active:focus,.open>.dropdown-toggle.btn-warning:focus,.btn-warning:active.focus,.btn-warning.active.focus,.open>.dropdown-toggle.btn-warning.focus{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:focus,.btn-danger.focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active:hover,.btn-danger.active:hover,.open>.dropdown-toggle.btn-danger:hover,.btn-danger:active:focus,.btn-danger.active:focus,.open>.dropdown-toggle.btn-danger:focus,.btn-danger:active.focus,.btn-danger.active.focus,.open>.dropdown-toggle.btn-danger.focus{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#337ab7;font-weight:normal;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height, visibility;-o-transition-property:height, visibility;transition-property:height, visibility;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle="buttons"]>.btn input[type="radio"],[data-toggle="buttons"]>.btn-group>.btn input[type="radio"],[data-toggle="buttons"]>.btn input[type="checkbox"],[data-toggle="buttons"]>.btn-group>.btn input[type="checkbox"]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*="col-"]{float:none;padding-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:normal;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:hidden;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0, -25%);-ms-transform:translate(0, -25%);-o-transform:translate(0, -25%);transform:translate(0, -25%);-webkit-transition:-webkit-transform 0.3s ease-out;-o-transition:-o-transform 0.3s ease-out;transition:transform 0.3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);-webkit-background-clip:padding-box;background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.clearfix:before,.clearfix:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.modal-header:before,.modal-header:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.clearfix:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.modal-header:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none !important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none !important}@media (max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table !important}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media (max-width:767px){.visible-xs-block{display:block !important}}@media (max-width:767px){.visible-xs-inline{display:inline !important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table !important}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table !important}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block !important}}@media (min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table !important}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}@media (min-width:1200px){.visible-lg-block{display:block !important}}@media (min-width:1200px){.visible-lg-inline{display:inline !important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block !important}}@media (max-width:767px){.hidden-xs{display:none !important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none !important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none !important}}@media (min-width:1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table !important}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}.visible-print-block{display:none !important}@media print{.visible-print-block{display:block !important}}.visible-print-inline{display:none !important}@media print{.visible-print-inline{display:inline !important}}.visible-print-inline-block{display:none !important}@media print{.visible-print-inline-block{display:inline-block !important}}@media print{.hidden-print{display:none !important}}
assets/css/vendor/bootstrap/index.html ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>403 Forbidden</title>
5
+ </head>
6
+ <body>
7
+ <p>Directory access is forbidden.</p>
8
+ </body>
9
+ </html>
assets/css/vendor/index.html ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>403 Forbidden</title>
5
+ </head>
6
+ <body>
7
+ <p>Directory access is forbidden.</p>
8
+ </body>
9
+ </html>
assets/fonts/embedpress.eot ADDED
Binary file
assets/fonts/embedpress.svg ADDED
@@ -0,0 +1 @@
 
1
+ <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" ><svg xmlns="http://www.w3.org/2000/svg"><metadata>Generated by Glyphter</metadata><defs><font id="embedpress" horiz-adv-x="0"><font-face units-per-em="1024" ascent="1024" descent="0" font-family="embedpress" font-weight="normal" /><missing-glyph horiz-adv-x="0" /><glyph unicode="&#x0041;" d="M245.836,87.022C245.836,87.022,307.34,148.527,307.34,148.527C307.34,148.527,148.527,307.34,148.527,307.34C148.527,307.34,87.022,245.836,87.022,245.836C87.022,245.836,87.022,173.507,87.022,173.507C87.022,173.507,173.545,173.507,173.545,173.507C173.545,173.507,173.545,86.985,173.545,86.985C173.545,86.985,245.874,86.985,245.874,86.985C245.874,86.985,245.836,87.022,245.836,87.022M599.306,714.253C599.306,724.17,594.348,729.128,584.432,729.128C579.928,729.128,576.067,727.538,572.926,724.397C572.926,724.397,206.587,358.058,206.587,358.058C203.445,354.916,201.856,351.056,201.856,346.552C201.856,336.635,206.814,331.677,216.73,331.677C221.234,331.677,225.095,333.267,228.236,336.408C228.236,336.408,594.575,702.747,594.575,702.747C597.717,705.889,599.306,709.749,599.306,714.253C599.306,714.253,599.306,714.253,599.306,714.253M562.82,843.999C562.82,843.999,843.999,562.82,843.999,562.82C843.999,562.82,281.679,0.5,281.679,0.5C281.679,0.5,0.5,0.5,0.5,0.5C0.5,0.5,0.5,281.679,0.5,281.679C0.5,281.679,562.82,843.999,562.82,843.999M1024.462,779.126C1024.462,755.243,1016.135,734.994,999.444,718.303C999.444,718.303,887.26,606.119,887.26,606.119C887.26,606.119,606.081,887.298,606.081,887.298C606.081,887.298,718.265,998.801,718.265,998.801C734.502,1015.946,754.751,1024.5,779.088,1024.5C802.971,1024.5,823.447,1015.946,840.593,998.801C840.593,998.801,999.406,840.63,999.406,840.63C1016.098,823.069,1024.424,802.554,1024.424,779.126C1024.424,779.126,1024.462,779.126,1024.462,779.126" class="icon-pencil"/><glyph unicode="&#x0042;" d="M683.067,511.963C683.067,559.075,666.417,599.281,633.08,632.618C599.743,665.955,559.538,682.604,512.425,682.604C465.313,682.604,425.107,665.955,391.77,632.618C358.433,599.281,341.784,559.075,341.784,511.963C341.784,464.85,358.433,424.645,391.77,391.308C425.107,357.971,465.313,341.321,512.425,341.321C559.538,341.321,599.743,357.971,633.08,391.308C666.417,424.645,683.067,464.85,683.067,511.963C683.067,511.963,683.067,511.963,683.067,511.963M1024.388,584.61C1024.388,584.61,1024.388,436.628,1024.388,436.628C1024.388,431.29,1022.596,426.175,1019.05,421.285C1015.503,416.394,1011.061,413.482,1005.722,412.624C1005.722,412.624,882.379,393.958,882.379,393.958C873.943,369.954,865.282,349.758,856.397,333.295C871.964,311.082,895.744,280.396,927.737,241.31C932.179,235.972,934.419,230.447,934.419,224.66C934.419,218.874,932.403,213.76,928.409,209.317C916.426,192.854,894.4,168.85,862.407,137.305C830.414,105.76,809.509,89.969,799.728,89.969C794.389,89.969,788.64,91.985,782.406,95.979C782.406,95.979,690.421,167.991,690.421,167.991C670.86,157.762,650.626,149.326,629.758,142.643C622.628,82.204,616.207,40.878,610.42,18.666C607.322,6.234,599.295,0,586.416,0C586.416,0,438.435,0,438.435,0C432.2,0,426.75,1.904,422.083,5.674C417.417,9.445,414.841,14.223,414.43,20.01C414.43,20.01,395.765,142.681,395.765,142.681C374.001,149.811,353.991,158.024,335.773,167.357C335.773,167.357,241.773,96.016,241.773,96.016C237.33,92.022,231.768,90.006,225.123,90.006C218.889,90.006,213.364,92.433,208.473,97.323C152.476,147.982,115.817,185.313,98.495,209.317C95.396,213.76,93.828,218.874,93.828,224.66C93.828,229.999,95.62,235.113,99.167,240.003C105.849,249.336,117.161,264.12,133.176,284.353C149.191,304.587,161.174,320.266,169.163,331.353C157.18,353.566,148.071,375.591,141.837,397.355C141.837,397.355,19.838,415.349,19.838,415.349C14.051,416.245,9.385,419.008,5.838,423.674C2.292,428.34,0.5,433.567,0.5,439.353C0.5,439.353,0.5,587.335,0.5,587.335C0.5,592.673,2.292,597.788,5.838,602.678C9.385,607.568,13.603,610.48,18.494,611.339C18.494,611.339,142.471,630.005,142.471,630.005C148.706,650.425,157.366,670.882,168.454,691.34C150.684,716.688,126.904,747.337,97.114,783.325C92.671,788.663,90.431,794.001,90.431,799.34C90.431,803.782,92.447,808.897,96.442,814.683C107.977,830.698,129.891,854.59,162.108,886.359C194.325,918.128,215.342,934.031,225.123,934.031C230.909,934.031,236.658,931.791,242.445,927.349C242.445,927.349,334.429,856.009,334.429,856.009C353.991,866.238,374.225,874.674,395.093,881.357C402.223,941.796,408.644,983.122,414.43,1005.334C417.529,1017.766,425.555,1024,438.435,1024C438.435,1024,586.416,1024,586.416,1024C592.65,1024,598.101,1022.096,602.767,1018.326C607.434,1014.555,610.01,1009.777,610.42,1003.99C610.42,1003.99,629.086,881.319,629.086,881.319C650.85,874.189,670.86,865.976,689.077,856.643C689.077,856.643,783.75,927.984,783.75,927.984C787.744,931.978,793.083,933.994,799.765,933.994C805.551,933.994,811.076,931.754,816.415,927.312C873.756,874.413,910.415,836.634,926.393,813.974C929.492,810.427,931.06,805.537,931.06,799.302C931.06,793.964,929.268,788.85,925.721,783.959C919.039,774.626,907.727,759.843,891.712,739.609C875.697,719.376,863.714,703.697,855.725,692.609C867.26,670.397,876.369,648.596,883.051,627.279C883.051,627.279,1005.05,608.614,1005.05,608.614C1010.837,607.718,1015.503,604.955,1019.05,600.289C1022.596,595.622,1024.388,590.396,1024.388,584.61C1024.388,584.61,1024.388,584.61,1024.388,584.61" class="icon-gear"/><glyph unicode="&#x0043;" d="M1024.5,200.483C1024.5,177.506,1016.439,157.957,1000.365,141.883C1000.365,141.883,883.117,24.635,883.117,24.635C867.043,8.561,847.494,0.5,824.517,0.5C801.541,0.5,781.991,8.561,765.918,24.635C765.918,24.635,512.5,278.053,512.5,278.053C512.5,278.053,259.082,24.635,259.082,24.635C243.009,8.561,223.459,0.5,200.483,0.5C177.506,0.5,157.957,8.561,141.883,24.635C141.883,24.635,24.635,141.883,24.635,141.883C8.561,157.957,0.5,177.506,0.5,200.483C0.5,223.459,8.561,243.009,24.635,259.082C24.635,259.082,278.053,512.5,278.053,512.5C278.053,512.5,24.635,765.918,24.635,765.918C8.561,781.991,0.5,801.541,0.5,824.517C0.5,847.494,8.561,867.043,24.635,883.117C24.635,883.117,141.883,1000.365,141.883,1000.365C157.957,1016.439,177.506,1024.5,200.483,1024.5C223.459,1024.5,243.009,1016.439,259.082,1000.365C259.082,1000.365,512.5,746.947,512.5,746.947C512.5,746.947,765.918,1000.365,765.918,1000.365C781.991,1016.439,801.541,1024.5,824.517,1024.5C847.494,1024.5,867.043,1016.439,883.117,1000.365C883.117,1000.365,1000.365,883.117,1000.365,883.117C1016.439,867.043,1024.5,847.494,1024.5,824.517C1024.5,801.541,1016.439,781.991,1000.365,765.918C1000.365,765.918,746.947,512.5,746.947,512.5C746.947,512.5,1000.365,259.082,1000.365,259.082C1016.439,243.009,1024.5,223.459,1024.5,200.483C1024.5,200.483,1024.5,200.483,1024.5,200.483" class="icon-x"/><glyph unicode="&#x0044;" d="M1007.313,405.792C1007.313,403.59,1007.089,402.022,1006.642,401.126C978.196,282.006,918.655,185.47,827.98,111.482C737.305,37.494,631.101,0.5,509.331,0.5C444.451,0.5,381.662,12.707,321.001,37.158C260.34,61.609,206.211,96.476,158.69,141.831C158.69,141.831,72.682,55.823,72.682,55.823C64.245,47.387,54.241,43.168,42.668,43.168C31.096,43.168,21.091,47.387,12.655,55.823C4.218,64.26,0,74.264,0,85.836C0,85.836,0,384.477,0,384.477C0,396.012,4.218,406.016,12.655,414.49C21.091,422.964,31.096,427.182,42.668,427.145C42.668,427.145,341.308,427.145,341.308,427.145C352.843,427.145,362.848,422.927,371.322,414.49C379.796,406.053,384.014,396.049,383.977,384.477C383.939,372.904,379.721,362.9,371.322,354.463C371.322,354.463,280.013,263.154,280.013,263.154C311.556,233.813,347.356,211.153,387.336,195.176C427.317,179.199,468.865,171.21,511.981,171.173C571.523,171.173,627.07,185.62,678.623,214.513C730.175,243.406,771.5,283.163,802.596,333.82C807.486,341.398,819.245,367.38,837.91,411.802C841.456,422.031,848.138,427.145,857.919,427.145C857.919,427.145,985.923,427.145,985.923,427.145C991.71,427.145,996.712,425.017,1000.93,420.799C1005.148,416.58,1007.276,411.578,1007.276,405.792C1007.276,405.792,1007.313,405.792,1007.313,405.792M1024,939.089C1024,939.089,1024,640.449,1024,640.449C1024,628.914,1019.782,618.909,1011.345,610.435C1002.909,601.961,992.904,597.743,981.332,597.78C981.332,597.78,682.692,597.78,682.692,597.78C671.157,597.78,661.152,601.999,652.678,610.435C644.204,618.872,639.986,628.876,640.023,640.449C640.061,652.021,644.279,662.025,652.678,670.462C652.678,670.462,744.659,762.443,744.659,762.443C678.884,823.328,601.349,853.752,512.019,853.752C452.477,853.752,396.93,839.306,345.377,810.412C293.825,781.519,252.5,741.762,221.404,691.106C216.514,683.528,204.755,657.546,186.09,613.123C182.544,602.895,175.862,597.78,166.081,597.78C166.081,597.78,33.41,597.78,33.41,597.78C27.624,597.78,22.622,599.908,18.404,604.127C14.185,608.345,12.058,613.347,12.058,619.133C12.058,619.133,12.058,623.799,12.058,623.799C40.951,742.92,100.94,839.455,192.026,913.443C283.111,987.431,389.763,1024.425,511.981,1024.425C576.861,1024.425,639.949,1012.106,701.282,987.431C762.615,962.756,817.042,928.002,864.601,883.094C864.601,883.094,951.244,969.102,951.244,969.102C959.68,977.539,969.685,981.757,981.257,981.757C992.829,981.757,1002.834,977.539,1011.27,969.102C1019.707,960.666,1023.925,950.661,1023.925,939.089C1023.925,939.089,1024,939.089,1024,939.089" class="icon-reload"/></font></defs></svg>
assets/fonts/embedpress.ttf ADDED
Binary file
assets/fonts/embedpress.woff ADDED
Binary file
assets/fonts/index.html ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>403 Forbidden</title>
5
+ </head>
6
+ <body>
7
+ <p>Directory access is forbidden.</p>
8
+ </body>
9
+ </html>
assets/index.html ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>403 Forbidden</title>
5
+ </head>
6
+ <body>
7
+ <p>Directory access is forbidden.</p>
8
+ </body>
9
+ </html>
assets/js/index.html ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>403 Forbidden</title>
5
+ </head>
6
+ <body>
7
+ <p>Directory access is forbidden.</p>
8
+ </body>
9
+ </html>
assets/js/preview.js ADDED
@@ -0,0 +1,1625 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * @package EmbedPress
3
+ * @author PressShack <help@pressshack.com>
4
+ * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
5
+ * @license GPLv2 or later
6
+ * @since 1.0
7
+ */
8
+
9
+ (function(window, $, String, $data) {
10
+ "use strict";
11
+
12
+ $(window.document).ready(function() {
13
+ String.prototype.capitalizeFirstLetter = function() {
14
+ return this.charAt(0).toUpperCase() + this.slice(1);
15
+ }
16
+
17
+ String.prototype.isValidUrl = function() {
18
+ var rule = /^(https?|ftp|embedpresss?):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i;
19
+
20
+ return rule.test(this.toString());
21
+ }
22
+
23
+ String.prototype.hasShortcode = function(shortcode) {
24
+ var shortcodeRule = new RegExp('\\['+ shortcode +'(?:\\]|.+?\\])', "ig");
25
+ return !!this.toString().match(shortcodeRule);
26
+ }
27
+
28
+ String.prototype.stripShortcode = function(shortcode) {
29
+ var stripRule = new RegExp('(\\['+ shortcode +'(?:\\]|.+?\\])|\\[\\/'+ shortcode +'\\])', "ig");
30
+ return this.toString().replace(stripRule, "");
31
+ }
32
+
33
+ String.prototype.setShortcodeAttribute = function(attr, value, shortcode, replaceInsteadOfMerge) {
34
+ replaceInsteadOfMerge = typeof replaceInsteadOfMerge === "undefined" ? false : replaceInsteadOfMerge;
35
+ var subject = this.toString();
36
+
37
+ if (subject.hasShortcode(shortcode)) {
38
+ var attributes = subject.getShortcodeAttributes(shortcode);
39
+
40
+ if (attributes.hasOwnProperty(attr)) {
41
+ if (replaceInsteadOfMerge) {
42
+ attributes[attr] = value;
43
+ } else {
44
+ attributes[attr] += " " + value;
45
+ }
46
+ } else {
47
+ attributes[attr] = value;
48
+ }
49
+
50
+ if (!!Object.keys(attributes).length) {
51
+ var parsedAttributes = [];
52
+ for (var attr in attributes) {
53
+ parsedAttributes.push(attr + '="' + attributes[attr] + '"');
54
+ }
55
+
56
+ subject = '[' + shortcode + ' ' + parsedAttributes.join(" ") + ']' + subject.stripShortcode(shortcode) + '[/' + shortcode + ']';
57
+ } else {
58
+ subject = '[' + shortcode + ']' + subject.stripShortcode(shortcode) + '[/' + shortcode + ']';
59
+ }
60
+
61
+ return subject;
62
+ } else {
63
+ return subject;
64
+ }
65
+ }
66
+
67
+ String.prototype.getShortcodeAttributes = function(shortcode) {
68
+ var subject = this.toString();
69
+ if (subject.hasShortcode(shortcode)) {
70
+ var attributes = {};
71
+ var propertiesString = (new RegExp(/\[embed\s*(.*?)\]/ig)).exec(subject)[1]; // Separate all shortcode attributes from the rest of the string
72
+ if (propertiesString.length > 0) {
73
+ var extractAttributesRule = new RegExp(/(\!?\w+-?\w*)(?:="(.+?)")?/ig); // Extract attributes and their values
74
+ var match;
75
+ while (match = extractAttributesRule.exec(propertiesString)) {
76
+ var attrName = match[1];
77
+ var attrValue;
78
+ if (match[2] === undefined) {
79
+ // Prevent `class` property being empty an treated as a boolean param
80
+ if (attrName.toLowerCase() !== "class") {
81
+ if (attrName.indexOf('!') === 0) {
82
+ attrName = attrName.replace('!', "");
83
+ attrValue = "false";
84
+ } else {
85
+ attrValue = "true";
86
+ }
87
+
88
+ attributes[attrName] = attrValue;
89
+ }
90
+ } else {
91
+ attrValue = match[2];
92
+ if (attrValue.isBoolean()) {
93
+ attrValue = attrValue.isFalse() ? "false" : "true";
94
+ }
95
+
96
+ attributes[attrName] = attrValue;
97
+ }
98
+ }
99
+ match = extractAttributesRule = null;
100
+ }
101
+ propertiesString = null;
102
+
103
+ return attributes;
104
+ } else {
105
+ return {};
106
+ }
107
+ }
108
+
109
+ String.prototype.isBoolean = function() {
110
+ var subject = this.toString().trim().toLowerCase();
111
+
112
+ return subject.isTrue(false) || subject.isFalse();
113
+ };
114
+
115
+ String.prototype.isTrue = function(defaultValue) {
116
+ var subject = this.toString().trim().toLowerCase();
117
+ defaultValue = typeof defaultValue === undefined ? true : defaultValue;
118
+
119
+ switch (subject) {
120
+ case "":
121
+ defaultValue += "";
122
+ return !defaultValue.isFalse();
123
+ case "1":
124
+ case "true":
125
+ case "on":
126
+ case "yes":
127
+ case "y":
128
+ return true;
129
+ default:
130
+ return false;
131
+ }
132
+ };
133
+
134
+ String.prototype.isFalse = function() {
135
+ var subject = this.toString().trim().toLowerCase();
136
+
137
+ switch (subject) {
138
+ case "0":
139
+ case "false":
140
+ case "off":
141
+ case "no":
142
+ case "n":
143
+ case "nil":
144
+ case "null":
145
+ return true;
146
+ default:
147
+ return false;
148
+ }
149
+ };
150
+
151
+ if (!$data.displayPreviewBox.length || $data.displayPreviewBox.isFalse()) {
152
+ return;
153
+ }
154
+
155
+ var SHORTCODE_REGEXP = new RegExp('\\[\/?'+ $data.EMBEDPRESS_SHORTCODE +'\\]', "gi");
156
+
157
+ var EmbedPressPreview = function() {
158
+ var self = this;
159
+
160
+ var PLG_SYSTEM_ASSETS_CSS_PATH = $data.EMBEDPRESS_URL_ASSETS +"css";
161
+ var PLG_CONTENT_ASSETS_CSS_PATH = PLG_SYSTEM_ASSETS_CSS_PATH;
162
+
163
+ /**
164
+ * The default params
165
+ *
166
+ * @type Object
167
+ */
168
+ self.params = {
169
+ juriRoot: '',
170
+ versionUID: '0'
171
+ };
172
+
173
+ /**
174
+ * True, if user agent is iOS
175
+ * @type Boolean True, if is iOS
176
+ */
177
+ self.iOS = /iPad|iPod|iPhone/.test(window.navigator.userAgent);
178
+
179
+ /**
180
+ * The active wrapper, activated by the mouse enter event
181
+ * @type Element
182
+ */
183
+ self.activeWrapper = null;
184
+
185
+ self.activeWrapperForModal = null;
186
+
187
+ /**
188
+ * The active controller panel
189
+ * @type Element
190
+ */
191
+ self.activeControllerPanel = null;
192
+
193
+ /**
194
+ * Init the plugin
195
+ *
196
+ * @param object params Override the plugin's params
197
+ * @return void
198
+ */
199
+ self.init = function (params) {
200
+ $.extend(self.params, params);
201
+
202
+ // Fix iOS doesn't firing click events on 'standard' elements
203
+ if (self.iOS) {
204
+ $(window.document.body).css('cursor', 'pointer');
205
+ }
206
+
207
+ $(self.onReady);
208
+ };
209
+
210
+ self.addEvent = function(event, element, callback) {
211
+ if (typeof element.on !== 'undefined') {
212
+ element.on(event, callback);
213
+ } else {
214
+ if (element['on' + event.capitalizeFirstLetter()]) {
215
+ element['on' + event.capitalizeFirstLetter()].add(callback);
216
+ }
217
+ }
218
+ };
219
+
220
+ self.isEmpty = function(list) {
221
+ return list.length === 0;
222
+ };
223
+
224
+ self.isDefined = function(attribute) {
225
+ return (typeof attribute !== 'undefined') && (attribute !== null);
226
+ }
227
+
228
+ self.makeId = function() {
229
+ var text = "";
230
+ var possible = "abcdefghijklmnopqrstuvwxyz0123456789";
231
+
232
+ for( var i=0; i < 5; i++ )
233
+ text += possible.charAt(Math.floor(Math.random() * possible.length));
234
+
235
+ return text;
236
+ };
237
+
238
+ self.loadAsyncDynamicJsCodeFromElement = function(subject, wrapper)
239
+ {
240
+ subject = $(subject);
241
+ if (subject.prop('tagName').toLowerCase() === "script") {
242
+ var scriptSrc = subject.attr('src') || null;
243
+ if (!scriptSrc) {
244
+ self.addScriptDeclaration(wrapper, subject.html());
245
+ } else {
246
+ self.addScript(scriptSrc);
247
+ }
248
+ } else {
249
+ var innerScriptsList = $('script', subject);
250
+ if (innerScriptsList.length > 0) {
251
+ $.each(innerScriptsList, function(innerScriptIndex, innerScript) {
252
+ self.loadAsyncDynamicJsCodeFromElement(innerScript);
253
+ });
254
+ }
255
+ }
256
+ }
257
+
258
+ /**
259
+ * Method executed on the document ready event
260
+ *
261
+ * @return void
262
+ */
263
+ self.onReady = function() {
264
+ if (self.tinymceIsAvailable()) {
265
+ // Wait until the editor is available
266
+ var interval = window.setInterval(
267
+ function() {
268
+
269
+ // @todo: Support multiple editors
270
+ self.editor = self.getEditor();
271
+
272
+ if (self.editor !== null) {
273
+ window.clearInterval(interval);
274
+ interval = null;
275
+
276
+ self.onFindEditor();
277
+ }
278
+ },
279
+ 200
280
+ );
281
+ }
282
+ };
283
+
284
+ /**
285
+ * Detects if tinymce object is available
286
+ * @return Boolean True, if available
287
+ */
288
+ self.tinymceIsAvailable = function() {
289
+ return typeof window.tinymce === 'object' || typeof window.tinyMCE === "object";
290
+ }
291
+
292
+ /**
293
+ * Returns true if the controller panel is active
294
+ * @return Boolean True, if the controller panel is active
295
+ */
296
+ self.controllerPanelIsActive = function() {
297
+ return typeof self.activeControllerPanel !== 'undefined' && self.activeControllerPanel !== null;
298
+ };
299
+
300
+ /**
301
+ * Returns the editor
302
+ * @return Object The editor
303
+ */
304
+ self.getEditor = function() {
305
+ if (window.tinymce.editors.length === 0) {
306
+ return null;
307
+ }
308
+
309
+ return window.tinymce.activeEditor;
310
+ };
311
+
312
+ /**
313
+ * Parses the content, sending it to the component which will
314
+ * look for urls to be parsed into embed codes
315
+ *
316
+ * @param string content The content
317
+ * @param function onsuccess The callback called on success
318
+ * @return void
319
+ */
320
+ self.getParsedContent = function(content, onsuccess) {
321
+ // Get the parsed content
322
+ $.ajax({
323
+ type: 'POST',
324
+ url: "admin-ajax.php",
325
+ data: {
326
+ action: "embedpress_do_ajax_request",
327
+ subject: content
328
+ },
329
+ success: onsuccess,
330
+ dataType: 'json',
331
+ async: true
332
+ });
333
+ };
334
+
335
+ self.addStylesheet = function(url) {
336
+ var head = self.editor.getDoc().getElementsByTagName('head')[0];
337
+
338
+ var $style = $('<link rel="stylesheet" type="text/css" href="' + url + '">');
339
+ $style.appendTo(head);
340
+ }
341
+
342
+ self.convertURLSchemeToPattern = function(scheme) {
343
+ var prefix = '(.*)((?:http|embedpress)s?:\\/\\/(?:www\\.)?',
344
+ suffix = '[\\/]?)(.*)',
345
+ pattern;
346
+
347
+ scheme = scheme.replace(/\*/g, '[a-zA-Z0-9=&_\\-\\?\\.\\/!\\+%:@,#]+');
348
+ scheme = scheme.replace(/\./g, '\\.');
349
+ scheme = scheme.replace(/\//g, '\\/');
350
+
351
+ return prefix + scheme + suffix;
352
+ };
353
+
354
+ self.getProvidersURLPatterns = function() {
355
+ // @todo: Add option to disable/enable the providers
356
+ var urlSchemes = [
357
+ // VideoPress
358
+ 'videopress.com/v/*',
359
+
360
+ // Tumblr
361
+ '*.tumblr.com/post/*',
362
+
363
+ // SmugMug
364
+ 'smugmug.com/*',
365
+
366
+ // SlideShare
367
+ 'slideshare.net/*',
368
+
369
+ // Reddit
370
+ 'reddit.com/r/[^/]+/comments/*',
371
+
372
+ // Photobucket
373
+ 'i*.photobucket.com/albums/*',
374
+ 'gi*.photobucket.com/groups/*',
375
+
376
+ // Cloudup
377
+ 'cloudup.com/*',
378
+
379
+ // Imgur
380
+ 'imgur.com/*',
381
+ 'i.imgur.com/*',
382
+
383
+ // YouTube (http://www.youtube.com/)
384
+ 'youtube.com/watch\\?*',
385
+
386
+ // IFTTT (http://www.ifttt.com/)
387
+ 'ifttt.com/recipes/*',
388
+
389
+ // Flickr (http://www.flickr.com/)
390
+ 'flickr.com/photos/*/*',
391
+ 'flic.kr/p/*',
392
+
393
+ // Viddler (http://www.viddler.com/)
394
+ 'viddler.com/v/*',
395
+
396
+ // Hulu (http://www.hulu.com/)
397
+ 'hulu.com/watch/*',
398
+
399
+ // Vimeo (http://vimeo.com/)
400
+ 'vimeo.com/*',
401
+ 'vimeo.com/groups/*/videos/*',
402
+
403
+ // CollegeHumor (http://www.collegehumor.com/)
404
+ 'collegehumor.com/video/*',
405
+
406
+ // Deviantart.com (http://www.deviantart.com)
407
+ '*.deviantart.com/art/*',
408
+ '*.deviantart.com/*#/d*',
409
+ 'fav.me/*',
410
+ 'sta.sh/*',
411
+
412
+ // SlideShare (http://www.slideshare.net/)
413
+ 'slideshare.net/*/*',
414
+ 'fr.slideshare.net/*/*',
415
+ 'de.slideshare.net/*/*',
416
+ 'es.slideshare.net/*/*',
417
+ 'pt.slideshare.net/*/*',
418
+
419
+ // chirbit.com (http://www.chirbit.com/)
420
+ 'chirb.it/*',
421
+
422
+ // nfb.ca (http://www.nfb.ca/)
423
+ '*.nfb.ca/film/*',
424
+
425
+ // Scribd (http://www.scribd.com/)
426
+ 'scribd.com/doc/*',
427
+
428
+ // Dotsub (http://dotsub.com/)
429
+ 'dotsub.com/view/*',
430
+
431
+ // Animoto (http://animoto.com/)
432
+ 'animoto.com/play/*',
433
+
434
+ // Rdio (http://rdio.com/)
435
+ '*.rdio.com/artist/*',
436
+ '*.rdio.com/people/*',
437
+
438
+ // MixCloud (http://mixcloud.com/)
439
+ 'mixcloud.com/*/*/',
440
+
441
+ // FunnyOrDie (http://www.funnyordie.com/)
442
+ 'funnyordie.com/videos/*',
443
+
444
+ // Ted (http://ted.com)
445
+ 'ted.com/talks/*',
446
+
447
+ // Sapo Videos (http://videos.sapo.pt)
448
+ 'videos.sapo.pt/*',
449
+
450
+ // Official FM (http://official.fm)
451
+ 'official.fm/tracks/*',
452
+ 'official.fm/playlists/*',
453
+
454
+ // HuffDuffer (http://huffduffer.com)
455
+ 'huffduffer.com/*/*',
456
+
457
+ // Shoudio (http://shoudio.com)
458
+ 'shoudio.com/*',
459
+ 'shoud.io/*',
460
+
461
+ // Moby Picture (http://www.mobypicture.com)
462
+ 'mobypicture.com/user/*/view/*',
463
+ 'moby.to/*',
464
+
465
+ // 23HQ (http://www.23hq.com)
466
+ '23hq.com/*/photo/*',
467
+
468
+ // Cacoo (https://cacoo.com)
469
+ 'cacoo.com/diagrams/*',
470
+
471
+ // Dipity (http://www.dipity.com)
472
+ 'dipity.com/*/*/',
473
+
474
+ // Roomshare (http://roomshare.jp)
475
+ 'roomshare.jp/post/*',
476
+ 'roomshare.jp/en/post/*',
477
+
478
+ // Dailymotion (http://www.dailymotion.com)
479
+ 'dailymotion.com/video/*',
480
+
481
+ // Crowd Ranking (http://crowdranking.com)
482
+ 'crowdranking.com/*/*',
483
+
484
+ // CircuitLab (https://www.circuitlab.com/)
485
+ 'circuitlab.com/circuit/*',
486
+
487
+ // Coub (http://coub.com/)
488
+ 'coub.com/view/*',
489
+ 'coub.com/embed/*',
490
+
491
+ // SpeakerDeck (https://speakerdeck.com)
492
+ 'speakerdeck.com/*/*',
493
+
494
+ // Instagram (https://instagram.com)
495
+ 'instagram.com/p/*',
496
+ 'instagr.am/p/*',
497
+
498
+ // SoundCloud (http://soundcloud.com/)
499
+ 'soundcloud.com/*',
500
+
501
+ // On Aol (http://on.aol.com/)
502
+ 'on.aol.com/video/*',
503
+
504
+ // Kickstarter (http://www.kickstarter.com)
505
+ 'kickstarter.com/projects/*',
506
+
507
+ // Ustream (http://www.ustream.tv)
508
+ '*.ustream.tv/*',
509
+ '*.ustream.com/*',
510
+
511
+ // Daily Mile (http://www.dailymile.com)
512
+ 'dailymile.com/people/*/entries/*',
513
+
514
+ // Sketchfab (http://sketchfab.com)
515
+ 'sketchfab.com/models/*',
516
+ 'sketchfab.com/*/folders/*',
517
+
518
+ // Meetup (http://www.meetup.com)
519
+ 'meetup.com/*',
520
+ 'meetu.ps/*',
521
+
522
+ // AudioSnaps (http://audiosnaps.com)
523
+ 'audiosnaps.com/k/*',
524
+
525
+ // RapidEngage (https://rapidengage.com)
526
+ 'rapidengage.com/s/*',
527
+
528
+ // Getty Images (http://www.gettyimages.com/)
529
+ 'gty.im/*',
530
+
531
+ // amCharts Live Editor (http://live.amcharts.com/)
532
+ 'live.amcharts.com/*',
533
+
534
+ // Infogram (https://infogr.am/)
535
+ 'infogr.am/*',
536
+
537
+ // ChartBlocks (http://www.chartblocks.com/)
538
+ 'public.chartblocks.com/c/*',
539
+
540
+ // ReleaseWire (http://www.releasewire.com/)
541
+ 'rwire.com/*',
542
+
543
+ // ShortNote (https://www.shortnote.jp/)
544
+ 'shortnote.jp/view/notes/*',
545
+
546
+ // EgliseInfo (http://egliseinfo.catholique.fr/)
547
+ 'egliseinfo.catholique.fr/*',
548
+
549
+ // Silk (http://www.silk.co/)
550
+ '*.silk.co/explore/*',
551
+ '*.silk.co/s/embed/*',
552
+
553
+ // Twitter
554
+ 'twitter.com/*/status/*',
555
+
556
+ // http://bambuser.com
557
+ 'bambuser.com/v/*',
558
+
559
+ // https://clyp.it
560
+ 'clyp.it/*',
561
+
562
+ // http://www.edocr.com
563
+ 'edocr.com/doc/*',
564
+
565
+ // https://gist.github.com
566
+ 'gist.github.com/*',
567
+
568
+ // http://issuu.com
569
+ 'issuu.com/*',
570
+
571
+ // https://portfolium.com
572
+ 'portfolium.com/*',
573
+
574
+ // https://www.reverbnation.com
575
+ 'reverbnation.com/*',
576
+
577
+ // http://rutube.ru
578
+ 'rutube.ru/video/*',
579
+
580
+ // https://spotify.com/
581
+ 'open.spotify.com/*',
582
+
583
+ // http://www.videojug.com
584
+ 'videojug.com/*',
585
+
586
+ // https://vine.com
587
+ 'vine.co/*',
588
+
589
+ // Facebook
590
+ 'facebook.com/*',
591
+
592
+ // Google Maps
593
+ 'google.com/*',
594
+ 'google.com.*/*',
595
+ 'maps.google.com/*',
596
+
597
+ // Google Docs
598
+ 'docs.google.com/presentation/*',
599
+ 'docs.google.com/document/*',
600
+ 'docs.google.com/spreadsheets/*',
601
+ 'docs.google.com/forms/*',
602
+ 'docs.google.com/drawings/*'
603
+ ],
604
+ patterns = [];
605
+
606
+ self.each(urlSchemes, function convertEachURLSchemesToPattern(scheme) {
607
+ patterns.push(self.convertURLSchemeToPattern(scheme));
608
+ });
609
+
610
+ return patterns;
611
+ };
612
+
613
+ self.addScript = function(source, callback) {
614
+ var doc = self.editor.getDoc(),
615
+ $script = $(doc.createElement('script')),
616
+ $head = $(doc.getElementsByTagName('head')[0]);
617
+ $script.attr('async', 1);
618
+ $head.append($script);
619
+
620
+ if (typeof callback !== 'undefined') {
621
+ $script.ready(callback);
622
+ }
623
+
624
+ $script.attr('src', source);
625
+ };
626
+
627
+ self.addScriptDeclaration = function(wrapper, declaration) {
628
+ var doc = self.editor.getDoc(),
629
+ $script = $(doc.createElement('script'));
630
+
631
+ $(wrapper).append($script);
632
+
633
+ $script.text(declaration);
634
+ };
635
+
636
+ self.addURLsPlaceholder = function(node, url) {
637
+ var uid = self.makeId();
638
+
639
+ var wrapperClasses = ["embedpress_wrapper", "embedpress_placeholder"];
640
+
641
+ var shortcodeAttributes = node.value.getShortcodeAttributes($data.EMBEDPRESS_SHORTCODE);
642
+ var customAttributes = shortcodeAttributes;
643
+
644
+ var customClasses = "";
645
+ if (!!Object.keys(shortcodeAttributes).length) {
646
+ var specialAttributes = ["class", "href", "data-href"];
647
+ // Iterates over each attribute of shortcodeAttributes to add the prefix "data-" if missing
648
+ var dataPrefix = "data-";
649
+ var prefixedShortcodeAttributes = [];
650
+ for (var attr in shortcodeAttributes) {
651
+ if (specialAttributes.indexOf(attr) === -1) {
652
+ if (attr.indexOf(dataPrefix) !== 0) {
653
+ prefixedShortcodeAttributes[dataPrefix + attr] = shortcodeAttributes[attr];
654
+ } else {
655
+ prefixedShortcodeAttributes[attr] = shortcodeAttributes[attr];
656
+ }
657
+ } else {
658
+ attr = attr.replace(dataPrefix, "");
659
+ if (attr === "class") {
660
+ wrapperClasses.push(shortcodeAttributes[attr]);
661
+ }
662
+ }
663
+ }
664
+
665
+ shortcodeAttributes = prefixedShortcodeAttributes;
666
+ prefixedShortcodeAttributes = dataPrefix = null;
667
+ }
668
+
669
+ if (("data-width" in shortcodeAttributes || "data-height" in shortcodeAttributes) && "data-responsive" in shortcodeAttributes) {
670
+ shortcodeAttributes['data-responsive'] = "false";
671
+ }
672
+
673
+ var wrapper = new self.Node('div', 1);
674
+ var wrapperSettings = {
675
+ 'class': Array.from(new Set(wrapperClasses)).join(" "),
676
+ 'data-url': url,
677
+ 'data-uid': uid,
678
+ 'id': 'embedpress_wrapper_' + uid,
679
+ 'data-loading-text': 'Loading...'
680
+ };
681
+
682
+ wrapperSettings = $.extend({}, wrapperSettings, shortcodeAttributes);
683
+
684
+ wrapper.attr(wrapperSettings);
685
+
686
+ var panel = new self.Node('div', 1);
687
+ panel.attr({
688
+ 'id': 'embedpress_controller_panel_' + uid,
689
+ 'class': 'embedpress_controller_panel embedpress_ignore_mouseout hidden'
690
+ });
691
+ wrapper.append(panel);
692
+
693
+ function createGhostNode(htmlTag, content) {
694
+ htmlTag = htmlTag || "span";
695
+ content = content || "&nbsp;";
696
+
697
+ var ghostNode = new self.Node(htmlTag, 1);
698
+ ghostNode.attr({
699
+ 'class': "hidden"
700
+ });
701
+
702
+ var ghostText = new self.Node('#text', 3);
703
+ ghostText.value = content;
704
+ ghostNode.append(ghostText);
705
+
706
+ return ghostNode;
707
+ }
708
+
709
+ var editButton = new self.Node('div', 1);
710
+ editButton.attr({
711
+ 'id': 'embedpress_button_edit_' + uid,
712
+ 'class': 'embedpress_ignore_mouseout embedpress_controller_button'
713
+ });
714
+ var editButtonIcon = new self.Node('div', 1);
715
+ editButtonIcon.attr({
716
+ 'class': 'embedpress-icon-pencil embedpress_ignore_mouseout'
717
+ });
718
+ editButtonIcon.append(createGhostNode());
719
+ editButton.append(editButtonIcon);
720
+ panel.append(editButton);
721
+
722
+ var removeButton = new self.Node('div', 1);
723
+ removeButton.attr({
724
+ 'id': 'embedpress_button_remove_' + uid,
725
+ 'class': 'embedpress_ignore_mouseout embedpress_controller_button'
726
+ });
727
+ var removeButtonIcon = new self.Node('div', 1);
728
+ removeButtonIcon.attr({
729
+ 'class': 'embedpress-icon-x embedpress_ignore_mouseout'
730
+ });
731
+ removeButtonIcon.append(createGhostNode());
732
+ removeButton.append(removeButtonIcon);
733
+ panel.append(removeButton);
734
+
735
+ node.replace(wrapper);
736
+
737
+ // Trigger the timeout which will load the content
738
+ window.setTimeout(function() {
739
+ self.parseContentAsync(uid, url, customAttributes);
740
+ }, 800);
741
+
742
+ return wrapper;
743
+ };
744
+
745
+ self.parseContentAsync = function(uid, url, customAttributes) {
746
+ customAttributes = typeof customAttributes === "undefined" ? {} : customAttributes;
747
+
748
+ url = self.decodeEmbedURLSpecialChars(url, true, customAttributes);
749
+
750
+ // Get the parsed embed code from the EmbedPress plugin
751
+ self.getParsedContent(url, function getParsedContentCallback(result) {
752
+ result.data.content = result.data.content.stripShortcode($data.EMBEDPRESS_SHORTCODE);
753
+
754
+ // Parse as DOM element
755
+ var $content;
756
+ try {
757
+ $content = $(result.data.content);
758
+ } catch(err) {
759
+ // Fallback to a div, if the result is not a html markup, e.g. a url
760
+ $content = $('<div>');
761
+ $content.html(result.data.content);
762
+ }
763
+
764
+ var $wrapper = $(self.getElementInContentById('embedpress_wrapper_' + uid));
765
+ var scripts = [];
766
+
767
+ $wrapper.removeClass('embedpress_placeholder');
768
+
769
+ $.each($content, function appendEachEmbedElement(index, element) {
770
+ // Check if the element is a script and do not add it now (if added here it wouldn't be executed)
771
+ if (element.tagName.toLowerCase() !== 'script') {
772
+ $wrapper.append($(element));
773
+
774
+ if (element.tagName.toLowerCase() === 'iframe') {
775
+ $(element).ready(function() {
776
+ window.setTimeout(function() {
777
+ $.each(self.editor.dom.select('div.embedpress_wrapper iframe'), function(index, iframe) {
778
+ self.fixIframeSize(iframe);
779
+ });
780
+ }, 300);
781
+ });
782
+ } else if (element.tagName.toLowerCase() === "div") {
783
+ if ($('img', $(element)).length || $('blockquote', $wrapper).length) {
784
+ // This ensures that the embed wrapper have the same width as its content
785
+ $($(element).parents('.embedpress_wrapper').get(0)).addClass('dynamic-width');
786
+ }
787
+
788
+ $(element).css('max-width', $($(element).parents('body').get(0)).width());
789
+ }
790
+ }
791
+
792
+ self.loadAsyncDynamicJsCodeFromElement(element, $wrapper);
793
+ });
794
+ });
795
+ };
796
+
797
+ self.encodeEmbedURLSpecialChars = function(content) {
798
+ if (content.match(SHORTCODE_REGEXP)) {
799
+ var subject = content.replace(SHORTCODE_REGEXP, '');
800
+
801
+ if (!subject.isValidUrl()) {
802
+ return content;
803
+ }
804
+
805
+ content = subject;
806
+ subject = null;
807
+ }
808
+
809
+ // Bypass the autolink plugin, avoiding to have the url converted to a link automatically
810
+ content = content.replace(/http(s?)\:\/\//i, 'embedpress$1://');
811
+
812
+ // Bypass the autolink plugin, avoiding to have some urls with @ being treated as email address (e.g. GMaps)
813
+ content = content.replace('@', '::__at__::').trim();
814
+
815
+ return content;
816
+ };
817
+
818
+ self.decodeEmbedURLSpecialChars = function(content, applyShortcode, attributes) {
819
+ var encodingRegexpRule = /embedpress(s?):\/\//;
820
+ applyShortcode = (typeof applyShortcode === "undefined") ? true : applyShortcode;
821
+ attributes = (typeof attributes === "undefined") ? {} : attributes;
822
+
823
+ var isEncoded = content.match(encodingRegexpRule);
824
+
825
+ // Restore http[s] in the url (converted to bypass autolink plugin)
826
+ content = content.replace(/embedpress(s?):\/\//, 'http$1://');
827
+ content = content.replace('::__at__::', '@').trim();
828
+
829
+ if ("class" in attributes) {
830
+ var classesList = attributes.class.split(/\s/g);
831
+ var shouldRemoveDynamicWidthClass = false;
832
+ for (var classIndex = 0; classIndex < classesList.length; classIndex++) {
833
+ if (classesList[classIndex] === "dynamic-width") {
834
+ shouldRemoveDynamicWidthClass = classIndex;
835
+ break;
836
+ }
837
+ }
838
+
839
+ if (shouldRemoveDynamicWidthClass !== false) {
840
+ classesList.splice(shouldRemoveDynamicWidthClass, 1);
841
+
842
+ if (classesList.length === 0) {
843
+ delete attributes.class;
844
+ }
845
+
846
+ attributes.class = classesList.join(" ");
847
+ }
848
+
849
+ shouldRemoveDynamicWidthClass = classesList = classIndex = null;
850
+ }
851
+
852
+ if (isEncoded && applyShortcode) {
853
+ var shortcode = '[' + $data.EMBEDPRESS_SHORTCODE;
854
+ if (!!Object.keys(attributes).length) {
855
+ var attrValue;
856
+
857
+ for (var attrName in attributes) {
858
+ attrValue = attributes[attrName];
859
+
860
+ // Prevent `class` property being empty an treated as a boolean param
861
+ if (attrName.toLowerCase() === "class" && !attrValue.length) {
862
+ continue;
863
+ }
864
+ else {
865
+ if (attrValue.isBoolean()) {
866
+ shortcode += " ";
867
+ if (attrValue.isFalse()) {
868
+ shortcode += "!";
869
+ }
870
+
871
+ shortcode += attrName
872
+ } else {
873
+ shortcode += ' '+ attrName +'="'+ attrValue +'"';
874
+ }
875
+ }
876
+ }
877
+ attrValue = attrName = null;
878
+ }
879
+
880
+ content = shortcode + ']' + content + '[/' + $data.EMBEDPRESS_SHORTCODE + ']';
881
+ }
882
+
883
+ return content;
884
+ };
885
+
886
+ /**
887
+ * Method executed after find the editor. It will make additional
888
+ * configurations and add the content's stylesheets for the preview
889
+ *
890
+ * @return void
891
+ */
892
+ self.onFindEditor = function() {
893
+ self.each = tinymce.each;
894
+ self.extend = tinymce.extend;
895
+ self.JSON = tinymce.util.JSON;
896
+ self.Node = tinymce.html.Node;
897
+
898
+ self.addStylesheet(PLG_SYSTEM_ASSETS_CSS_PATH + '/font.css?' + self.params.versionUID);
899
+ self.addStylesheet(PLG_SYSTEM_ASSETS_CSS_PATH + '/preview.css?' + self.params.versionUID);
900
+ self.addStylesheet(PLG_CONTENT_ASSETS_CSS_PATH + '/embedpress.css?' + self.params.versionUID);
901
+ self.addEvent('paste', self.editor, self.onPaste);
902
+ self.addEvent('nodechange', self.editor, self.onNodeChange);
903
+ self.addEvent('keydown', self.editor, self.onKeyDown);
904
+
905
+ self.addEvent('undo', self.editor, self.onUndo); // TinyMCE
906
+ self.addEvent('undo', self.editor.undoManager, self.onUndo); // JCE
907
+
908
+ // Add the node filter that will convert the url into the preview box for the embed code
909
+ // @todo: Recognize <a> tags as well
910
+ self.editor.parser.addNodeFilter('#text', function addNodeFilterIntoParser(nodes, arg) {
911
+ self.each(nodes, function eachNodeInParser(node) {
912
+ var subject = node.value;
913
+ if (!subject.isValidUrl()) {
914
+ if (!subject.match(SHORTCODE_REGEXP)) {
915
+ return;
916
+ }
917
+ }
918
+
919
+ subject = self.decodeEmbedURLSpecialChars(subject);
920
+ if (!subject.isValidUrl()) {
921
+ if (!subject.match(SHORTCODE_REGEXP)) {
922
+ return;
923
+ }
924
+ }
925
+
926
+ subject = node.value.stripShortcode($data.EMBEDPRESS_SHORTCODE).trim();
927
+
928
+ // These patterns need to have groups for the pre and post texts
929
+ var patterns = self.getProvidersURLPatterns();
930
+
931
+ self.each(patterns, function eachPatternForNodeFilterInParser(pattern) {
932
+ var regex = new RegExp(pattern),
933
+ matches,
934
+ value;
935
+
936
+ value = self.decodeEmbedURLSpecialChars(subject).trim();
937
+
938
+ matches = value.match(regex);
939
+ if (matches !== null && !!matches.length) {
940
+ var preText = matches[1];
941
+ var url = self.encodeEmbedURLSpecialChars(matches[2]);
942
+ var postText = matches[3];
943
+ var wrapper = self.addURLsPlaceholder(node, url);
944
+
945
+ // Add the pre text if exists
946
+ var text;
947
+ if (preText !== '') {
948
+ text = new self.Node('#text', 3);
949
+ text.value = preText.trim();
950
+
951
+ // Insert before
952
+ wrapper.parent.insert(text, wrapper, true);
953
+ }
954
+
955
+ // Add the post text if exists
956
+ if (postText !== '') {
957
+ text = new self.Node('#text', 3);
958
+ text.value = postText.trim();
959
+
960
+ // Insert after
961
+ wrapper.parent.insert(text, wrapper, false);
962
+ }
963
+ }
964
+ });
965
+ });
966
+ });
967
+
968
+ // Add the filter that will convert the preview box/embed code back to the raw url
969
+ self.editor.serializer.addNodeFilter('div', function addNodeFilterIntoSerializer(nodes, arg) {
970
+ self.each(nodes, function eachNodeInSerializer(node) {
971
+ var nodeClasses = (node.attributes.map.class || "").split(' ');
972
+ var wrapperFactoryClasses = ["embedpress_wrapper", "embedpress_placeholder"];
973
+
974
+ var isWrapped = nodeClasses.filter(function(n) {
975
+ return wrapperFactoryClasses.indexOf(n) != -1;
976
+ }).length > 0;
977
+
978
+ if (isWrapped) {
979
+ var factoryAttributes = ["id", "style", "data-loading-text", "data-uid", "data-url"];
980
+ var customAttributes = {};
981
+ var dataPrefix = "data-";
982
+ for (var attr in node.attributes.map) {
983
+ if (attr.toLowerCase() !== "class") {
984
+ if (factoryAttributes.indexOf(attr) < 0) {
985
+ // Remove the "data-" prefix for more readability
986
+ customAttributes[attr.replace(dataPrefix, "")] = node.attributes.map[attr];
987
+ }
988
+ } else {
989
+ var customClasses = [];
990
+ for (var wrapperClassIndex in nodeClasses) {
991
+ var wrapperClass = nodeClasses[wrapperClassIndex];
992
+ if (wrapperFactoryClasses.indexOf(wrapperClass) === -1) {
993
+ customClasses.push(wrapperClass);
994
+ }
995
+ }
996
+
997
+ if (!!customClasses.length) {
998
+ customAttributes.class = customClasses.join(" ");
999
+ }
1000
+ }
1001
+ }
1002
+
1003
+ var text = new self.Node('#text', 3);
1004
+ text.value = self.decodeEmbedURLSpecialChars(node.attributes.map['data-url'].trim(), true, customAttributes);
1005
+
1006
+ node.replace(text);
1007
+
1008
+ // @todo: Remove/avoid to add empty paragraphs before and after the text every time we run this
1009
+ }
1010
+ });
1011
+ });
1012
+
1013
+ // Add event to reconfigure wrappers every time the content is loaded
1014
+ tinymce.each(tinymce.editors, function onEachEditor(editor) {
1015
+ self.addEvent('loadContent', editor, function onInitEditor(ed) {
1016
+ self.configureWrappers();
1017
+ });
1018
+ });
1019
+
1020
+ // Add the edit form
1021
+
1022
+ // @todo: This is needed only for JCE, to fix the img placeholder. Try to find out a better approach to avoid the placeholder blink
1023
+ window.setTimeout(
1024
+ function afterTimeoutOnFindEditor() {
1025
+ /*
1026
+ * This is required because after load/refresh the page, the
1027
+ * onLoadContent is not being triggered automatically, so
1028
+ * we force the event
1029
+ */
1030
+ self.editor.load();
1031
+ },
1032
+ // If in JCE the user see the placeholder (img) instead of the iframe after load/refresh the pagr, this time is too short
1033
+ 500
1034
+ );
1035
+ };
1036
+
1037
+ self.fixIframeSize = function(iframe) {
1038
+ var maxWidth = 480;
1039
+ if ($(iframe).width() > maxWidth && !$(iframe).data('size-fixed')) {
1040
+ var ratio = $(iframe).height() / $(iframe).width();
1041
+ $(iframe).width(maxWidth);
1042
+ $(iframe).height(maxWidth * ratio);
1043
+ $(iframe).css('max-width', maxWidth);
1044
+ $(iframe).attr('max-width', maxWidth);
1045
+
1046
+ $(iframe).data('size-fixed', true);
1047
+ }
1048
+ }
1049
+
1050
+ /**
1051
+ * Function triggered on mouse enter the wrapper
1052
+ *
1053
+ * @param object e The event
1054
+ * @return void
1055
+ */
1056
+ self.onMouseEnter = function(e) {
1057
+ self.displayPreviewControllerPanel($(e.currentTarget));
1058
+ };
1059
+
1060
+ /**
1061
+ * Function triggered on mouse get out of the wrapper
1062
+ *
1063
+ * @param object e The event
1064
+ * @return void
1065
+ */
1066
+ self.onMouseOut = function(e) {
1067
+ // Check if the destiny is not a child element
1068
+ // Chrome
1069
+ if (self.isDefined(e.toElement)) {
1070
+ if (e.toElement.parentElement == e.fromElement
1071
+ || $(e.toElement).hasClass('embedpress_ignore_mouseout')
1072
+ ) {
1073
+ return false;
1074
+ }
1075
+ }
1076
+
1077
+ // Firefox
1078
+ if (self.isDefined(e.relatedTarget)) {
1079
+ if ($(e.relatedTarget).hasClass('embedpress_ignore_mouseout')) {
1080
+ return false;
1081
+ }
1082
+ }
1083
+
1084
+ self.hidePreviewControllerPanel();
1085
+ };
1086
+
1087
+ /**
1088
+ * Function called on paste event in the editor
1089
+ *
1090
+ * @param object e The event
1091
+ * @return void
1092
+ */
1093
+ self.onPaste = function(e, b) {
1094
+ var event;
1095
+
1096
+ // Prevent default paste behavior. We have 2 arguments because the difference between JCE and TinyMCE.
1097
+ // Sometimes, the argument e is the editor, instead of the event
1098
+ if (e.preventDefault) {
1099
+ event = e;
1100
+ } else {
1101
+ event = b;
1102
+ }
1103
+
1104
+ // Check for clipboard data in various places for cross-browser compatibility
1105
+ // Get that data as text
1106
+ var content = ((event.originalEvent || event).clipboardData || window.clipboardData).getData('Text');
1107
+
1108
+ // Check if the pasted content has a recognized embed url pattern
1109
+ var patterns = self.getProvidersURLPatterns();
1110
+
1111
+ self.each(patterns, function eachPatternForOnPaste(pattern) {
1112
+ var regex = new RegExp(pattern),
1113
+ matches = content.match(regex),
1114
+ url;
1115
+
1116
+ if (matches !== null && !!matches.length) {
1117
+ event.preventDefault();
1118
+
1119
+ content += '<span>&nbsp;</span>'; // This assures that the cursor are positioned after the embed
1120
+
1121
+ // Let TinyMCE do the heavy lifting for inserting that content into the self.editor
1122
+ // We cancel the default behavior and insert using command to trigger the node change and the parser
1123
+ self.editor.execCommand('mceInsertContent', false, content);
1124
+
1125
+ self.configureWrappers();
1126
+ }
1127
+ });
1128
+ };
1129
+
1130
+ /**
1131
+ * Method trigered on every node change, to detect new lines. It will
1132
+ * try to fix a default behavior for some editors of clone the parent
1133
+ * element when adding a line break. This will clone the embed wrapper
1134
+ * if we set the cursor after a preview wrapper and hit enter.
1135
+ *
1136
+ * @param object e The event
1137
+ * @return void
1138
+ */
1139
+ self.onNodeChange = function(e) {
1140
+ // Fix the clone parent on break lines issue
1141
+ // Check if a line break was added
1142
+ if (e.element.tagName === 'BR') {
1143
+ // Check one of the parent elements is a clonned embed wrapper
1144
+ if (e.parents.length > 0) {
1145
+ $.each(e.parents, function(index, parent) {
1146
+ if ($(parent).hasClass('embedpress_wrapper')) {
1147
+ // Remove the cloned wrapper and replace with a 'br' tag
1148
+ $(parent).replaceWith($('<br>'));
1149
+ }
1150
+ });
1151
+ }
1152
+ } else if (e.element.tagName === "IFRAME") {
1153
+ if (e.parents.length > 0) {
1154
+ $.each(e.parents, function(index, parent) {
1155
+ parent = $(parent);
1156
+ if (parent.hasClass('embedpress_wrapper')) {
1157
+ var wrapper = $('.embedpress-wrapper', parent);
1158
+ if (wrapper.length > 1) {
1159
+ wrapper.get(0).remove();
1160
+ }
1161
+ }
1162
+ });
1163
+ }
1164
+ }
1165
+ };
1166
+
1167
+ self.onKeyDown = function(e) {
1168
+ var node = self.editor.selection.getNode();
1169
+
1170
+ if (e.keyCode == 8 || e.keyCode == 46) {
1171
+ if (node.nodeName.toLowerCase() === 'p') {
1172
+ children = $(node).children();
1173
+ if (children.length > 0) {
1174
+ $.each(children, function() {
1175
+ // On delete, make sure to remove the wrapper and children, not only the wrapper
1176
+ if ($(this).hasClass('embedpress_wrapper') || $(this).hasClass('embedpress_ignore_mouseout')) {
1177
+ $(this).remove();
1178
+
1179
+ self.editor.focus();
1180
+ }
1181
+ });
1182
+ }
1183
+ }
1184
+ } else {
1185
+ // Ignore the arrows keys
1186
+ var arrowsKeyCodes = [37, 38, 39, 40];
1187
+ if (arrowsKeyCodes.indexOf(e.keyCode) == -1) {
1188
+
1189
+ // Check if we are inside a preview wrapper
1190
+ if ($(node).hasClass('embedpress_wrapper') || $(node).hasClass('embedpress_ignore_mouseout')) {
1191
+ // Avoid delete the wrapper or block line break if we are inside the wrapper
1192
+ if (e.keyCode == 13) {
1193
+ wrapper = $(self.getWrapperFromChild(node));
1194
+ if (wrapper.length > 0) {
1195
+ // Creates a temporary element which will be inserted after the wrapper
1196
+ var tmpId = '__embedpress__tmp_' + self.makeId();
1197
+ wrapper.after($('<span id="' + tmpId + '"></span>'));
1198
+ // Get and select the temporary element
1199
+ var span = self.editor.dom.select('span#' + tmpId)[0];
1200
+ self.editor.selection.select(span);
1201
+ // Remove the temporary element
1202
+ $(span).remove();
1203
+ }
1204
+
1205
+ return true;
1206
+ } else {
1207
+ // If we are inside the embed preview, ignore any key to avoid edition
1208
+ return self.cancelEvent(e);
1209
+ }
1210
+ }
1211
+ }
1212
+ }
1213
+
1214
+ return true;
1215
+ }
1216
+
1217
+ self.getWrapperFromChild = function(element) {
1218
+ // Is the wrapper
1219
+ if ($(element).hasClass('embedpress_wrapper')) {
1220
+ return element;
1221
+ } else {
1222
+ var $parent = $(element).parent();
1223
+
1224
+ if ($parent.length > 0) {
1225
+ return self.getWrapperFromChild($parent[0]);
1226
+ }
1227
+ }
1228
+
1229
+ return false;
1230
+ };
1231
+
1232
+ self.onUndo = function(e) {
1233
+ // Force re-render everything
1234
+ self.editor.load();
1235
+ };
1236
+
1237
+ self.cancelEvent = function(e) {
1238
+ e.preventDefault();
1239
+ e.stopPropagation();
1240
+ self.editor.dom.events.cancel();
1241
+
1242
+ return false;
1243
+ };
1244
+
1245
+ /**
1246
+ * Method executed when the edit button is clicked. It will display
1247
+ * a field with the current url, to update the current embed's source
1248
+ * url.
1249
+ *
1250
+ * @param Object e The event
1251
+ * @return void
1252
+ */
1253
+ self.onClickEditButton = function(e) {
1254
+ // Prevent edition of the panel
1255
+ self.cancelEvent(e);
1256
+
1257
+ self.activeWrapperForModal = self.activeWrapper;
1258
+
1259
+ var $wrapper = self.activeWrapperForModal;
1260
+ var wrapperUid = $wrapper.prop('id').replace("embedpress_wrapper_", "");
1261
+
1262
+ var customAttributes = {};
1263
+
1264
+ var embedInnerWrapper = $('.embedpress-wrapper', $wrapper);
1265
+ var embedItem = $('iframe', $wrapper);
1266
+ if (!embedItem.length) {
1267
+ embedItem = null;
1268
+ }
1269
+
1270
+ $.each(embedInnerWrapper.attributes, function() {
1271
+ if (this.specified) {
1272
+ if (this.name !== "class") {
1273
+ customAttributes[this.name.replace('data-', "").toLowerCase()] = this.value;
1274
+ }
1275
+ }
1276
+ });
1277
+
1278
+ var embedWidth = (((embedItem && embedItem.width()) || embedInnerWrapper.data('width')) || embedInnerWrapper.width()) || "";
1279
+ var embedHeight = (((embedItem && embedItem.height()) || embedInnerWrapper.data('height')) || embedInnerWrapper.height()) || "";
1280
+
1281
+ embedItem = embedInnerWrapper = null;
1282
+
1283
+ $('<div class="loader-indicator"><i class="embedpress-icon-reload"></i></div>').appendTo($wrapper);
1284
+
1285
+ setTimeout(function() {
1286
+ $.ajax({
1287
+ type: "GET",
1288
+ url: "admin-ajax.php",
1289
+ data: {
1290
+ action: "embedpress_get_embed_url_info",
1291
+ url: self.decodeEmbedURLSpecialChars($wrapper.data('url'), false)
1292
+ },
1293
+ beforeSend: function(request, requestSettings) {
1294
+ $('.loader-indicator', $wrapper).addClass('is-loading');
1295
+ },
1296
+ success: function(response) {
1297
+ if (!response) {
1298
+ bootbox.alert('Unable to get a valid response from the server.');
1299
+ return;
1300
+ }
1301
+
1302
+ if (response.canBeResponsive) {
1303
+ var embedShouldBeResponsive = true;
1304
+ if ("width" in customAttributes || "height" in customAttributes) {
1305
+ embedShouldBeResponsive = false;
1306
+ } else if ("responsive" in customAttributes && customAttributes['responsive'].isFalse()) {
1307
+ embedShouldBeResponsive = false;
1308
+ }
1309
+ }
1310
+
1311
+ bootbox.dialog({
1312
+ title: "Editing Embed properties",
1313
+ message: '<form id="form-'+ wrapperUid +'" embedpress>'+
1314
+ '<div class="row">'+
1315
+ '<div class="col-md-12">'+
1316
+ '<div class="form-group">'+
1317
+ '<label for="input-url-'+ wrapperUid +'">Url</label>'+
1318
+ '<input class="form-control" type="url" id="input-url-'+ wrapperUid +'" value="'+ self.decodeEmbedURLSpecialChars($wrapper.data('url'), false) +'">'+
1319
+ '</div>'+
1320
+ '</div>'+
1321
+ '</div>'+
1322
+ '<div class="row">'+
1323
+ (response.canBeResponsive ?
1324
+ '<div class="col-md-12">'+
1325
+ '<label>Responsive</label>'+
1326
+ '<div class="form-group">'+
1327
+ '<label class="radio-inline">'+
1328
+ '<input type="radio" name="input-responsive-'+ wrapperUid +'" id="input-responsive-1-'+ wrapperUid +'" value="1"'+ (embedShouldBeResponsive ? ' checked' : '') +'> Yes'+
1329
+ '</label>'+
1330
+ '<label class="radio-inline">'+
1331
+ '<input type="radio" name="input-responsive-'+ wrapperUid +'" id="input-responsive-0-'+ wrapperUid +'" value="0"'+ (!embedShouldBeResponsive ? ' checked' : '') +'> No'+
1332
+ '</label>'+
1333
+ '</div>'+
1334
+ '</div>' : '')+
1335
+ '<div class="col-md-6">'+
1336
+ '<div class="form-group">'+
1337
+ '<label for="input-width-'+ wrapperUid +'">Width</label>'+
1338
+ '<input class="form-control" type="integer" id="input-width-'+ wrapperUid +'" value="'+ embedWidth +'"'+ (embedShouldBeResponsive ? ' disabled' : '') +'>'+
1339
+ '</div>'+
1340
+ '</div>'+
1341
+ '<div class="col-md-6">'+
1342
+ '<div class="form-group">'+
1343
+ '<label for="input-height-'+ wrapperUid +'">Height</label>'+
1344
+ '<input class="form-control" type="integer" id="input-height-'+ wrapperUid +'" value="'+ embedHeight +'"'+ (embedShouldBeResponsive ? ' disabled' : '') +'>'+
1345
+ '</div>'+
1346
+ '</div>'+
1347
+ '</div>'+
1348
+ '</form>',
1349
+ buttons: {
1350
+ danger: {
1351
+ label: "Cancel",
1352
+ className: "btn-default",
1353
+ callback: function() {
1354
+ // do nothing
1355
+ self.activeWrapperForModal = null;
1356
+ }
1357
+ },
1358
+ success: {
1359
+ label: "Save",
1360
+ className: "btn-primary",
1361
+ callback: function() {
1362
+ var $wrapper = self.activeWrapperForModal;
1363
+
1364
+ // Select the current wrapper as a base for the new element
1365
+ self.editor.focus();
1366
+ self.editor.selection.select($wrapper[0]);
1367
+
1368
+ $wrapper.children().remove();
1369
+ $wrapper.remove();
1370
+
1371
+ if (response.canBeResponsive) {
1372
+ if ($('#form-'+ wrapperUid +' input[name="input-responsive-'+ wrapperUid +'"]:checked').val().isFalse()) {
1373
+ var embedCustomWidth = $('#input-width-'+ wrapperUid).val();
1374
+ if (parseInt(embedCustomWidth) > 0) {
1375
+ customAttributes['width'] = embedCustomWidth;
1376
+ }
1377
+
1378
+ var embedCustomHeight = $('#input-height-'+ wrapperUid).val();
1379
+ if (parseInt(embedCustomHeight) > 0) {
1380
+ customAttributes['height'] = embedCustomHeight;
1381
+ }
1382
+
1383
+ customAttributes['responsive'] = "false";
1384
+ } else {
1385
+ delete customAttributes['width'];
1386
+ delete customAttributes['height'];
1387
+
1388
+ customAttributes['responsive'] = "true";
1389
+ }
1390
+ } else {
1391
+ var embedCustomWidth = $('#input-width-'+ wrapperUid).val();
1392
+ if (parseInt(embedCustomWidth) > 0) {
1393
+ customAttributes['width'] = embedCustomWidth;
1394
+ }
1395
+
1396
+ var embedCustomHeight = $('#input-height-'+ wrapperUid).val();
1397
+ if (parseInt(embedCustomHeight) > 0) {
1398
+ customAttributes['height'] = embedCustomHeight;
1399
+ }
1400
+ }
1401
+
1402
+ var customAttributesList = [];
1403
+ if (!!Object.keys(customAttributes).length) {
1404
+ for (var attrName in customAttributes) {
1405
+ customAttributesList.push(attrName + '="' + customAttributes[attrName] + '"');
1406
+ }
1407
+ }
1408
+
1409
+ var shortcode = '['+ $data.EMBEDPRESS_SHORTCODE + (customAttributesList.length > 0 ? " "+ customAttributesList.join(" ") : "") +']'+ $('#input-url-'+ wrapperUid).val() +'[/'+ $data.EMBEDPRESS_SHORTCODE +']';
1410
+ // We do not directly replace the node because it was causing a bug on a second edit attempt
1411
+ self.editor.execCommand('mceInsertContent', false, shortcode);
1412
+
1413
+ self.configureWrappers();
1414
+ }
1415
+ }
1416
+ }
1417
+ });
1418
+
1419
+ $('form[embedpress]').on('change', 'input[type="radio"]', function(e) {
1420
+ var self = $(this);
1421
+ var form = self.parents('form[embedpress]');
1422
+
1423
+ $('input[type="integer"]', form).prop('disabled', self.val().isTrue());
1424
+ });
1425
+ },
1426
+ complete: function(request, textStatus) {
1427
+ $('.loader-indicator', $wrapper).removeClass('is-loading');
1428
+
1429
+ setTimeout(function() {
1430
+ $('.loader-indicator', $wrapper).remove();
1431
+ }, 350);
1432
+ },
1433
+ dataType: "json",
1434
+ async: true
1435
+ });
1436
+ }, 200);
1437
+
1438
+ return false;
1439
+ };
1440
+
1441
+ /**
1442
+ * Method executed when the remove button is clicked. It will remove
1443
+ * the preview and embed code, adding a mark to ignore the url
1444
+ *
1445
+ * @param Object e The event
1446
+ * @return void
1447
+ */
1448
+ self.onClickRemoveButton = function(e) {
1449
+ // Prevent edition of the panel
1450
+ self.cancelEvent(e);
1451
+
1452
+ var $wrapper = self.activeWrapper;
1453
+
1454
+ $wrapper.children().remove();
1455
+ $wrapper.remove();
1456
+
1457
+ return false;
1458
+ };
1459
+
1460
+ self.recursivelyAddClass = function(element, className) {
1461
+ $(element).children().each(function(index, child) {
1462
+ $(child).addClass(className);
1463
+
1464
+ var grandChild = $(child).children();
1465
+ if (grandChild.length > 0) {
1466
+ self.recursivelyAddClass(child, className)
1467
+ }
1468
+ });
1469
+ };
1470
+
1471
+ self.setInterval = function(callback, time, timeout) {
1472
+ var elapsed = 0;
1473
+ var iteraction = 0;
1474
+
1475
+ var interval = window.setInterval(function() {
1476
+ elapsed += time;
1477
+ iteraction++;
1478
+
1479
+ if (elapsed <= timeout) {
1480
+ callback(iteraction, elapsed);
1481
+ } else {
1482
+ self.stopInterval(interval);
1483
+ }
1484
+ }, time);
1485
+
1486
+ return interval;
1487
+ };
1488
+
1489
+ self.stopInterval = function(interval) {
1490
+ window.clearInterval(interval);
1491
+ interval = null;
1492
+ };
1493
+
1494
+ /**
1495
+ * Configure unconfigured embed wrappers, adding events and css
1496
+ * @return void
1497
+ */
1498
+ self.configureWrappers = function() {
1499
+ window.setTimeout(
1500
+ function configureWrappersTimeOut() {
1501
+ var doc = self.editor.getDoc(),
1502
+ total = 0,
1503
+ $wrapper = null,
1504
+ $iframe = null;
1505
+
1506
+ // Get all the wrappers
1507
+ var wrappers = doc.getElementsByClassName('embedpress_wrapper');
1508
+ total = wrappers.length;
1509
+ if (total > 0) {
1510
+ for (var i = 0; i < total; i++) {
1511
+ $wrapper = $(wrappers[i]);
1512
+
1513
+ // Check if the wrapper wasn't already configured
1514
+ if ($wrapper.data('configured') != true) {
1515
+ // A timeout was set to avoid block the content loading
1516
+ window.setTimeout(function() {
1517
+ // @todo: Check if we need a limit of levels to avoid use too much resources
1518
+ self.recursivelyAddClass($wrapper, 'embedpress_ignore_mouseout');
1519
+ }, 500);
1520
+
1521
+ // Fix the wrapper size. Wait until find the child iframe. L
1522
+ var interval = self.setInterval(function(iteraction) {
1523
+ var $childIframes = $wrapper.find('iframe');
1524
+
1525
+ if ($childIframes.length > 0) {
1526
+ $.each($childIframes, function(index, iframe) {
1527
+ // Facebook has more than one iframe, we need to ignore the Cross Domain Iframes
1528
+ if ($(iframe).attr('id') !== 'fb_xdm_frame_https'
1529
+ && $(iframe).attr('id') !== 'fb_xdm_frame_http'
1530
+ ) {
1531
+ $wrapper.css('width', $(iframe).width() + 'px');
1532
+ self.stopInterval(interval);
1533
+ }
1534
+ });
1535
+ }
1536
+ }, 500, 8000);
1537
+
1538
+ $wrapper.on('mouseenter', self.onMouseEnter);
1539
+ $wrapper.on('mouseout', self.onMouseOut);
1540
+ $wrapper.data('configured', true);
1541
+ }
1542
+ }
1543
+ }
1544
+ },
1545
+ 200
1546
+ );
1547
+ };
1548
+
1549
+ /**
1550
+ * Hide the controller panel
1551
+ *
1552
+ * @return void
1553
+ */
1554
+ self.hidePreviewControllerPanel = function() {
1555
+ if (self.controllerPanelIsActive()) {
1556
+ $(self.activeControllerPanel).addClass('hidden');
1557
+ self.activeControllerPanel = null;
1558
+ self.activeWrapper = null;
1559
+ }
1560
+ };
1561
+
1562
+ /**
1563
+ * Get an element by id in the editor's content
1564
+ *
1565
+ * @param String id The element id
1566
+ * @return Element The found element or null, wrapped by jQuery
1567
+ */
1568
+ self.getElementInContentById = function(id) {
1569
+ var doc = self.editor.getDoc();
1570
+
1571
+ return $(doc.getElementById(id));
1572
+ };
1573
+
1574
+ /**
1575
+ * Show the controller panel
1576
+ *
1577
+ * @param element $wrapper The wrapper which will be activate
1578
+ * @return void
1579
+ */
1580
+ self.displayPreviewControllerPanel = function($wrapper) {
1581
+ if (self.controllerPanelIsActive() && $wrapper !== self.activeWrapper) {
1582
+ self.hidePreviewControllerPanel();
1583
+ }
1584
+
1585
+ if (!self.controllerPanelIsActive()) {
1586
+ var uid = $wrapper.data('uid');
1587
+ var $panel = self.getElementInContentById('embedpress_controller_panel_' + uid);
1588
+
1589
+ if (!$panel.data('event-set')) {
1590
+ var $editButton = self.getElementInContentById('embedpress_button_edit_' + uid);
1591
+ var $removeButton = self.getElementInContentById('embedpress_button_remove_' + uid);
1592
+
1593
+ self.addEvent('mousedown', $editButton, self.onClickEditButton);
1594
+ self.addEvent('mousedown', $removeButton, self.onClickRemoveButton);
1595
+
1596
+ // Prevent the action of set cursor into the panel after click
1597
+ self.addEvent('mousedown', $panel, self.cancelEvent);
1598
+
1599
+ $panel.data('event-set', true);
1600
+ }
1601
+
1602
+ // Update the position of the control bar
1603
+ var next = $panel.next()[0];
1604
+ if (typeof next !== 'undefined') {
1605
+ if (next.nodeName.toLowerCase() === 'iframe') {
1606
+ $panel.css('left', ($(next).width() / 2));
1607
+ }
1608
+ }
1609
+
1610
+ // Show the bar
1611
+ $panel.removeClass('hidden');
1612
+
1613
+ self.activeControllerPanel = $panel;
1614
+ self.activeWrapper = $wrapper;
1615
+ }
1616
+ };
1617
+ };
1618
+
1619
+ if (!window.EmbedPressPreview) {
1620
+ window.EmbedPressPreview = new EmbedPressPreview();
1621
+ }
1622
+
1623
+ window.EmbedPressPreview.init($data.previewSettings);
1624
+ });
1625
+ })(window, jQuery, String, $data);
assets/js/vendor/bootbox.min.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ /**
2
+ * bootbox.js v4.4.0
3
+ *
4
+ * http://bootboxjs.com/license.txt
5
+ */
6
+ !function(a,b){"use strict";"function"==typeof define&&define.amd?define(["jquery"],b):"object"==typeof exports?module.exports=b(require("jquery")):a.bootbox=b(a.jQuery)}(this,function a(b,c){"use strict";function d(a){var b=q[o.locale];return b?b[a]:q.en[a]}function e(a,c,d){a.stopPropagation(),a.preventDefault();var e=b.isFunction(d)&&d.call(c,a)===!1;e||c.modal("hide")}function f(a){var b,c=0;for(b in a)c++;return c}function g(a,c){var d=0;b.each(a,function(a,b){c(a,b,d++)})}function h(a){var c,d;if("object"!=typeof a)throw new Error("Please supply an object of options");if(!a.message)throw new Error("Please specify a message");return a=b.extend({},o,a),a.buttons||(a.buttons={}),c=a.buttons,d=f(c),g(c,function(a,e,f){if(b.isFunction(e)&&(e=c[a]={callback:e}),"object"!==b.type(e))throw new Error("button with key "+a+" must be an object");e.label||(e.label=a),e.className||(e.className=2>=d&&f===d-1?"btn-primary":"btn-default")}),a}function i(a,b){var c=a.length,d={};if(1>c||c>2)throw new Error("Invalid argument length");return 2===c||"string"==typeof a[0]?(d[b[0]]=a[0],d[b[1]]=a[1]):d=a[0],d}function j(a,c,d){return b.extend(!0,{},a,i(c,d))}function k(a,b,c,d){var e={className:"bootbox-"+a,buttons:l.apply(null,b)};return m(j(e,d,c),b)}function l(){for(var a={},b=0,c=arguments.length;c>b;b++){var e=arguments[b],f=e.toLowerCase(),g=e.toUpperCase();a[f]={label:d(g)}}return a}function m(a,b){var d={};return g(b,function(a,b){d[b]=!0}),g(a.buttons,function(a){if(d[a]===c)throw new Error("button key "+a+" is not allowed (options are "+b.join("\n")+")")}),a}var n={dialog:"<div class='bootbox modal' tabindex='-1' role='dialog'><div class='modal-dialog'><div class='modal-content'><div class='modal-body'><div class='bootbox-body'></div></div></div></div></div>",header:"<div class='modal-header'><h4 class='modal-title'></h4></div>",footer:"<div class='modal-footer'></div>",closeButton:"<button type='button' class='bootbox-close-button close' data-dismiss='modal' aria-hidden='true'>&times;</button>",form:"<form class='bootbox-form'></form>",inputs:{text:"<input class='bootbox-input bootbox-input-text form-control' autocomplete=off type=text />",textarea:"<textarea class='bootbox-input bootbox-input-textarea form-control'></textarea>",email:"<input class='bootbox-input bootbox-input-email form-control' autocomplete='off' type='email' />",select:"<select class='bootbox-input bootbox-input-select form-control'></select>",checkbox:"<div class='checkbox'><label><input class='bootbox-input bootbox-input-checkbox' type='checkbox' /></label></div>",date:"<input class='bootbox-input bootbox-input-date form-control' autocomplete=off type='date' />",time:"<input class='bootbox-input bootbox-input-time form-control' autocomplete=off type='time' />",number:"<input class='bootbox-input bootbox-input-number form-control' autocomplete=off type='number' />",password:"<input class='bootbox-input bootbox-input-password form-control' autocomplete='off' type='password' />"}},o={locale:"en",backdrop:"static",animate:!0,className:null,closeButton:!0,show:!0,container:"body"},p={};p.alert=function(){var a;if(a=k("alert",["ok"],["message","callback"],arguments),a.callback&&!b.isFunction(a.callback))throw new Error("alert requires callback property to be a function when provided");return a.buttons.ok.callback=a.onEscape=function(){return b.isFunction(a.callback)?a.callback.call(this):!0},p.dialog(a)},p.confirm=function(){var a;if(a=k("confirm",["cancel","confirm"],["message","callback"],arguments),a.buttons.cancel.callback=a.onEscape=function(){return a.callback.call(this,!1)},a.buttons.confirm.callback=function(){return a.callback.call(this,!0)},!b.isFunction(a.callback))throw new Error("confirm requires a callback");return p.dialog(a)},p.prompt=function(){var a,d,e,f,h,i,k;if(f=b(n.form),d={className:"bootbox-prompt",buttons:l("cancel","confirm"),value:"",inputType:"text"},a=m(j(d,arguments,["title","callback"]),["cancel","confirm"]),i=a.show===c?!0:a.show,a.message=f,a.buttons.cancel.callback=a.onEscape=function(){return a.callback.call(this,null)},a.buttons.confirm.callback=function(){var c;switch(a.inputType){case"text":case"textarea":case"email":case"select":case"date":case"time":case"number":case"password":c=h.val();break;case"checkbox":var d=h.find("input:checked");c=[],g(d,function(a,d){c.push(b(d).val())})}return a.callback.call(this,c)},a.show=!1,!a.title)throw new Error("prompt requires a title");if(!b.isFunction(a.callback))throw new Error("prompt requires a callback");if(!n.inputs[a.inputType])throw new Error("invalid prompt type");switch(h=b(n.inputs[a.inputType]),a.inputType){case"text":case"textarea":case"email":case"date":case"time":case"number":case"password":h.val(a.value);break;case"select":var o={};if(k=a.inputOptions||[],!b.isArray(k))throw new Error("Please pass an array of input options");if(!k.length)throw new Error("prompt with select requires options");g(k,function(a,d){var e=h;if(d.value===c||d.text===c)throw new Error("given options in wrong format");d.group&&(o[d.group]||(o[d.group]=b("<optgroup/>").attr("label",d.group)),e=o[d.group]),e.append("<option value='"+d.value+"'>"+d.text+"</option>")}),g(o,function(a,b){h.append(b)}),h.val(a.value);break;case"checkbox":var q=b.isArray(a.value)?a.value:[a.value];if(k=a.inputOptions||[],!k.length)throw new Error("prompt with checkbox requires options");if(!k[0].value||!k[0].text)throw new Error("given options in wrong format");h=b("<div/>"),g(k,function(c,d){var e=b(n.inputs[a.inputType]);e.find("input").attr("value",d.value),e.find("label").append(d.text),g(q,function(a,b){b===d.value&&e.find("input").prop("checked",!0)}),h.append(e)})}return a.placeholder&&h.attr("placeholder",a.placeholder),a.pattern&&h.attr("pattern",a.pattern),a.maxlength&&h.attr("maxlength",a.maxlength),f.append(h),f.on("submit",function(a){a.preventDefault(),a.stopPropagation(),e.find(".btn-primary").click()}),e=p.dialog(a),e.off("shown.bs.modal"),e.on("shown.bs.modal",function(){h.focus()}),i===!0&&e.modal("show"),e},p.dialog=function(a){a=h(a);var d=b(n.dialog),f=d.find(".modal-dialog"),i=d.find(".modal-body"),j=a.buttons,k="",l={onEscape:a.onEscape};if(b.fn.modal===c)throw new Error("$.fn.modal is not defined; please double check you have included the Bootstrap JavaScript library. See http://getbootstrap.com/javascript/ for more details.");if(g(j,function(a,b){k+="<button data-bb-handler='"+a+"' type='button' class='btn "+b.className+"'>"+b.label+"</button>",l[a]=b.callback}),i.find(".bootbox-body").html(a.message),a.animate===!0&&d.addClass("fade"),a.className&&d.addClass(a.className),"large"===a.size?f.addClass("modal-lg"):"small"===a.size&&f.addClass("modal-sm"),a.title&&i.before(n.header),a.closeButton){var m=b(n.closeButton);a.title?d.find(".modal-header").prepend(m):m.css("margin-top","-10px").prependTo(i)}return a.title&&d.find(".modal-title").html(a.title),k.length&&(i.after(n.footer),d.find(".modal-footer").html(k)),d.on("hidden.bs.modal",function(a){a.target===this&&d.remove()}),d.on("shown.bs.modal",function(){d.find(".btn-primary:first").focus()}),"static"!==a.backdrop&&d.on("click.dismiss.bs.modal",function(a){d.children(".modal-backdrop").length&&(a.currentTarget=d.children(".modal-backdrop").get(0)),a.target===a.currentTarget&&d.trigger("escape.close.bb")}),d.on("escape.close.bb",function(a){l.onEscape&&e(a,d,l.onEscape)}),d.on("click",".modal-footer button",function(a){var c=b(this).data("bb-handler");e(a,d,l[c])}),d.on("click",".bootbox-close-button",function(a){e(a,d,l.onEscape)}),d.on("keyup",function(a){27===a.which&&d.trigger("escape.close.bb")}),b(a.container).append(d),d.modal({backdrop:a.backdrop?"static":!1,keyboard:!1,show:!1}),a.show&&d.modal("show"),d},p.setDefaults=function(){var a={};2===arguments.length?a[arguments[0]]=arguments[1]:a=arguments[0],b.extend(o,a)},p.hideAll=function(){return b(".bootbox").modal("hide"),p};var q={bg_BG:{OK:"Ок",CANCEL:"Отказ",CONFIRM:"Потвърждавам"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},cs:{OK:"OK",CANCEL:"Zrušit",CONFIRM:"Potvrdit"},da:{OK:"OK",CANCEL:"Annuller",CONFIRM:"Accepter"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},el:{OK:"Εντάξει",CANCEL:"Ακύρωση",CONFIRM:"Επιβεβαίωση"},en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},et:{OK:"OK",CANCEL:"Katkesta",CONFIRM:"OK"},fa:{OK:"قبول",CANCEL:"لغو",CONFIRM:"تایید"},fi:{OK:"OK",CANCEL:"Peruuta",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},he:{OK:"אישור",CANCEL:"ביטול",CONFIRM:"אישור"},hu:{OK:"OK",CANCEL:"Mégsem",CONFIRM:"Megerősít"},hr:{OK:"OK",CANCEL:"Odustani",CONFIRM:"Potvrdi"},id:{OK:"OK",CANCEL:"Batal",CONFIRM:"OK"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"},ja:{OK:"OK",CANCEL:"キャンセル",CONFIRM:"確認"},lt:{OK:"Gerai",CANCEL:"Atšaukti",CONFIRM:"Patvirtinti"},lv:{OK:"Labi",CANCEL:"Atcelt",CONFIRM:"Apstiprināt"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},no:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},pl:{OK:"OK",CANCEL:"Anuluj",CONFIRM:"Potwierdź"},pt:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Confirmar"},ru:{OK:"OK",CANCEL:"Отмена",CONFIRM:"Применить"},sq:{OK:"OK",CANCEL:"Anulo",CONFIRM:"Prano"},sv:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},th:{OK:"ตกลง",CANCEL:"ยกเลิก",CONFIRM:"ยืนยัน"},tr:{OK:"Tamam",CANCEL:"İptal",CONFIRM:"Onayla"},zh_CN:{OK:"OK",CANCEL:"取消",CONFIRM:"确认"},zh_TW:{OK:"OK",CANCEL:"取消",CONFIRM:"確認"}};return p.addLocale=function(a,c){return b.each(["OK","CANCEL","CONFIRM"],function(a,b){if(!c[b])throw new Error("Please supply a translation for '"+b+"'")}),q[a]={OK:c.OK,CANCEL:c.CANCEL,CONFIRM:c.CONFIRM},p},p.removeLocale=function(a){return delete q[a],p},p.setLocale=function(a){return p.setDefaults("locale",a)},p.init=function(c){return a(c||b)},p});
assets/js/vendor/bootstrap/bootstrap.js ADDED
@@ -0,0 +1,418 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Bootstrap v3.3.5 (http://getbootstrap.com)
3
+ * Copyright 2011-2016 Twitter, Inc.
4
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5
+ */
6
+
7
+ /*!
8
+ * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=f9591b2f58105c5fa28db0e6eba864bd)
9
+ * Config saved to config.json and https://gist.github.com/f9591b2f58105c5fa28db0e6eba864bd
10
+ */
11
+ if (typeof jQuery === 'undefined') {
12
+ throw new Error('Bootstrap\'s JavaScript requires jQuery')
13
+ }
14
+ +function ($) {
15
+ 'use strict';
16
+ var version = $.fn.jquery.split(' ')[0].split('.')
17
+ if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 2)) {
18
+ throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3')
19
+ }
20
+ }(jQuery);
21
+
22
+ /* ========================================================================
23
+ * Bootstrap: modal.js v3.3.6
24
+ * http://getbootstrap.com/javascript/#modals
25
+ * ========================================================================
26
+ * Copyright 2011-2015 Twitter, Inc.
27
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
28
+ * ======================================================================== */
29
+
30
+
31
+ +function ($) {
32
+ 'use strict';
33
+
34
+ // MODAL CLASS DEFINITION
35
+ // ======================
36
+
37
+ var Modal = function (element, options) {
38
+ this.options = options
39
+ this.$body = $(document.body)
40
+ this.$element = $(element)
41
+ this.$dialog = this.$element.find('.modal-dialog')
42
+ this.$backdrop = null
43
+ this.isShown = null
44
+ this.originalBodyPad = null
45
+ this.scrollbarWidth = 0
46
+ this.ignoreBackdropClick = false
47
+
48
+ if (this.options.remote) {
49
+ this.$element
50
+ .find('.modal-content')
51
+ .load(this.options.remote, $.proxy(function () {
52
+ this.$element.trigger('loaded.bs.modal')
53
+ }, this))
54
+ }
55
+ }
56
+
57
+ Modal.VERSION = '3.3.6'
58
+
59
+ Modal.TRANSITION_DURATION = 300
60
+ Modal.BACKDROP_TRANSITION_DURATION = 150
61
+
62
+ Modal.DEFAULTS = {
63
+ backdrop: true,
64
+ keyboard: true,
65
+ show: true
66
+ }
67
+
68
+ Modal.prototype.toggle = function (_relatedTarget) {
69
+ return this.isShown ? this.hide() : this.show(_relatedTarget)
70
+ }
71
+
72
+ Modal.prototype.show = function (_relatedTarget) {
73
+ var that = this
74
+ var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
75
+
76
+ this.$element.trigger(e)
77
+
78
+ if (this.isShown || e.isDefaultPrevented()) return
79
+
80
+ this.isShown = true
81
+
82
+ this.checkScrollbar()
83
+ this.setScrollbar()
84
+ this.$body.addClass('modal-open')
85
+
86
+ this.escape()
87
+ this.resize()
88
+
89
+ this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
90
+
91
+ this.$dialog.on('mousedown.dismiss.bs.modal', function () {
92
+ that.$element.one('mouseup.dismiss.bs.modal', function (e) {
93
+ if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
94
+ })
95
+ })
96
+
97
+ this.backdrop(function () {
98
+ var transition = $.support.transition && that.$element.hasClass('fade')
99
+
100
+ if (!that.$element.parent().length) {
101
+ that.$element.appendTo(that.$body) // don't move modals dom position
102
+ }
103
+
104
+ that.$element
105
+ .show()
106
+ .scrollTop(0)
107
+
108
+ that.adjustDialog()
109
+
110
+ if (transition) {
111
+ that.$element[0].offsetWidth // force reflow
112
+ }
113
+
114
+ that.$element.addClass('in')
115
+
116
+ that.enforceFocus()
117
+
118
+ var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
119
+
120
+ transition ?
121
+ that.$dialog // wait for modal to slide in
122
+ .one('bsTransitionEnd', function () {
123
+ that.$element.trigger('focus').trigger(e)
124
+ })
125
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
126
+ that.$element.trigger('focus').trigger(e)
127
+ })
128
+ }
129
+
130
+ Modal.prototype.hide = function (e) {
131
+ if (e) e.preventDefault()
132
+
133
+ e = $.Event('hide.bs.modal')
134
+
135
+ this.$element.trigger(e)
136
+
137
+ if (!this.isShown || e.isDefaultPrevented()) return
138
+
139
+ this.isShown = false
140
+
141
+ this.escape()
142
+ this.resize()
143
+
144
+ $(document).off('focusin.bs.modal')
145
+
146
+ this.$element
147
+ .removeClass('in')
148
+ .off('click.dismiss.bs.modal')
149
+ .off('mouseup.dismiss.bs.modal')
150
+
151
+ this.$dialog.off('mousedown.dismiss.bs.modal')
152
+
153
+ $.support.transition && this.$element.hasClass('fade') ?
154
+ this.$element
155
+ .one('bsTransitionEnd', $.proxy(this.hideModal, this))
156
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
157
+ this.hideModal()
158
+ }
159
+
160
+ Modal.prototype.enforceFocus = function () {
161
+ $(document)
162
+ .off('focusin.bs.modal') // guard against infinite focus loop
163
+ .on('focusin.bs.modal', $.proxy(function (e) {
164
+ if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
165
+ this.$element.trigger('focus')
166
+ }
167
+ }, this))
168
+ }
169
+
170
+ Modal.prototype.escape = function () {
171
+ if (this.isShown && this.options.keyboard) {
172
+ this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
173
+ e.which == 27 && this.hide()
174
+ }, this))
175
+ } else if (!this.isShown) {
176
+ this.$element.off('keydown.dismiss.bs.modal')
177
+ }
178
+ }
179
+
180
+ Modal.prototype.resize = function () {
181
+ if (this.isShown) {
182
+ $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
183
+ } else {
184
+ $(window).off('resize.bs.modal')
185
+ }
186
+ }
187
+
188
+ Modal.prototype.hideModal = function () {
189
+ var that = this
190
+ this.$element.hide()
191
+ this.backdrop(function () {
192
+ that.$body.removeClass('modal-open')
193
+ that.resetAdjustments()
194
+ that.resetScrollbar()
195
+ that.$element.trigger('hidden.bs.modal')
196
+ })
197
+ }
198
+
199
+ Modal.prototype.removeBackdrop = function () {
200
+ this.$backdrop && this.$backdrop.remove()
201
+ this.$backdrop = null
202
+ }
203
+
204
+ Modal.prototype.backdrop = function (callback) {
205
+ var that = this
206
+ var animate = this.$element.hasClass('fade') ? 'fade' : ''
207
+
208
+ if (this.isShown && this.options.backdrop) {
209
+ var doAnimate = $.support.transition && animate
210
+
211
+ this.$backdrop = $(document.createElement('div'))
212
+ .addClass('modal-backdrop ' + animate)
213
+ .appendTo(this.$body)
214
+
215
+ this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
216
+ if (this.ignoreBackdropClick) {
217
+ this.ignoreBackdropClick = false
218
+ return
219
+ }
220
+ if (e.target !== e.currentTarget) return
221
+ this.options.backdrop == 'static'
222
+ ? this.$element[0].focus()
223
+ : this.hide()
224
+ }, this))
225
+
226
+ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
227
+
228
+ this.$backdrop.addClass('in')
229
+
230
+ if (!callback) return
231
+
232
+ doAnimate ?
233
+ this.$backdrop
234
+ .one('bsTransitionEnd', callback)
235
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
236
+ callback()
237
+
238
+ } else if (!this.isShown && this.$backdrop) {
239
+ this.$backdrop.removeClass('in')
240
+
241
+ var callbackRemove = function () {
242
+ that.removeBackdrop()
243
+ callback && callback()
244
+ }
245
+ $.support.transition && this.$element.hasClass('fade') ?
246
+ this.$backdrop
247
+ .one('bsTransitionEnd', callbackRemove)
248
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
249
+ callbackRemove()
250
+
251
+ } else if (callback) {
252
+ callback()
253
+ }
254
+ }
255
+
256
+ // these following methods are used to handle overflowing modals
257
+
258
+ Modal.prototype.handleUpdate = function () {
259
+ this.adjustDialog()
260
+ }
261
+
262
+ Modal.prototype.adjustDialog = function () {
263
+ var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
264
+
265
+ this.$element.css({
266
+ paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
267
+ paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
268
+ })
269
+ }
270
+
271
+ Modal.prototype.resetAdjustments = function () {
272
+ this.$element.css({
273
+ paddingLeft: '',
274
+ paddingRight: ''
275
+ })
276
+ }
277
+
278
+ Modal.prototype.checkScrollbar = function () {
279
+ var fullWindowWidth = window.innerWidth
280
+ if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
281
+ var documentElementRect = document.documentElement.getBoundingClientRect()
282
+ fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
283
+ }
284
+ this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
285
+ this.scrollbarWidth = this.measureScrollbar()
286
+ }
287
+
288
+ Modal.prototype.setScrollbar = function () {
289
+ var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
290
+ this.originalBodyPad = document.body.style.paddingRight || ''
291
+ if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
292
+ }
293
+
294
+ Modal.prototype.resetScrollbar = function () {
295
+ this.$body.css('padding-right', this.originalBodyPad)
296
+ }
297
+
298
+ Modal.prototype.measureScrollbar = function () { // thx walsh
299
+ var scrollDiv = document.createElement('div')
300
+ scrollDiv.className = 'modal-scrollbar-measure'
301
+ this.$body.append(scrollDiv)
302
+ var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
303
+ this.$body[0].removeChild(scrollDiv)
304
+ return scrollbarWidth
305
+ }
306
+
307
+
308
+ // MODAL PLUGIN DEFINITION
309
+ // =======================
310
+
311
+ function Plugin(option, _relatedTarget) {
312
+ return this.each(function () {
313
+ var $this = $(this)
314
+ var data = $this.data('bs.modal')
315
+ var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
316
+
317
+ if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
318
+ if (typeof option == 'string') data[option](_relatedTarget)
319
+ else if (options.show) data.show(_relatedTarget)
320
+ })
321
+ }
322
+
323
+ var old = $.fn.modal
324
+
325
+ $.fn.modal = Plugin
326
+ $.fn.modal.Constructor = Modal
327
+
328
+
329
+ // MODAL NO CONFLICT
330
+ // =================
331
+
332
+ $.fn.modal.noConflict = function () {
333
+ $.fn.modal = old
334
+ return this
335
+ }
336
+
337
+
338
+ // MODAL DATA-API
339
+ // ==============
340
+
341
+ $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
342
+ var $this = $(this)
343
+ var href = $this.attr('href')
344
+ var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
345
+ var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
346
+
347
+ if ($this.is('a')) e.preventDefault()
348
+
349
+ $target.one('show.bs.modal', function (showEvent) {
350
+ if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
351
+ $target.one('hidden.bs.modal', function () {
352
+ $this.is(':visible') && $this.trigger('focus')
353
+ })
354
+ })
355
+ Plugin.call($target, option, this)
356
+ })
357
+
358
+ }(jQuery);
359
+
360
+ /* ========================================================================
361
+ * Bootstrap: transition.js v3.3.6
362
+ * http://getbootstrap.com/javascript/#transitions
363
+ * ========================================================================
364
+ * Copyright 2011-2015 Twitter, Inc.
365
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
366
+ * ======================================================================== */
367
+
368
+
369
+ +function ($) {
370
+ 'use strict';
371
+
372
+ // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
373
+ // ============================================================
374
+
375
+ function transitionEnd() {
376
+ var el = document.createElement('bootstrap')
377
+
378
+ var transEndEventNames = {
379
+ WebkitTransition : 'webkitTransitionEnd',
380
+ MozTransition : 'transitionend',
381
+ OTransition : 'oTransitionEnd otransitionend',
382
+ transition : 'transitionend'
383
+ }
384
+
385
+ for (var name in transEndEventNames) {
386
+ if (el.style[name] !== undefined) {
387
+ return { end: transEndEventNames[name] }
388
+ }
389
+ }
390
+
391
+ return false // explicit for ie8 ( ._.)
392
+ }
393
+
394
+ // http://blog.alexmaccaw.com/css-transitions
395
+ $.fn.emulateTransitionEnd = function (duration) {
396
+ var called = false
397
+ var $el = this
398
+ $(this).one('bsTransitionEnd', function () { called = true })
399
+ var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
400
+ setTimeout(callback, duration)
401
+ return this
402
+ }
403
+
404
+ $(function () {
405
+ $.support.transition = transitionEnd()
406
+
407
+ if (!$.support.transition) return
408
+
409
+ $.event.special.bsTransitionEnd = {
410
+ bindType: $.support.transition.end,
411
+ delegateType: $.support.transition.end,
412
+ handle: function (e) {
413
+ if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
414
+ }
415
+ }
416
+ })
417
+
418
+ }(jQuery);
assets/js/vendor/bootstrap/bootstrap.min.js ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Bootstrap v3.3.5 (http://getbootstrap.com)
3
+ * Copyright 2011-2016 Twitter, Inc.
4
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5
+ */
6
+
7
+ /*!
8
+ * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=f9591b2f58105c5fa28db0e6eba864bd)
9
+ * Config saved to config.json and https://gist.github.com/f9591b2f58105c5fa28db0e6eba864bd
10
+ */
11
+ if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(t){"use strict";var e=t.fn.jquery.split(" ")[0].split(".");if(e[0]<2&&e[1]<9||1==e[0]&&9==e[1]&&e[2]<1||e[0]>2)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3")}(jQuery),+function(t){"use strict";function e(e,o){return this.each(function(){var s=t(this),n=s.data("bs.modal"),r=t.extend({},i.DEFAULTS,s.data(),"object"==typeof e&&e);n||s.data("bs.modal",n=new i(this,r)),"string"==typeof e?n[e](o):r.show&&n.show(o)})}var i=function(e,i){this.options=i,this.$body=t(document.body),this.$element=t(e),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,t.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};i.VERSION="3.3.6",i.TRANSITION_DURATION=300,i.BACKDROP_TRANSITION_DURATION=150,i.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},i.prototype.toggle=function(t){return this.isShown?this.hide():this.show(t)},i.prototype.show=function(e){var o=this,s=t.Event("show.bs.modal",{relatedTarget:e});this.$element.trigger(s),this.isShown||s.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',t.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){o.$element.one("mouseup.dismiss.bs.modal",function(e){t(e.target).is(o.$element)&&(o.ignoreBackdropClick=!0)})}),this.backdrop(function(){var s=t.support.transition&&o.$element.hasClass("fade");o.$element.parent().length||o.$element.appendTo(o.$body),o.$element.show().scrollTop(0),o.adjustDialog(),s&&o.$element[0].offsetWidth,o.$element.addClass("in"),o.enforceFocus();var n=t.Event("shown.bs.modal",{relatedTarget:e});s?o.$dialog.one("bsTransitionEnd",function(){o.$element.trigger("focus").trigger(n)}).emulateTransitionEnd(i.TRANSITION_DURATION):o.$element.trigger("focus").trigger(n)}))},i.prototype.hide=function(e){e&&e.preventDefault(),e=t.Event("hide.bs.modal"),this.$element.trigger(e),this.isShown&&!e.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),t(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),t.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",t.proxy(this.hideModal,this)).emulateTransitionEnd(i.TRANSITION_DURATION):this.hideModal())},i.prototype.enforceFocus=function(){t(document).off("focusin.bs.modal").on("focusin.bs.modal",t.proxy(function(t){this.$element[0]===t.target||this.$element.has(t.target).length||this.$element.trigger("focus")},this))},i.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",t.proxy(function(t){27==t.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},i.prototype.resize=function(){this.isShown?t(window).on("resize.bs.modal",t.proxy(this.handleUpdate,this)):t(window).off("resize.bs.modal")},i.prototype.hideModal=function(){var t=this;this.$element.hide(),this.backdrop(function(){t.$body.removeClass("modal-open"),t.resetAdjustments(),t.resetScrollbar(),t.$element.trigger("hidden.bs.modal")})},i.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},i.prototype.backdrop=function(e){var o=this,s=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var n=t.support.transition&&s;if(this.$backdrop=t(document.createElement("div")).addClass("modal-backdrop "+s).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",t.proxy(function(t){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(t.target===t.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),n&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!e)return;n?this.$backdrop.one("bsTransitionEnd",e).emulateTransitionEnd(i.BACKDROP_TRANSITION_DURATION):e()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var r=function(){o.removeBackdrop(),e&&e()};t.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",r).emulateTransitionEnd(i.BACKDROP_TRANSITION_DURATION):r()}else e&&e()},i.prototype.handleUpdate=function(){this.adjustDialog()},i.prototype.adjustDialog=function(){var t=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&t?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!t?this.scrollbarWidth:""})},i.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},i.prototype.checkScrollbar=function(){var t=window.innerWidth;if(!t){var e=document.documentElement.getBoundingClientRect();t=e.right-Math.abs(e.left)}this.bodyIsOverflowing=document.body.clientWidth<t,this.scrollbarWidth=this.measureScrollbar()},i.prototype.setScrollbar=function(){var t=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",t+this.scrollbarWidth)},i.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},i.prototype.measureScrollbar=function(){var t=document.createElement("div");t.className="modal-scrollbar-measure",this.$body.append(t);var e=t.offsetWidth-t.clientWidth;return this.$body[0].removeChild(t),e};var o=t.fn.modal;t.fn.modal=e,t.fn.modal.Constructor=i,t.fn.modal.noConflict=function(){return t.fn.modal=o,this},t(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(i){var o=t(this),s=o.attr("href"),n=t(o.attr("data-target")||s&&s.replace(/.*(?=#[^\s]+$)/,"")),r=n.data("bs.modal")?"toggle":t.extend({remote:!/#/.test(s)&&s},n.data(),o.data());o.is("a")&&i.preventDefault(),n.one("show.bs.modal",function(t){t.isDefaultPrevented()||n.one("hidden.bs.modal",function(){o.is(":visible")&&o.trigger("focus")})}),e.call(n,r,this)})}(jQuery),+function(t){"use strict";function e(){var t=document.createElement("bootstrap"),e={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var i in e)if(void 0!==t.style[i])return{end:e[i]};return!1}t.fn.emulateTransitionEnd=function(e){var i=!1,o=this;t(this).one("bsTransitionEnd",function(){i=!0});var s=function(){i||t(o).trigger(t.support.transition.end)};return setTimeout(s,e),this},t(function(){t.support.transition=e(),t.support.transition&&(t.event.special.bsTransitionEnd={bindType:t.support.transition.end,delegateType:t.support.transition.end,handle:function(e){return t(e.target).is(this)?e.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery);
assets/js/vendor/bootstrap/index.html ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>403 Forbidden</title>
5
+ </head>
6
+ <body>
7
+ <p>Directory access is forbidden.</p>
8
+ </body>
9
+ </html>
assets/js/vendor/index.html ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>403 Forbidden</title>
5
+ </head>
6
+ <body>
7
+ <p>Directory access is forbidden.</p>
8
+ </body>
9
+ </html>
autoloader.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package EmbedPress
4
+ * @author PressShack <help@pressshack.com>
5
+ * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
6
+ * @license GPLv2 or later
7
+ * @since 1.0
8
+ */
9
+
10
+ use \EmbedPress\AutoLoader;
11
+
12
+ defined('ABSPATH') or die("No direct script access allowed.");
13
+
14
+ $autoLoaderFullClassName = EMBEDPRESS_NAMESPACE .'\\'. EMBEDPRESS_AUTOLOADER_NAME;
15
+ if (!defined('EMBEDPRESS_IS_LOADED') || !class_exists($autoLoaderFullClassName)) {
16
+ define('EMBEDPRESS_IS_LOADED', true);
17
+
18
+ if (!class_exists($autoLoaderFullClassName)) {
19
+ require_once EMBEDPRESS_PATH_CORE . EMBEDPRESS_AUTOLOADER_NAME .'.php';
20
+ }
21
+
22
+ AutoLoader::register(str_replace('\\', "", EMBEDPRESS_NAMESPACE), EMBEDPRESS_PATH_CORE);
23
+ }
24
+ unset($autoLoaderFullClassName);
changelog.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ == Changelog ==
2
+ = 1.0 =
3
+ Release Date: 2016-07-27
4
+
5
+ * Initial release.
embedpress.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * EmbedPress plugin bootstrap file.
4
+ *
5
+ * @link http://pressshack.com/embedpress/
6
+ * @package EmbedPress
7
+ * @author PressShack <help@pressshack.com>
8
+ * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
9
+ * @license GPLv2 or later
10
+ * @since 1.0
11
+ *
12
+ * @embedpress
13
+ * Plugin Name: EmbedPress
14
+ * Plugin URI: http://pressshack.com/embedpress/
15
+ * Description: EmbedPress lets you embed anything in WordPress! Also, you can enhance their uniqueness by passing custom parameters to each one of them.
16
+ * Version: 1.0
17
+ * Author: PressShack
18
+ * Author URI: http://pressshack.com/
19
+ */
20
+
21
+ use \EmbedPress\Plugin;
22
+
23
+ require_once plugin_dir_path(__FILE__) .'includes.php';
24
+
25
+ (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
26
+
27
+ function onPluginActivationCallback()
28
+ {
29
+ Plugin::onPluginActivationCallback();
30
+ }
31
+
32
+ function onPluginDeactivationCallback()
33
+ {
34
+ Plugin::onPluginDeactivationCallback();
35
+ }
36
+
37
+ register_activation_hook(__FILE__, 'onPluginActivationCallback');
38
+ register_deactivation_hook(__FILE__, 'onPluginDeactivationCallback');
39
+
40
+ $embedPressPlugin = new Plugin();
41
+ $embedPressPlugin->initialize();
includes.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ defined('ABSPATH') or die("No direct script access allowed.");
3
+
4
+ /**
5
+ * File responsible for defining basic general constants used by the plugin.
6
+ *
7
+ * @package EmbedPress
8
+ * @author PressShack <help@pressshack.com>
9
+ * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
10
+ * @license GPLv2 or later
11
+ * @since 1.0
12
+ */
13
+
14
+ if (!defined('EMBEDPRESS_PLG_NAME')) {
15
+ define('EMBEDPRESS_PLG_NAME', "EmbedPress");
16
+ }
17
+
18
+ if (!defined('EMBEDPRESS_PLG_VERSION')) {
19
+ define('EMBEDPRESS_PLG_VERSION', "1.0");
20
+ }
21
+
22
+ if (!defined('EMBEDPRESS_PATH_BASE')) {
23
+ define('EMBEDPRESS_PATH_BASE', plugin_dir_path(__FILE__));
24
+ }
25
+
26
+ if (!defined('EMBEDPRESS_PATH_CORE')) {
27
+ define('EMBEDPRESS_PATH_CORE', EMBEDPRESS_PATH_BASE ."EmbedPress/");
28
+ }
29
+
30
+ if (!defined('EMBEDPRESS_PATH_LIBRARIES')) {
31
+ define('EMBEDPRESS_PATH_LIBRARIES', EMBEDPRESS_PATH_BASE ."library/");
32
+ }
33
+
34
+ if (!defined('EMBEDPRESS_URL_ASSETS')) {
35
+ define('EMBEDPRESS_URL_ASSETS', plugins_url(EMBEDPRESS_PLG_NAME) ."/assets/");
36
+ }
37
+
38
+ if (!defined('EMBEDPRESS_NAMESPACE')) {
39
+ define('EMBEDPRESS_NAMESPACE', "\\EmbedPress");
40
+ }
41
+
42
+ if (!defined('EMBEDPRESS_AUTOLOADER_NAME')) {
43
+ define('EMBEDPRESS_AUTOLOADER_NAME', "AutoLoader");
44
+ }
45
+
46
+ if (!defined('EMBEDPRESS_SHORTCODE')) {
47
+ define('EMBEDPRESS_SHORTCODE', "embed");
48
+ }
49
+
50
+ // Run libraries's autoload script
51
+ require_once EMBEDPRESS_PATH_LIBRARIES ."autoload.php";
52
+ // Run the plugin autoload script
53
+ require_once EMBEDPRESS_PATH_BASE ."autoloader.php";
54
+ ?>
index.html ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>403 Forbidden</title>
5
+ </head>
6
+ <body>
7
+ <p>Directory access is forbidden.</p>
8
+ </body>
9
+ </html>
library/autoload.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload.php @generated by Composer
4
+
5
+ require_once __DIR__ . '/composer' . '/autoload_real.php';
6
+
7
+ return ComposerAutoloaderInit15b942fc6af6974ec5ec3a1e7a92e45dP::getLoader();
library/composer/ClassLoader.php ADDED
@@ -0,0 +1,413 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Composer.
5
+ *
6
+ * (c) Nils Adermann <naderman@naderman.de>
7
+ * Jordi Boggiano <j.boggiano@seld.be>
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Composer\Autoload;
14
+
15
+ /**
16
+ * ClassLoader implements a PSR-0 class loader
17
+ *
18
+ * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
19
+ *
20
+ * $loader = new \Composer\Autoload\ClassLoader();
21
+ *
22
+ * // register classes with namespaces
23
+ * $loader->add('Symfony\Component', __DIR__.'/component');
24
+ * $loader->add('Symfony', __DIR__.'/framework');
25
+ *
26
+ * // activate the autoloader
27
+ * $loader->register();
28
+ *
29
+ * // to enable searching the include path (eg. for PEAR packages)
30
+ * $loader->setUseIncludePath(true);
31
+ *
32
+ * In this example, if you try to use a class in the Symfony\Component
33
+ * namespace or one of its children (Symfony\Component\Console for instance),
34
+ * the autoloader will first look for the class under the component/
35
+ * directory, and it will then fallback to the framework/ directory if not
36
+ * found before giving up.
37
+ *
38
+ * This class is loosely based on the Symfony UniversalClassLoader.
39
+ *
40
+ * @author Fabien Potencier <fabien@symfony.com>
41
+ * @author Jordi Boggiano <j.boggiano@seld.be>
42
+ */
43
+ class ClassLoader
44
+ {
45
+ // PSR-4
46
+ private $prefixLengthsPsr4 = array();
47
+ private $prefixDirsPsr4 = array();
48
+ private $fallbackDirsPsr4 = array();
49
+
50
+ // PSR-0
51
+ private $prefixesPsr0 = array();
52
+ private $fallbackDirsPsr0 = array();
53
+
54
+ private $useIncludePath = false;
55
+ private $classMap = array();
56
+
57
+ private $classMapAuthoritative = false;
58
+
59
+ public function getPrefixes()
60
+ {
61
+ if (!empty($this->prefixesPsr0)) {
62
+ return call_user_func_array('array_merge', $this->prefixesPsr0);
63
+ }
64
+
65
+ return array();
66
+ }
67
+
68
+ public function getPrefixesPsr4()
69
+ {
70
+ return $this->prefixDirsPsr4;
71
+ }
72
+
73
+ public function getFallbackDirs()
74
+ {
75
+ return $this->fallbackDirsPsr0;
76
+ }
77
+
78
+ public function getFallbackDirsPsr4()
79
+ {
80
+ return $this->fallbackDirsPsr4;
81
+ }
82
+
83
+ public function getClassMap()
84
+ {
85
+ return $this->classMap;
86
+ }
87
+
88
+ /**
89
+ * @param array $classMap Class to filename map
90
+ */
91
+ public function addClassMap(array $classMap)
92
+ {
93
+ if ($this->classMap) {
94
+ $this->classMap = array_merge($this->classMap, $classMap);
95
+ } else {
96
+ $this->classMap = $classMap;
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Registers a set of PSR-0 directories for a given prefix, either
102
+ * appending or prepending to the ones previously set for this prefix.
103
+ *
104
+ * @param string $prefix The prefix
105
+ * @param array|string $paths The PSR-0 root directories
106
+ * @param bool $prepend Whether to prepend the directories
107
+ */
108
+ public function add($prefix, $paths, $prepend = false)
109
+ {
110
+ if (!$prefix) {
111
+ if ($prepend) {
112
+ $this->fallbackDirsPsr0 = array_merge(
113
+ (array) $paths,
114
+ $this->fallbackDirsPsr0
115
+ );
116
+ } else {
117
+ $this->fallbackDirsPsr0 = array_merge(
118
+ $this->fallbackDirsPsr0,
119
+ (array) $paths
120
+ );
121
+ }
122
+
123
+ return;
124
+ }
125
+
126
+ $first = $prefix[0];
127
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
128
+ $this->prefixesPsr0[$first][$prefix] = (array) $paths;
129
+
130
+ return;
131
+ }
132
+ if ($prepend) {
133
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
134
+ (array) $paths,
135
+ $this->prefixesPsr0[$first][$prefix]
136
+ );
137
+ } else {
138
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
139
+ $this->prefixesPsr0[$first][$prefix],
140
+ (array) $paths
141
+ );
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Registers a set of PSR-4 directories for a given namespace, either
147
+ * appending or prepending to the ones previously set for this namespace.
148
+ *
149
+ * @param string $prefix The prefix/namespace, with trailing '\\'
150
+ * @param array|string $paths The PSR-0 base directories
151
+ * @param bool $prepend Whether to prepend the directories
152
+ *
153
+ * @throws \InvalidArgumentException
154
+ */
155
+ public function addPsr4($prefix, $paths, $prepend = false)
156
+ {
157
+ if (!$prefix) {
158
+ // Register directories for the root namespace.
159
+ if ($prepend) {
160
+ $this->fallbackDirsPsr4 = array_merge(
161
+ (array) $paths,
162
+ $this->fallbackDirsPsr4
163
+ );
164
+ } else {
165
+ $this->fallbackDirsPsr4 = array_merge(
166
+ $this->fallbackDirsPsr4,
167
+ (array) $paths
168
+ );
169
+ }
170
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
171
+ // Register directories for a new namespace.
172
+ $length = strlen($prefix);
173
+ if ('\\' !== $prefix[$length - 1]) {
174
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
175
+ }
176
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
177
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
178
+ } elseif ($prepend) {
179
+ // Prepend directories for an already registered namespace.
180
+ $this->prefixDirsPsr4[$prefix] = array_merge(
181
+ (array) $paths,
182
+ $this->prefixDirsPsr4[$prefix]
183
+ );
184
+ } else {
185
+ // Append directories for an already registered namespace.
186
+ $this->prefixDirsPsr4[$prefix] = array_merge(
187
+ $this->prefixDirsPsr4[$prefix],
188
+ (array) $paths
189
+ );
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Registers a set of PSR-0 directories for a given prefix,
195
+ * replacing any others previously set for this prefix.
196
+ *
197
+ * @param string $prefix The prefix
198
+ * @param array|string $paths The PSR-0 base directories
199
+ */
200
+ public function set($prefix, $paths)
201
+ {
202
+ if (!$prefix) {
203
+ $this->fallbackDirsPsr0 = (array) $paths;
204
+ } else {
205
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Registers a set of PSR-4 directories for a given namespace,
211
+ * replacing any others previously set for this namespace.
212
+ *
213
+ * @param string $prefix The prefix/namespace, with trailing '\\'
214
+ * @param array|string $paths The PSR-4 base directories
215
+ *
216
+ * @throws \InvalidArgumentException
217
+ */
218
+ public function setPsr4($prefix, $paths)
219
+ {
220
+ if (!$prefix) {
221
+ $this->fallbackDirsPsr4 = (array) $paths;
222
+ } else {
223
+ $length = strlen($prefix);
224
+ if ('\\' !== $prefix[$length - 1]) {
225
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
226
+ }
227
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
228
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
229
+ }
230
+ }
231
+
232
+ /**
233
+ * Turns on searching the include path for class files.
234
+ *
235
+ * @param bool $useIncludePath
236
+ */
237
+ public function setUseIncludePath($useIncludePath)
238
+ {
239
+ $this->useIncludePath = $useIncludePath;
240
+ }
241
+
242
+ /**
243
+ * Can be used to check if the autoloader uses the include path to check
244
+ * for classes.
245
+ *
246
+ * @return bool
247
+ */
248
+ public function getUseIncludePath()
249
+ {
250
+ return $this->useIncludePath;
251
+ }
252
+
253
+ /**
254
+ * Turns off searching the prefix and fallback directories for classes
255
+ * that have not been registered with the class map.
256
+ *
257
+ * @param bool $classMapAuthoritative
258
+ */
259
+ public function setClassMapAuthoritative($classMapAuthoritative)
260
+ {
261
+ $this->classMapAuthoritative = $classMapAuthoritative;
262
+ }
263
+
264
+ /**
265
+ * Should class lookup fail if not found in the current class map?
266
+ *
267
+ * @return bool
268
+ */
269
+ public function isClassMapAuthoritative()
270
+ {
271
+ return $this->classMapAuthoritative;
272
+ }
273
+
274
+ /**
275
+ * Registers this instance as an autoloader.
276
+ *
277
+ * @param bool $prepend Whether to prepend the autoloader or not
278
+ */
279
+ public function register($prepend = false)
280
+ {
281
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
282
+ }
283
+
284
+ /**
285
+ * Unregisters this instance as an autoloader.
286
+ */
287
+ public function unregister()
288
+ {
289
+ spl_autoload_unregister(array($this, 'loadClass'));
290
+ }
291
+
292
+ /**
293
+ * Loads the given class or interface.
294
+ *
295
+ * @param string $class The name of the class
296
+ * @return bool|null True if loaded, null otherwise
297
+ */
298
+ public function loadClass($class)
299
+ {
300
+ if ($file = $this->findFile($class)) {
301
+ includeFile($file);
302
+
303
+ return true;
304
+ }
305
+ }
306
+
307
+ /**
308
+ * Finds the path to the file where the class is defined.
309
+ *
310
+ * @param string $class The name of the class
311
+ *
312
+ * @return string|false The path if found, false otherwise
313
+ */
314
+ public function findFile($class)
315
+ {
316
+ // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
317
+ if ('\\' == $class[0]) {
318
+ $class = substr($class, 1);
319
+ }
320
+
321
+ // class map lookup
322
+ if (isset($this->classMap[$class])) {
323
+ return $this->classMap[$class];
324
+ }
325
+ if ($this->classMapAuthoritative) {
326
+ return false;
327
+ }
328
+
329
+ $file = $this->findFileWithExtension($class, '.php');
330
+
331
+ // Search for Hack files if we are running on HHVM
332
+ if ($file === null && defined('HHVM_VERSION')) {
333
+ $file = $this->findFileWithExtension($class, '.hh');
334
+ }
335
+
336
+ if ($file === null) {
337
+ // Remember that this class does not exist.
338
+ return $this->classMap[$class] = false;
339
+ }
340
+
341
+ return $file;
342
+ }
343
+
344
+ private function findFileWithExtension($class, $ext)
345
+ {
346
+ // PSR-4 lookup
347
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
348
+
349
+ $first = $class[0];
350
+ if (isset($this->prefixLengthsPsr4[$first])) {
351
+ foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
352
+ if (0 === strpos($class, $prefix)) {
353
+ foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
354
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
355
+ return $file;
356
+ }
357
+ }
358
+ }
359
+ }
360
+ }
361
+
362
+ // PSR-4 fallback dirs
363
+ foreach ($this->fallbackDirsPsr4 as $dir) {
364
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
365
+ return $file;
366
+ }
367
+ }
368
+
369
+ // PSR-0 lookup
370
+ if (false !== $pos = strrpos($class, '\\')) {
371
+ // namespaced class name
372
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
373
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
374
+ } else {
375
+ // PEAR-like class name
376
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
377
+ }
378
+
379
+ if (isset($this->prefixesPsr0[$first])) {
380
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
381
+ if (0 === strpos($class, $prefix)) {
382
+ foreach ($dirs as $dir) {
383
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
384
+ return $file;
385
+ }
386
+ }
387
+ }
388
+ }
389
+ }
390
+
391
+ // PSR-0 fallback dirs
392
+ foreach ($this->fallbackDirsPsr0 as $dir) {
393
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
394
+ return $file;
395
+ }
396
+ }
397
+
398
+ // PSR-0 include paths.
399
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
400
+ return $file;
401
+ }
402
+ }
403
+ }
404
+
405
+ /**
406
+ * Scope isolated include.
407
+ *
408
+ * Prevents access to $this/self from included files.
409
+ */
410
+ function includeFile($file)
411
+ {
412
+ include $file;
413
+ }
library/composer/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ Copyright (c) 2015 Nils Adermann, Jordi Boggiano
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished
9
+ to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+
library/composer/autoload_classmap.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_classmap.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname(dirname($vendorDir));
7
+
8
+ return array(
9
+ );
library/composer/autoload_namespaces.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_namespaces.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname(dirname($vendorDir));
7
+
8
+ return array(
9
+ 'Embera' => array($vendorDir . '/ostraining/embera/Lib'),
10
+ );
library/composer/autoload_psr4.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_psr4.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname(dirname($vendorDir));
7
+
8
+ return array(
9
+ );
library/composer/autoload_real.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_real.php @generated by Composer
4
+
5
+ class ComposerAutoloaderInit15b942fc6af6974ec5ec3a1e7a92e45dP
6
+ {
7
+ private static $loader;
8
+
9
+ public static function loadClassLoader($class)
10
+ {
11
+ if ('Composer\Autoload\ClassLoader' === $class) {
12
+ require __DIR__ . '/ClassLoader.php';
13
+ }
14
+ }
15
+
16
+ public static function getLoader()
17
+ {
18
+ if (null !== self::$loader) {
19
+ return self::$loader;
20
+ }
21
+
22
+ spl_autoload_register(array('ComposerAutoloaderInit15b942fc6af6974ec5ec3a1e7a92e45dP', 'loadClassLoader'), true, true);
23
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit15b942fc6af6974ec5ec3a1e7a92e45dP', 'loadClassLoader'));
25
+
26
+ $map = require __DIR__ . '/autoload_namespaces.php';
27
+ foreach ($map as $namespace => $path) {
28
+ $loader->set($namespace, $path);
29
+ }
30
+
31
+ $map = require __DIR__ . '/autoload_psr4.php';
32
+ foreach ($map as $namespace => $path) {
33
+ $loader->setPsr4($namespace, $path);
34
+ }
35
+
36
+ $classMap = require __DIR__ . '/autoload_classmap.php';
37
+ if ($classMap) {
38
+ $loader->addClassMap($classMap);
39
+ }
40
+
41
+ $loader->register(true);
42
+
43
+ return $loader;
44
+ }
45
+ }
46
+
47
+ function composerRequire15b942fc6af6974ec5ec3a1e7a92e45dP($file)
48
+ {
49
+ require $file;
50
+ }
library/composer/index.html ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>403 Forbidden</title>
5
+ </head>
6
+ <body>
7
+ <p>Directory access is forbidden.</p>
8
+ </body>
9
+ </html>
library/composer/installed.json ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "name": "ostraining/embera",
4
+ "version": "1.8.18",
5
+ "version_normalized": "1.8.18.0",
6
+ "source": {
7
+ "type": "git",
8
+ "url": "https://github.com/OSTraining/Embera.git",
9
+ "reference": "aa96304045a6338c687989e41ada96f5bf78d262"
10
+ },
11
+ "dist": {
12
+ "type": "zip",
13
+ "url": "https://api.github.com/repos/OSTraining/Embera/zipball/aa96304045a6338c687989e41ada96f5bf78d262",
14
+ "reference": "aa96304045a6338c687989e41ada96f5bf78d262",
15
+ "shasum": ""
16
+ },
17
+ "require": {
18
+ "php": ">=5.3"
19
+ },
20
+ "time": "2016-02-18 23:24:47",
21
+ "type": "library",
22
+ "installation-source": "dist",
23
+ "autoload": {
24
+ "psr-0": {
25
+ "Embera": "Lib/"
26
+ }
27
+ },
28
+ "license": [
29
+ "MIT"
30
+ ],
31
+ "authors": [
32
+ {
33
+ "name": "Michael Pratt",
34
+ "email": "pratt@hablarmierda.net",
35
+ "homepage": "http://www.michael-pratt.com",
36
+ "role": "Author/Developer"
37
+ }
38
+ ],
39
+ "description": "Oembed consumer library, that gives information about urls. It helps you replace urls to 60+ sites like youtube or vimeo, with their html embed code.",
40
+ "homepage": "https://github.com/OSTraining/Embera",
41
+ "keywords": [
42
+ "Auto embed",
43
+ "Embed",
44
+ "Embed Text",
45
+ "Instagram",
46
+ "Oembed",
47
+ "Twitter",
48
+ "Url Embed",
49
+ "Vimeo",
50
+ "Vine",
51
+ "Youtube"
52
+ ],
53
+ "support": {
54
+ "source": "https://github.com/OSTraining/Embera/tree/1.8.18"
55
+ }
56
+ }
57
+ ]
library/index.html ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>403 Forbidden</title>
5
+ </head>
6
+ <body>
7
+ <p>Directory access is forbidden.</p>
8
+ </body>
9
+ </html>
library/ostraining/embera/LICENSE ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT LICENSE
2
+ Copyright (C) 2016 by Michael Pratt <pratt@hablarmierda.net>
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
library/ostraining/embera/Lib/Embera/Adapters/Service.php ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Service.php
4
+ *
5
+ * @package Adapters
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Adapters;
14
+
15
+ /**
16
+ * This is an abstract class and all Service/Providers should extend it.
17
+ */
18
+ abstract class Service
19
+ {
20
+ /**
21
+ * @var mixed Instance of \Embera\Url
22
+ * (Marking this as mixed instead of object because scrutinizer complains about type check on preg_match)
23
+ */
24
+ protected $url;
25
+
26
+ /** @var object Instance of \Embera\Oembed */
27
+ protected $oembed = null;
28
+
29
+ /** @var array Associative array with config/parameters to be sent to the oembed provider */
30
+ protected $config = array();
31
+
32
+ /** @var array Array with all the errors */
33
+ protected $errors = array();
34
+
35
+ /** @var string The api url for the current service */
36
+ protected $apiUrl = null;
37
+
38
+ /**
39
+ * Validates that the url belongs to this service.
40
+ * Should be implemented on all children and should
41
+ * return a boolean (preg_match returns 0 or 1 that
42
+ * is why I'm also allowing 'int' as a return type).
43
+ *
44
+ * The current url is made available via $this->url
45
+ *
46
+ * @return bool|int
47
+ */
48
+ abstract protected function validateUrl();
49
+
50
+ /**
51
+ * Construct
52
+ *
53
+ * @param string $url
54
+ * @param array $config
55
+ * @param object $oembed
56
+ * @return void
57
+ *
58
+ * @throws InvalidArgumentException when the given url doesnt match the current service
59
+ */
60
+ public function __construct($url, array $config = array(), \Embera\Oembed $oembed)
61
+ {
62
+ $this->url = new \Embera\Url($url);
63
+ $this->normalizeUrl();
64
+
65
+ if (!$this->validateUrl()) {
66
+ throw new \InvalidArgumentException('Url ' . $this->url . ' seems to be invalid for the ' . get_class($this) . ' service');
67
+ }
68
+
69
+ $this->config = array_replace_recursive(array(
70
+ 'params' => array(
71
+ 'maxwidth' => 0,
72
+ 'maxheight' => 0,
73
+ )
74
+ ), $config);
75
+
76
+ $this->oembed = $oembed;
77
+ }
78
+
79
+ /**
80
+ * Gets the information from an Oembed provider
81
+ * when this fails, it tries to provide a fakeResponse.
82
+ * Returns an associative array with a (common) Oembed response.
83
+ *
84
+ * @return array
85
+ */
86
+ public function getInfo()
87
+ {
88
+ try {
89
+
90
+ if ($res = $this->oembed->getResourceInfo($this->config['oembed'], $this->apiUrl, (string) $this->url, $this->config['params'])) {
91
+ return $this->modifyResponse($res);
92
+ }
93
+
94
+ } catch (\Exception $e) {
95
+ $this->errors[] = $e->getMessage();
96
+ }
97
+
98
+ /**
99
+ * Use fakeResponses when the oembed setting is null or false
100
+ * If the oembed config is true, the user strictly wants real responses
101
+ */
102
+ if (!$this->config['oembed'] && $response = $this->fakeResponse()) {
103
+ $fakeResponse = new \Embera\FakeResponse($this->config, $response);
104
+ return $this->modifyResponse($fakeResponse->buildResponse());
105
+ }
106
+
107
+ return array();
108
+ }
109
+
110
+ /**
111
+ * Appends custom parameters for the oembed request
112
+ *
113
+ * @param array $params
114
+ * @return void
115
+ */
116
+ public function appendParams(array $params = array())
117
+ {
118
+ $this->config['params'] = array_merge($this->config['params'], $params);
119
+ }
120
+
121
+ /**
122
+ * Returns the url
123
+ *
124
+ * @return string
125
+ */
126
+ public function getUrl()
127
+ {
128
+ return (string) $this->url;
129
+ }
130
+
131
+ /**
132
+ * Returns an array with all the parameters for the oembed request
133
+ *
134
+ * @return array
135
+ */
136
+ public function getParams()
137
+ {
138
+ return $this->config['params'];
139
+ }
140
+
141
+ /**
142
+ * Returns an array with found errors
143
+ *
144
+ * @return array
145
+ */
146
+ public function getErrors()
147
+ {
148
+ return $this->errors;
149
+ }
150
+
151
+ /**
152
+ * This method fakes a Oembed response.
153
+ *
154
+ * It should be overwritten by the service
155
+ * itself if the service is capable to determine
156
+ * an html embed code based on the url or by other methods.
157
+ *
158
+ * @return array with data that the oembed response should have
159
+ * @codeCoverageIgnore
160
+ */
161
+ public function fakeResponse()
162
+ {
163
+ return array();
164
+ }
165
+
166
+ /**
167
+ * Normalizes a url.
168
+ * This method should be overwritten by the
169
+ * service itself, if needed.
170
+ *
171
+ * Use the $this->url property to do the job
172
+ *
173
+ * @return void
174
+ */
175
+ protected function normalizeUrl() {}
176
+
177
+ /**
178
+ * Gives the ability to modify the response/fake-response array
179
+ * from an oembed provider.
180
+ *
181
+ * It should be overwritten by the service when needed
182
+ *
183
+ * @param array $response
184
+ * @return array
185
+ */
186
+ protected function modifyResponse(array $response = array())
187
+ {
188
+ return $response;
189
+ }
190
+ }
191
+
192
+ ?>
library/ostraining/embera/Lib/Embera/Autoload.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Autoload.php
4
+ * The Embera Autoloader, to be used when there is no composer around.
5
+ *
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ if (function_exists('spl_autoload_register'))
14
+ {
15
+ spl_autoload_register(function ($class) {
16
+ $class = __DIR__ . '/' . str_replace('\\', DIRECTORY_SEPARATOR, str_replace('Embera\\', '', $class)) . '.php';
17
+ if (file_exists($class))
18
+ require $class;
19
+ });
20
+ }
21
+
22
+ ?>
library/ostraining/embera/Lib/Embera/Embera.php ADDED
@@ -0,0 +1,258 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Embera.php
4
+ *
5
+ * @package Embera
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera;
14
+
15
+ /**
16
+ * The Main Class of this library
17
+ */
18
+ class Embera
19
+ {
20
+ /** @var int Class constant with the current Version of this library */
21
+ const VERSION = '1.8.18';
22
+
23
+ /** @var object Instance of \Embera\Oembed */
24
+ protected $oembed;
25
+
26
+ /** @var object Instance of \Embera\Providers */
27
+ protected $providers;
28
+
29
+ /** @var array Configuration Settings */
30
+ protected $config = array();
31
+
32
+ /** @var array Fetched errors */
33
+ protected $errors = array();
34
+
35
+ /** @var string The pattern used to extract urls from a text */
36
+ protected $urlRegex = '~\bhttps?://[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))~i';
37
+
38
+ /** @var string The pattern used to extract urls from a text when the embed:// prefix option is enabled */
39
+ protected $urlEmbedRegex = '~\bembed://[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))~i';
40
+
41
+ /**
42
+ * Constructs the object and also instantiates the \Embera\Oembed Object
43
+ * and stores it into the $oembed properoty
44
+ *
45
+ * @param array $config
46
+ * @return void
47
+ */
48
+ public function __construct(array $config = array())
49
+ {
50
+ $this->config = array_replace_recursive(array(
51
+ /**
52
+ * The oembed setting represents the behaviour of the library.
53
+ * The default value (since version 1.8.0) is null, which means that the
54
+ * library will first try to get the data from the oembed endpoint and if that fails
55
+ * it tries to use a fake response.
56
+ *
57
+ * When true is given it ONLY tries to get the info from the endpoint directly... It DOES NOT fallback
58
+ * to fake responses.
59
+ *
60
+ * Finally, when false is given it ONLY uses fake responses.
61
+ */
62
+ 'oembed' => null,
63
+ 'use_embed_prefix' => false,
64
+ 'params' => array(
65
+ 'width' => 0,
66
+ 'maxwidth' => 0,
67
+ 'height' => 0,
68
+ 'maxheight' => 0,
69
+ ),
70
+ 'custom_params' => array(),
71
+ 'http' => array(),
72
+ 'fake' => array(),
73
+ ), $config);
74
+
75
+
76
+ $this->config['params']['maxwidth'] = max(
77
+ $this->config['params']['width'],
78
+ $this->config['params']['maxwidth']
79
+ );
80
+
81
+ $this->config['params']['maxheight'] = max(
82
+ $this->config['params']['height'],
83
+ $this->config['params']['maxheight']
84
+ );
85
+
86
+ unset($this->config['params']['height'], $this->config['params']['width']);
87
+
88
+ $this->oembed = new \Embera\Oembed(new \Embera\HttpRequest($this->config['http']));
89
+ $this->providers = new \Embera\Providers($this->config, $this->oembed);
90
+ }
91
+
92
+ /**
93
+ * Embeds known/available services into the
94
+ * given text.
95
+ *
96
+ * @param string $body
97
+ * @return string
98
+ */
99
+ public function autoEmbed($body = null)
100
+ {
101
+ if (!is_string($body)) {
102
+ $this->errors[] = 'For auto-embedding purposes, the input must be a string';
103
+ } elseif ($data = $this->getUrlInfo($body)) {
104
+ $table = array();
105
+ foreach ($data as $url => $service) {
106
+ if (!empty($service['html'])) {
107
+ $table[$url] = $service['html'];
108
+ }
109
+ }
110
+
111
+ return strtr($body, $table);
112
+ }
113
+
114
+ return $body;
115
+ }
116
+
117
+ /**
118
+ * Finds all the information about a url (or a collection of urls)
119
+ *
120
+ * @param string|array $body An array or string with urls
121
+ * @return array
122
+ */
123
+ public function getUrlInfo($body = null)
124
+ {
125
+ $results = array();
126
+ if ($providers = $this->getProviders($body)) {
127
+ foreach ($providers as $url => $service) {
128
+ $info = $service->getInfo();
129
+
130
+ // Check if we don't have a provider_name set, and set it based on the class name
131
+ if (!isset($info['provider_name'])) {
132
+ $reflect = new \ReflectionClass($service);
133
+ $info['provider_name'] = $reflect->getShortName();
134
+ unset($reflect);
135
+ }
136
+
137
+ // Add the provider_alias if not exists
138
+ if (!isset($info['provider_alias'])) {
139
+ $info['provider_alias'] = preg_replace('/[^a-z0-9\-]/i', '-', $info['provider_name']);
140
+ $info['provider_alias'] = strtolower(str_replace('--', '-', $info['provider_alias']));
141
+ }
142
+
143
+ // Add the wrapper_class if not exists
144
+ if (!isset($info['wrapper_class'])) {
145
+ $info['wrapper_class'] = '';
146
+ }
147
+
148
+ $results[$url] = $info;
149
+ $this->errors = array_merge($this->errors, $service->getErrors());
150
+ }
151
+ }
152
+
153
+ return array_filter($results);
154
+ }
155
+
156
+ /**
157
+ * Finds all the valid urls inside the given text,
158
+ * compares which are allowed and returns an array
159
+ * with the detected providers
160
+ *
161
+ * @param null|string|array $body An array or string with Urls
162
+ * @return array
163
+ */
164
+ protected function getProviders($body = '')
165
+ {
166
+ $regex = ($this->config['use_embed_prefix'] === true ? $this->urlEmbedRegex : $this->urlRegex);
167
+ if (is_array($body)) {
168
+
169
+ $body = array_filter($body, function ($arr) use ($regex) {
170
+ return preg_match($regex, $arr);
171
+ });
172
+
173
+ $services = $this->providers->getAll($body);
174
+ } elseif (preg_match_all($regex, $body, $matches)) {
175
+ $services = $this->providers->getAll($matches['0']);
176
+ } else {
177
+ return array();
178
+ }
179
+
180
+ return $this->clean($services);
181
+ }
182
+
183
+ /**
184
+ * Adds a new Provider into the service map
185
+ *
186
+ * @param string $host The host for the map
187
+ * @param string|object $class The class or object that should manage the provider
188
+ * @param array $params Custom parameters that should be sent in the url for this Provider
189
+ * @return void
190
+ */
191
+ public function addProvider($host, $class, array $params = array())
192
+ {
193
+ $this->providers->addProvider($host, $class, $params);
194
+ }
195
+
196
+ /**
197
+ * Strips invalid providers from the list
198
+ *
199
+ * @param array $services
200
+ * @return array
201
+ */
202
+ protected function clean(array $services = array())
203
+ {
204
+ if (empty($services)) {
205
+ return array();
206
+ }
207
+
208
+ if (!empty($this->config['allow'])) {
209
+ $allow = array_map('strtolower', (array) $this->config['allow']);
210
+ $services = array_filter($services, function ($arr) use ($allow) {
211
+ $serviceName = strtolower(basename(str_replace('\\', '/', get_class($arr))));
212
+ return (in_array($serviceName, $allow));
213
+ });
214
+ }
215
+
216
+ if (!empty($services) && !empty($this->config['deny'])) {
217
+ $deny = array_map('strtolower', (array) $this->config['deny']);
218
+ $services = array_filter($services, function ($arr) use ($deny) {
219
+ $serviceName = strtolower(basename(str_replace('\\', '/', get_class($arr))));
220
+ return (!in_array($serviceName, $deny));
221
+ });
222
+ }
223
+
224
+ return (array) $services;
225
+ }
226
+
227
+ /**
228
+ * Gets the last error found
229
+ *
230
+ * @return string
231
+ */
232
+ public function getLastError()
233
+ {
234
+ return end($this->errors);
235
+ }
236
+
237
+ /**
238
+ * Returns an array with all the errors
239
+ *
240
+ * @return array
241
+ */
242
+ public function getErrors()
243
+ {
244
+ return $this->errors;
245
+ }
246
+
247
+ /**
248
+ * Checks if there were errors
249
+ *
250
+ * @return bool
251
+ */
252
+ public function hasErrors()
253
+ {
254
+ return (!empty($this->errors));
255
+ }
256
+ }
257
+
258
+ ?>
library/ostraining/embera/Lib/Embera/FakeResponse.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FakeResponse.php
4
+ *
5
+ * @package Embera
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera;
14
+
15
+ /**
16
+ * This class manages fake oembed responses
17
+ */
18
+ class FakeResponse
19
+ {
20
+ /** @var array Configuration Array */
21
+ protected $config = array();
22
+
23
+ /** @var array Array with default oembed data */
24
+ protected $response = array(
25
+ 'version' => '1.0',
26
+ 'provider_name' => '',
27
+ 'url' => '',
28
+ 'title' => '',
29
+ 'author_name' => '',
30
+ 'author_url' => '',
31
+ 'cache_age' => 0,
32
+ 'embera_using_fake' => 1
33
+ );
34
+
35
+ /**
36
+ * Construct
37
+ *
38
+ * @param array $config
39
+ * @param array $response
40
+ * @return void
41
+ */
42
+ public function __construct(array $config = array(), array $response = array())
43
+ {
44
+ $this->config = array_replace_recursive(array(
45
+ 'fake' => array(
46
+ 'width' => 420,
47
+ 'height' => 315
48
+ ),
49
+ 'params' => array(
50
+ 'maxwidth' => 0,
51
+ 'maxheight' => 0,
52
+ )
53
+ ), $config);
54
+
55
+ $this->config['fake']['width'] = max($this->config['fake']['width'], $this->config['params']['maxwidth']);
56
+ $this->config['fake']['height'] = max($this->config['fake']['height'], $this->config['params']['maxheight']);
57
+ unset($this->config['params']);
58
+
59
+ $this->response = array_merge($this->response, $this->config['fake'], $response);
60
+ }
61
+
62
+ /**
63
+ * Builds the fake response.
64
+ * This replaces placeholders that are present in $config['fake']
65
+ * into the response array
66
+ *
67
+ * @return array
68
+ */
69
+ public function buildResponse()
70
+ {
71
+ $return = array();
72
+ foreach ($this->response as $k => $v)
73
+ {
74
+ $return[$k] = str_replace(array_map(function ($name){
75
+ return '{' . $name . '}';
76
+ }, array_keys($this->config['fake'])), array_values($this->config['fake']), $v);
77
+ }
78
+
79
+ return $return;
80
+ }
81
+ }
82
+
83
+ ?>
library/ostraining/embera/Lib/Embera/Formatter.php ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Formatter.php
4
+ *
5
+ * @package Embera
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ *
12
+ */
13
+ namespace Embera;
14
+
15
+ /**
16
+ * A formatter that acts as a Decorator for the main library.
17
+ * It outputs the oembed data as a custom string.
18
+ */
19
+ class Formatter
20
+ {
21
+ /** @var object Instance of \Embera\Embera */
22
+ protected $embera;
23
+
24
+ /** @var bool Wether or not to allow offline responses */
25
+ protected $allowOffline;
26
+
27
+ /** @var array Fetched errors */
28
+ protected $errors = array();
29
+
30
+ /** @var string The template with placeholders to be replaced with the data from an ombed response */
31
+ protected $template;
32
+
33
+ /**
34
+ * Constructor
35
+ *
36
+ * @param object $embera Instance of \Embera\Embera
37
+ * @param bool $allowOffline Wether or not to allow offline embera
38
+ * @return void
39
+ */
40
+ public function __construct(\Embera\Embera $embera, $allowOffline = false)
41
+ {
42
+ $this->embera = $embera;
43
+ $this->allowOffline = $allowOffline;
44
+ }
45
+
46
+ /**
47
+ * Sets a template with placeholders, that should be
48
+ * replaced by the data from an oembed response.
49
+ *
50
+ *
51
+ * @param string $template
52
+ * @param string|array $body An array or string with Urls
53
+ * @return string
54
+ */
55
+ public function setTemplate($template, $body = null)
56
+ {
57
+ $this->template = $template;
58
+
59
+ if (!is_null($body)) {
60
+ return $this->transform($body);
61
+ }
62
+
63
+ return '';
64
+ }
65
+
66
+ /**
67
+ * This method transforms an array or a string with urls
68
+ * into another string using a specified template.
69
+ *
70
+ * @param string|array $body An array or string with Urls
71
+ * @return string
72
+ */
73
+ public function transform($body = null)
74
+ {
75
+ $providers = array();
76
+ if ($urls = $this->embera->getUrlInfo($body)) {
77
+ foreach ($urls as $url => $data) {
78
+ if (!$this->allowOffline && (int) $data['embera_using_fake'] === 1) {
79
+ $this->errors[] = 'Using fake oembed response on ' . $url;
80
+ continue;
81
+ }
82
+
83
+ $providers[$url] = str_replace(
84
+ array_map(
85
+ function ($name) {
86
+ return '{' . $name . '}';
87
+ },
88
+ array_keys($data)
89
+ ),
90
+ array_values($data),
91
+ $this->template
92
+ );
93
+ }
94
+ }
95
+
96
+ if (is_array($body)) {
97
+ $return = implode('', $providers);
98
+ } else {
99
+ $return = str_replace(array_keys($providers), array_values($providers), $body);
100
+ }
101
+
102
+ // Remove unchanged placeholders
103
+ return preg_replace('~{([\w\d\-_]+)}~i', '', $return);
104
+ }
105
+
106
+ /**
107
+ * Gets the last error found
108
+ *
109
+ * @return string
110
+ */
111
+ public function getLastError()
112
+ {
113
+ $errors = $this->getErrors();
114
+ return end($errors);
115
+ }
116
+
117
+ /**
118
+ * Returns an array with all the errors
119
+ *
120
+ * @return array
121
+ */
122
+ public function getErrors()
123
+ {
124
+ return array_merge($this->embera->getErrors(), $this->errors);
125
+ }
126
+
127
+ /**
128
+ * Checks if there were errors
129
+ *
130
+ * @return bool
131
+ */
132
+ public function hasErrors()
133
+ {
134
+ return ($this->embera->hasErrors() || !empty($this->errors));
135
+ }
136
+
137
+ /**
138
+ * Truly decorate the embera object. With this
139
+ * method Im preserving compatability with the
140
+ * API of the decorated object.
141
+ *
142
+ * @param string $method
143
+ * @param array $args
144
+ * @return mixed
145
+ *
146
+ * @throws InvalidArgumentException when a method was not found
147
+ */
148
+ public function __call($method, $args)
149
+ {
150
+ if (is_callable(array($this->embera, $method))) {
151
+ return call_user_func_array(array($this->embera, $method), $args);
152
+ }
153
+
154
+ throw new \InvalidArgumentException('No method ' . $method . ' was found');
155
+ }
156
+ }
157
+ ?>
library/ostraining/embera/Lib/Embera/HttpRequest.php ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * HttpRequest.php
4
+ *
5
+ * @package Embera
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera;
14
+
15
+ /**
16
+ * This class is in charge of doing http requests. Its a very minimal
17
+ * wrapper for curl or file_get_contents
18
+ */
19
+ class HttpRequest
20
+ {
21
+ /** @var array Array with custom curl/fopen options */
22
+ protected $config = array();
23
+
24
+ /** @var string User Agent String */
25
+ protected $userAgent = 'Mozilla/5.0 PHP/Embera';
26
+
27
+ /**
28
+ * Constructor
29
+ *
30
+ * @param array $config
31
+ * @return void
32
+ */
33
+ public function __construct(array $config = array())
34
+ {
35
+ $this->config = array_merge(array(
36
+ 'curl' => array(),
37
+ 'fopen' => array(),
38
+ 'force_redirects' => false,
39
+ 'prefer_curl' => true,
40
+ ), $config);
41
+ }
42
+
43
+ /**
44
+ * Executes http requests
45
+ *
46
+ * @param string $url
47
+ * @param array $params Additional parameters for the respective part
48
+ * @return string
49
+ *
50
+ * @throws Exception when an error ocurred or if no way to do a request exists
51
+ */
52
+ public function fetch($url, array $params = array())
53
+ {
54
+ $params = array_merge(array(
55
+ 'curl' => array(),
56
+ 'fopen' => array(),
57
+ ), $params);
58
+
59
+ if (function_exists('curl_init') && $this->config['prefer_curl']) {
60
+ return $this->curl($url, $params['curl']);
61
+ }
62
+
63
+ return $this->fileGetContents($url, $params['fopen']);
64
+ }
65
+
66
+ /**
67
+ * Uses Curl to fetch data from an url
68
+ *
69
+ * @param string $url
70
+ * @param array $params Additional parameters for the respective part
71
+ * @return string
72
+ *
73
+ * @throws Exception when the returned status code is not 200 or no data was found
74
+ */
75
+ protected function curl($url, array $params = array())
76
+ {
77
+ // Not using array_merge here because that function reindexes numeric keys
78
+ $options = $params + $this->config['curl'] + array(
79
+ CURLOPT_USERAGENT => $this->userAgent,
80
+ CURLOPT_ENCODING => '',
81
+ CURLOPT_FOLLOWLOCATION => true,
82
+ );
83
+
84
+ $options[CURLOPT_URL] = $url;
85
+ $options[CURLOPT_HEADER] = true;
86
+ $options[CURLOPT_RETURNTRANSFER] = 1;
87
+
88
+ // CURLOPT_FOLLOWLOCATION doesnt play well with open_basedir/safe_mode
89
+ if (ini_get('safe_mode') || ini_get('open_basedir')) {
90
+ $options[CURLOPT_FOLLOWLOCATION] = false;
91
+ $options[CURLOPT_TIMEOUT] = 15;
92
+ $this->config['force_redirects'] = true;
93
+ }
94
+
95
+ $handler = curl_init();
96
+ curl_setopt_array($handler, $options);
97
+ $response = curl_exec($handler);
98
+
99
+ $status = curl_getinfo($handler, CURLINFO_HTTP_CODE);
100
+ $headerSize = curl_getinfo($handler, CURLINFO_HEADER_SIZE);
101
+
102
+ $header = substr($response, 0, $headerSize);
103
+ $body = substr($response, $headerSize);
104
+ curl_close($handler);
105
+
106
+ if ($this->config['force_redirects'] && in_array($status, array('301', '302'))) {
107
+
108
+ if (preg_match('~(?:location|uri): ?([^\n]+)~i', $header, $matches)) {
109
+
110
+ $url = trim($matches['1']);
111
+
112
+ // Relative redirections
113
+ if (substr($url, 0, 1) == '/') {
114
+ $parsed = parse_url($options[CURLOPT_URL]);
115
+ $url = $parsed['scheme'] . '://' . rtrim($parsed['host'], '/') . $url;
116
+ }
117
+
118
+ return $this->curl($url, $options);
119
+ }
120
+ }
121
+
122
+ if (empty($body) || !in_array($status, array('200'))) {
123
+ throw new \Exception($status . ': Invalid response for ' . $url);
124
+ }
125
+
126
+ return $body;
127
+ }
128
+
129
+ /**
130
+ * Uses file_get_contents to fetch data from an url
131
+ *
132
+ * @param string $url
133
+ * @param array $params Additional parameters for the respective part
134
+ * @return string
135
+ *
136
+ * @throws Exception when allow_url_fopen is disabled or when no data was returned
137
+ */
138
+ protected function fileGetContents($url, array $params = array())
139
+ {
140
+ if (!ini_get('allow_url_fopen')) {
141
+ throw new \Exception('Could not execute lookup, allow_url_fopen is disabled');
142
+ }
143
+
144
+ if (!filter_var($url, FILTER_VALIDATE_URL)) {
145
+ throw new \Exception('Invalid url ' . $url);
146
+ }
147
+
148
+ $defaultOptions = array(
149
+ 'method' => 'GET',
150
+ 'user_agent' => $this->userAgent,
151
+ 'follow_location' => 1,
152
+ 'max_redirects' => 20,
153
+ 'timeout' => 40
154
+ );
155
+
156
+ $context = array('http' => array_merge($defaultOptions, $this->config['fopen'], $params));
157
+ if ($data = file_get_contents($url, false, stream_context_create($context))) {
158
+ return $data;
159
+ }
160
+
161
+ throw new \Exception('Invalid Server Response from ' . $url);
162
+ }
163
+ }
164
+
165
+ ?>
library/ostraining/embera/Lib/Embera/Oembed.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Oembed.php
4
+ *
5
+ * @package Embera
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera;
14
+
15
+ /**
16
+ * This class manages requests and responses
17
+ * from an Oembed Endpoint.
18
+ *
19
+ * TODO: Support xml responses
20
+ */
21
+ class Oembed
22
+ {
23
+ /** @var object Instance of \Embera\HttpRequest */
24
+ protected $http;
25
+
26
+ /**
27
+ * Construct
28
+ *
29
+ * @param object $http Instance of \Embera\HttpRequest
30
+ * @return void
31
+ */
32
+ public function __construct(\Embera\HttpRequest $http)
33
+ {
34
+ $this->http = $http;
35
+ }
36
+
37
+ /**
38
+ * Gets information about a resource
39
+ *
40
+ * @param bool $behaviour Wether or not to use fake responses only
41
+ * @param string $apiUrl The Url to the Oembed provider
42
+ * @param string $url The original url, we want information from
43
+ * @param array $params An associative array with parameters to be sent to the
44
+ * Oembed provider.
45
+ * @return array
46
+ */
47
+ public function getResourceInfo($behaviour, $apiUrl, $url, array $params = array())
48
+ {
49
+ if ($behaviour === false) {
50
+ return array();
51
+ }
52
+
53
+ return $this->lookup($this->constructUrl($apiUrl, array_merge($params, array('url' => $url))));
54
+ }
55
+
56
+ /**
57
+ * Executes a http request to the given url and
58
+ * returns an associative array with the fetched data.
59
+ *
60
+ * @param string $url
61
+ * @return array
62
+ *
63
+ * @throws Exception From the Http object only if there is no way
64
+ * to perform the request or if the response from
65
+ * the server is empty/invalid.
66
+ */
67
+ protected function lookup($url)
68
+ {
69
+ $response = $this->http->fetch($url);
70
+ $json = json_decode($response, true);
71
+
72
+ if ($json) {
73
+ return array_merge(array('embera_using_fake' => 0), $json);
74
+ }
75
+
76
+ return array();
77
+ }
78
+
79
+ /**
80
+ * Builds a valid Oembed query string based on the given parameters,
81
+ * Since this method uses the http_build_query function, there is no
82
+ * need to pass urlencoded parameters, http_build_query already does
83
+ * this for us.
84
+ *
85
+ * @param string $apiUrl The Url to the Oembed Api
86
+ * @param array $params Parameters for the query string
87
+ * @return string
88
+ */
89
+ protected function constructUrl($apiUrl, array $params = array())
90
+ {
91
+ return $apiUrl . ((strpos($apiUrl, '?') === false) ? '?' : '&') . http_build_query(array_filter($params));
92
+ }
93
+ }
94
+
95
+ ?>
library/ostraining/embera/Lib/Embera/Providers.php ADDED
@@ -0,0 +1,284 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Providers.php
4
+ *
5
+ * @package Embera
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera;
14
+
15
+ /**
16
+ * Finds and loads Services/Providers based on the
17
+ * host of a url.
18
+ */
19
+ class Providers
20
+ {
21
+ /** @var array Configuration Settings */
22
+ protected $config = array();
23
+
24
+ /** @var object instance of \Embera\Oembed*/
25
+ protected $oembed;
26
+
27
+ /** @var array Custom parameters for each host/provider */
28
+ protected $customParams = array();
29
+
30
+ /** @var array Hosts with wildcards, calculated at runtime */
31
+ protected $wildCardHosts = array();
32
+
33
+ /** @var array Massive array with the mapping of host -> provider class relation. */
34
+ protected $services = array(
35
+ '23hq.com' => '\Embera\Providers\Hq23',
36
+ 'live.amcharts.com' => '\Embera\Providers\AmCharts',
37
+ 'animatron.com' => '\Embera\Providers\Animatron',
38
+ 'animoto.com' => '\Embera\Providers\Animoto',
39
+ 'on.aol.com' => '\Embera\Providers\AolOn',
40
+ '5min.com' => '\Embera\Providers\AolOn',
41
+ 'alpha.app.net' => '\Embera\Providers\AppNet',
42
+ 'audiosnaps.com' => '\Embera\Providers\AudioSnaps',
43
+ 'photos.app.net' => '\Embera\Providers\AppNet',
44
+ 'bambuser.com' => '\Embera\Providers\Bambuser',
45
+ '*.blip.tv' => '\Embera\Providers\BlipTV',
46
+ 'cacoo.com' => '\Embera\Providers\Cacoo',
47
+ 'public.chartblocks.com' => '\Embera\Providers\Chartblocks',
48
+ 'chirb.it' => '\Embera\Providers\Chirbit',
49
+ 'clyp.it' => '\Embera\Providers\Clyp',
50
+ 'codepoints.net' => '\Embera\Providers\Codepoints',
51
+ 'circuitlab.com' => '\Embera\Providers\CircuitLab',
52
+ 'collegehumor.com' => '\Embera\Providers\CollegeHumor',
53
+ 'coub.com' => '\Embera\Providers\Coub',
54
+ 'crowdranking.com' => '\Embera\Providers\CrowdRanking',
55
+ 'c9ng.com' => '\Embera\Providers\CrowdRanking',
56
+ 'dailymile.com' => '\Embera\Providers\DailyMile',
57
+ '*.dailymotion.com' => '\Embera\Providers\DailyMotion',
58
+ 'dai.ly' => '\Embera\Providers\DailyMotion',
59
+ '*.deviantart.com' => '\Embera\Providers\Deviantart',
60
+ 'fav.me' => '\Embera\Providers\Deviantart',
61
+ 'sta.sh' => '\Embera\Providers\Deviantart',
62
+ 'dipity.com' => '\Embera\Providers\Dipity',
63
+ 'dotsub.com' => '\Embera\Providers\DotSub',
64
+ 'edocr.com' => '\Embera\Providers\Edocr',
65
+ 'egliseinfo.catholique.fr' => '\Embera\Providers\EgliseInfo',
66
+ 'facebook.com' => '\Embera\Providers\Facebook',
67
+ 'flickr.com' => '\Embera\Providers\Flickr',
68
+ 'flic.kr' => '\Embera\Providers\Flickr',
69
+ 'funnyordie.com' => '\Embera\Providers\FunnyOrDie',
70
+ 'geograph.org.uk' => '\Embera\Providers\GeographUk',
71
+ 'geograph.co.uk' => '\Embera\Providers\GeographUk',
72
+ 'geograph.ie' => '\Embera\Providers\GeographUk',
73
+ 'geo.hlipp.de' => '\Embera\Providers\GeographDe',
74
+ 'geo-en.hlipp.de' => '\Embera\Providers\GeographDe',
75
+ 'germany.geograph.org' => '\Embera\Providers\GeographDe',
76
+ 'channel-islands.geographs.org' => '\Embera\Providers\GeographCI',
77
+ 'channel-islands.geograph.org' => '\Embera\Providers\GeographCI',
78
+ 'channel-islands.geographs.org.gg' => '\Embera\Providers\GeographCI',
79
+ 'channel-islands.geographs.org.je' => '\Embera\Providers\GeographCI',
80
+ 'gettyimages.com' => '\Embera\Providers\GettyImages',
81
+ 'gty.im' => '\Embera\Providers\GettyImages',
82
+ 'gfycat.com' => '\Embera\Providers\Gfycat',
83
+ 'gist.github.com' => '\Embera\Providers\GithubGist',
84
+ 'gmep.org' => '\Embera\Providers\Gmep',
85
+ 'huffduffer.com' => '\Embera\Providers\Huffduffer',
86
+ 'hulu.com' => '\Embera\Providers\Hulu',
87
+ 'ifixit.com' => '\Embera\Providers\IFixIt',
88
+ 'ifttt.com' => '\Embera\Providers\IFTTT',
89
+ 'infogr.am' => '\Embera\Providers\Infogram',
90
+ 'instagram.com' => '\Embera\Providers\Instagram',
91
+ 'instagr.am' => '\Embera\Providers\Instagram',
92
+ 'issuu.com' => '\Embera\Providers\Issuu',
93
+ 'kickstarter.com' => '\Embera\Providers\Kickstarter',
94
+ 'learningapps.org' => '\Embera\Providers\LearningApps',
95
+ 'meetup.com' => '\Embera\Providers\Meetup',
96
+ 'meetu.ps' => '\Embera\Providers\Meetup',
97
+ 'mixcloud.com' => '\Embera\Providers\MixCloud',
98
+ 'mobypicture.com' => '\Embera\Providers\MobyPicture',
99
+ 'moby.to' => '\Embera\Providers\MobyPicture',
100
+ 'nfb.ca' => '\Embera\Providers\NFB',
101
+ 'mix.office.com' => '\Embera\Providers\Officemix',
102
+ 'official.fm' => '\Embera\Providers\OfficialFM',
103
+ 'oumy.com' => '\Embera\Providers\Oumy',
104
+ 'pastery.net' => '\Embera\Providers\Pastery',
105
+ '*.polldaddy.com' => '\Embera\Providers\PollDaddy',
106
+ 'polleverywhere.com' => '\Embera\Providers\PollEveryWhere',
107
+ 'portfolium.com' => '\Embera\Providers\Portfolium',
108
+ 'rapidengage.com' => '\Embera\Providers\Rapidengage',
109
+ 'rdio.com' => '\Embera\Providers\Rdio',
110
+ 'rd.io' => '\Embera\Providers\Rdio',
111
+ 'releasewire.com' => '\Embera\Providers\ReleaseWire',
112
+ 'rwire.com' => '\Embera\Providers\ReleaseWire',
113
+ 'repubhub.icopyright.net' => '\Embera\Providers\RepubHub',
114
+ 'reverbnation.com' => '\Embera\Providers\Reverbnation',
115
+ 'revision3.com' => '\Embera\Providers\Revision3',
116
+ 'roomshare.jp' => '\Embera\Providers\Roomshare',
117
+ 'rutube.ru' => '\Embera\Providers\Rutube',
118
+ 'videos.sapo.pt' => '\Embera\Providers\Sapo',
119
+ 'screenr.com' => '\Embera\Providers\Screenr',
120
+ 'scribd.com' => '\Embera\Providers\Scribd',
121
+ 'shortnote.jp' => '\Embera\Providers\ShortNote',
122
+ '*.shoudio.com' => '\Embera\Providers\Shoudio',
123
+ '*.shoud.io' => '\Embera\Providers\Shoudio',
124
+ 'showtheway.io' => '\Embera\Providers\Showtheway',
125
+ '*.silk.co' => '\Embera\Providers\Silk',
126
+ 'sketchfab.com' => '\Embera\Providers\Sketchfab',
127
+ '*.slideshare.net' => '\Embera\Providers\SlideShare',
128
+ '*.soundcloud.com' => '\Embera\Providers\SoundCloud',
129
+ 'speakerdeck.com' => '\Embera\Providers\Speakerdeck',
130
+ '*.spotify.com' => '\Embera\Providers\Spotify',
131
+ 'spoti.fi' => '\Embera\Providers\Spotify',
132
+ 'sway.com' => '\Embera\Providers\Sway',
133
+ 'ted.com' => '\Embera\Providers\Ted',
134
+ 'theysaidso.com' => '\Embera\Providers\TheySaidSo',
135
+ 'twitter.com' => '\Embera\Providers\Twitter',
136
+ 'ustream.tv' => '\Embera\Providers\Ustream',
137
+ 'ustream.com' => '\Embera\Providers\Ustream',
138
+ 'verse.media' => '\Embera\Providers\Verse',
139
+ 'viddler.com' => '\Embera\Providers\Viddler',
140
+ 'videofork.com' => '\Embera\Providers\VideoFork',
141
+ 'videojug.com' => '\Embera\Providers\VideoJug',
142
+ 'vimeo.com' => '\Embera\Providers\Vimeo',
143
+ 'wordpress.tv' => '\Embera\Providers\WordpressTV',
144
+ 'blog.wordpress.tv' => '\Embera\Providers\WordpressTV',
145
+ 'yfrog.com' => '\Embera\Providers\YFrog',
146
+ 'yfrog.us' => '\Embera\Providers\YFrog',
147
+ 'twitter.yfrog.com' => '\Embera\Providers\YFrog',
148
+ 'video.yandex.ru' => '\Embera\Providers\Yandex',
149
+ 'm.youtube.com' => '\Embera\Providers\Youtube',
150
+ 'youtube.com' => '\Embera\Providers\Youtube',
151
+ 'youtu.be' => '\Embera\Providers\Youtube',
152
+ 'vine.co' => '\Embera\Providers\Vine',
153
+ );
154
+
155
+ /**
156
+ * Construct
157
+ *
158
+ * @param array $config Associative array with configuration options
159
+ * @param object $oembed Instance of \Embera\Oembed
160
+ * @return void
161
+ */
162
+ public function __construct(array $config = array(), \Embera\Oembed $oembed)
163
+ {
164
+ $this->config = array_replace_recursive(array(
165
+ 'params' => array(),
166
+ 'custom_params' => array(),
167
+ 'fake' => array()
168
+ ), $config);
169
+
170
+ $this->oembed = $oembed;
171
+ }
172
+
173
+ /**
174
+ * Finds services for the given $urls.
175
+ *
176
+ * @param array $urls An array with all the available urls
177
+ * @return array An Array with loaded services
178
+ */
179
+ protected function findServices(array $urls = array())
180
+ {
181
+ $return = array();
182
+ $this->extractCustomParams($this->config['custom_params']);
183
+ foreach (array_unique($urls) as $u) {
184
+
185
+ try {
186
+ $host = $this->getHost($u);
187
+ if (isset($this->services[$host])) {
188
+ $provider = new \ReflectionClass($this->services[$host]);
189
+ $return[$u] = $provider->newInstance($u, $this->config, $this->oembed);
190
+
191
+ if (isset($this->customParams[$host])) {
192
+ $return[$u]->appendParams($this->customParams[$host]);
193
+ }
194
+ }
195
+ } catch (\Exception $e) {
196
+ //echo $e->getMessage() . PHP_EOL;
197
+ }
198
+ }
199
+
200
+ return $return;
201
+ }
202
+
203
+ /**
204
+ * Adds a new Provider into the service map
205
+ *
206
+ * @param string $host The host for the map
207
+ * @param string|object $class The class or object that should manage the provider
208
+ * @param array $params Custom parameters that should be sent in the url for this Provider
209
+ * @return void
210
+ */
211
+ public function addProvider($host, $class, array $params = array())
212
+ {
213
+ $host = preg_replace('~^(?:www)\.~i', '', strtolower($host));
214
+ $this->services[$host] = $class;
215
+ $this->customParams[$host] = $params;
216
+ }
217
+
218
+ /**
219
+ * Gets a normalized host for the given $url
220
+ *
221
+ * @param string $url
222
+ * @return string
223
+ *
224
+ * @throws InvalidArgumentException when the url seems to be invalid
225
+ */
226
+ protected function getHost($url)
227
+ {
228
+ $data = parse_url($url);
229
+ if (empty($data['host'])) {
230
+ throw new \InvalidArgumentException('The Url: ' . $url . ' seems to be invalid');
231
+ }
232
+
233
+ $host = preg_replace('~^(?:www|player)\.~i', '', strtolower($data['host']));
234
+ if (isset($this->services[$host])) {
235
+ return $host;
236
+ } else if (isset($this->services['*.' . $host])) {
237
+ return '*.' . $host;
238
+ } else if (!empty($this->wildCardHosts)) {
239
+ $trans = array('\*' => '(?:.*)');
240
+ foreach ($this->wildCardHosts as $value) {
241
+ $regex = strtr(preg_quote($value, '~'), $trans);
242
+ if (preg_match('~' . $regex . '~i', $host)) {
243
+ return $value;
244
+ }
245
+ }
246
+ }
247
+
248
+ return $host;
249
+ }
250
+
251
+ /**
252
+ * Extracts custom parameters for a Provider
253
+ *
254
+ * @param array $params
255
+ * @return array
256
+ */
257
+ protected function extractCustomParams(array $params = array())
258
+ {
259
+ foreach ($params as $name => $values) {
260
+ foreach ($this->services as $host => $service) {
261
+ if (preg_match('~' . preg_quote($name, '~') . '~i', $service)) {
262
+ $this->customParams[$host] = (array) $values;
263
+ }
264
+ }
265
+ }
266
+ }
267
+
268
+ /**
269
+ * Returns an array with all valid services found.
270
+ *
271
+ * @param array|string $urls An array with urls or a url string
272
+ * @return array
273
+ */
274
+ public function getAll($urls)
275
+ {
276
+ $this->wildCardHosts = array_filter(array_keys($this->services), function($key) {
277
+ return (strpos($key, '*') !== false);
278
+ });
279
+
280
+ return $this->findServices((array) $urls);
281
+ }
282
+ }
283
+
284
+ ?>
library/ostraining/embera/Lib/Embera/Providers/AmCharts.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * AmCharts.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The AmCharts Live Charts Provider
17
+ * @link http://live.amcharts.com
18
+ */
19
+ class AmCharts extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://live.amcharts.com/oembed/?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->invalidPattern('amcharts\.com/new');
28
+ return (preg_match('~live\.amcharts\.com/([^ /]+)/?$~i', $this->url));
29
+ }
30
+
31
+ /** inline {@inheritdoc} */
32
+ protected function normalizeUrl()
33
+ {
34
+ $this->url->stripQueryString();
35
+ $this->url->convertToHttp();
36
+
37
+ if (preg_match('~amcharts\.com/([^ /]+)(/edit/?)?~i', $this->url, $matches)) {
38
+ $this->url = new \Embera\Url('http://live.amcharts.com/' . $matches['1'] . '/');
39
+ }
40
+ }
41
+
42
+ /** inline {@inheritdoc} */
43
+ public function fakeResponse()
44
+ {
45
+ preg_match('~amcharts\.com/([^ /]+)~i', $this->url, $matches);
46
+ $url = 'http://live.amcharts.com/' . $matches['1'];
47
+
48
+ return array(
49
+ 'type' => 'rich',
50
+ 'provider_name' => 'amCharts',
51
+ 'provider_url' => 'http://www.amcharts.com/',
52
+ 'thumbnail_url' => 'http://generated.amcharts.com/' . substr($matches['1'], 0, 2) . '/' . $matches['1'] . '-full.png',
53
+ 'thumbnail_width' => 404,
54
+ 'thumbnail_height' => 300,
55
+ 'canonical' => $url . '/',
56
+ 'html' => '<iframe width="{width}" height="{height}" src="' . $url . '/embed/" frameborder="0"></iframe>',
57
+ );
58
+ }
59
+ }
60
+
61
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Animatron.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Animatron.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The Animatron Provider
17
+ * @link https://www.animatron.com/
18
+ */
19
+ class Animatron extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'https://www.animatron.com/oembed/json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+ $this->url->stripLastSlash();
29
+ $this->url->stripWWW();
30
+ $this->url->convertToHttps();
31
+
32
+ return (preg_match('~animatron\.com/project/(?:[^/]+)$~i', $this->url));
33
+ }
34
+ }
35
+
36
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Animoto.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Animoto.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The animoto.com Provider
17
+ * @link http://animoto.com
18
+ * @link http://help.animoto.com/entries/109992-oEmbed-API
19
+ *
20
+ * @todo It could be posible to give offline support for this service
21
+ * but the query string inside the iframe src requires a parameter named 'r'
22
+ * which must be valid, and there is no way to determine it from the url.
23
+ */
24
+ class Animoto extends \Embera\Adapters\Service
25
+ {
26
+ /** inline {@inheritdoc} */
27
+ protected $apiUrl = 'http://animoto.com/oembeds/create?format=json';
28
+
29
+ /** inline {@inheritdoc} */
30
+ protected function validateUrl()
31
+ {
32
+ return (preg_match('~/play/(?:[\w\d]+)/?$~i', $this->url));
33
+ }
34
+ }
35
+
36
+ ?>
library/ostraining/embera/Lib/Embera/Providers/AolOn.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * AolOn.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The on.aol.com Provider
17
+ * @link http://on.aol.com
18
+ */
19
+ class AolOn extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://on.aol.com/api';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->convertToHttp();
28
+ $this->url->stripQueryString();
29
+ $this->url->stripLastSlash();
30
+
31
+ return (preg_match('~aol\.com/video/(?:[^/]+)-(?:[\d]+)$~i', $this->url));
32
+ }
33
+
34
+ /** inline {@inheritdoc} */
35
+ protected function normalizeUrl()
36
+ {
37
+ if (preg_match('~5min\.com/video/(([^/]+)-([\d]+))~i', $this->url, $matches))
38
+ $this->url = new \Embera\Url('http://on.aol.com/video/' . $matches['1']);
39
+ }
40
+
41
+ /** inline {@inheritdoc} */
42
+ protected function modifyResponse(array $response = array())
43
+ {
44
+ if (!empty($response['html']))
45
+ {
46
+ $replace = array('<![CDATA[' => '', ']]>' => '', '\'' => '"');
47
+ $response['html'] = str_ireplace(array_keys($replace), array_values($replace), $response['html']);
48
+ }
49
+
50
+ return $response;
51
+ }
52
+
53
+ /** inline {@inheritdoc} */
54
+ public function fakeResponse()
55
+ {
56
+ preg_match('~([\d]+)$~i', $this->url, $matches);
57
+
58
+ return array(
59
+ 'type' => 'video',
60
+ 'provider_name' => 'on.aol.com',
61
+ 'provider_url' => 'http://on.aol.com',
62
+ 'video_id' => $matches['1'],
63
+ 'html' => '<iframe width="{width}" height="{height}" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen src="http://embed.5min.com/PlayerSeed/?playList=' . $matches['1'] . '&autoStart=true"></iframe>',
64
+ );
65
+ }
66
+ }
67
+
68
+ ?>
library/ostraining/embera/Lib/Embera/Providers/AppNet.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * AppNet.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The alpha|photos.app.net Provider
17
+ * @link http://alpha.app.net
18
+ * @link http://photos.app.net
19
+ * @link http://developers.app.net/docs/other/oembed/
20
+ */
21
+ class AppNet extends \Embera\Adapters\Service
22
+ {
23
+ /** inline {@inheritdoc} */
24
+ protected $apiUrl = 'https://alpha-api.app.net/oembed';
25
+
26
+ /** inline {@inheritdoc} */
27
+ protected function validateUrl()
28
+ {
29
+ $this->url->stripLastSlash();
30
+
31
+ return (preg_match('~alpha\.app\.net/(?:[^/]+)/(?:post)/(?:[0-9]+)~i', $this->url) ||
32
+ preg_match('~photos\.app\.net/(?:[0-9]+)/([?:0-9]+)~i', $this->url));
33
+ }
34
+ }
35
+
36
+ ?>
library/ostraining/embera/Lib/Embera/Providers/AudioSnaps.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * AudioSnaps.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The audiosnaps.com Provider
17
+ * @link http://audiosnaps.com
18
+ */
19
+ class AudioSnaps extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://audiosnaps.com/service/oembed?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ return (preg_match('~audiosnaps\.com/k/(?:[^/]+)/$~i', $this->url));
28
+ }
29
+
30
+ /** inline {@inheritdoc} */
31
+ protected function normalizeUrl()
32
+ {
33
+ if (preg_match('~audiosnaps\.com/k/([^/]+)$~i', $this->url, $matches)) {
34
+ $this->url = new \Embera\Url('http://audiosnaps.com/k/' . $matches[1] . '/');
35
+ }
36
+ }
37
+
38
+ /** inline {@inheritdoc} */
39
+ public function fakeResponse()
40
+ {
41
+ preg_match('~audiosnaps\.com/k/([^/]+)/?$~i', $this->url, $matches);
42
+ $id = $matches['1'];
43
+
44
+ return array(
45
+ 'type' => 'rich',
46
+ 'provider_name' => 'AudioSnaps',
47
+ 'provider_url' => 'http://audiosnaps.com',
48
+ 'html' => '<iframe width="{width}" height="{height}" src="http://audiosnaps.com/i/embed/' . $id . '/?framed=1" frameborder="0" ></iframe>',
49
+ );
50
+ }
51
+ }
52
+
53
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Bambuser.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Bambuser.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The bambuser.com Provider
17
+ * @link http://bambuser.com
18
+ * @link http://bambuser.com/api/embed_oembed
19
+ */
20
+ class Bambuser extends \Embera\Adapters\Service
21
+ {
22
+ /** inline {@inheritdoc} */
23
+ protected $apiUrl = 'http://api.bambuser.com/oembed.json';
24
+
25
+ /** inline {@inheritdoc} */
26
+ protected function validateUrl()
27
+ {
28
+ $this->url->stripLastSlash();
29
+ $this->url->stripWWW();
30
+
31
+ return (
32
+ preg_match('~bambuser\.com/v/(?:[0-9]+)$~i', $this->url) || preg_match('~bambuser\.com/channel/(?:[^/]+)$~i', $this->url)
33
+ );
34
+ }
35
+
36
+ /** inline {@inheritdoc} */
37
+ public function normalizeUrl()
38
+ {
39
+ if (preg_match('~bambuser\.com/channel/(?:[^/]+)/broadcast/([0-9]+)~i', $this->url, $matches)) {
40
+ $this->url = new \Embera\Url('http://bambuser.com/v/' . $matches['1']);
41
+ }
42
+ }
43
+
44
+ /** inline {@inheritdoc} */
45
+ public function fakeResponse()
46
+ {
47
+ $defaults = array(
48
+ 'type' => 'video',
49
+ 'provider_name' => 'Bambuser.com',
50
+ 'provider_url' => 'http://bambuser.com',
51
+ );
52
+
53
+ $html = '<object id="bplayer" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="{width}" height="{height}">';
54
+ $html .= '<embed allowfullscreen="true" allowscriptaccess="always" wmode="transparent" type="application/x-shockwave-flash" name="bplayer" src="https://static.bambuser.com/r/player.swf?{query}&amp;context=oembed" width="{width}" height="{height}" />';
55
+ $html .= '<param name="movie" value="https://static.bambuser.com/r/player.swf?context=oembed&amp;{query}" />';
56
+ $html .= '<param name="allowfullscreen" value="true" />';
57
+ $html .= '<param name="allowscriptaccess" value="always" />';
58
+ $html .= '<param name="wmode" value="transparent" />';
59
+ $html .= '</object>';
60
+
61
+ if (preg_match('~/v/([0-9]+)$~i', $this->url, $matches)) {
62
+ return array_merge(
63
+ $defaults,
64
+ array('html' => str_replace('{query}', 'vid=' . $matches['1'], $html))
65
+ );
66
+ }
67
+ else if (preg_match('~/channel/([^/]+)~i', $this->url, $matches))
68
+ {
69
+ return array_merge(
70
+ $defaults,
71
+ array('html' => str_replace('{query}', 'username=' . urlencode($matches['1']), $html))
72
+ );
73
+ }
74
+
75
+ return array();
76
+ }
77
+
78
+ }
79
+
80
+ ?>
library/ostraining/embera/Lib/Embera/Providers/BlipTV.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BlipTV.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The blip.tv Provider
17
+ * @link http://blip.tv
18
+ */
19
+ class BlipTV extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://blip.tv/oembed/';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ return (preg_match('~blip\.tv/(?:[^/]+)/(?:[^/]+)-([0-9]+)/?$~i', $this->url));
28
+ }
29
+ }
30
+
31
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Cacoo.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Cacoo.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The cacoo.com Provider
17
+ * @link http://cacoo.com
18
+ * @link https://cacoo.com/lang/en/api_oembed
19
+ */
20
+ class Cacoo extends \Embera\Adapters\Service
21
+ {
22
+ /** inline {@inheritdoc} */
23
+ protected $apiUrl = 'http://cacoo.com/oembed.json';
24
+
25
+ /** inline {@inheritdoc} */
26
+ protected function validateUrl()
27
+ {
28
+ $this->url->stripWWW();
29
+ $this->url->stripLastSlash();
30
+ $this->url->convertToHttps();
31
+
32
+ return (preg_match('~cacoo\.com/diagrams/(?:[\w\d]+)$~i', $this->url));
33
+ }
34
+
35
+ /** inline {@inheritdoc} */
36
+ protected function normalizeUrl()
37
+ {
38
+ if (preg_match('~/diagrams/([\w\d]+)/~i', $this->url, $matches)) {
39
+ $this->url = new \Embera\Url('https://cacoo.com/diagrams/' . $matches['1']);
40
+ }
41
+ }
42
+
43
+ /** inline {@inheritdoc} */
44
+ public function fakeResponse()
45
+ {
46
+ preg_match('~/diagrams/([\w\d]+)/?$~i', $this->url, $matches);
47
+
48
+ return array(
49
+ 'type' => 'rich',
50
+ 'provider_name' => 'Cacoo',
51
+ 'provider_url' => 'http://cacoo.com',
52
+ 'html' => '<iframe src="https://cacoo.com/diagrams/' . $matches['1'] . '/view?w={width}&h={height}" width="{width}" height="{height}" frameborder="0"></iframe>',
53
+ 'thumbnail_url' => 'https://cacoo.com/diagrams/' . $matches['1'] . '-w{width}-h{height}.png'
54
+ );
55
+ }
56
+ }
57
+
58
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Chartblocks.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Chartblocks.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The chartblocks.com Provider
17
+ */
18
+ class Chartblocks extends \Embera\Adapters\Service
19
+ {
20
+ /** inline {@inheritdoc} */
21
+ protected $apiUrl = 'http://embed.chartblocks.com/1.0/oembed?format=json';
22
+
23
+ /** inline {@inheritdoc} */
24
+ protected function validateUrl()
25
+ {
26
+ $this->url->convertToHttp();
27
+ return (preg_match('~chartblocks\.com/c/([^ ]+)/?$~i', $this->url));
28
+ }
29
+
30
+ /** inline {@inheritdoc} */
31
+ public function fakeResponse()
32
+ {
33
+ preg_match('~chartblocks\.com/c/([0-9A-z]+)~i', $this->url, $m);
34
+
35
+ return array(
36
+ 'type' => 'rich',
37
+ 'provider_name' => 'ChartBlocks',
38
+ 'provider_url' => 'http://www.chartblocks.com',
39
+ 'title' => 'Unknown title',
40
+ 'thumbnail_url' => 'https://d3ugvbs94d921r.cloudfront.net/' . $m['1'] . '.png',
41
+ 'html' => '<iframe class="chartblocks-embed" src="//embed.chartblocks.com/1.0/?c=' . $m['1'] . '" height="{height}" width="{width}" frameborder="0"></iframe>',
42
+ );
43
+ }
44
+ }
45
+
46
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Chirbit.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Chirbit.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The chirb.it Provider
17
+ * @link http://chirb.it
18
+ */
19
+ class Chirbit extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://chirb.it/oembed.json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ return (preg_match('~chirb\.it/(?:[\w\d]+)/?$~i', $this->url));
28
+ }
29
+
30
+ /** inline {@inheritdoc} */
31
+ protected function normalizeUrl()
32
+ {
33
+ if (preg_match('~chirb\.it/wp/([\w\d]+)/?~i', $this->url, $matches))
34
+ $this->url = new \Embera\Url('http://chirb.it/' . $matches['1']);
35
+ }
36
+
37
+ /** inline {@inheritdoc} */
38
+ public function fakeResponse()
39
+ {
40
+ preg_match('~chirb\.it/([\w\d]+)/?~i', $this->url, $matches);
41
+
42
+ return array(
43
+ 'type' => 'rich',
44
+ 'provider_name' => 'chirbit',
45
+ 'provider_url' => 'http://www.chirbit.com/',
46
+ 'thumbnail_url' => 'http://chirb.it/chirbit_oembedpic.jpg',
47
+ 'html' => '<iframe height="{height}" frameborder="0" width="{width}" scrolling="NO" src="http://chirb.it/wp/' . $matches['1'] . '">This browser does not show iframe content. Listen to this chirbit here <a href="http://chirb.it/' . $matches['1'] . '">http://chirb.it/' . $matches['1'] . '</a></iframe>',
48
+ );
49
+ }
50
+
51
+ }
52
+
53
+ ?>
library/ostraining/embera/Lib/Embera/Providers/CircuitLab.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * CircuitLab.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The circuitlab.com Provider
17
+ * @link https://www.circuitlab.com
18
+ */
19
+ class CircuitLab extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'https://www.circuitlab.com/circuit/oembed/';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->addWWW();
28
+ $this->url->convertToHttps();
29
+ $this->url->stripQueryString();
30
+
31
+ return (preg_match('~circuitlab\.com/circuit/(?:[\w\d]+)/(?:[^/]*)/?$~i', $this->url));
32
+ }
33
+
34
+ /** inline {@inheritdoc} */
35
+ protected function normalizeUrl()
36
+ {
37
+ if (preg_match('~circuitlab\.com/c([\w\d]+)/?$~i', $this->url, $matches)) {
38
+ $this->url = new \Embera\Url('https://www.circuitlab.com/circuit/' . $matches['1'] . '/');
39
+ }
40
+ }
41
+
42
+ /** inline {@inheritdoc} */
43
+ public function fakeResponse()
44
+ {
45
+ preg_match('~circuitlab\.com/circuit/([\w\d]+)/~i', $this->url, $matches);
46
+
47
+ return array(
48
+ 'type' => 'rich',
49
+ 'provider_name' => 'CircuitLab',
50
+ 'provider_url' => 'https://www.circuitlab.com/',
51
+ 'html' => '<iframe src="https://www.circuitlab.com/circuit/' . $matches['1'] . '/embed_target/?width={width}" scrolling="no" frameborder="0" width="{width}" height="{height}"></iframe>',
52
+ );
53
+ }
54
+ }
55
+
56
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Clyp.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Clyp.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The clyp.it Provider
17
+ *
18
+ * TODO: Its fairly easy to allow fake responses for single urls
19
+ * but is not that simple when using playlists, since the playlist
20
+ * oembed response only embeds the first audio
21
+ *
22
+ * A sample Implementation is commented out, because the current way
23
+ * provider tests are made does not allow selective urls, and this provider
24
+ * is eventually going to fail when a playlist url is given.
25
+ */
26
+ class Clyp extends \Embera\Adapters\Service
27
+ {
28
+ /** inline {@inheritdoc} */
29
+ protected $apiUrl = 'http://api.clyp.it/oembed';
30
+
31
+ /** inline {@inheritdoc} */
32
+ protected function validateUrl()
33
+ {
34
+ $this->url->stripLastSlash();
35
+ $this->url->stripWWW();
36
+
37
+ return (preg_match('~clyp\.it/([^ ]{8,12}|playlist/[^ ]{8,12})$~i', $this->url));
38
+ }
39
+
40
+ /** inline {@inheritdoc}
41
+ public function fakeResponse()
42
+ {
43
+ if (preg_match('~/playlist/~i', $this->url) {
44
+ return array();
45
+ }
46
+
47
+ return array(
48
+ 'type' => 'rich',
49
+ 'provider_name' => 'Clyp',
50
+ 'provider_url' => 'http://clyp.it',
51
+ 'title' => 'Unknown title',
52
+ 'html' => '<iframe width="{width}" height="{height}" src="http://clyp.it/' . basename($this->url) . '/widget" frameborder="0"></iframe>',
53
+ );
54
+ }
55
+ */
56
+ }
57
+
58
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Codepoints.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Codepoints.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The Codepoints Provider
17
+ * @link http://codepoints.net
18
+ */
19
+ class Codepoints extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'https://codepoints.net/api/v1/oembed?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+ $this->url->stripLastSlash();
29
+ $this->url->stripWWW();
30
+ $this->url->convertToHttps();
31
+
32
+ return (preg_match('~codepoints\.net/U\+(?:[\w]+)$~i', $this->url));
33
+ }
34
+
35
+ /** inline {@inheritdoc} */
36
+ public function fakeResponse()
37
+ {
38
+ preg_match('~/U\+([\w]+)$~i', $this->url, $m);
39
+
40
+ return array(
41
+ 'type' => 'rich',
42
+ 'provider_name' => 'Codepoints.net',
43
+ 'provider_url' => 'http://codepoints.net/',
44
+ 'thumbnail_url' => 'http://codepoints.net/api/v1/glyph/' . $m['1'],
45
+ 'html' => '<iframe src="http://codepoints.net/U+' . $m['1'] . '?embed" style="width: {width}px; height: {height}px; border: 1px solid #444;"></iframe>',
46
+ );
47
+ }
48
+ }
49
+
50
+ ?>
library/ostraining/embera/Lib/Embera/Providers/CollegeHumor.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * CollegeHumor.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The CollegeHumor.com Provider
17
+ * @link http://www.collegehumor.com/
18
+ */
19
+ class CollegeHumor extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://www.collegehumor.com/oembed.json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->addWWW();
28
+ return (preg_match('~collegehumor\.com/(?:video|embed)/(?:[0-9]{5,10})/?~i', $this->url));
29
+ }
30
+
31
+ /** inline {@inheritdoc} */
32
+ protected function modifyResponse(array $response = array())
33
+ {
34
+ if (!empty($response['html'])) {
35
+ $spam = array('~<p>(?:.*)</p>~i', '~<div (?:.*)</div>~i');
36
+ $response['html'] = preg_replace($spam, '', $response['html']);
37
+ }
38
+
39
+ return $response;
40
+ }
41
+
42
+ /** inline {@inheritdoc} */
43
+ public function fakeResponse()
44
+ {
45
+ $url = str_replace(array('/video/', '/embed/'), '/e/', $this->url);
46
+ return array(
47
+ 'type' => 'video',
48
+ 'provider_name' => 'CollegeHumor',
49
+ 'provider_url' => 'http://www.collegehumor.com',
50
+ 'html' => '<iframe src="' . $url . '" width="{width}" height="{height}" frameborder="0" webkitAllowFullScreen allowFullScreen></iframe>',
51
+ );
52
+ }
53
+ }
54
+
55
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Coub.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Coub.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The coub.com Provider
17
+ * @link http://coub.com
18
+ */
19
+ class Coub extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://coub.com/api/oembed.json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+ $this->url->stripLastSlash();
29
+ $this->url->stripWWW();
30
+
31
+ return (preg_match('~coub\.com/(?:view|embed)/(?:[\w\d]+)$~i', $this->url));
32
+ }
33
+
34
+ /** inline {@inheritdoc} */
35
+ public function fakeResponse()
36
+ {
37
+ preg_match('~/([\w\d]+)$~i', $this->url, $matches);
38
+
39
+ return array(
40
+ 'type' => 'video',
41
+ 'provider_name' => 'Coub',
42
+ 'provider_url' => 'http://coub.com',
43
+ 'url' => (string) $this->url,
44
+ 'html' => '<iframe src="http://coub.com/embed/' . $matches['1'] . '" allowfullscreen="true" frameborder="0" width="{width}" height="{height}"></iframe>',
45
+ );
46
+ }
47
+ }
48
+
49
+ ?>
library/ostraining/embera/Lib/Embera/Providers/CrowdRanking.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * CrowdRanking.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The crowdranking.com Provider
17
+ * @link crowdranking.com
18
+ */
19
+ class CrowdRanking extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://crowdranking.com/api/oembed.json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripWWW();
28
+ return (preg_match('~crowdranking\.com/(?:crowdrankings|rankings|topics|widgets|r)/(?:[^/]+)/?$~i', $this->url));
29
+ }
30
+
31
+ /** inline {@inheritdoc} */
32
+ protected function normalizeUrl()
33
+ {
34
+ if (preg_match('~c9ng\.com/r/([^/]+)/?$~i', $this->url, $matches))
35
+ $this->url = new \Embera\Url('http://crowdranking.com/r/' . $matches['1']);
36
+ }
37
+
38
+ /** inline {@inheritdoc} */
39
+ public function fakeResponse()
40
+ {
41
+ $url = preg_replace('~/(crowdrankings|rankings|topics|r)/~i', '/widgets/', $this->url);
42
+ return array(
43
+ 'type' => 'rich',
44
+ 'provider_name' => 'crowdranking',
45
+ 'provider_url' => 'http://crowdranking.com',
46
+ 'web_page' => (string) $this->url,
47
+ 'html' => '<iframe src="' . $url . '.iframe?from=oembed&amp;frontmedia=true&amp;v=1" width="{width}" height="{height}" frameborder="0" scrolling="no" allowtransparency="true" style="border-style:none;width:{width}px;height:{height}px;background:transparent;overflow:hidden;"></iframe>',
48
+ );
49
+ }
50
+ }
51
+
52
+ ?>
library/ostraining/embera/Lib/Embera/Providers/DailyMile.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * DailyMile.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The dailymile.com Provider
17
+ * @link http://www.dailymile.com
18
+ * @link http://www.dailymile.com/api/oembed
19
+ */
20
+ class DailyMile extends \Embera\Adapters\Service
21
+ {
22
+ /** inline {@inheritdoc} */
23
+ protected $apiUrl = 'http://api.dailymile.com/oembed?format=json';
24
+
25
+ /** inline {@inheritdoc} */
26
+ protected function validateUrl()
27
+ {
28
+ return (preg_match('~/people/(?:[^/]+)/entries/(?:[0-9]+)/?$~i', $this->url));
29
+ }
30
+ }
31
+
32
+ ?>
library/ostraining/embera/Lib/Embera/Providers/DailyMotion.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * DailyMotion.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The DailyMotion.com Provider
17
+ * @link http://dailymotion.com
18
+ * @link http://www.dailymotion.com/doc/api/oembed.html
19
+ */
20
+ class DailyMotion extends \Embera\Adapters\Service
21
+ {
22
+ /** inline {@inheritdoc} */
23
+ protected $apiUrl = 'http://www.dailymotion.com/services/oembed?format=json';
24
+
25
+ /** inline {@inheritdoc} */
26
+ protected function validateUrl()
27
+ {
28
+ $this->url->addWWW();
29
+ $this->url->stripQueryString();
30
+ $this->url->stripLastSlash();
31
+
32
+ return (preg_match('~dailymotion\.com/video/(?:[^/]+)/?~i', $this->url));
33
+ }
34
+
35
+ /** inline {@inheritdoc} */
36
+ protected function normalizeUrl()
37
+ {
38
+ if (preg_match('~dailymotion\.com/(?:embed/)?(?:video|live)/([^/]+)/?~i', $this->url, $matches)) {
39
+ $this->url = new \Embera\Url('http://www.dailymotion.com/video/' . $matches['1']);
40
+ } else if (preg_match('~dai\.ly/([^/]+)/?~i', $this->url, $matches)) {
41
+ $this->url = new \Embera\Url('http://www.dailymotion.com/video/' . $matches['1']);
42
+ }
43
+ }
44
+
45
+ /** inline {@inheritdoc} */
46
+ public function fakeResponse()
47
+ {
48
+ preg_match('~/video/([^/]+)~i', $this->url, $matches);
49
+
50
+ @list($videoId, $videoTitle) = explode('_', $matches['1'], 2);
51
+
52
+ return array(
53
+ 'type' => 'video',
54
+ 'provider_name' => 'Dailymotion',
55
+ 'provider_url' => 'http://www.dailymotion.com',
56
+ 'title' => (!empty($videoTitle) ? str_replace(array('-', '_'), ' ', $videoTitle) : 'Unknown Title'),
57
+ 'html' => '<iframe frameborder="0" width="{width}" height="{height}" src="http://www.dailymotion.com/embed/video/' . $videoId . '" allowfullscreen></iframe>'
58
+ );
59
+ }
60
+ }
61
+
62
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Deviantart.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Deviantart.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The deviantart.com Provider
17
+ * @link http://deviantart.com
18
+ * @link http://www.deviantart.com/developers/oembed
19
+ */
20
+ class Deviantart extends \Embera\Adapters\Service
21
+ {
22
+ /** inline {@inheritdoc} */
23
+ protected $apiUrl = 'http://backend.deviantart.com/oembed?format=json';
24
+
25
+ /** inline {@inheritdoc} */
26
+ protected function validateUrl()
27
+ {
28
+ return (preg_match('~(deviantart\.com/art/(?:[^/]+)|(?:sta\.sh|fav\.me)/([^/]+))/?$~i', $this->url));
29
+ }
30
+
31
+ /** inline {@inheritdoc} */
32
+ protected function modifyResponse(array $response = array())
33
+ {
34
+ if (empty($response['html']))
35
+ {
36
+ if (strtolower($response['type']) == 'photo')
37
+ {
38
+ $html = '<a href="' . $response['url'] . '" target="_blank">';
39
+ $html .= '<img class="deviantart-oembed" src="' . $response['thumbnail_url_200h'] . '" width="' . $response['thumbnail_width_200h'] . '" height="' . $response['thumbnail_height_200h'] . '" alt="' . htmlspecialchars($response['title'], ENT_QUOTES, 'UTF-8') . '" title="' . htmlspecialchars($response['title'], ENT_QUOTES, 'UTF-8') . '">';
40
+ $html .= '</a>';
41
+
42
+ $response['html'] = $html;
43
+ }
44
+ }
45
+
46
+ return $response;
47
+ }
48
+ }
49
+
50
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Dipity.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Dipity.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The dipity.com Provider
17
+ * @link http://www.dipity.com
18
+ */
19
+ class Dipity extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://www.dipity.com/oembed/timeline/?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+
29
+ return (preg_match('~dipity\.com/(?:[^/]+)/(?:[^/]+)/?$~i', $this->url));
30
+ }
31
+
32
+ /** inline {@inheritdoc} */
33
+ public function fakeResponse()
34
+ {
35
+ $this->url->stripLastSlash();
36
+ $title = preg_replace('~^(.*)/~', '', $this->url);
37
+ $title = str_replace('-', ' ', $title);
38
+
39
+ $html = '<div class="dipity_embed" style="width:{width}px; margin:0; padding:0;">';
40
+ $html .= '<iframe width="{width}" height="{height}" src="' . (string) $this->url . '/?mode=embed&skin=true_mono&z=0#tl" style="border:1px solid #CCC;"></iframe>';
41
+ $html .= '<p style="margin:0;font-family:Arial,sans;font-size:13px;text-align:center"><a href="' . (string) $this->url . '/">' . $title . '</a> on <a href="http://www.dipity.com/">Dipity</a>.</p>';
42
+ $html .= '</div>';
43
+
44
+ return array(
45
+ 'type' => 'rich',
46
+ 'provider_name' => 'Dipity',
47
+ 'provider_url' => 'http://www.dipity.com',
48
+ 'html' => $html,
49
+ );
50
+ }
51
+ }
52
+
53
+ ?>
library/ostraining/embera/Lib/Embera/Providers/DotSub.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * DotSub.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The dotsub.com Provider
17
+ * @link http://dotsub.com/
18
+ * @link http://dotsub.com/solutions/oEmbed
19
+ */
20
+ class DotSub extends \Embera\Adapters\Service
21
+ {
22
+ /** inline {@inheritdoc} */
23
+ protected $apiUrl = 'http://dotsub.com/services/oembed?format=json';
24
+
25
+ /** inline {@inheritdoc} */
26
+ protected function validateUrl()
27
+ {
28
+ $this->url->stripQueryString();
29
+ $this->url->stripLastSlash();
30
+
31
+ return (preg_match('~dotsub\.com/view/(?:[a-f0-9]+)-(?:[a-f0-9]+)-(?:[a-f0-9]+)-(?:[a-f0-9]+)-(?:[a-f0-9]+)$~i', $this->url));
32
+ }
33
+
34
+ /** inline {@inheritdoc} */
35
+ protected function normalizeUrl()
36
+ {
37
+ if (preg_match('~/(?:media|view)/([0-9a-f\-]+)~i', $this->url, $matches))
38
+ $this->url = new \Embera\Url('http://dotsub.com/view/' . $matches['1']);
39
+ }
40
+
41
+ /** inline {@inheritdoc} */
42
+ public function fakeResponse()
43
+ {
44
+ $url = str_replace('/view/', '/media/', $this->url);
45
+ return array(
46
+ 'type' => 'video',
47
+ 'provider_name' => 'DotSUB',
48
+ 'provider_url' => 'http://dotsub.com',
49
+ 'thumbnail_url' => $url . '/t',
50
+ 'html' => '<iframe src="' . $url . '/e/c?width={width}&height={height}" frameborder="0" width="{width}" height="{height}"></iframe>',
51
+ );
52
+ }
53
+ }
54
+
55
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Edocr.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Edocr.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The edocr.com Provider
17
+ * @link http://www.edocr.com/
18
+ * @link http://www.edocr.com/oembed-documentation
19
+ */
20
+ class Edocr extends \Embera\Adapters\Service
21
+ {
22
+ /** inline {@inheritdoc} */
23
+ protected $apiUrl = 'http://www.edocr.com/api/oembed?format=json';
24
+
25
+ /** inline {@inheritdoc} */
26
+ protected function validateUrl()
27
+ {
28
+ $this->url->stripQueryString();
29
+ $this->url->stripLastSlash();
30
+ $this->url->addWWW();
31
+
32
+ return (preg_match('~edocr\.com/doc/(?:[0-9]+)/(?:[^/]+)$~i', $this->url));
33
+ }
34
+ }
35
+
36
+ ?>
library/ostraining/embera/Lib/Embera/Providers/EgliseInfo.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * EgliseInfo.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The EgliseInfo Provider
17
+ * @link http://egliseinfo.catholique.fr/
18
+ */
19
+ class EgliseInfo extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://egliseinfo.catholique.fr/api/oembed?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ return (preg_match('~egliseinfo\.catholique\.fr/([^ ]+)~i', $this->url));
28
+ }
29
+ }
30
+
31
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Facebook.php ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Facebook.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The Facebook Provider (Public posts and videos)
17
+ * @link https://www.facebook.com
18
+ * @link https://developers.facebook.com/docs/plugins/oembed-endpoints
19
+ */
20
+ class Facebook extends \Embera\Adapters\Service
21
+ {
22
+ /**
23
+ * inline {@inheritdoc}
24
+ * This Provider is kind of special, because it uses different oembed endpoints
25
+ * based on the given url. The default value of the endpoint is null and is set
26
+ * during the process of getting the url information.
27
+ */
28
+ protected $apiUrl = null;
29
+
30
+ /** Patterns that match posts urls */
31
+ protected $postPatterns = array(
32
+ /**
33
+ * https://www.facebook.com/{page-name}/posts/{post-id}
34
+ * https://www.facebook.com/{username}/posts/{post-id}
35
+ * https://www.facebook.com/{username}/activity/{activity-id}
36
+ *
37
+ * Undocumented: https://www.facebook.com/{username}/photos/{photo-id}
38
+ */
39
+ '~facebook\.com/(?:[^/]+)/(?:posts|activity|photos)/(?:[^/]+)/?~i',
40
+
41
+ /**
42
+ * https://www.facebook.com/notes/{username}/{note-url}/{note-id}
43
+ */
44
+ '~facebook\.com/notes/(?:[^/]+)/(?:[^/]+)/(?:[^/]+)/?~i',
45
+
46
+ /**
47
+ * https://www.facebook.com/photo.php?fbid={photo-id}
48
+ * https://www.facebook.com/permalink.php?story_fbid={post-id}
49
+ */
50
+ '~facebook\.com/(?:photo|permalink)\.php\?(?:(story_)?fbid)=(?:[^ ]+)~i',
51
+
52
+ /**
53
+ * https://www.facebook.com/photos/{photo-id}
54
+ * https://www.facebook.com/questions/{question-id}
55
+ */
56
+ '~facebook\.com/(?:photos|questions)/(?:[^/ ]+)/?~i',
57
+
58
+ /**
59
+ * NOTE: This url scheme is stated to be supported, however
60
+ * I havent found any example that work. I'm leaving it
61
+ * but I suspect that its not valid anymore.. we know how
62
+ * facebook is with API's :/
63
+ *
64
+ * However in order to be really complaint with the documentation
65
+ * I'm leaving the pattern.
66
+ *
67
+ * https://www.facebook.com/media/set?set={set-id}
68
+ */
69
+ '~facebook\.com/media/set/?\?set=(?:[^/ ]+)~i',
70
+ );
71
+
72
+
73
+ /** Patterns that match video urls */
74
+ protected $videoPatterns = array(
75
+ /**
76
+ * https://www.facebook.com/{page-name}/videos/{video-id}/
77
+ * https://www.facebook.com/{username}/videos/{video-id}/
78
+ */
79
+ '~facebook\.com/(?:[^/]+)/videos/(?:[^/]+)/?~i',
80
+
81
+ /**
82
+ ` * https://www.facebook.com/video.php?id={video-id}
83
+ * https://www.facebook.com/video.php?v={video-id}
84
+ */
85
+ '~facebook\.com/video\.php\?(?:id|v)=(?:[^ ]+)~i',
86
+ );
87
+
88
+ /** inline {@inheritdoc} */
89
+ protected function validateUrl()
90
+ {
91
+ $this->url->convertToHttps();
92
+ return ($this->urlMatchesPattern(array_merge($this->postPatterns, $this->videoPatterns)));
93
+ }
94
+
95
+ /**
96
+ * Checks if $this->url matches the given list of patterns
97
+ *
98
+ * @param array $patternList Array with regex
99
+ * @return bool
100
+ */
101
+ protected function urlMatchesPattern(array $patternList)
102
+ {
103
+ foreach ($patternList as $p) {
104
+ if (preg_match($p, $this->url)) {
105
+ return true;
106
+ }
107
+ }
108
+
109
+ return false;
110
+ }
111
+
112
+ /**
113
+ * inline {@inheritdoc}
114
+ *
115
+ * Im overriding this method because I need to set the
116
+ * endpoint based on the given url. By default we're always assuming
117
+ * it is a post url unless we have a specific video match.
118
+ *
119
+ * Why? Because we already did url validation and We dont want
120
+ * to loop over both sets of patterns all over again right? So
121
+ * we just need to loop over the smaller one ;)
122
+ */
123
+ public function getInfo()
124
+ {
125
+ $this->apiUrl = 'https://www.facebook.com/plugins/post/oembed.json/';
126
+ if ($this->urlMatchesPattern($this->videoPatterns)) {
127
+ $this->apiUrl = 'https://www.facebook.com/plugins/video/oembed.json/';
128
+ }
129
+
130
+ return parent::getInfo();
131
+ }
132
+ }
133
+
134
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Flickr.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Flickr.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The Flickr.com Provider
17
+ * @link http://www.flickr.com
18
+ */
19
+ class Flickr extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://www.flickr.com/services/oembed?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ return (preg_match('~/photos/(?:[^/]+)/(?:[0-9]+)/?~i', $this->url) || preg_match('~flic\.kr/p/(?:[^/]+)~i', $this->url));
28
+ }
29
+
30
+ /** inline {@inheritdoc} */
31
+ protected function normalizeUrl()
32
+ {
33
+ if (preg_match('~/photos/([^/"\'<>]+)/([0-9]+)/?~i', $this->url, $matches))
34
+ $this->url = new \Embera\Url('http://www.flickr.com/photos/' . $matches['1'] . '/' . $matches['2'] . '/');
35
+ }
36
+
37
+ /** inline {@inheritdoc} */
38
+ protected function modifyResponse(array $response = array())
39
+ {
40
+ if (empty($response['html']))
41
+ {
42
+ $html = '<a href="' . $response['url'] . '" target="_blank">';
43
+ $html .= '<img class="flickr-oembed" src="' . $response['thumbnail_url'] . '" width="' . $response['thumbnail_width'] . '" height="' . $response['thumbnail_height'] . '" alt="' . htmlspecialchars($response['title'], ENT_QUOTES, 'UTF-8') . '" title="' . htmlspecialchars($response['title'], ENT_QUOTES, 'UTF-8') . '">';
44
+ $html .= '</a>';
45
+
46
+ $response['html'] = $html;
47
+ }
48
+
49
+ return $response;
50
+ }
51
+ }
52
+
53
+ ?>
library/ostraining/embera/Lib/Embera/Providers/FunnyOrDie.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * FunnyOrDie.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The funnyordie.com Provider
17
+ */
18
+ class FunnyOrDie extends \Embera\Adapters\Service
19
+ {
20
+ /** inline {@inheritdoc} */
21
+ protected $apiUrl = 'http://www.funnyordie.com/oembed.json';
22
+
23
+ /** inline {@inheritdoc} */
24
+ protected function validateUrl()
25
+ {
26
+ $this->url->stripQueryString();
27
+ $this->url->stripLastSlash();
28
+
29
+ return (preg_match('~funnyordie\.com/videos/(?:[\w\d]+)~i', $this->url));
30
+ }
31
+
32
+ /** inline {@inheritdoc} */
33
+ protected function normalizeUrl()
34
+ {
35
+ if (preg_match('~\.com/embed/~i', $this->url))
36
+ $this->url = new \Embera\Url(str_ireplace('/embed/', '/videos/', $this->url));
37
+ }
38
+
39
+ /** inline {@inheritdoc} */
40
+ protected function modifyResponse(array $response = array())
41
+ {
42
+ if (!empty($response['html']))
43
+ $response['html'] = preg_replace('~<div(.*)</div>~is', '', trim($response['html']));
44
+
45
+ return $response;
46
+ }
47
+
48
+ /** inline {@inheritdoc} */
49
+ public function fakeResponse()
50
+ {
51
+ preg_match('~/videos/([\w\d]+)/?~', $this->url, $matches);
52
+ return array(
53
+ 'type' => 'video',
54
+ 'provider_name' => 'Funny or Die',
55
+ 'provider_url' => 'http://www.funnyordie.com',
56
+ 'html' => '<iframe src="http://www.funnyordie.com/embed/' . $matches['1'] . '" width="{width}" height="{height}" frameborder="0" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe>',
57
+ );
58
+ }
59
+ }
60
+
61
+ ?>
library/ostraining/embera/Lib/Embera/Providers/GeographCI.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * GeographCI.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The channel-islands.geographs.org Provider
17
+ * @link http://channel-islands.geographs.org
18
+ *
19
+ * @todo This Service doesnt provide an html key on response its not possible to generate one from the url alone.
20
+ */
21
+ class GeographCI extends \Embera\Adapters\Service
22
+ {
23
+ /** inline {@inheritdoc} */
24
+ protected $apiUrl = 'http://www.geograph.org.gg/api/oembed?format=json';
25
+
26
+ /** inline {@inheritdoc} */
27
+ protected function validateUrl()
28
+ {
29
+ return (preg_match('~/photo/(?:[0-9]+)/?$~i', $this->url));
30
+ }
31
+ }
32
+
33
+ ?>
library/ostraining/embera/Lib/Embera/Providers/GeographDe.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * GeographDe.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The hlipp.de Provider
17
+ * @link http://hlipp.de
18
+ *
19
+ * @todo This Service doesnt provide an html key on response its not possible to generate one from the url alone.
20
+ */
21
+ class GeographDe extends \Embera\Adapters\Service
22
+ {
23
+ /** inline {@inheritdoc} */
24
+ protected $apiUrl = 'http://geo.hlipp.de/restapi.php/api/oembed?format=json';
25
+
26
+ /** inline {@inheritdoc} */
27
+ protected function validateUrl()
28
+ {
29
+ return (preg_match('~/photo/(?:[0-9]+)/?$~i', $this->url));
30
+ }
31
+ }
32
+
33
+ ?>
library/ostraining/embera/Lib/Embera/Providers/GeographUk.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * GeographUk.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The geograph.co.uk Provider
17
+ * @link http://geograph.co.uk
18
+ *
19
+ * @todo This Service doesnt provide an html key on response its not possible to generate one from the url alone.
20
+ */
21
+ class GeographUk extends \Embera\Adapters\Service
22
+ {
23
+ /** inline {@inheritdoc} */
24
+ protected $apiUrl = 'http://api.geograph.org.uk/api/oembed?format=json';
25
+
26
+ /** inline {@inheritdoc} */
27
+ protected function validateUrl()
28
+ {
29
+ return (preg_match('~/photo/(?:[0-9]+)/?$~i', $this->url));
30
+ }
31
+ }
32
+
33
+ ?>
library/ostraining/embera/Lib/Embera/Providers/GettyImages.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * GettyImages.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The gettyimages.com Provider
17
+ *
18
+ * @link https://www.gettyimages.com
19
+ *
20
+ * Supports:
21
+ * http://gty.im/a0200-000024
22
+ * http://www.gettyimages.com/detail/photo/dog-in-car-royalty-free-image/a0200-000024
23
+ */
24
+ class GettyImages extends \Embera\Adapters\Service
25
+ {
26
+ /** inline {@inheritdoc} */
27
+ protected $apiUrl = 'http://embed.gettyimages.com/oembed?caller=embera';
28
+
29
+ /** inline {@inheritdoc} */
30
+ protected function validateUrl()
31
+ {
32
+ return (preg_match('~gty\.im/([a-z0-9\-]+)$~i', $this->url));
33
+ }
34
+
35
+ /** inline {@inheritdoc} */
36
+ protected function normalizeUrl()
37
+ {
38
+ $this->url->stripWWW();
39
+ $this->url->convertToHttp();
40
+ $this->url->stripQueryString();
41
+ $this->url->stripLastSlash();
42
+
43
+ if (preg_match('~gettyimages\.com/detail/photo/(?:[^/]+)/([a-z0-9\-]+)$~i', $this->url, $matches)) {
44
+ $this->url = new \Embera\Url('http://gty.im/' . $matches['1']);
45
+ }
46
+ }
47
+ }
48
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Gfycat.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Gfycat.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The Gfycat Provider
17
+ * @link https://gfycat.com
18
+ */
19
+ class Gfycat extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = '';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+ $this->url->stripLastSlash();
29
+ $this->url->stripWWW();
30
+
31
+ $banned = array('api', 'terms', 'privacy', 'about', 'dmca', 'search');
32
+ $this->url->invalidPattern('(gfycat\.com/(' . implode('|', $banned) . ')$)');
33
+
34
+ return (preg_match('~gfycat\.com/(?:[^/]+)$~i', $this->url));
35
+ }
36
+
37
+ /** inline {@inheritdoc} */
38
+ public function fakeResponse()
39
+ {
40
+ $url = preg_replace('~gfycat\.com/~i', 'gfycat.com/ifr/', $this->url);
41
+
42
+ return array(
43
+ 'type' => 'video',
44
+ 'provider_name' => 'Gfycat',
45
+ 'provider_url' => 'https://gfycat.com',
46
+ 'html' => '<iframe src="' . $url . '" frameborder="0" scrolling="no" width="{width}" height="{height}" style="-webkit-backface-visibility: hidden;-webkit-transform: scale(1);" ></iframe>'
47
+ );
48
+ }
49
+ }
50
+
51
+ ?>
library/ostraining/embera/Lib/Embera/Providers/GithubGist.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * GithubGist.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The gist.github.com Provider
17
+ * @link https://gist.github.com
18
+ */
19
+ class GithubGist extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'https://github.com/api/oembed?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+ $this->url->stripLastSlash();
29
+
30
+ return (preg_match('~/(?:[\d]+)$~i', $this->url));
31
+ }
32
+
33
+ /** inline {@inheritdoc} */
34
+ protected function normalizeUrl()
35
+ {
36
+ if (preg_match('~github\.com/(?:[^/]+)/([\d]+)/?~i', $this->url, $matches))
37
+ $this->url->overwrite('https://gist.github.com/' . $matches['1']);
38
+ }
39
+
40
+ /** inline {@inheritdoc} */
41
+ protected function modifyResponse(array $response = array())
42
+ {
43
+ $this->url->discardChanges();
44
+ if (preg_match('~github\.com/([^/]+)/([\d]+)~i', $this->url, $matches))
45
+ $response['html'] = '<script type="text/javascript" src="https://gist.github.com/' . $matches['1'] . '/' . $matches['2'] . '.js"></script>';
46
+
47
+ return $response;
48
+ }
49
+
50
+ /** inline {@inheritdoc} */
51
+ public function fakeResponse()
52
+ {
53
+ $this->url->discardChanges();
54
+ if (preg_match('~github\.com/([^/]+)/([\d]+)~i', $this->url, $matches))
55
+ {
56
+ return array(
57
+ 'type' => 'rich',
58
+ 'provider_name' => 'GitHub',
59
+ 'provider_url' => 'https://github.com',
60
+ 'html' => '<script type="text/javascript" src="https://gist.github.com/' . $matches['1'] . '/' . $matches['2'] . '.js"></script>',
61
+ 'title' => 'gist:' . $matches['2']
62
+ );
63
+ }
64
+
65
+ return array();
66
+ }
67
+ }
68
+
69
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Gmep.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Gmep.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The gmep.org Provider
17
+ * @link http://gmep.org
18
+ */
19
+ class Gmep extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'https://gmep.org/oembed.json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+ $this->url->stripLastSlash();
29
+ $this->url->convertToHttps();
30
+ $this->url->stripWWW();
31
+
32
+ return (preg_match('~gmep\.org/media/(?:[0-9]+)$~i', $this->url));
33
+ }
34
+
35
+ /** inline {@inheritdoc} */
36
+ protected function modifyResponse(array $response = array())
37
+ {
38
+ if (empty($response['html']) && $response['type'] =='photo')
39
+ {
40
+ $html = '<a href="' . $response['url'] . '" target="_blank">';
41
+ $html .= '<img class="gmep-oembed" src="' . $response['thumbnail_url'] . '" width="' . $response['thumbnail_width'] . '" height="' . $response['thumbnail_height'] . '" alt="' . htmlspecialchars($response['title'], ENT_QUOTES, 'UTF-8') . '" title="' . htmlspecialchars($response['title'], ENT_QUOTES, 'UTF-8') . '">';
42
+ $html .= '</a>';
43
+
44
+ $response['html'] = $html;
45
+ }
46
+
47
+ return $response;
48
+ }
49
+ }
50
+
51
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Hq23.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Hq23.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The 23hq.com Provider
17
+ * @link http://23hq.com
18
+ */
19
+ class Hq23 extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://www.23hq.com/23/oembed?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ return (preg_match('~23hq\.com/(?:[^/]+)/photo/(?:[0-9]+)/?~i', $this->url));
28
+ }
29
+
30
+ /** inline {@inheritdoc} */
31
+ protected function modifyResponse(array $response = array())
32
+ {
33
+ if (empty($response['html']))
34
+ {
35
+ $html = '<a href="' . $response['url'] . '" target="_blank">';
36
+ $html .= '<img class="23hq-oembed" src="' . $response['thumbnail_url'] . '" width="' . $response['thumbnail_width'] . '" height="' . $response['thumbnail_height'] . '" alt="' . htmlspecialchars($response['title'], ENT_QUOTES, 'UTF-8') . '" title="' . htmlspecialchars($response['title'], ENT_QUOTES, 'UTF-8') . '">';
37
+ $html .= '</a>';
38
+
39
+ $response['html'] = $html;
40
+ }
41
+
42
+ return $response;
43
+ }
44
+ }
45
+
46
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Huffduffer.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Huffduffer.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The huffduffer.com Provider
17
+ * @link http://huffduffer.com
18
+ */
19
+ class Huffduffer extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://huffduffer.com/oembed?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ return (preg_match('~huffduffer\.com/(?:[^/]+)/(?:[0-9]+)/?$~i', $this->url));
28
+ }
29
+ }
30
+
31
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Hulu.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Hulu.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The Hulu.com Provider
17
+ * @link http://hulu.com
18
+ */
19
+ class Hulu extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://www.hulu.com/api/oembed.json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripLastSlash();
28
+ $this->url->addWWW();
29
+
30
+ return (preg_match('~hulu\.com/watch/([0-9]{4,10})~i', $this->url));
31
+ }
32
+
33
+ /** inline {@inheritdoc} */
34
+ protected function normalizeUrl()
35
+ {
36
+ if (preg_match('~/watch/([0-9]{4,10})~i', $this->url, $matches))
37
+ $this->url = new \Embera\Url('http://www.hulu.com/watch/' . $matches['1']);
38
+ }
39
+ }
40
+
41
+ ?>
library/ostraining/embera/Lib/Embera/Providers/IFTTT.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * IFTTT.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The ifttt.com Provider
17
+ * @link https://ifttt.com
18
+ */
19
+ class IFTTT extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'https://ifttt.com/oembed/?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->convertToHttps();
28
+
29
+ return (preg_match('~ifttt\.com/recipes/(?:[0-9]+)/?$~i', $this->url));
30
+ }
31
+
32
+ /** inline {@inheritdoc} */
33
+ public function fakeResponse()
34
+ {
35
+ preg_match('~/([0-9]+)/?$~i', $this->url, $matches);
36
+ $html = '<a href="https://ifttt.com/view_embed_recipe/' . $matches['1'] . '" target="_blank" class="embed_recipe embed_recipe-l_28" id= "embed_recipe-' . $matches['1'] . '"><img src="https://ifttt.com/recipe_embed_img/' . $matches['1'] . '" alt="" width="{width}px"/></a>';
37
+ $html .= '<script async type="text/javascript" src= "//ifttt.com/assets/embed_recipe.js"></script>';
38
+ return array(
39
+ 'type' => 'rich',
40
+ 'provider_name' => 'IFTTT',
41
+ 'provider_url' => 'https://ifttt.com',
42
+ 'html' => $html
43
+ );
44
+ }
45
+ }
46
+
47
+ ?>
library/ostraining/embera/Lib/Embera/Providers/IFixIt.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * IFixIt.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The ifixit.com Provider
17
+ * @link http://www.ifixit.com/api/doc/embed
18
+ * @link http://www.ifixit.com/
19
+ */
20
+ class IFixIt extends \Embera\Adapters\Service
21
+ {
22
+ /** inline {@inheritdoc} */
23
+ protected $apiUrl = 'http://www.ifixit.com/Embed?format=json';
24
+
25
+ /** inline {@inheritdoc} */
26
+ protected function validateUrl()
27
+ {
28
+ return (preg_match('~ifixit\.com/(?:Guide|Teardown)/(?:[\w\d\+ %]+)/(?:[\d/]+)/?$~i', $this->url));
29
+ }
30
+
31
+ /** inline {@inheritdoc} */
32
+ public function fakeResponse()
33
+ {
34
+ preg_match('~/(\d{4,20})/?~i', $this->url, $matches);
35
+ return array(
36
+ 'type' => 'rich',
37
+ 'provider_name' => 'iFixit',
38
+ 'provider_url' => 'http://www.ifixit.com',
39
+ 'html' => '<script type="text/javascript" src="http://d1luk0418egahw.cloudfront.net/static/embed/ifixit-embed.3.js?id=' . $matches['1'] . '"></script>',
40
+ );
41
+ }
42
+ }
43
+
44
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Infogram.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Infogram.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The infogr.am Provider
17
+ * @link https://infogr.am
18
+ *
19
+ * @TODO: This provider COULD support offline respones.
20
+ */
21
+ class Infogram extends \Embera\Adapters\Service
22
+ {
23
+ /** inline {@inheritdoc} */
24
+ protected $apiUrl = 'https://infogr.am/oembed/?format=json';
25
+
26
+ /** inline {@inheritdoc} */
27
+ protected function validateUrl()
28
+ {
29
+ $this->url->convertToHttps();
30
+ $this->url->stripQueryString();
31
+ $this->url->stripLastSlash();
32
+ $this->url->invalidPattern('infogr\.am/(?:pricing|register|login|search|terms|privacy|featured|education|brands|organizations)$');
33
+
34
+ return (preg_match('~infogr\.am/([^/ ]+)$~i', $this->url));
35
+ }
36
+ }
37
+
38
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Instagram.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Instagram.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The instragram.com Provider
17
+ * @link https://instagram.com
18
+ */
19
+ class Instagram extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://api.instagram.com/oembed?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+ return (preg_match('~/p/([A-Za-z0-9-_]+)/?$~i', $this->url));
29
+ }
30
+
31
+ /** inline {@inheritdoc} */
32
+ protected function modifyResponse(array $response = array())
33
+ {
34
+ if (empty($response['html']) && !empty($response['url'])) {
35
+ $extension = strtolower(pathinfo(parse_url($response['url'],PHP_URL_PATH),PATHINFO_EXTENSION));
36
+ if (in_array($extension, array('jpg', 'jpeg', 'png', 'gif'))) {
37
+ $html = '<a href="' . $response['url'] . '" target="_blank">';
38
+ $html .= '<img class="instagram-oembed" src="' . $response['url'] . '" width="' . $response['width'] . '" height="' . $response['height'] . '" alt="' . htmlspecialchars($response['title'], ENT_QUOTES, 'UTF-8') . '" title="' . htmlspecialchars($response['title'], ENT_QUOTES, 'UTF-8') . '">';
39
+ $html .= '</a>';
40
+ $response['html'] = $html;
41
+ }
42
+ }
43
+
44
+ return $response;
45
+ }
46
+ }
47
+
48
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Issuu.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Issuu.php
4
+ *
5
+ * @package Providers
6
+ * @author Rob Taylor <rob@uxblondon.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Embera\Providers;
13
+
14
+ /**
15
+ * The issuu.com Provider
16
+ * @link https://issuu.com
17
+ */
18
+ class Issuu extends \Embera\Adapters\Service
19
+ {
20
+ /** inline {@inheritdoc} */
21
+ protected $apiUrl = 'http://issuu.com/oembed_wp';
22
+
23
+ /** inline {@inheritdoc} */
24
+ protected function validateUrl()
25
+ {
26
+ return (preg_match('~https?://(www\.)?issuu\.com/.+/docs/.+~i', $this->url));
27
+ }
28
+
29
+ /** inline {@inheritdoc} */
30
+ public function fakeResponse()
31
+ {
32
+ $queryString = parse_url($this->url, PHP_URL_QUERY);
33
+ parse_str($queryString, $q);
34
+
35
+ if (isset($q['e']) && preg_match('~^(?:[a-z0-9\/]+)$~i', $q['e'])) {
36
+ $html = '<div data-configid="' . $q['e'] . '" style="width: {width}px; height: {height}px" class="issuuembed"></div>';
37
+ $html .= '<script type="text/javascript" src="//e.issuu.com/embed.js" async="true"></script>';
38
+
39
+ return array(
40
+ 'type' => 'rich',
41
+ 'provider_name' => 'Issuu',
42
+ 'provider_url' => 'https://issuu.com',
43
+ 'html' => $html
44
+ );
45
+ }
46
+ }
47
+ }
48
+
49
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Kickstarter.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Kickstarter.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The kickstarter.com Provider
17
+ * @link http://www.kickstarter.com
18
+ */
19
+ class Kickstarter extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://www.kickstarter.com/services/oembed';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+ $this->url->stripLastSlash();
29
+ $this->url->addWWW();
30
+
31
+ return (preg_match('~/projects/(?:[^/]+)/(?:[^/]+)$~i', $this->url));
32
+ }
33
+
34
+ /** inline {@inheritdoc} */
35
+ public function fakeResponse()
36
+ {
37
+ return array(
38
+ 'type' => 'rich',
39
+ 'provider_name' => 'Kickstarter',
40
+ 'provider_url' => 'http://www.kickstarter.com',
41
+ 'html' => '<iframe frameborder="0" height="{height}" src="' . $this->url . '/widget/video.html" width="{width}"></iframe>',
42
+ );
43
+ }
44
+ }
45
+
46
+ ?>
library/ostraining/embera/Lib/Embera/Providers/LearningApps.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * LearningApps.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The LearningApps.org Provider
17
+ */
18
+ class LearningApps extends \Embera\Adapters\Service
19
+ {
20
+ /** inline {@inheritdoc} */
21
+ protected $apiUrl = 'http://learningapps.org/oembed.php?format=json';
22
+
23
+ /** inline {@inheritdoc} */
24
+ protected function validateUrl()
25
+ {
26
+ $this->url->stripQueryString();
27
+ $this->url->stripLastSlash();
28
+ return (preg_match('~learningapps\.org/(?:[0-9]+)$~i', $this->url));
29
+ }
30
+ }
31
+
32
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Meetup.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Meetup.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The meetup.com Provider
17
+ * @link http://www.meetup.com/meetup_api/docs/oembed/
18
+ * @link http://www.meetup.com
19
+ */
20
+ class Meetup extends \Embera\Adapters\Service
21
+ {
22
+ /** inline {@inheritdoc} */
23
+ protected $apiUrl = 'https://api.meetup.com/oembed?format=json';
24
+
25
+ /** inline {@inheritdoc} */
26
+ protected function validateUrl()
27
+ {
28
+ $this->url->stripQueryString();
29
+
30
+ return (preg_match('~meetup\.com/(?:.+)~i', $this->url) ||
31
+ preg_match('~meetu\.ps/(?:[\w\d]+)/?$~i', $this->url) );
32
+ }
33
+ }
34
+
35
+ ?>
library/ostraining/embera/Lib/Embera/Providers/MixCloud.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * MixCloud.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The mixcloud.com Provider
17
+ * @link http://www.mixcloud.com/developers/documentation/
18
+ * @link http://www.mixcloud.com
19
+ */
20
+ class MixCloud extends \Embera\Adapters\Service
21
+ {
22
+ /** inline {@inheritdoc} */
23
+ protected $apiUrl = 'http://www.mixcloud.com/oembed/?format=json';
24
+
25
+ /** inline {@inheritdoc} */
26
+ protected function validateUrl()
27
+ {
28
+ // Urls with this words/pattern dont work
29
+ $this->url->invalidPattern('mixcloud\.com/(?:categories|advertise|developers)/(?:[^/]+)/?$');
30
+
31
+ return (preg_match('~mixcloud\.com/(?:[^/]+)/(?:[^/]+)/?$~i', $this->url));
32
+ }
33
+ }
34
+
35
+ ?>
library/ostraining/embera/Lib/Embera/Providers/MobyPicture.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * MobyPicture.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The mobypicture.com Provider
17
+ * @link http://mobypicture.com
18
+ */
19
+ class MobyPicture extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://api.mobypicture.com/oEmbed?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ return (preg_match('~mobypicture\.com/user/(?:[^/]+)/view/(?:[0-9]+)/?$~i', $this->url) ||
28
+ preg_match('~moby\.to/(?:[\w\d]+)$~', $this->url));
29
+ }
30
+
31
+ /** inline {@inheritdoc} */
32
+ protected function modifyResponse(array $response = array())
33
+ {
34
+ if (empty($response['html']))
35
+ {
36
+ if (strtolower($response['type']) == 'photo')
37
+ {
38
+ $html = '<a href="' . $response['url'] . '" target="_blank">';
39
+ $html .= '<img class="mobypicture-oembed" src="' . $response['url'] . '" width="200" height="200" alt="' . htmlspecialchars($response['title'], ENT_QUOTES, 'UTF-8') . '" title="' . htmlspecialchars($response['title'], ENT_QUOTES, 'UTF-8') . '">';
40
+ $html .= '</a>';
41
+
42
+ $response['html'] = $html;
43
+ }
44
+ }
45
+
46
+ return $response;
47
+ }
48
+ }
49
+
50
+ ?>
library/ostraining/embera/Lib/Embera/Providers/NFB.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * NFB.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The nfb.ca Provider
17
+ * @link http://www.nfb.ca
18
+ */
19
+ class NFB extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://www.nfb.ca/remote/services/oembed/?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+ $this->url->stripLastSlash();
29
+
30
+ return (preg_match('~/film/(?:[^/]+)$~i', $this->url));
31
+ }
32
+
33
+ /** inline {@inheritdoc} */
34
+ protected function normalizeUrl()
35
+ {
36
+ $this->url->overwrite(preg_replace('~/embed/player$~i', '', $this->url));
37
+ }
38
+
39
+ /** inline {@inheritdoc} */
40
+ protected function modifyResponse(array $response = array())
41
+ {
42
+ if (!empty($response['html']))
43
+ {
44
+ // The html response comes "encoded" ... booooo :(, need to decode in order to work..
45
+ // Bad API, bad bad bad!
46
+ $response['html'] = html_entity_decode($response['html'], ENT_QUOTES, 'UTF-8');
47
+ $response['html'] = preg_replace('~<p(.*)</p>~is', '', $response['html']);
48
+ }
49
+
50
+ return $response;
51
+ }
52
+
53
+ /** inline {@inheritdoc} */
54
+ public function fakeResponse()
55
+ {
56
+ return array(
57
+ 'type' => 'video',
58
+ 'provider_name' => 'National Film Board of Canda',
59
+ 'provider_url' => 'http://www.nfb.ca',
60
+ 'html' => '<iframe src="' . $this->url . '/embed/player" width="{width}" height="{height}" ></iframe>',
61
+ );
62
+ }
63
+ }
64
+
65
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Officemix.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Officemix.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The Officemix Provider
17
+ * @link https://mix.office.com
18
+ */
19
+ class Officemix extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'https://mix.office.com/oembed?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+ $this->url->stripLastSlash();
29
+ $this->url->convertToHttps();
30
+
31
+ return (preg_match('~mix\.office\.com/(?:watch|embed)/(?:[^/]+)$~i', $this->url));
32
+ }
33
+
34
+ /** inline {@inheritdoc} */
35
+ public function fakeResponse()
36
+ {
37
+ preg_match('~/(?:watch|embed)/([^/]+)$~i', $this->url, $m);
38
+
39
+ return array(
40
+ 'type' => 'rich',
41
+ 'provider_name' => 'Officemix',
42
+ 'provider_url' => 'https://mix.office.com',
43
+ 'html' => '<iframe width="{width}" height="{height}" src="https://mix.office.com/embed/' . $m['1'] . '" title="" frameborder="0" allowfullscreen></iframe>',
44
+ );
45
+ }
46
+ }
47
+
48
+ ?>
library/ostraining/embera/Lib/Embera/Providers/OfficialFM.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * OfficialFM.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The official.fm Provider
17
+ * @link http://official.fm
18
+ */
19
+ class OfficialFM extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://official.fm/services/oembed.json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+ $this->url->stripLastSlash();
29
+ $this->url->stripWWW();
30
+
31
+ return (preg_match('~official\.fm/(?:tracks|playlists)/(?:[^/]+)$~i', $this->url));
32
+ }
33
+
34
+ /** inline {@inheritdoc} */
35
+ protected function modifyResponse(array $response = array())
36
+ {
37
+ if (!empty($response['html']))
38
+ $response['html'] = str_replace('\'', '"', $response['html']);
39
+
40
+ return $response;
41
+ }
42
+
43
+ /** inline {@inheritdoc} */
44
+ public function fakeResponse()
45
+ {
46
+ preg_match('~/(?:tracks|playlists)/([^/]+)$~i', $this->url, $matches);
47
+
48
+ return array(
49
+ 'type' => 'rich',
50
+ 'provider_name' => 'Official.fm',
51
+ 'provider_url' => 'http://official.fm',
52
+ 'html' => '<iframe width="{width}" height="{height}" src="//official.fm/player?width={width}&height={height}&feed=%2F%2Fofficial.fm%2Ffeed%2Fplaylists%2F' . $matches['1'] . '.json" frameborder="0"></iframe>'
53
+ );
54
+ }
55
+ }
56
+
57
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Oumy.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Oumy.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The Oumy Provider
17
+ * @link https://oumy.com
18
+ */
19
+ class Oumy extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'https://www.oumy.com/oembed?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+ $this->url->stripLastSlash();
29
+ $this->url->stripWWW();
30
+
31
+ return (preg_match('~oumy\.com/v/(?:[^/]+)$~i', $this->url));
32
+ }
33
+
34
+ /** inline {@inheritdoc} */
35
+ public function fakeResponse()
36
+ {
37
+ preg_match('~/v/([^/]+)$~i', $this->url, $m);
38
+
39
+ return array(
40
+ 'type' => 'video',
41
+ 'provider_name' => 'Oumy',
42
+ 'provider_url' => 'https://www.oumy.com',
43
+ 'html' => '<iframe src="https://www.oumy.com/embed/' . $m['1'] . '" width="{width}" height="{height}" scrolling="no" frameborder="1" style="border: 1px solid black;" allowfullscreen /> '
44
+ );
45
+ }
46
+ }
47
+
48
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Pastery.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Pastery.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The Pastery Provider
17
+ * @link https://www.pastery.net/
18
+ */
19
+ class Pastery extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'https://www.pastery.net/oembed/?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ return (preg_match('~pastery\.net/(?:[^/]+)/?$~i', $this->url));
28
+ }
29
+ }
30
+
31
+ ?>
library/ostraining/embera/Lib/Embera/Providers/PollDaddy.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PollDaddy.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The polldaddy.com Provider
17
+ * @link http://support.polldaddy.com/oembed/
18
+ * @link http://polldaddy.com
19
+ *
20
+ * TODO: This provider should be able to provide fake responses,
21
+ * but there are cases when it is not possible, so the code is commented
22
+ * out.
23
+ */
24
+ class PollDaddy extends \Embera\Adapters\Service
25
+ {
26
+ /** inline {@inheritdoc} */
27
+ protected $apiUrl = 'http://polldaddy.com/oembed/?format=json';
28
+
29
+ /** inline {@inheritdoc} */
30
+ protected function validateUrl()
31
+ {
32
+ $this->url->convertToHttp();
33
+ $this->url->stripWWW();
34
+
35
+ return (preg_match('~polldaddy\.com/(?:poll|s|ratings)/(?:[^/]+)/?$~i', $this->url));
36
+ }
37
+
38
+ /** inline {@inheritdoc} */
39
+ protected function modifyResponse(array $response = array())
40
+ {
41
+ if (!empty($response['html'])) {
42
+ $response['html'] = preg_replace('~<noscript>(.*)</noscript>~is', '', $response['html']);
43
+ }
44
+
45
+ return $response;
46
+ }
47
+
48
+ /** inline {@inheritdoc} */
49
+ /*
50
+ public function fakeResponse()
51
+ {
52
+ if (preg_match('~/poll/([\d]+)/?$~i', $this->url, $matches))
53
+ {
54
+ return array(
55
+ 'type' => 'rich',
56
+ 'provider_name' => 'Polldaddy',
57
+ 'provider_url' => 'http://polldaddy.com',
58
+ 'html' => '<script type="text/javascript" charset="utf-8" src="http://static.polldaddy.com/p/' . $matches['1'] . '.js"></script>'
59
+ );
60
+ }
61
+
62
+ return array();
63
+ } */
64
+ }
65
+
66
+ ?>
library/ostraining/embera/Lib/Embera/Providers/PollEveryWhere.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PollEveryWhere.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The polleverywhere.com Provider
17
+ * @link http://polleverywhere.com
18
+ */
19
+ class PollEveryWhere extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://www.polleverywhere.com/services/oembed/?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->addWWW();
28
+
29
+ return (preg_match('~polleverywhere\.com/(?:polls|free_text_polls|multiple_choice_polls)/(?:[\w\d]+)/?$~i', $this->url));
30
+ }
31
+
32
+ /**
33
+ * The html code from polleverywhere doesnt work
34
+ public function fakeResponse()
35
+ {
36
+ $this->url->stripQueryString();
37
+ $this->url->stripLastSlash();
38
+
39
+ return array(
40
+ 'type' => 'rich',
41
+ 'provider_name' => 'Poll Everywhere',
42
+ 'provider_url' => 'http://www.polleverywhere.com',
43
+ 'html' => '<script language="javascript" src="' . $this->url . '/web.js?results_count_format=percent" type="text/javascript"></script>'
44
+ );
45
+ } */
46
+ }
47
+
48
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Portfolium.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Portfolium.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The portfolium.com Provider
17
+ * @link https://api.portfolium.com/#!/oembed/oembed_index_get
18
+ * @link https://portfolium.com
19
+ */
20
+ class Portfolium extends \Embera\Adapters\Service
21
+ {
22
+ /** inline {@inheritdoc} */
23
+ protected $apiUrl = 'https://api.portfolium.com/oembed?format=json';
24
+
25
+ /** inline {@inheritdoc} */
26
+ protected function validateUrl()
27
+ {
28
+ $this->url->stripQueryString();
29
+ $this->url->stripLastSlash();
30
+
31
+ return (preg_match('~portfolium\.com\/entry\/(?:[^ /]+)$~i', $this->url));
32
+ }
33
+ }
34
+
35
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Rapidengage.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Rapidengage.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The rapidengage.com Provider
17
+ * @link https://rapidengage.com
18
+ * @link https://rapidengage.com/developer/docs#oembed
19
+ */
20
+ class Rapidengage extends \Embera\Adapters\Service
21
+ {
22
+ /** inline {@inheritdoc} */
23
+ protected $apiUrl = 'https://rapidengage.com/api/oembed';
24
+
25
+ /** inline {@inheritdoc} */
26
+ protected function validateUrl()
27
+ {
28
+ $this->url->stripQueryString();
29
+ $this->url->stripLastSlash();
30
+ $this->url->stripWWW();
31
+ $this->url->convertToHttps();
32
+
33
+ return (preg_match('~rapidengage\.com/s/(?:[^ /]+)$~i', $this->url));
34
+ }
35
+ }
36
+
37
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Rdio.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Rdio.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The rdio.com rd.io Provider
17
+ * @link http://developer.rdio.com/docs/oEmbed
18
+ * @link http://rdio.com
19
+ */
20
+ class Rdio extends \Embera\Adapters\Service
21
+ {
22
+ /** inline {@inheritdoc} */
23
+ protected $apiUrl = 'http://www.rdio.com/api/oembed/?format=json';
24
+
25
+ /** inline {@inheritdoc} */
26
+ protected function validateUrl()
27
+ {
28
+ return (preg_match('~rd\.io/(?:[\w]+)/(?:[\w\d]+)/?$~i', $this->url) ||
29
+ preg_match('~rdio\.com/artist/(?:[\d\w-_\+\%\./]+)/album/(?:.+)~i', $this->url) ||
30
+ preg_match('~rdio\.com/people/(?:[\d\w-_\+\%\./]+)/playlists/(?:.+)~i', $this->url));
31
+ }
32
+ }
33
+
34
+ ?>
library/ostraining/embera/Lib/Embera/Providers/ReleaseWire.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ReleaseWire.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The releasewire.com Provider
17
+ * TODO: This service could support offline responses
18
+ */
19
+ class ReleaseWire extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://publisher.releasewire.com/oembed/';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ return (preg_match('~rwire\.com/(?:[0-9]+)$~i', $this->url));
28
+ }
29
+
30
+ /** inline {@inheritdoc} */
31
+ protected function normalizeUrl()
32
+ {
33
+ $this->url->stripQueryString();
34
+ $this->url->stripLastSlash();
35
+
36
+ if (preg_match('~press-releases/release-([0-9]+)\.htm~i', $this->url, $matches)) {
37
+ $this->url = new \Embera\Url('http://rwire.com/' . $matches[1]);
38
+ }
39
+ }
40
+ }
41
+
42
+ ?>
library/ostraining/embera/Lib/Embera/Providers/RepubHub.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * RepubHub.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The http://repubhub.icopyright.net Provider
17
+ */
18
+ class RepubHub extends \Embera\Adapters\Service
19
+ {
20
+ /** inline {@inheritdoc} */
21
+ protected $apiUrl = 'http://repubhub.icopyright.net/oembed.act?format=json';
22
+
23
+ /** inline {@inheritdoc} */
24
+ protected function validateUrl()
25
+ {
26
+ return (preg_match('~repubhub\.icopyright\.net/freePost.act\?([^ ]+)~i', $this->url));
27
+ }
28
+ }
29
+
30
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Reverbnation.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Reverbnation.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The reverbnation.com Provider
17
+ * @link https://www.reverbnation.com
18
+ */
19
+ class Reverbnation extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'https://www.reverbnation.com/oembed?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+ $this->url->stripLastSlash();
29
+ $this->url->convertToHttps();
30
+
31
+ $banned = array(
32
+ 'band-promotion',
33
+ 'signup',
34
+ 'pricing',
35
+ 'connect',
36
+ 'termsandconditions',
37
+ 'termsandconditions',
38
+ 'privacy',
39
+ 'copyright',
40
+ 'trademark',
41
+ 'refund',
42
+ 'abuse',
43
+ 'developers',
44
+ 'band-promotion',
45
+ 'industryprofessionals',
46
+ 'fan-promotion',
47
+ 'venue-promotion',
48
+ );
49
+
50
+ $this->url->invalidPattern('(?:\.com/(' . implode('|', $banned) . '))$');
51
+
52
+ return (
53
+ preg_match('~\.com/(?:[^ /]+)$~i', $this->url) ||
54
+ preg_match('~\.com/(?:[^ /]+)/songs?/(?:[^ /]+)$~i', $this->url)
55
+ );
56
+ }
57
+ }
58
+
59
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Revision3.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Revision3.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The Revision3.com Provider
17
+ * @link http://revision3.com
18
+ */
19
+ class Revision3 extends \Embera\Adapters\Service
20
+ {
21
+
22
+ /** inline {@inheritdoc} */
23
+ protected $apiUrl = 'http://revision3.com/api/oembed/?format=json';
24
+
25
+ /** inline {@inheritdoc} */
26
+ protected function validateUrl()
27
+ {
28
+ $this->url->invalidPattern('revision3\.com/(?:network|host|advertise)/');
29
+
30
+ return (preg_match('~revision3\.com/([^/]+)/([^/]+)/?~i', $this->url));
31
+ }
32
+ }
33
+
34
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Roomshare.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Roomshare.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The roomshare.jp Provider
17
+ * @link http://roomshare.jp
18
+ */
19
+ class Roomshare extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://roomshare.jp/en/oembed.json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+
29
+ return (preg_match('~roomshare\.jp/post/(?:[0-9]+)/?$~i', $this->url) ||
30
+ preg_match('~roomshare\.jp/(?:[^/]+)/post/(?:[0-9]+)/?$~i', $this->url) );
31
+ }
32
+ }
33
+
34
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Rutube.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Rutube.php
4
+ *
5
+ * @package Providers
6
+ * @author dotzero <mail@dotzero.ru>
7
+ * @link http://www.dotzero.ru/
8
+ */
9
+
10
+ namespace Embera\Providers;
11
+
12
+ /**
13
+ * The Rutube.ru Provider
14
+ */
15
+ class Rutube extends \Embera\Adapters\Service
16
+ {
17
+ /** inline {@inheritdoc} */
18
+ protected $apiUrl = 'http://rutube.ru/api/oembed/?format=json';
19
+
20
+ /** inline {@inheritdoc} */
21
+ protected function validateUrl()
22
+ {
23
+ $this->url->stripWWW();
24
+ $this->url->stripQueryString();
25
+
26
+ return (preg_match('~\/video\/([a-z0-9]{25,})~i', $this->url));
27
+ }
28
+
29
+ /** inline {@inheritdoc} */
30
+ protected function normalizeUrl()
31
+ {
32
+ $this->url->stripQueryString();
33
+
34
+ if (preg_match('~\/video\/([a-z0-9]{25,})~i', $this->url, $matches)) {
35
+ $this->url = new \Embera\Url('http://rutube.ru/video/' . $matches['1'] . '/');
36
+ }
37
+ }
38
+
39
+ /** inline {@inheritdoc} */
40
+ public function fakeResponse()
41
+ {
42
+ preg_match('~\/video\/([a-z0-9]{25,})~i', $this->url, $matches);
43
+
44
+ return array(
45
+ 'type' => 'video',
46
+ 'provider_name' => 'Rutube',
47
+ 'provider_url' => 'http://rutube.ru',
48
+ 'title' => 'Unknown title',
49
+ 'html' => '<iframe src="//rutube.ru/video/embed/' . $matches['1'] . '" width="{width}" height="{height}" frameborder="0" title="" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>',
50
+ );
51
+ }
52
+ }
library/ostraining/embera/Lib/Embera/Providers/Sapo.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Sapo.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The sapo.pt Provider
17
+ * @link http://videos.sapo.pt
18
+ */
19
+ class Sapo extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://videos.sapo.pt/oembed?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+ $this->url->stripLastSlash();
29
+
30
+ return (preg_match('~sapo\.pt/(?:[\w\d]+)$~i', $this->url));
31
+ }
32
+
33
+ /** inline {@inheritdoc} */
34
+ public function fakeResponse()
35
+ {
36
+ return array(
37
+ 'type' => 'video',
38
+ 'provider_name' => 'Sapo Videos',
39
+ 'provider_url' => 'http://videos.sapo.com',
40
+ 'html' => '<iframe src="http://videos.sapo.pt/playhtml?file=' . $this->url . '/mov/1&quality=sd" frameborder="0" scrolling="no" width="{width}" height="{height}"></iframe>',
41
+ );
42
+ }
43
+ }
44
+
45
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Screenr.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Screenr.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The screenr.com Provider
17
+ * @link http://screenr.com
18
+ */
19
+ class Screenr extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://www.screenr.com/api/oembed.json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+ $this->url->stripLastSlash();
29
+ $this->url->invalidPattern('screenr\.com/(?:record|stream|terms|privacy|help)$');
30
+
31
+ return (preg_match('~screenr\.com/(?:[\w\d]+)$~i', $this->url));
32
+ }
33
+
34
+ /** inline {@inheritdoc} */
35
+ public function fakeResponse()
36
+ {
37
+ preg_match('~/([\w\d]+)$~i', $this->url, $matches);
38
+
39
+ return array(
40
+ 'type' => 'video',
41
+ 'provider_name' => 'Screenr',
42
+ 'provider_url' => 'http://screenr.com',
43
+ 'html' => '<iframe src="http://www.screenr.com/embed/' . $matches['1'] . '" width="{width}" height="{height}" frameborder="0"></iframe>',
44
+ );
45
+ }
46
+ }
47
+
48
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Scribd.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Scribd.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The scribd.com Provider
17
+ * @link http://scribd.com
18
+ */
19
+ class Scribd extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://www.scribd.com/services/oembed/?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+
29
+ return (preg_match('~scribd\.com/doc/(?:[0-9]+)/(?:[^/]+)/?$~i', $this->url));
30
+ }
31
+
32
+ /** inline {@inheritdoc} */
33
+ protected function modifyResponse(array $response = array())
34
+ {
35
+ if (!empty($response['html']))
36
+ {
37
+ $response['html'] = str_replace('#{root_url}', 'http://www.scribd.com/', $response['html']);
38
+ $response['html'] = preg_replace('~\s+~i', ' ', $response['html']); // Remove double spaces
39
+ }
40
+
41
+ return $response;
42
+ }
43
+
44
+ /** inline {@inheritdoc} */
45
+ public function fakeResponse()
46
+ {
47
+ preg_match('~/doc/([\d]+)/~i', $this->url, $matches);
48
+
49
+ return array(
50
+ 'type' => 'rich',
51
+ 'provider_name' => 'Scribd',
52
+ 'provider_url' => 'http://www.scribd.com',
53
+ 'html' => '<iframe class="scribd_iframe_embed" data-aspect-ratio="" frameborder="0" height="{height}" id="' . $matches['1'] . '" scrolling="no" src="http://www.scribd.com/embeds/' . $matches['1'] . '/content" width="100%"></iframe><script type="text/javascript">(function() { var scribd = document.createElement("script"); scribd.type = "text/javascript"; scribd.async = true; scribd.src = "http://www.scribd.com/javascripts/embed_code/inject.js"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(scribd, s); })();</script>',
54
+ );
55
+ }
56
+ }
57
+
58
+ ?>
library/ostraining/embera/Lib/Embera/Providers/ShortNote.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ShortNote.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The shortnote.jp Provider
17
+ * @link https://www.shortnote.jp
18
+ */
19
+ class ShortNote extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'https://www.shortnote.jp/oembed/?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->convertToHttps();
28
+ $this->url->addWWW();
29
+ $this->url->stripLastSlash();
30
+
31
+ return (preg_match('~shortnote\.jp/view/notes/(?:[^ /]+)$~is', $this->url));
32
+ }
33
+
34
+
35
+ /** inline {@inheritdoc} */
36
+ public function fakeResponse()
37
+ {
38
+ preg_match('~/view/notes/([^ /]+)~i', $this->url, $matches);
39
+
40
+ return array(
41
+ 'type' => 'rich',
42
+ 'provider_name' => 'ShortNote',
43
+ 'provider_url' => 'https://www.shortnote.jp/',
44
+ 'html' => '<iframe src="https://www.shortnote.jp/view/notes/' . $matches['1'] . '/embed" frameborder="0" width="{width}" height="{height}"></iframe>',
45
+ );
46
+ }
47
+ }
48
+
49
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Shoudio.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Shoudio.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The shoudio.com Provider
17
+ * @link http://shoudio.com
18
+ */
19
+ class Shoudio extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://shoudio.com/api/oembed?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripLastSlash();
28
+ $this->url->stripWWW();
29
+
30
+ return (preg_match('~shoudio\.com/(?:user|channel|venue|collection)/(?:.+)~i', $this->url) ||
31
+ preg_match('~shoud\.io/(?:[0-9]+)$~i', $this->url));
32
+ }
33
+ }
34
+
35
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Showtheway.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Showtheway.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The Showtheway Provider
17
+ * @link https://showtheway.io/
18
+ */
19
+ class Showtheway extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'https://showtheway.io/oembed?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripWWW();
28
+ $this->url->convertToHttps();
29
+
30
+ return (preg_match('~showtheway\.io/to/(?:[^/]+)$~i', $this->url));
31
+ }
32
+ }
33
+
34
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Silk.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Silk.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The silk.co Provider
17
+ * @link https://silk.co
18
+ */
19
+ class Silk extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://www.silk.co/oembed/?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+ return (preg_match('~silk\.co/(?:explore|s/embed)/(?:[^ ]+)$~i', $this->url));
29
+ }
30
+
31
+ /** inline {@inheritdoc} */
32
+ public function fakeResponse()
33
+ {
34
+ $url = preg_replace('~^https?://~i', '//', $this->url);
35
+ $url = preg_replace('~\.silk\.co/(?:explore)/~i', '.silk.co/s/embed/', $url);
36
+
37
+ $html = '<div style="display: inline-block; width: 100%; min-height: {height}px;">';
38
+ $html .= '<div style="position: relative; padding-bottom: 100%; padding-top:25px; height: 0;">';
39
+ $html .= '<iframe src="' . $url . '?oembed=" style="border:0;position: absolute; top:0; left:0; width: 100%;height:100%; min-height: {height}px;"></iframe>';
40
+ $html .= '</div></div>';
41
+
42
+ return array(
43
+ 'type' => 'rich',
44
+ 'provider_name' => 'Silk.co',
45
+ 'provider_url' => 'https://silk.co',
46
+ 'html' => $html,
47
+ );
48
+ }
49
+ }
50
+
51
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Sketchfab.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Sketchfab.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The sketchfab.com Provider
17
+ * @link http://sketchfab.com
18
+ */
19
+ class Sketchfab extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'https://sketchfab.com/oembed';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripLastSlash();
28
+
29
+ return (
30
+ preg_match('~sketchfab\.com/models/(?:[^/]+)$~i', $this->url) ||
31
+ preg_match('~sketchfab\.com/(?:[^/]+)/folders/(?:[^/]+)$~i', $this->url)
32
+ );
33
+ }
34
+
35
+ /** inline {@inheritdoc} */
36
+ protected function normalizeUrl()
37
+ {
38
+ $this->url->stripWWW();
39
+ $this->url->convertToHttps();
40
+
41
+ // old urls
42
+ if (preg_match('~sketchfab\.com/show/([^/]+)/?$~i', $this->url, $matches)) {
43
+ $this->url = new \Embera\Url('https://sketchfab.com/models/' . $matches[1]);
44
+ } else if (preg_match('~(/embed/?)$~', $this->url)) {
45
+ $this->url = new \Embera\Url(preg_replace('~(/embed/?)$~', '', $this->url));
46
+ }
47
+ }
48
+
49
+ /** inline {@inheritdoc} */
50
+ protected function modifyResponse(array $response = array())
51
+ {
52
+ if (!empty($response['html'])) {
53
+ $response['html'] = preg_replace('~<p(.*)>(.*)</p>~is', '', $response['html']);
54
+ }
55
+
56
+ return $response;
57
+ }
58
+
59
+ /** inline {@inheritdoc} */
60
+ public function fakeResponse()
61
+ {
62
+ if (preg_match('~sketchfab\.com/(?:[^/]+)/folders/([^/]+)$~i', $this->url, $m)) {
63
+ $url = 'https://sketchfab.com/playlists/embed?folder=' . $m['1'];
64
+ } else {
65
+ $url = str_replace('/show/', '/embed/', $this->url) . '/embed';
66
+ }
67
+
68
+ return array(
69
+ 'type' => 'rich',
70
+ 'provider_name' => 'Sketchfab',
71
+ 'provider_url' => 'http://sketchfab.com',
72
+ 'html' => '<iframe width="{width}" height="{height}" src="' . $url . '" frameborder="0" allowfullscreen mozallowfullscreen="true" webkitallowfullscreen="true" onmousewheel=""></iframe>'
73
+ );
74
+ }
75
+ }
76
+
77
+ ?>
library/ostraining/embera/Lib/Embera/Providers/SlideShare.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SlideShare.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The slideshare.net Provider
17
+ * @link http://www.slideshare.net/developers/oembed
18
+ * @link http://www.slideshare.net
19
+ */
20
+ class SlideShare extends \Embera\Adapters\Service
21
+ {
22
+ /** inline {@inheritdoc} */
23
+ protected $apiUrl = 'http://www.slideshare.net/api/oembed/2?format=json';
24
+
25
+ /** inline {@inheritdoc} */
26
+ protected function validateUrl()
27
+ {
28
+ // urls with the about|newlist stuff in the middle dont work
29
+ $this->url->invalidPattern('slideshare\.net/(?:about|newlist)/(?:[\w\d_-]+)/?$');
30
+
31
+ return (preg_match('~slideshare\.net/(?:[\w\d_-]+)/(?:[\w\d_-]+)/?$~i', $this->url));
32
+ }
33
+ }
34
+
35
+ ?>
library/ostraining/embera/Lib/Embera/Providers/SoundCloud.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SoundCloud.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The soundcloud.com Provider
17
+ * @link http://soundcloud.com
18
+ */
19
+ class SoundCloud extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'https://soundcloud.com/oembed?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripLastSlash();
28
+ $this->url->invalidPattern('soundcloud\.com/(explore|creators|groups)/?$');
29
+
30
+ return (preg_match('~soundcloud\.com/(?:[\w\d\-_]+)~i', $this->url));
31
+ }
32
+ }
33
+
34
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Speakerdeck.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Speakerdeck.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The speakerdeck.com Provider
17
+ * @link http://speakerdeck.com
18
+ */
19
+ class Speakerdeck extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'https://speakerdeck.com/oembed.json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ return (preg_match('~speakerdeck\.com/([^/]{2,})/([^/]+)/?$~i', $this->url));
28
+ }
29
+ }
30
+
31
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Spotify.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Spotify.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The spotify.com Provider
17
+ */
18
+ class Spotify extends \Embera\Adapters\Service
19
+ {
20
+ /** inline {@inheritdoc} */
21
+ protected $apiUrl = 'https://embed.spotify.com/oembed/';
22
+
23
+ /** inline {@inheritdoc} */
24
+ protected function validateUrl()
25
+ {
26
+ return (
27
+ preg_match('~spotify\.com/(?:track|album)/(?:[^/]+)(?:/[^/]*)?$~i', $this->url) ||
28
+ preg_match('~spotify\.com/user/(?:[^/]+)/playlist/(?:[^/]+)/?$~i', $this->url) ||
29
+ preg_match('~spoti\.fi/(?:[^/]+)$~i', $this->url)
30
+ );
31
+ }
32
+
33
+ /** inline {@inheritdoc} */
34
+ protected function normalizeUrl()
35
+ {
36
+ $this->url->convertToHttps();
37
+ $this->url->stripQueryString();
38
+ $this->url->stripLastSlash();
39
+
40
+ if (preg_match('~spotify\.com/(track|album)/([^/]+)/(?:[^/]*)$~i', $this->url, $matches)) {
41
+ $this->url = new \Embera\Url('https://play.spotify.com/' . $matches['1'] . '/' . $matches['2']);
42
+ }
43
+
44
+ }
45
+
46
+ /** inline {@inheritdoc} */
47
+ public function fakeResponse()
48
+ {
49
+ if (preg_match('~spoti\.fi~i', $this->url)) {
50
+ return array();
51
+ }
52
+
53
+ preg_match('~/(track|album|user)/.+~i', $this->url, $matches);
54
+ $code = str_replace('/', ':', rtrim($matches['0'], '/ '));
55
+
56
+ return array(
57
+ 'type' => 'rich',
58
+ 'provider_name' => 'Spotify',
59
+ 'provider_url' => 'https://www.spotify.com',
60
+ 'title' => 'Unknown title',
61
+ 'html' => '<iframe src="https://embed.spotify.com/?uri=spotify' . $code . '" width="{width}" height="{height}" frameborder="0" allowtransparency="true"></iframe>',
62
+ );
63
+ }
64
+ }
65
+
66
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Sway.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Sway.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The sway.com Provider
17
+ * @link https://sway.com
18
+ */
19
+ class Sway extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'https://sway.com/api/v1.0/oembed?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripWWW();
28
+ $this->url->stripQueryString();
29
+ $this->url->stripLastSlash();
30
+ $this->url->convertToHttps();
31
+
32
+ return (preg_match('~sway\.com/([^ /]+)$~i', $this->url));
33
+ }
34
+
35
+ /** inline {@inheritdoc} */
36
+ public function fakeResponse()
37
+ {
38
+ $url = 'https://sway.com/s/' . trim(str_replace('https://sway.com/', '', $this->url), ' /') . '/embed';
39
+ $html = '<iframe width="{width}" height="{height}" src="' . $url . '" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border: none; max-width:100%; max-height:100vh" allowfullscreen webkitallowfullscreen mozallowfullscreen msallowfullscreen></iframe>';
40
+
41
+ return array(
42
+ 'type' => 'rich',
43
+ 'provider_name' => 'Sway.co',
44
+ 'provider_url' => 'https://sway.com',
45
+ 'html' => $html,
46
+ );
47
+ }
48
+ }
49
+
50
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Ted.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Ted.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The ted.com Provider
17
+ * @link http://ted.com
18
+ */
19
+ class Ted extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://www.ted.com/talks/oembed.json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ return (preg_match('~ted\.com/talks/(?:.*)\.html$~i', $this->url));
28
+ }
29
+
30
+ /** inline {@inheritdoc} */
31
+ public function fakeResponse()
32
+ {
33
+ $url = preg_replace('~http(?:.*)ted\.com/~i', 'http://embed.ted.com/$1', $this->url);
34
+ return array(
35
+ 'type' => 'video',
36
+ 'provider_name' => 'TED',
37
+ 'provider_url' => 'http://ted.com',
38
+ 'html' => '<iframe src="' . $url . '" width="{width}" height="{height}" frameborder="0" scrolling="no" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe',
39
+ );
40
+ }
41
+ }
42
+
43
+ ?>
library/ostraining/embera/Lib/Embera/Providers/TheySaidSo.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TheySaidSo.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The TheySaidSo.com Provider
17
+ * @link https://theysaidso.com
18
+ */
19
+ class TheySaidSo extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'https://theysaidso.com/extensions/oembed?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+ $this->url->stripLastSlash();
29
+ $this->url->stripWWW();
30
+ $this->url->convertToHttps();
31
+
32
+ return (preg_match('~theysaidso\.com/(?:i|quote)/(?:[^/]+)$~i', $this->url));
33
+ }
34
+
35
+ /** inline {@inheritdoc} */
36
+ protected function modifyResponse(array $response = array())
37
+ {
38
+ if (empty($response['html'])) {
39
+ if ($response['type'] == 'photo') {
40
+ $response['html'] = sprintf('<img src="%s" alt="" title="" class="embera-img-theysaidso" />', $response['url']);
41
+ } else {
42
+ $response['html'] = sprintf('<a href="%s" class="embera-link-theysaidso" title="">%s</a>', $response['url'], $response['url']);
43
+ }
44
+ }
45
+
46
+ return $response;
47
+ }
48
+ }
49
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Twitter.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Twitter.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The twitter.com Provider
17
+ * @link https://twitter.com
18
+ */
19
+ class Twitter extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'https://api.twitter.com/1/statuses/oembed.json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripLastSlash();
28
+
29
+ return (preg_match('~twitter\.com/(?:[\w\d-_]+)/status/(?:[0-9]+)~i', $this->url));
30
+ }
31
+
32
+ /** inline {@inheritdoc} */
33
+ protected function normalizeUrl()
34
+ {
35
+ if (preg_match('~twitter\.com/(?:\#\!|/)?([\w\d-_]+)/status/([0-9]+)~i', $this->url, $matches))
36
+ $this->url = new \Embera\Url('https://twitter.com/' . $matches['1'] . '/status/' . $matches['2']);
37
+ }
38
+ }
39
+
40
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Ustream.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Ustream.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The ustream.tv|com Provider
17
+ * @link http://ustream.tv
18
+ */
19
+ class Ustream extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://www.ustream.tv/oembed';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripLastSlash();
28
+ $this->url->invalidPattern('ustream\.(?:com|tv)/(?:explore|howto|upcomming|our-company|services|premium-membership|search)$');
29
+
30
+ return (preg_match('~ustream\.(?:com|tv)/channel/(?:[\w\d\-_]+)$~i', $this->url) ||
31
+ preg_match('~ustream\.(?:com|tv)/recorded/(?:[\w\d\-_]+)$~i', $this->url) ||
32
+ preg_match('~ustream\.(?:com|tv)/(?:[\w\d\-_]+)$~i', $this->url));
33
+ }
34
+ }
35
+
36
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Verse.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Verse.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The Verse Media Provider
17
+ * @link https://verse.media
18
+ */
19
+ class Verse extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://verse.media/services/oembed/?format=json';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripWWW();
28
+ $this->url->stripQueryString();
29
+ return (preg_match('~verse\.media/stories/(?:[^ ]+)$~i', $this->url));
30
+ }
31
+
32
+ /** inline {@inheritdoc} */
33
+ public function fakeResponse()
34
+ {
35
+ $html = '<div class="verse-player-embed">';
36
+ $html .= '<style>.verse-player-embed {position: relative; padding-bottom: calc(56.25% + 55px); height: 0; overflow: hidden; max-width: 100%; } .verse-player-embed iframe, .verse-player-embed object, .verse-player-embed embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }</style>';
37
+ $html .= '<iframe src="' . $this->url . '" frameborder="0" allowfullscreen ></iframe>';
38
+ $html .= '</div>';
39
+
40
+ return array(
41
+ 'type' => 'video',
42
+ 'provider_name' => 'Verse',
43
+ 'provider_url' => 'http://verse.media',
44
+ 'html' => $html,
45
+ );
46
+ }
47
+ }
48
+
49
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Viddler.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Viddler.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The Viddler.com Provider
17
+ */
18
+ class Viddler extends \Embera\Adapters\Service
19
+ {
20
+ /** inline {@inheritdoc} */
21
+ protected $apiUrl = 'http://www.viddler.com/oembed/?format=json';
22
+
23
+ /** inline {@inheritdoc} */
24
+ protected function validateUrl()
25
+ {
26
+ $this->url->addWWW();
27
+
28
+ return (preg_match('~viddler\.com/(?:v|embed)/(?:[0-9a-f]{7,12})/?$~i', $this->url));
29
+ }
30
+
31
+ /** inline {@inheritdoc} */
32
+ protected function normalizeUrl()
33
+ {
34
+ if (preg_match('~viddler\.com/(?:embed|v)/([^/]+)/?~i', $this->url, $matches))
35
+ $this->url = new \Embera\Url('http://www.viddler.com/v/' . $matches['1']);
36
+ }
37
+
38
+ /** inline {@inheritdoc} */
39
+ public function fakeResponse()
40
+ {
41
+ preg_match('~/(?:v|embed)/([0-9a-f]{7,12})/?~i', $this->url, $matches);
42
+
43
+ return array(
44
+ 'type' => 'video',
45
+ 'provider_name' => 'Viddler',
46
+ 'provider_url' => 'http://www.viddler.com',
47
+ 'title' => 'Unknown title',
48
+ 'html' => '<iframe width="{width}" height="{height}" src="http://viddler.com/embed/' . $matches['1'] . '" frameborder="0" allowfullscreen></iframe>',
49
+ );
50
+ }
51
+ }
52
+
53
+ ?>
library/ostraining/embera/Lib/Embera/Providers/VideoFork.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * VideoFork.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The videofork.com Provider
17
+ */
18
+ class VideoFork extends \Embera\Adapters\Service
19
+ {
20
+ /**
21
+ * inline {@inheritdoc}
22
+ *
23
+ * This services doesnt have one single endpoint, but instead
24
+ * every video has its own oembed url based on the id of the
25
+ * video.
26
+ */
27
+ protected $apiUrl = 'http://videofork.com/oembed/';
28
+
29
+ /** inline {@inheritdoc} */
30
+ protected function validateUrl()
31
+ {
32
+ return (preg_match('~videofork\.com/(?:play|oembed)/(?:[0-9]+)$~i', $this->url));
33
+ }
34
+
35
+ /** inline {@inheritdoc} */
36
+ protected function normalizeUrl()
37
+ {
38
+ if (preg_match('~/(?:play|oembed)/([0-9]+)~i', $this->url, $matches)) {
39
+ // Overwrite the oembed endpoint with a valid one
40
+ $this->apiUrl = 'http://videofork.com/oembed/' . $matches['1'];
41
+ $this->url = new \Embera\Url('http://videofork.com/play/' . $matches['1']);
42
+ }
43
+ }
44
+
45
+ /** inline {@inheritdoc} */
46
+ public function fakeResponse()
47
+ {
48
+ $url = str_replace('/play/', '/embed/', $this->url);
49
+
50
+ return array(
51
+ 'type' => 'video',
52
+ 'provider_name' => 'VideoFork',
53
+ 'provider_url' => 'http://videofork.com',
54
+ 'html' => '<object width="{width}" height="{height}"> <param name="movie" value="' . $url . '"></param> <param name="allowFullScreen" value="true"></param> <param name="allowscriptaccess" value="always"></param> <embed src="' . $url . '" type="application/x-shockwave-flash" width="{width}" height="{height}" allowscriptaccess="always" allowfullscreen="true"></embed> </object>',
55
+ );
56
+ }
57
+ }
58
+
59
+ ?>
library/ostraining/embera/Lib/Embera/Providers/VideoJug.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * VideoJug.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The videojug.com Provider
17
+ */
18
+ class VideoJug extends \Embera\Adapters\Service
19
+ {
20
+ /** inline {@inheritdoc} */
21
+ protected $apiUrl = 'http://www.videojug.com/oembed.json';
22
+
23
+ /** inline {@inheritdoc} */
24
+ protected function validateUrl()
25
+ {
26
+ $this->url->stripLastSlash();
27
+
28
+ return (preg_match('~videojug\.com/(?:interview|film)/(?:[^/]+)$~i', $this->url));
29
+ }
30
+ }
31
+
32
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Vimeo.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Vimeo.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The Vimeo.com Provider
17
+ */
18
+ class Vimeo extends \Embera\Adapters\Service
19
+ {
20
+ /** inline {@inheritdoc} */
21
+ protected $apiUrl = 'http://vimeo.com/api/oembed.json';
22
+
23
+ /** inline {@inheritdoc} */
24
+ protected function validateUrl()
25
+ {
26
+ $this->url->stripWWW();
27
+ $this->url->stripLastSlash();
28
+
29
+ return (preg_match('~/(?:[0-9]{5,12})$~i', $this->url));
30
+ }
31
+
32
+ /** inline {@inheritdoc} */
33
+ protected function normalizeUrl()
34
+ {
35
+ $this->url->stripQueryString();
36
+
37
+ if (preg_match('~/([0-9]{5,12})/?$~i', $this->url, $matches))
38
+ $this->url = new \Embera\Url('http://vimeo.com/' . $matches['1']);
39
+ }
40
+
41
+ /** inline {@inheritdoc} */
42
+ public function fakeResponse()
43
+ {
44
+ preg_match('~/([0-9]{5,12})$~i', $this->url, $matches);
45
+
46
+ return array(
47
+ 'type' => 'video',
48
+ 'provider_name' => 'Vimeo',
49
+ 'provider_url' => 'http://www.vimeo.com',
50
+ 'title' => 'Unknown title',
51
+ 'html' => '<iframe src="http://player.vimeo.com/' . $matches['1'] . '" width="{width}" height="{height}" frameborder="0" title="" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>',
52
+ );
53
+ }
54
+ }
55
+
56
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Vine.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Vine.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The vine.co Provider
17
+ * @link https://vine.co
18
+ * @link https://dev.twitter.com/web/vine/oembed
19
+ */
20
+ class Vine extends \Embera\Adapters\Service
21
+ {
22
+ /** inline {@inheritdoc} */
23
+ protected $apiUrl = 'https://vine.co/oembed.json';
24
+
25
+ /** inline {@inheritdoc} */
26
+ protected function validateUrl()
27
+ {
28
+ $this->url->stripQueryString();
29
+ $this->url->stripLastSlash();
30
+ $this->url->convertToHttps();
31
+
32
+ return (preg_match('~vine\.co/v/(?:[^/]+)$~i', $this->url));
33
+ }
34
+
35
+ /** inline {@inheritdoc} */
36
+ public function fakeResponse()
37
+ {
38
+ return array(
39
+ 'type' => 'video',
40
+ 'provider_name' => 'Vine',
41
+ 'provider_url' => 'https://vine.co',
42
+ 'title' => 'Unknown title',
43
+ 'html' => '<iframe class="vine-embed" src="' . (string) $this->url . '/embed/simple" width="{width}" height="{height}" frameborder="0"></iframe><script async src="//platform.vine.co/static/scripts/embed.js"></script>',
44
+ );
45
+ }
46
+ }
47
+
48
+ ?>
library/ostraining/embera/Lib/Embera/Providers/WordpressTV.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WordpressTV.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The wordpress.tv Provider
17
+ */
18
+ class WordpressTV extends \Embera\Adapters\Service
19
+ {
20
+ /** inline {@inheritdoc} */
21
+ protected $apiUrl = 'http://public-api.wordpress.com/oembed/1.0/?format=json&for=wpcom-auto-discovery';
22
+
23
+ /** inline {@inheritdoc} */
24
+ protected function validateUrl()
25
+ {
26
+ return (preg_match('~wordpress\.tv/(?:[0-9]+)/(?:[0-9]+)/(?:[0-9]+)/(?:[^/]+)/?$~i', $this->url));
27
+ }
28
+ }
29
+
30
+ ?>
library/ostraining/embera/Lib/Embera/Providers/YFrog.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * YFrog.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The yfrog.com|yfrog.us Provider
17
+ * @link http://yfrog.com
18
+ */
19
+ class YFrog extends \Embera\Adapters\Service
20
+ {
21
+ /** inline {@inheritdoc} */
22
+ protected $apiUrl = 'http://www.yfrog.com/api/oembed';
23
+
24
+ /** inline {@inheritdoc} */
25
+ protected function validateUrl()
26
+ {
27
+ $this->url->stripQueryString();
28
+ $this->url->stripLastSlash();
29
+
30
+ return (preg_match('~yfrog\.(?:com|us)/([\w\d]{7,})$~i', $this->url));
31
+ }
32
+
33
+ /** inline {@inheritdoc} */
34
+ protected function modifyResponse(array $response = array())
35
+ {
36
+ if (empty($response['html']))
37
+ $response['html'] = '<a href="' . $this->url . '" target="_blank"><img class="yfrog-oembed" src="' . $response['thumbnail_url'] . '" alt=""></a>';
38
+
39
+ return $response;
40
+ }
41
+ }
42
+
43
+ ?>
library/ostraining/embera/Lib/Embera/Providers/Yandex.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Yandex.php
4
+ *
5
+ * @package Providers
6
+ * @author dotzero <mail@dotzero.ru>
7
+ * @link http://www.dotzero.ru/
8
+ */
9
+
10
+ namespace Embera\Providers;
11
+
12
+ /**
13
+ * The Yandex.ru Provider
14
+ */
15
+ class Yandex extends \Embera\Adapters\Service
16
+ {
17
+ /** inline {@inheritdoc} */
18
+ protected $apiUrl = 'http://video.yandex.ru/oembed.json';
19
+
20
+ /** inline {@inheritdoc} */
21
+ protected function validateUrl()
22
+ {
23
+ $this->url->stripQueryString();
24
+
25
+ return (preg_match('~\/users\/([a-zA-Z0-9\_\.-]+)\/view\/([0-9]+)~i', $this->url));
26
+ }
27
+
28
+ /** inline {@inheritdoc} */
29
+ protected function normalizeUrl()
30
+ {
31
+ $this->url->stripQueryString();
32
+
33
+ if (preg_match('~\/users\/([a-zA-Z0-9\_\.-]+)\/view\/([0-9]+)~i', $this->url, $matches)) {
34
+ $this->url = new \Embera\Url('http://video.yandex.ru/users/' . $matches['1'] . '/view/' . $matches['2'] . '/');
35
+ }
36
+ }
37
+ }
library/ostraining/embera/Lib/Embera/Providers/Youtube.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Yotube.php
4
+ *
5
+ * @package Providers
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera\Providers;
14
+
15
+ /**
16
+ * The youtube.com Provider
17
+ */
18
+ class Youtube extends \Embera\Adapters\Service
19
+ {
20
+ /** inline {@inheritdoc} */
21
+ protected $apiUrl = 'http://www.youtube.com/oembed?format=json';
22
+
23
+ /** inline {@inheritdoc} */
24
+ protected function validateUrl()
25
+ {
26
+ return (preg_match('~v=(?:[a-z0-9_-]+)~i', $this->url));
27
+ }
28
+
29
+ /** inline {@inheritdoc} */
30
+ protected function normalizeUrl()
31
+ {
32
+ if (preg_match('~(?:v=|youtu\.be/|youtube\.com/embed/)([a-z0-9_-]+)~i', $this->url, $matches)) {
33
+ $this->url = new \Embera\Url('http://www.youtube.com/watch?v=' . $matches[1]);
34
+ }
35
+ }
36
+
37
+ /** inline {@inheritdoc} */
38
+ public function fakeResponse()
39
+ {
40
+ preg_match('~v=([a-z0-9_-]+)~i', $this->url, $matches);
41
+
42
+ return array(
43
+ 'type' => 'video',
44
+ 'provider_name' => 'Youtube',
45
+ 'provider_url' => 'http://www.youtube.com',
46
+ 'title' => 'Unknown title',
47
+ 'html' => '<iframe width="{width}" height="{height}" src="//www.youtube.com/embed/' . $matches['1'] . '" frameborder="0" allowfullscreen></iframe>',
48
+ );
49
+ }
50
+ }
51
+
52
+ ?>
library/ostraining/embera/Lib/Embera/Url.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Url.php
4
+ *
5
+ * @package Embera
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Embera;
14
+
15
+ /**
16
+ * This class is used to preform common/popular
17
+ * tasks into a url string
18
+ */
19
+ class Url
20
+ {
21
+ /** @var string The url */
22
+ protected $url;
23
+
24
+ /** @var string Placeholder for the original url */
25
+ protected $original;
26
+
27
+ /**
28
+ * Construct
29
+ *
30
+ * @param string $url A valid url string
31
+ * @return void
32
+ */
33
+ public function __construct($url) { $this->url = $this->original = preg_replace('~^embed:~i', 'http:', $url); }
34
+
35
+ /**
36
+ * Returns the full url when
37
+ * the object is casted into a string
38
+ *
39
+ * @return string
40
+ */
41
+ public function __toString() { return $this->url; }
42
+
43
+ /**
44
+ * Searches the url for a pattern $pattern.
45
+ * If the pattern matches, the url is marked as invalid
46
+ * and is emptied.
47
+ *
48
+ * @param string $pattern
49
+ * @return void
50
+ */
51
+ public function invalidPattern($pattern)
52
+ {
53
+ if (preg_match('~' . $pattern . '~i', $this->url))
54
+ $this->url = '';
55
+ }
56
+
57
+ /**
58
+ * Overwrites the value of $this->url with
59
+ * the given parameter.
60
+ *
61
+ * @param string $url
62
+ * @return void
63
+ */
64
+ public function overwrite($url) { $this->url = $url; }
65
+
66
+ /**
67
+ * Discards changes made to a url, and goes back to the original
68
+ * url.
69
+ *
70
+ * @return void
71
+ */
72
+ public function discardChanges() { $this->url = $this->original; }
73
+
74
+ /**
75
+ * Strips the query string from the url
76
+ *
77
+ * @return void
78
+ */
79
+ public function stripQueryString() { $this->url = preg_replace('~(\?|#)(.*)$~i', '', $this->url); }
80
+
81
+ /**
82
+ * Strips the / at the end of a url
83
+ *
84
+ * @return void
85
+ */
86
+ public function stripLastSlash() { $this->url = rtrim($this->url, '/'); }
87
+
88
+ /**
89
+ * Strips starting www from the url
90
+ *
91
+ * @return void
92
+ */
93
+ public function stripWWW() { $this->url = str_ireplace('://www.', '://', $this->url); }
94
+
95
+ /**
96
+ * Adds www. subdomain to the urls
97
+ *
98
+ * @return void
99
+ */
100
+ public function addWWW()
101
+ {
102
+ if (!preg_match('~^https?://www\.~i', $this->url))
103
+ $this->url = str_ireplace('://', '://www.', $this->url);
104
+ }
105
+
106
+ /**
107
+ * Replaces https protocol to http
108
+ *
109
+ * @return void
110
+ */
111
+ public function convertToHttp() { $this->url = str_ireplace('https://', 'http://', $this->url); }
112
+
113
+ /**
114
+ * Replaces http protocol to https
115
+ *
116
+ * @return void
117
+ */
118
+ public function convertToHttps() { $this->url = str_ireplace('http://', 'https://', $this->url); }
119
+ }
120
+
121
+ ?>
library/ostraining/embera/PROVIDERS.md ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Supported Sites
2
+ ===============
3
+ This is the complete list of supported providers.
4
+ Sites marked with an `*` allow offline html embedding.
5
+
6
+ - [23hq](http://23hq.com)
7
+ - [AmCharts](http://live.amcharts.com)
8
+ - [Animatron](https://animatron.com)
9
+ - [Animoto](http://animoto.com)
10
+ - * [Aol On](http://on.aol.com) (which is also [5min.com](http://5min.com))
11
+ - [Alpha App.NET](https://alpha.app.net)
12
+ - * [AudioSnaps](http://audiosnaps.com/)
13
+ - * [Bambuser](http://bambuser.com)
14
+ - [BlipTV](http://blip.tv)
15
+ - * [Cacoo](http://cacoo.com)
16
+ - * [ChartBlocks](http://chartblocks.com)
17
+ - * [Chirbit](http://chirb.it)
18
+ - [Clyp](http://clyp.it)
19
+ - * [Codepoints](https://codepoints.net)
20
+ - * [CircuitLab](https://www.circuitlab.com)
21
+ - * [CollegeHumor](http://www.collegehumor.com)
22
+ - * [Coub](http://coub.com)
23
+ - * [Crowd Ranking](http://crowdranking.com)
24
+ - [Daily Mile](http://dailymile.com)
25
+ - * [DailyMotion](http://www.dailymotion.com/)
26
+ - [Deviantart](http://deviantart.com)
27
+ - * [Dipity](http://dipity.com)
28
+ - * [Dotsub](http://dotsub.com)
29
+ - [Edocr](http://edocr.com)
30
+ - [EgliseInfo](http://egliseinfo.catholique.fr)
31
+ - [Facebook](https://facebook.com) (Public Posts)
32
+ - [Flickr](http://flickr.com)
33
+ - * [Funny Or Die](http://www.funnyordie.com)
34
+ - [Geograph Channel Islands](http://channel-islands.geographs.org)
35
+ - [Geograph DE](http://geo-en.hlipp.de)
36
+ - [Geograph UK](http://geograph.org.uk)
37
+ - [GettyImages](http://www.gettyimages.com)
38
+ - * [Gfycat](http://gfycat.com)
39
+ - * [Github Gist](https://gist.github.com)
40
+ - [Gmep](http://gmep.org)
41
+ - [HuffDuffer](http://huffduffer.com)
42
+ - [Hulu](http://www.hulu.com)
43
+ - * [IFixIT](http://ifixit.com)
44
+ - * [IFTTT](http://ifttt.com)
45
+ - [Infogram](https://infogr.am)
46
+ - [Instagram](http://instagram.com)
47
+ - * [Issuu](https://issuu.com) (Offline response available only when the url has the `e` parameter)
48
+ - * [Kickstarter](http://www.kickstarter.com)
49
+ - [LearningApps](http://learningapps.org)
50
+ - [Meetup](http://meetup.com)
51
+ - [MixCloud](http://mixcloud.com)
52
+ - [MobyPicture](http://mobypicture.com)
53
+ - * [NFB](http://www.nfb.ca)
54
+ - * [OfficeMix](http://mix.office.com)
55
+ - * [OfficialFM](http://official.fm)
56
+ - * [Oumy](https://www.oumy.com)
57
+ - [Pastery](https://www.pastery.net)
58
+ - * [PollDaddy](http://polldaddy.com)
59
+ - [PollEveryWhere](http://www.polleverywhere.com)
60
+ - [Porfolium](https://portfolium.com)
61
+ - [Rapidengage](https://rapidengage.com/)
62
+ - [Rdio](http://rdio.com)
63
+ - [Release Wire](http://releasewire.com)
64
+ - [RepubHub](http://repubhub.icopyright.net)
65
+ - [Reverbnation](https://www.reverbnation.com)
66
+ - [Revision3](http://revision3.com)
67
+ - [Roomshare](http://roomshare.jp)
68
+ - * [Sapo Videos](http://videos.sapo.pt)
69
+ - * [Screenr](http://www.screenr.com)
70
+ - * [Scribd](http://www.scribd.com)
71
+ - * [ShortNote](https://www.shortnote.jp)
72
+ - * [Rutube](https://rutube.ru)
73
+ - [Shoudio](http://shoudio.com)
74
+ - [ShowTheWay](http://showtheway.io)
75
+ - * [Silk](https://silk.co)
76
+ - * [Sketchfab](http://sketchfab.com)
77
+ - [SlideShare](http://www.slideshare.net)
78
+ - [SoundCloud](http://soundcloud.com)
79
+ - [SpeakerDeck](https://speackerdeck.com)
80
+ - * [Spotify](http://spotify.com)
81
+ - * [Sway](https://sway.com)
82
+ - * [Ted](http://ted.com)
83
+ - [TheySaidSo](https://theysaidso.com)
84
+ - [Twitter](https://twitter.com)
85
+ - [Ustream](http://ustream.tv)
86
+ - * [Verse](http://verse.media)
87
+ - * [Viddler](http://www.viddler.com)
88
+ - * [VideoFork](http://videofork.com)
89
+ - [VideoJug](http://www.videojug.com)
90
+ - * [Vimeo](http://vimeo.com/)
91
+ - * [Vine](http://vine.co/)
92
+ - [WordpressTV](http://wordpress.tv)
93
+ - [Yandex.Video](http://video.yandex.ru)
94
+ - [yfrog.com](http://yfrog.com)
95
+ - * [Youtube](http://www.youtube.com/)
library/ostraining/embera/README.md ADDED
@@ -0,0 +1,363 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Embera
2
+ ======
3
+ [![Build Status](https://secure.travis-ci.org/mpratt/Embera.png?branch=master)](http://travis-ci.org/mpratt/Embera) [![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/mpratt/Embera/badges/quality-score.png?s=6122b04c188cd1d245088484966600f2ccb549fb)](https://scrutinizer-ci.com/g/mpratt/Embera/) [![Code Coverage](https://scrutinizer-ci.com/g/mpratt/Embera/badges/coverage.png?s=4cb389493e1806afc497bc53699538454502ea49)](https://scrutinizer-ci.com/g/mpratt/Embera/) [![Latest Stable Version](https://poser.pugx.org/mpratt/embera/v/stable.png)](https://packagist.org/packages/mpratt/embera) [![Total Downloads](https://poser.pugx.org/mpratt/embera/downloads.png)](https://packagist.org/packages/mpratt/embera)
4
+
5
+ Embera is a [Oembed](http://oembed.com/) consumer library written in PHP. Basically what it does is take urls from a text and queries the matching
6
+ service for information about the media.
7
+
8
+ If you are like me, in most cases all you want is to convert a simple Url to a valid html embed code. Now, the sweet thing about Embera, is that
9
+ some providers allow you to skip the part about making the request to a Oembed Provider and still get a valid html embed code! Read the `Offline Support`
10
+ section for more information.
11
+
12
+ On the other hand, there are some oembed providers that dont return html embedable code - Embera detects this and most of the time, it tries to generate
13
+ a valid html code for you to use.
14
+
15
+ Check out the `Basic Usage` instructions for more information.
16
+
17
+ Supported Sites
18
+ ===============
19
+ Embera supports **60+** sites. Sites marked with an `*` allow offline html embedding
20
+
21
+ - * [Youtube](http://www.youtube.com/)
22
+ - * [Vimeo](http://vimeo.com/)
23
+ - * [DailyMotion](http://www.dailymotion.com/)
24
+ - [Instagram](http://instagram.com)
25
+ - [SoundCloud](http://soundcloud.com)
26
+ - [Twitter](https://twitter.com)
27
+ - * [Ted](http://ted.com)
28
+ - [Flickr](http://flickr.com)
29
+ - [Revision3](http://revision3.com)
30
+ - [Hulu](http://www.hulu.com)
31
+ - * [Kickstarter](http://www.kickstarter.com)
32
+ - [Deviantart](http://deviantart.com)
33
+ - [Facebook](https://facebook.com) (Public Posts/Videos)
34
+ - * [Scribd](http://www.scribd.com)
35
+
36
+ **And many many more!** for the full list checkout the [PROVIDERS.md](https://github.com/mpratt/Embera/blob/master/PROVIDERS.md) file.
37
+
38
+ Requirements
39
+ ============
40
+ - PHP >= 5.3
41
+ - Curl or `allow_url_fopen` must be enabled
42
+
43
+ Installation
44
+ ============
45
+
46
+ ### Install with Composer
47
+ If you're using [Composer](https://github.com/composer/composer) to manage
48
+ dependencies, you can use this library by creating a composer.json and adding this:
49
+
50
+ {
51
+ "require": {
52
+ "mpratt/embera": "~1.0"
53
+ }
54
+ }
55
+
56
+ Save it and run `composer.phar install`
57
+
58
+ ### Standalone Installation (without Composer)
59
+ Download the latest release or clone this repository, place the `Lib/Embera` directory on your project. Afterwards, you only need to include
60
+ the Autoload.php file.
61
+
62
+ ```php
63
+ require '/path/to/Embera/Autoload.php';
64
+ $embera = new \Embera\Embera();
65
+ ```
66
+
67
+ Or if you already have PSR-0 complaint autoloader, you just need to register Embera
68
+ ```php
69
+ $loader->registerNamespace('Embera', 'path/to/Embera');
70
+ ```
71
+
72
+ Basic Usage
73
+ ===========
74
+
75
+ For autoconverting urls into html embedable code, use the `autoEmbed()` method:
76
+ ```php
77
+ $text = 'Hi, I just saw this video http://www.dailymotion.com/video/xxwxe1_harlem-shake-de-los-simpsons_fun';
78
+ $embera = new \Embera\Embera();
79
+ echo $embera->autoEmbed($text);
80
+ /* Hi, I just saw this video <iframe src="http://www.dailymotion.com/embed/video/xxwxe1" ..... */
81
+ ```
82
+
83
+ The Embera object accepts an array with configuration options, so lets say you want to specify width or height:
84
+ ```php
85
+ $config = array(
86
+ 'params' => array(
87
+ 'width' => 300,
88
+ 'height' => 500
89
+ )
90
+ );
91
+
92
+ $text = 'Check this video out http://vimeo.com/groups/shortfilms/videos/66185763';
93
+
94
+ $embera = new \Embera\Embera($config);
95
+ echo $embera->autoEmbed($text);
96
+
97
+ /*Check this video out <iframe src="http://player.vimeo.com/video/66185763" width="300" height="480" ....*/
98
+ ```
99
+
100
+ Do you want to allow embedding only from a few Sites?
101
+ ```php
102
+ $config = array(
103
+ 'allow' => array('Youtube', 'Vimeo')
104
+ );
105
+
106
+ $text = 'http://vimeo.com/groups/shortfilms/videos/66185763
107
+ http://www.flickr.com/photos/bees/8597283706/in/photostream
108
+ http://youtube.com/watch?v=J---aiyznGQ';
109
+
110
+ $embera = new \Embera\Embera($config);
111
+
112
+ echo $embera->autoEmbed($text);
113
+ // The flickr url remains the same
114
+ ```
115
+
116
+ Or perhaps you want to deny embedding from sites?
117
+ ```php
118
+ $config = array(
119
+ 'deny' => array('Youtube', 'Vimeo')
120
+ );
121
+
122
+ $text = 'http://dailymotion.com/video/xp30q9_bmw-serie3-2012-en-mexico_auto
123
+ http://vimeo.com/groups/shortfilms/videos/66185763
124
+ http://youtube.com/watch?v=J---aiyznGQ';
125
+
126
+ $embera = new \Embera\Embera($config);
127
+
128
+ echo $embera->autoEmbed($text);
129
+ // Only the dailymotion link will be autoconverted
130
+ ```
131
+
132
+ As an alternative you can embed urls only if they start with the embed:// prefix.
133
+ ```php
134
+ $config = array(
135
+ 'use_embed_prefix' => true
136
+ );
137
+
138
+ $text = 'embed://dailymotion.com/video/xp30q9_bmw-serie3-2012-en-mexico_auto
139
+ http://youtube.com/watch?v=J---aiyznGQ';
140
+
141
+ $embera = new \Embera\Embera($config);
142
+
143
+ echo $embera->autoEmbed($text);
144
+ // Only the dailymotion link will be autoconverted
145
+ ```
146
+
147
+ Maybe you are interested on seeing the full oembed response from the urls.
148
+ Use the `getUrlInfo()` method that returns an array with the complete information about
149
+ the media located in the url
150
+ ```php
151
+ $embera = new \Embera\Embera();
152
+ print_r($embera->getUrlInfo('http://dailymotion.com/video/xp30q9_bmw-serie3-2012-en-mexico_auto'));
153
+ ```
154
+
155
+ You can even feed an array full with urls and inspect the oembed response for
156
+ each one them.
157
+ ```php
158
+ $urls = array('http://vimeo.com/groups/shortfilms/videos/66185763',
159
+ 'http://vimeo.com/47360546',
160
+ 'http://www.flickr.com/photos/bees/8597283706/in/photostream',
161
+ 'http://youtube.com/watch?v=J---aiyznGQ');
162
+
163
+ $embera = new \Embera\Embera();
164
+ print_r($embera->getUrlInfo($urls));
165
+ ```
166
+
167
+ Remember that some Oembed Providers append more/different information (and others less) this depends heavily from each provider and
168
+ the type of media you are requesting.
169
+
170
+ Advanced Usage
171
+ ==============
172
+
173
+ ### Offline Support
174
+ One of the key features of Embera is offline support. This feature allows you to get at least the html embed code for some services,
175
+ without having to make a real http request to the oembed provider. What Offline support really means, is that the html embed code is constructed
176
+ from the original url given, this also means that most of the other information such as the title or the author's name, is probably going to be missing.
177
+ Lets call that a fake response.
178
+
179
+ Take a look at the [PROVIDERS.md](https://github.com/mpratt/Embera/blob/master/PROVIDERS.md) to see which providers allow offline support.
180
+
181
+ There is a configuration setting called `oembed` that should be used in order to change the way the library communicates with the oembed endpoint.
182
+ By default the value equals null, which means that Embera will first try to get the data from the oembed endpoint and if that fails it tries to return a
183
+ fake response. This behaviour is useful when there are problems connecting with the oembed provider! This means that you get at least an html embedable code.
184
+
185
+ When the `oembed` setting equals `true` the library gets the data directly from the oembed provider. If something goes wrong with the request, Embera skips
186
+ the usage of fake responses.
187
+
188
+ On the other hand you can set the `oembed` setting to `false` and by doing that, you will always get fake responses. By doing this you can skip the request
189
+ to the oembed provider. This library has offline support for a bunch of providers.
190
+
191
+ ```php
192
+ $config = array(
193
+ 'oembed' => false
194
+ );
195
+
196
+ $text = 'http://vimeo.com/groups/shortfilms/videos/66185763
197
+ http://www.flickr.com/photos/bees/8597283706/in/photostream';
198
+
199
+ $embera = new \Embera\Embera($config);
200
+ echo $embera->autoEmbed($text);
201
+
202
+ /* <iframe src="http://player.vimeo.com/66185763" width="420" height="315" ...
203
+ http://www.flickr.com/photos/bees/8597283706/in/photostream */
204
+
205
+ /* Since Embera doesnt have Flickr offline support, the url stays the same. */
206
+ ```
207
+
208
+
209
+ When using the `getUrlInfo()` method, it is possible to see if the information from the provider came
210
+ directly from the oembed endpoint or if it was generated by the offline feature. If you see in the response,
211
+ the key `embera_using_fake` equal `0`, means that the library got the results from the Oembed provider.
212
+ When it equals `1`, the html embed code was generated by the library.
213
+
214
+ ### Error Checking
215
+ There are 3 methods for error checking `bool hasErrors()`, `array getErrors()` and `string getLastError()`
216
+ ```php
217
+ $embera = new \Embera\Embera();
218
+ $result = $embera->autoEmbed($text);
219
+
220
+ if ($embera->hasErrors())
221
+ echo $embera->getLastError();
222
+
223
+ // Or you can inspect all the errors
224
+ print_r($embera->getErrors());
225
+ ```
226
+
227
+ ### Output Formatting
228
+ Using the `\Embera\Formatter` object and the decorator pattern you are able to create templates with placeholders and
229
+ Embera will fill them with the relevant information from the oembed response.
230
+
231
+ A placeholder, in this case, is a word enclosed by `{}`, for example `{title}` which should give
232
+ you the title of the media. You can use any word from the oembed response ({provider_name}, {thumbnail_url}, {html}, {type}, etc).
233
+
234
+ The `Formatter` object has 2 more methods - `setTemplate()` and `transform()`
235
+ ```php
236
+ $embera = new \Embera\Embera();
237
+ $embera = new \Embera\Formatter($embera);
238
+
239
+ $embera->setTemplate('<div class="myclass">{provider_name}: {title} <p>{html}</p></div>');
240
+
241
+ echo $embera->transform(array('url1', 'url2', 'url3'));
242
+ // <div class="myclass">provider for url1: the title of url1 <p>embed code for url 1</p></div>
243
+ // <div class="myclass">provider for url2: the title of url2 <p>embed code for url 2</p></div>
244
+ // <div class="myclass">provider for url3: the title of url3 <p>embed code for url 3</p></div>
245
+ ```
246
+
247
+ You can also give a string with urls and they will be replaced by the given template
248
+ ```php
249
+ $embera = new \Embera\Embera();
250
+ $embera = new \Embera\Formatter($embera);
251
+
252
+ $embera->setTemplate('<div class="oembed">{html}</div>');
253
+
254
+ echo $embera->transform('Hey checkout this video http://url.com/video/id');
255
+ // hey checkout this video <div class="oembed">embed code for url.com/video/id</div>
256
+ ```
257
+
258
+ If you like you can use a shorter syntax, just by passing a string or array as a second parameter to the
259
+ `setTemplate` method
260
+ ```php
261
+ $embera = new \Embera\Formatter(new \Embera\Embera());
262
+ echo $embera->setTemplate('<div class="oembed">{html}</div>', array('url1.com', 'url2.com', 'url3.com'));
263
+ ```
264
+
265
+ ### Adding Custom Providers
266
+ Lets say you have a **private** Oembed Provider and you want to manage it with `Embera`. Well you can do it, first you have to create
267
+ a new class that extends the `\Embera\Adapters\Service` class. You can use one of the included providers in the /Embera/Providers
268
+ directory to get an idea of what it needs to have.
269
+
270
+ After that you need to use the `addProvider()` method. This method requires that you specify the host of your service,
271
+ the class you created and __optionally__ you can pass a third parameter, an array with data that should be used on the query string
272
+ to your Oembed Provider, for example an API key.
273
+ ```php
274
+ /**
275
+ * A very basic custom Service
276
+ */
277
+ class CustomService extends \Embera\Adapters\Service
278
+ {
279
+ protected $apiUrl = 'http://custom-service.com/oembed.json';
280
+ public function validateUrl(){ return preg_match('~customservice\.com/([0-9]+)~i', $this->url); }
281
+ }
282
+
283
+ $urls = array(
284
+ 'http://customservice.com/9879837498',
285
+ 'http://www.customservice.com/98756478',
286
+ 'http://customservice.com/9879837498/'
287
+ );
288
+
289
+ $embera = new \Embera\Embera();
290
+ $embera->addProvider('customservice.com', 'CustomService', array('api_key' => '********'));
291
+ $response = $embera->getUrlInfo($urls);
292
+
293
+ print_r($response);
294
+ ```
295
+
296
+ However, If the provider is public, the best way to deal with it is to open a bug report right here on github so
297
+ I can create a class for the service and everyone benefits from it.
298
+
299
+ **Important**: __xml__ responses are **not** supported by `Embera` at the moment! Use JSON instead.
300
+
301
+ ### Adding custom query string parameters to a service
302
+ Some Oembed providers support custom parameters. For example Twitter allows the `align` parameter, which
303
+ applies alignment styles to the html embed code. Most of the providers have documentation available
304
+ where you can search for possible parameters.
305
+
306
+ Use the config array:
307
+ ```php
308
+ $config = array(
309
+ 'custom_params' => array(
310
+ 'Twitter' => array('align' => 'center', 'hide_media' => 1)
311
+ )
312
+ );
313
+
314
+ $embera = new \Embera\Embera($config);
315
+ ```
316
+
317
+ In this case Im passing the align and hide_media parameters to the twitter service.
318
+ As a general rule, you just have to specify the Name of the service as a key and an
319
+ associative array with the parameters.
320
+
321
+ ### Modifying attributes of fake/offline responses
322
+ By default services with offline support have a width of 420px and height of 315px.
323
+ You can modify this attributes via the config array:
324
+ ```php
325
+ $config = array(
326
+ 'fake' => array(
327
+ 'width' => 800,
328
+ 'height' => 300
329
+ )
330
+ );
331
+
332
+ $embera = new \Embera\Embera($config);
333
+ ```
334
+
335
+ ### Passing Options to the HttpRequest Class
336
+ The \Embera\HttpRequest class is a simple wrapper for `curl` and `file_get_contents` (when the `allow_url_fopen` directive is
337
+ enabled).
338
+
339
+ You can pass options for each one of them when needed
340
+ ```php
341
+ $config = array(
342
+ 'http' => array(
343
+ 'curl' => array(
344
+ CURLOPT_CONNECTTIMEOUT => 1000 // Connect timeout for curl
345
+ ),
346
+ 'fopen' => array(
347
+ 'header' => "Content-Type: plain/text", // Send a header with file_get_contents/fopen
348
+ )
349
+ )
350
+ );
351
+
352
+ $embera = new \Embera\Embera($config);
353
+ ```
354
+
355
+ License
356
+ =======
357
+ **MIT**
358
+ For the full copyright and license information, please view the LICENSE file.
359
+
360
+ Author
361
+ =====
362
+ Hi! I'm Michael Pratt and I'm from Colombia!
363
+ My [Personal Website](http://www.michael-pratt.com) is in spanish.
library/ostraining/embera/Tests/Autoload.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Setup the environment
4
+ */
5
+ date_default_timezone_set('UTC');
6
+ if (file_exists(__DIR__ . '/../vendor/autoload.php'))
7
+ require __DIR__ . '/../vendor/autoload.php';
8
+ else
9
+ require __DIR__ . '/../Lib/Embera/Autoload.php';
10
+
11
+ /**
12
+ * HttpRequest Mockup
13
+ * @codeCoverageIgnore
14
+ */
15
+ class MockHttpRequest extends \Embera\HttpRequest
16
+ {
17
+ public $response;
18
+ public function fetch($url, array $params = array())
19
+ {
20
+ $url = true;
21
+ return $this->response;
22
+ }
23
+ }
24
+
25
+ /**
26
+ * A custom Service
27
+ */
28
+ class CustomService extends \Embera\Adapters\Service
29
+ {
30
+ protected $apiUrl = 'http://my-custom-service.com/oembed.json';
31
+ public function validateUrl()
32
+ {
33
+ return preg_match('~customservice\.com/([0-9]+)~i', $this->url);
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Oembed Mockup
39
+ * @codeCoverageIgnore
40
+ */
41
+ class MockOembed extends \Embera\Oembed
42
+ {
43
+ public function getResourceInfo($behaviour, $apiUrl, $url, array $params = array())
44
+ {
45
+ $behaviour = $apiUrl = $url = $params = true;
46
+ return array();
47
+ }
48
+ }
49
+ ?>
library/ostraining/embera/Tests/TestEmbera.php ADDED
@@ -0,0 +1,241 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestEmbera.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ class TestEmbera extends PHPUnit_Framework_TestCase
14
+ {
15
+ public function testInvalidAutoEmbedInput()
16
+ {
17
+ $input = array('http://www.youtube.com/watch?v=GP18O6gSWSw&feature=share&list=PL4EF7BAD98F9812B6');
18
+ $embera = new \Embera\Embera();
19
+
20
+ $this->assertEquals($input, $embera->autoEmbed($input));
21
+ $this->assertTrue($embera->hasErrors());
22
+ $this->assertTrue(is_string($embera->getLastError()));
23
+ $this->assertCount(1, $embera->getErrors());
24
+ }
25
+
26
+ public function testInvalidAutoEmbedInput2()
27
+ {
28
+ $input = null;
29
+ $embera = new \Embera\Embera();
30
+
31
+ $this->assertEquals($input, $embera->autoEmbed($input));
32
+ $this->assertTrue(is_string($embera->getLastError()));
33
+ $this->assertTrue($embera->hasErrors());
34
+ $this->assertCount(1, $embera->getErrors());
35
+ }
36
+
37
+ public function testAutoEmbedwithoutKnownServices()
38
+ {
39
+ $input = 'hola este texto debería seguir igual.';
40
+ $embera = new \Embera\Embera();
41
+
42
+ $this->assertEquals($input, $embera->autoEmbed($input));
43
+ }
44
+
45
+ public function testAutoEmbedwithoutKnownServices2()
46
+ {
47
+ $input = 'hola este texto debería seguir igual. http://www.google.com ';
48
+ $embera = new \Embera\Embera();
49
+
50
+ $this->assertEquals($input, $embera->autoEmbed($input));
51
+ }
52
+
53
+ public function testFakeUrlInspection()
54
+ {
55
+ $validUrls = array('http://www.youtube.com/watch?v=MpVHQnIvTXo',
56
+ 'http://youtu.be/fSUK4WgQ3vk',
57
+ 'http://www.youtube.com/watch?v=T3O1nffTG-k');
58
+
59
+ $embera = new \Embera\Embera(array('oembed' => false));
60
+ $result = $embera->getUrlInfo($validUrls);
61
+
62
+ $this->assertCount(count($validUrls), $result);
63
+ }
64
+
65
+ public function testFakeAutoEmbed()
66
+ {
67
+ $text = 'Hey Checkout this video http://www.youtube.com/watch?v=MpVHQnIvTXo, Its just great';
68
+ $embera = new \Embera\Embera(array('oembed' => false));
69
+ $result = $embera->autoEmbed($text);
70
+
71
+ $this->assertContains('<iframe', $result);
72
+ $this->assertEmpty($embera->getLastError());
73
+ }
74
+
75
+ public function testCustomProvider()
76
+ {
77
+ $oembed = new MockOembed(new MockHttpRequest());
78
+ $customParams = array('apikey' => 'myapikey');
79
+ $urls = array(
80
+ 'http://customservice.com/9879837498',
81
+ 'http://host.com/stuff/yes',
82
+ 'http://customservice.com/hi',
83
+ 'http://www.customservice.com/98756478',
84
+ 'http://customservice.com/9879837498/'
85
+ );
86
+
87
+ $p = new \Embera\Providers(array('oembed' => true), $oembed);
88
+ $p->addProvider('www.customservice.com', 'CustomService', $customParams);
89
+
90
+ $this->assertCount(3, $p->getAll($urls));
91
+
92
+ $all = $p->getAll($urls);
93
+ foreach ($all as $s) {
94
+ $params = array_filter($s->getParams());
95
+ $this->assertEquals($params, $customParams);
96
+ }
97
+ }
98
+
99
+ public function testCustomProvider2()
100
+ {
101
+ $urls = array(
102
+ 'http://customservice.com/9879837498',
103
+ 'http://host.com/stuff/yes',
104
+ 'http://customservice.com/hi',
105
+ 'http://www.customservice.com/98756478',
106
+ 'http://customservice.com/9879837498/'
107
+ );
108
+
109
+ $embera = new \Embera\Embera();
110
+ $embera->addProvider('www.customservice.com', 'CustomService', array());
111
+
112
+ $reflection = new ReflectionClass('\Embera\Embera');
113
+ $method = $reflection->getMethod('getProviders');
114
+ $method->setAccessible(true);
115
+
116
+ $providers = $method->invoke($embera, $urls);
117
+ $this->assertCount(3, $providers);
118
+ }
119
+
120
+ public function testUrlString()
121
+ {
122
+ $validUrls = 'Hey what up! http://www.youtube.com/watch?v=MpVHQnIvTXo this is great http://youtu.be/fSUK4WgQ3vk';
123
+
124
+ $embera = new \Embera\Embera(array('oembed' => false));
125
+ $result = $embera->getUrlInfo($validUrls);
126
+ $this->assertCount(2, $result);
127
+ }
128
+
129
+ public function testCustomParams()
130
+ {
131
+ $config = array(
132
+ 'custom_params' => array(
133
+ 'Youtube' => array('custom' => 'none'),
134
+ 'vimeO' => array('apikey' => '8987928734234'),
135
+ 'CustomService' => array('align' => 'left')
136
+ )
137
+ );
138
+
139
+ $embera = new \Embera\Embera($config);
140
+
141
+ $reflection = new ReflectionClass('\Embera\Embera');
142
+ $method = $reflection->getMethod('getProviders');
143
+ $method->setAccessible(true);
144
+
145
+ $providers = $method->invoke($embera, array(
146
+ 'http://customservice.com/12345',
147
+ 'http://stuff.com/unknown',
148
+ 'http://youtu.be/fSUK4WgQ3vk',
149
+ 'http://www.youtube.com/watch?v=MpVHQnIvTXo',
150
+ 'http://vimeo.com/groups/shortfilms/videos/63313811/',
151
+ 'http://www.dailymotion.com/video/xzxtaf_red-bull-400-alic-y-stadlober-ganan-en-eslovenia_sport/',
152
+ ));
153
+
154
+ $this->assertCount(4, $providers);
155
+
156
+ foreach($providers as $p)
157
+ {
158
+ $class = strtolower(basename(str_replace('\\', '/', get_class($p))));
159
+ $params = array_filter($p->getParams());
160
+
161
+ if ($class == 'youtube')
162
+ $this->assertEquals($params, $config['custom_params']['Youtube']);
163
+ else if ($class == 'vimeo')
164
+ $this->assertEquals($params, $config['custom_params']['vimeO']);
165
+ else
166
+ $this->assertTrue(empty($params), 'Param array for ' . $class . ' - ' . print_r($params, true));
167
+ }
168
+ }
169
+
170
+ public function testDenyService()
171
+ {
172
+ $validUrls = array('http://www.youtube.com/watch?v=MpVHQnIvTXo',
173
+ 'http://youtu.be/fSUK4WgQ3vk',
174
+ 'http://vimeo.com/groups/shortfilms/videos/63313811/',
175
+ 'http://www.youtube.com/watch?v=T3O1nffTG-k');
176
+
177
+ $embera = new \Embera\Embera(array('oembed' => false, 'deny' => array('Youtube')));
178
+ $result = $embera->getUrlInfo($validUrls);
179
+ $this->assertCount(1, $result);
180
+
181
+ $embera = new \Embera\Embera(array('oembed' => false, 'deny' => array('youTube')));
182
+ $result = $embera->getUrlInfo($validUrls);
183
+ $this->assertCount(1, $result);
184
+ }
185
+
186
+ public function testAllowService()
187
+ {
188
+ $validUrls = array('http://www.youtube.com/watch?v=MpVHQnIvTXo',
189
+ 'http://youtu.be/fSUK4WgQ3vk',
190
+ 'http://vimeo.com/groups/shortfilms/videos/63313811/',
191
+ 'http://www.dailymotion.com/video/xzxtaf_red-bull-400-alic-y-stadlober-ganan-en-eslovenia_sport/',
192
+ 'http://www.youtube.com/watch?v=T3O1nffTG-k');
193
+
194
+ $embera = new \Embera\Embera(array('oembed' => false, 'allow' => array('Vimeo', 'dailyMotion')));
195
+ $result = $embera->getUrlInfo($validUrls);
196
+ $this->assertCount(2, $result);
197
+
198
+ $embera = new \Embera\Embera(array('oembed' => false, 'allow' => array('Youtube', 'Dailymotion')));
199
+ $result = $embera->getUrlInfo($validUrls);
200
+ $this->assertCount((count($validUrls) - 1), $result);
201
+ }
202
+
203
+ public function testEmbedPrefixService()
204
+ {
205
+ $validUrls = array('embed://www.youtube.com/watch?v=MpVHQnIvTXo',
206
+ 'http://youtu.be/fSUK4WgQ3vk',
207
+ 'http://vimeo.com/groups/shortfilms/videos/63313811/',
208
+ 'embed://www.dailymotion.com/video/xzxtaf_red-bull-400-alic-y-stadlober-ganan-en-eslovenia_sport/',
209
+ 'embed://www.youtube.com/watch?v=T3O1nffTG-k');
210
+
211
+ $embera = new \Embera\Embera(array('oembed' => false, 'use_embed_prefix' => false));
212
+ $result = $embera->getUrlInfo($validUrls);
213
+ $this->assertCount(2, $result);
214
+
215
+ $embera = new \Embera\Embera(array('oembed' => false, 'use_embed_prefix' => true));
216
+ $result = $embera->getUrlInfo($validUrls);
217
+ $this->assertCount(3, $result);
218
+ }
219
+
220
+ public function testReplaceOrderOnAutoEmbed()
221
+ {
222
+ $expected = array(
223
+ '<iframe width="420" height="315" src="//www.youtube.com/embed/fSUK4WgQ3vk" frameborder="0" allowfullscreen></iframe>',
224
+ '<iframe width="420" height="315" src="//www.youtube.com/embed/fSUK4WgQ3vkIII" frameborder="0" allowfullscreen></iframe>',
225
+ '<iframe width="420" height="315" src="//www.youtube.com/embed/fSUK4WgQ3vkII" frameborder="0" allowfullscreen></iframe>'
226
+ );
227
+
228
+ $urls = array(
229
+ 'http://youtu.be/fSUK4WgQ3vk',
230
+ 'http://youtu.be/fSUK4WgQ3vkIII',
231
+ 'http://youtu.be/fSUK4WgQ3vkII'
232
+ );
233
+
234
+ $embera = new \Embera\Embera(array('oembed' => false));
235
+ $result = $embera->autoEmbed(implode(', ', $urls));
236
+
237
+ $this->assertEquals($result, implode(', ', $expected));
238
+ }
239
+ }
240
+
241
+ ?>
library/ostraining/embera/Tests/TestFakeResponse.php ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestFakeResponse.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ class TestFakeResponse extends PHPUnit_Framework_TestCase
14
+ {
15
+ public function testResponse()
16
+ {
17
+ $config = array(
18
+ 'fake' => array(
19
+ 'width' => 420,
20
+ 'height' => 315
21
+ ),
22
+ 'params' => array(
23
+ 'maxwidth' => 0,
24
+ 'maxheight' => 0,
25
+ )
26
+ );
27
+
28
+ $response = array(
29
+ 'provider_name' => 'a provider name',
30
+ 'html' => '<div style="height:{height}px;width:{width}px">hi</div>'
31
+ );
32
+
33
+ $fakeResponse = new \Embera\FakeResponse($config, $response);
34
+ $response = $fakeResponse->buildResponse();
35
+
36
+ $this->assertEquals($response['width'], 420);
37
+ $this->assertEquals($response['height'], 315);
38
+ $this->assertEquals($response['html'], '<div style="height:315px;width:420px">hi</div>');
39
+ $this->assertEquals($response['version'], '1.0');
40
+ $this->assertEquals($response['url'], '');
41
+ }
42
+
43
+ public function testResponse2()
44
+ {
45
+ $config = array(
46
+ 'fake' => array(
47
+ 'width' => 420,
48
+ 'height' => 315
49
+ ),
50
+ 'params' => array(
51
+ 'maxwidth' => 500,
52
+ )
53
+ );
54
+
55
+ $response = array(
56
+ 'provider_name' => 'a provider name',
57
+ 'html' => '<div style="height:{height}px;width:{width}px">hi</div>'
58
+ );
59
+
60
+ $fakeResponse = new \Embera\FakeResponse($config, $response);
61
+ $response = $fakeResponse->buildResponse();
62
+
63
+ $this->assertEquals($response['width'], 500);
64
+ $this->assertEquals($response['height'], 315);
65
+ $this->assertEquals($response['html'], '<div style="height:315px;width:500px">hi</div>');
66
+ $this->assertEquals($response['version'], '1.0');
67
+ $this->assertEquals($response['url'], '');
68
+ }
69
+
70
+ public function testResponse3()
71
+ {
72
+ $config = array(
73
+ 'fake' => array(
74
+ 'width' => 500,
75
+ 'height' => 315,
76
+ 'url' => 'http://hi.com',
77
+ 'thumb' => 'http://image.com'
78
+ ),
79
+ 'params' => array(
80
+ 'maxwidth' => 210,
81
+ )
82
+ );
83
+
84
+ $response = array(
85
+ 'provider_name' => 'a provider name',
86
+ 'html' => '<div style="height:{height}px;width:{width}px">hi</div>'
87
+ );
88
+
89
+ $fakeResponse = new \Embera\FakeResponse($config, $response);
90
+ $response = $fakeResponse->buildResponse();
91
+
92
+ $this->assertEquals($response['width'], 500);
93
+ $this->assertEquals($response['height'], 315);
94
+ $this->assertEquals($response['html'], '<div style="height:315px;width:500px">hi</div>');
95
+ $this->assertEquals($response['version'], '1.0');
96
+ $this->assertEquals($response['url'], 'http://hi.com');
97
+ $this->assertEquals($response['thumb'], 'http://image.com');
98
+ }
99
+ }
100
+
101
+ ?>
library/ostraining/embera/Tests/TestFormatter.php ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestFormatter.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ class TestFormatter extends PHPUnit_Framework_TestCase
14
+ {
15
+ public function testTemplateArray()
16
+ {
17
+ $urls = array(
18
+ 'http://youtu.be/fSUK4WgQ3vk',
19
+ 'http://www.youtube.com/watch?v=T3O1nffTG-k'
20
+ );
21
+
22
+ $embera = new \Embera\Embera();
23
+ $embera = new \Embera\Formatter($embera);
24
+ $embera->setTemplate('{html}|');
25
+
26
+ $result = $embera->transform($urls);
27
+ $this->assertCount(count($urls), explode('|', trim($result, '|')));
28
+ }
29
+
30
+ public function testTemplateString()
31
+ {
32
+ $embera = new \Embera\Embera();
33
+ $embera = new \Embera\Formatter($embera);
34
+ $embera->setTemplate('<div class="hey">{html}</div>');
35
+ $result = $embera->transform('Hey did you see http://www.youtube.com/watch?v=MpVHQnIvTXo');
36
+
37
+ $this->assertContains('<div class="hey"><iframe', $result);
38
+ }
39
+
40
+ public function testOfflineSupport()
41
+ {
42
+ $urls = array(
43
+ 'http://www.youtube.com/watch?v=MpVHQnIvTXo',
44
+ 'http://youtu.be/fSUK4WgQ3vk',
45
+ );
46
+
47
+ $embera = new \Embera\Embera(array('oembed' => false));
48
+ $embera = new \Embera\Formatter($embera);
49
+ $embera->setTemplate('<div class="hi">{html}</div>');
50
+
51
+ $result = $embera->transform($urls);
52
+ $this->assertEmpty($result);
53
+ $this->assertTrue($embera->hasErrors());
54
+ $this->assertCount(count($urls), $embera->getErrors());
55
+
56
+ $last = $embera->getLastError();
57
+ $this->assertTrue(!empty($last));
58
+ }
59
+
60
+ public function testOfflineSupport2()
61
+ {
62
+ $urls = array('http://youtu.be/fSUK4WgQ3vk');
63
+
64
+ $embera = new \Embera\Embera(array('oembed' => false));
65
+ $embera = new \Embera\Formatter($embera, true);
66
+ $embera->setTemplate('<div class="hi">{html}</div>');
67
+
68
+ $result = $embera->transform($urls);
69
+ $this->assertContains('<iframe', $result);
70
+ }
71
+
72
+ public function testSupportForDecoratedObjectAPI()
73
+ {
74
+ $urls = array(
75
+ 'http://www.youtube.com/watch?v=MpVHQnIvTXo',
76
+ 'http://youtu.be/fSUK4WgQ3vk',
77
+ );
78
+
79
+ $embera = new \Embera\Embera(array('oembed' => false));
80
+ $embera = new \Embera\Formatter($embera);
81
+
82
+ $result = $embera->autoEmbed(implode(' ', $urls));
83
+ $this->assertTrue(!empty($result));
84
+ $this->assertContains('<iframe', $result);
85
+ }
86
+
87
+ public function testSupportForDecoratedObjectAPI2()
88
+ {
89
+ $this->setExpectedException('InvalidArgumentException');
90
+
91
+ $embera = new \Embera\Embera(array('oembed' => false));
92
+ $embera = new \Embera\Formatter($embera);
93
+
94
+ $last = $embera->getLastError();
95
+ $this->assertTrue(empty($last));
96
+
97
+ $embera->unknownMethodName();
98
+ }
99
+
100
+ public function testUnknownWebsites()
101
+ {
102
+ $embera = new \Embera\Embera();
103
+ $embera = new \Embera\Formatter($embera);
104
+
105
+ $this->assertEmpty($embera->setTemplate('{html}', array('url1.com', 'url2.com', 'url3.com')));
106
+ $this->assertEquals($embera->setTemplate('{html}', 'unknown url http://hey.com'), 'unknown url http://hey.com');
107
+ }
108
+
109
+ public function testRemoveEmptyPlaceholders()
110
+ {
111
+ $urls = array('http://youtu.be/fSUK4WgQ3vk');
112
+
113
+ $embera = new \Embera\Embera();
114
+ $embera = new \Embera\Formatter($embera);
115
+ $embera->setTemplate('{unknown_key}');
116
+
117
+ $result = $embera->transform($urls);
118
+ $this->assertEquals($result, '');
119
+ }
120
+ }
121
+
122
+ ?>
library/ostraining/embera/Tests/TestHttpRequest.php ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestHttpRequest.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ class TestHttpRequest extends PHPUnit_Framework_TestCase
14
+ {
15
+ /**
16
+ * This needs more execution time ..
17
+ * @large
18
+ */
19
+ public function testInvalidUrl()
20
+ {
21
+ $this->setExpectedException('Exception');
22
+
23
+ $http = new \Embera\HttpRequest();
24
+ $http->fetch('this is an invalid url');
25
+ }
26
+
27
+ /**
28
+ * This needs more execution time ..
29
+ * @large
30
+ */
31
+ public function testInvalidUrl2()
32
+ {
33
+ $this->setExpectedException('Exception');
34
+
35
+ if (!ini_get('allow_url_fopen'))
36
+ {
37
+ $this->markTestIncomplete('Could not test file_get_contents wrapper, allow_url_fopen is closed');
38
+ return ;
39
+ }
40
+
41
+ $http = new \Embera\HttpRequest(array('prefer_curl' => false));
42
+ $http->fetch('this is an invalid url');
43
+ }
44
+
45
+ /**
46
+ * This needs more execution time ..
47
+ * @large
48
+ */
49
+ public function testFetchCurl()
50
+ {
51
+ $http = new \Embera\HttpRequest();
52
+ $response = $http->fetch('http://httpbin.org/user-agent');
53
+ $response = json_decode($response, true);
54
+
55
+ $this->assertEquals('Mozilla/5.0 PHP/Embera', $response['user-agent']);
56
+
57
+ $config = array(
58
+ 'curl' => array(
59
+ CURLOPT_USERAGENT => 'PHP/Morcilla',
60
+ )
61
+ );
62
+
63
+ $http = new \Embera\HttpRequest($config);
64
+ $response = $http->fetch('http://httpbin.org/user-agent');
65
+ $response = json_decode($response, true);
66
+
67
+ $this->assertEquals('PHP/Morcilla', $response['user-agent']);
68
+
69
+ $config = array(
70
+ 'curl' => array(
71
+ CURLOPT_FOLLOWLOCATION => 0,
72
+ CURLOPT_USERAGENT => 'PHP/Morcilla 2',
73
+ ),
74
+ 'force_redirects' => true
75
+ );
76
+
77
+ $http = new \Embera\HttpRequest($config);
78
+ $response = $http->fetch('http://httpbin.org/relative-redirect/2');
79
+ $response = json_decode($response, true);
80
+
81
+ $this->assertEquals('http://httpbin.org/get', $response['url']);
82
+
83
+ $response = $http->fetch('http://httpbin.org/redirect-to?url=' . urlencode('http://httpbin.org/user-agent'));
84
+ $response = json_decode($response, true);
85
+
86
+ $this->assertEquals('PHP/Morcilla 2', $response['user-agent']);
87
+
88
+ $config = array(
89
+ 'curl' => array(
90
+ CURLOPT_FOLLOWLOCATION => 1,
91
+ CURLOPT_USERAGENT => 'PHP/Morcilla 3',
92
+ ),
93
+ );
94
+
95
+ $http = new \Embera\HttpRequest($config);
96
+ $response = $http->fetch('http://httpbin.org/relative-redirect/2');
97
+ $response = json_decode($response, true);
98
+
99
+ $this->assertEquals('http://httpbin.org/get', $response['url']);
100
+
101
+ $response = $http->fetch('http://httpbin.org/redirect-to?url=' . urlencode('http://httpbin.org/user-agent'));
102
+ $response = json_decode($response, true);
103
+
104
+ $this->assertEquals('PHP/Morcilla 3', $response['user-agent']);
105
+ }
106
+
107
+ /**
108
+ * This needs more execution time ..
109
+ * @large
110
+ */
111
+ public function testFetchFileGetcontents()
112
+ {
113
+ if (!ini_get('allow_url_fopen'))
114
+ {
115
+ $this->markTestIncomplete('Could not test file_get_contents wrapper, allow_url_fopen is closed');
116
+ return ;
117
+ }
118
+
119
+ $config = array(
120
+ 'prefer_curl' => false,
121
+ 'fopen' => array(
122
+ 'user_agent' => 'PHP/FGC Morcilla'
123
+ )
124
+ );
125
+
126
+ $http = new \Embera\HttpRequest($config);
127
+ $response = $http->fetch('http://httpbin.org/user-agent');
128
+ $response = json_decode($response, true);
129
+
130
+ $this->assertEquals('PHP/FGC Morcilla', $response['user-agent']);
131
+
132
+ $http = new \Embera\HttpRequest($config);
133
+ $response = $http->fetch('http://httpbin.org/relative-redirect/2');
134
+ $response = json_decode($response, true);
135
+
136
+ $this->assertEquals('http://httpbin.org/get', $response['url']);
137
+
138
+ $response = $http->fetch('http://httpbin.org/redirect-to?url=' . urlencode('http://httpbin.org/user-agent'));
139
+ $response = json_decode($response, true);
140
+
141
+ $this->assertEquals('PHP/FGC Morcilla', $response['user-agent']);
142
+ }
143
+
144
+ /**
145
+ * This needs more execution time ..
146
+ * @large
147
+ */
148
+ public function testOptionsPrecedence()
149
+ {
150
+ $config = array(
151
+ 'curl' => array(
152
+ CURLOPT_USERAGENT => 'PHP/Morcilla 1',
153
+ )
154
+ );
155
+
156
+ $http = new \Embera\HttpRequest($config);
157
+ $response = $http->fetch('http://httpbin.org/user-agent', array(
158
+ 'curl' => array(
159
+ CURLOPT_USERAGENT => 'PHP/Morcilla 2',
160
+ )
161
+ ));
162
+
163
+ $response = json_decode($response, true);
164
+
165
+ $this->assertEquals('PHP/Morcilla 2', $response['user-agent']);
166
+ }
167
+ }
168
+
169
+ ?>
library/ostraining/embera/Tests/TestOembed.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestOembed.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ class TestOembed extends PHPUnit_Framework_TestCase
14
+ {
15
+ public function testResourceInfoOembedDisabled()
16
+ {
17
+ $oembed = new \Embera\Oembed(new MockHttpRequest());
18
+ $return = $oembed->getResourceInfo(true, 'dummyurl1', 'dummyurl2');
19
+ $this->assertEquals($return, array());
20
+ }
21
+
22
+ public function testResourceInfoOembedJson()
23
+ {
24
+ $value = array('value1' => 10, 'value2' => 30);
25
+
26
+ $http = new MockHttpRequest();
27
+ $http->response = json_encode($value);
28
+
29
+ $oembed = new \Embera\Oembed($http);
30
+ $return = $oembed->getResourceInfo(true, 'dummyurl', 'dummy_url2');
31
+ unset($return['embera_using_fake']);
32
+
33
+ $this->assertEquals($return, $value);
34
+ }
35
+
36
+ public function testResourceInfoOembedInvalidJson()
37
+ {
38
+ $value = 'this text is not a json object';
39
+
40
+ $http = new MockHttpRequest();
41
+ $http->response = $value;
42
+
43
+ $oembed = new \Embera\Oembed($http);
44
+ $return = $oembed->getResourceInfo(true, 'dummyurl', 'dummy_url2');
45
+ $this->assertEquals($return, array());
46
+ }
47
+
48
+ public function testUrlConstruction()
49
+ {
50
+ $oembed = new \Embera\Oembed(new MockHttpRequest());
51
+ $reflection = new ReflectionClass('\Embera\Oembed');
52
+ $method = $reflection->getMethod('constructUrl');
53
+ $method->setAccessible(true);
54
+
55
+ $this->assertEquals($method->invoke($oembed, 'http://www.apiurl.com/', array('house' => '1', 'value2' => '3', 'format' => 'json')),
56
+ 'http://www.apiurl.com/?house=1&value2=3&format=json');
57
+
58
+ $this->assertEquals($method->invoke($oembed, 'http://www.apiurl.com', array('width' => '100', 'format' => 'xml')),
59
+ 'http://www.apiurl.com?width=100&format=xml');
60
+
61
+ $this->assertEquals($method->invoke($oembed, 'http://www.apiurl.com/?url=100', array('maxheight' => 400, 'format' => 'json')),
62
+ 'http://www.apiurl.com/?url=100&maxheight=400&format=json');
63
+
64
+ $this->assertEquals($method->invoke($oembed, 'http://www.apiurl.com/hellow/', array('format' => 'json')),
65
+ 'http://www.apiurl.com/hellow/?format=json');
66
+
67
+ $this->assertEquals($method->invoke($oembed, 'http://www.apiurl.com/', array('height' => '2000')),
68
+ 'http://www.apiurl.com/?height=2000');
69
+
70
+ $this->assertEquals($method->invoke($oembed, 'http://www.apiurl.com/', array()),
71
+ 'http://www.apiurl.com/?');
72
+ }
73
+ }
74
+
75
+ ?>
library/ostraining/embera/Tests/TestProviders.php ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestProviders.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ class TestProviders extends PHPUnit_Framework_TestCase
14
+ {
15
+ /** @var array with urls */
16
+ protected $urls;
17
+
18
+ public function testEmptyOrInvalidProviders()
19
+ {
20
+ $oembed = new MockOembed(new MockHttpRequest());
21
+
22
+ $p = new \Embera\Providers(array('oembed' => true), $oembed);
23
+ $this->assertEmpty($p->getAll(array()));
24
+
25
+ $p = new \Embera\Providers(array('oembed' => true), $oembed);
26
+ $this->assertEmpty($p->getAll(null));
27
+
28
+ $p = new \Embera\Providers(array('oembed' => true), $oembed);
29
+ $this->assertEmpty($p->getAll('http://www.unknown.com'));
30
+
31
+ $urls = array('http://www.unknown.com/path/stuf/?hi=1', 'http://www.thewalkingdead.com/stuff/');
32
+ $p = new \Embera\Providers(array('oembed' => true), $oembed);
33
+ $this->assertEmpty($p->getAll($urls));
34
+ }
35
+
36
+ protected function getRandomUrls(array $urls = array(), $count = 1)
37
+ {
38
+ if ($count >= count($urls)) {
39
+ return $urls;
40
+ }
41
+
42
+ shuffle($urls);
43
+ return array_slice($urls, 0, $count);
44
+ }
45
+
46
+ /**
47
+ * This is where it gets nasty.
48
+ *
49
+ * This method is used to validate the behaviour of a Service Provider.
50
+ * All the other methods found down here, are used to test different
51
+ * parts of the service.
52
+ *
53
+ * Now, every service has a test file which extends this class
54
+ * and uses this method to validate everything.
55
+ *
56
+ * Why? I had so much duplicated code...
57
+ * I know it looks ugly, but, its more convenient.
58
+ *
59
+ * @large
60
+ */
61
+ protected function validateProvider($s)
62
+ {
63
+ if (empty($this->urls)) {
64
+ throw new Exception('No urls specified for the service ' . $s);
65
+ }
66
+
67
+ // Use all the available urls
68
+ $rounds = (defined('FULL_TEST') && FULL_TEST ? 1000 : 1);
69
+
70
+ $this->validateDetection($s, $this->urls['valid'], $this->urls['invalid']);
71
+ $this->validateRealResponse($s, $this->getRandomUrls($this->urls['valid'], $rounds));
72
+
73
+ if (!empty($this->urls['normalize'])) {
74
+ $this->validateUrlNormalization($s, $this->urls['normalize']);
75
+ }
76
+
77
+ if (!empty($this->urls['fake'])) {
78
+ $this->validateFakeResponse($s, $this->getRandomUrls($this->urls['valid'], $rounds), $this->urls['fake']);
79
+ }
80
+
81
+ if (!empty($this->urls['private'])) {
82
+ $this->validatePrivateUrlResponse($s, $this->urls['private']);
83
+ }
84
+
85
+ $this->validateWrongUrlResponse($s, $this->getRandomUrls($this->urls['invalid'], 3));
86
+ }
87
+
88
+ /**
89
+ * Checks if all valid urls are correctly detected
90
+ * @medium
91
+ */
92
+ protected function validateDetection($s, array $validUrls, array $invalidUrls)
93
+ {
94
+ $oembed = new MockOembed(new MockHttpRequest());
95
+
96
+ $p = new \Embera\Providers(array('oembed' => true), $oembed);
97
+ $this->assertCount(count($validUrls), $p->getAll($validUrls), $s . ' The valid Urls dont seem to be detected correctly');
98
+
99
+ $p = new \Embera\Providers(array('oembed' => true), $oembed);
100
+ $this->assertCount(count($validUrls), $p->getAll(array_merge($validUrls, $invalidUrls)), $s . ' There is at least one invalid url recognized as valid');
101
+
102
+ $p = new \Embera\Providers(array('oembed' => true), $oembed);
103
+ $this->assertCount(1, $p->getAll($validUrls[mt_rand(0, (count($validUrls) - 1))]), $s . ' One Correct url seems to be invalid');
104
+ }
105
+
106
+ /**
107
+ * Validates the response for an array of urls
108
+ * @large
109
+ */
110
+ protected function validateRealResponse($service, array $validUrls)
111
+ {
112
+ $oembed = new \Embera\Oembed(new \Embera\HttpRequest());
113
+ $service = '\Embera\Providers\\' . $service;
114
+
115
+ foreach ($validUrls as $url) {
116
+ $test = new $service($url, array(
117
+ 'oembed' => true,
118
+ 'fake' => array(),
119
+ 'params' => array()
120
+ ), $oembed);
121
+
122
+ $result = $test->getInfo();
123
+
124
+ if (!isset($result['embera_using_fake'])) {
125
+ $this->markTestIncomplete($service . ': Embera_using_fake index not defined on ' . $url . ' - Probably the response took too long - Using url ' . $test->getUrl());
126
+ return ;
127
+ }
128
+
129
+ $this->assertTrue($result['embera_using_fake'] == 0, $service . ': Using Fake on ' . $url);
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Validates that a url on this service is correctly normalized
135
+ * @medium
136
+ */
137
+ protected function validateUrlNormalization($service, array $normalizeUrls)
138
+ {
139
+ $oembed = new MockOembed(new MockHttpRequest());
140
+ $service = '\Embera\Providers\\' . $service;
141
+
142
+ foreach ($normalizeUrls as $given => $expected) {
143
+ $test = new $service($given, array('oembed' => false, 'fake' => array(), 'params' => array()), $oembed);
144
+ $this->assertEquals($test->getUrl(), $expected);
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Validates a fake response
150
+ * @large
151
+ */
152
+ protected function validateFakeResponse($service, array $validUrls, array $fakeResponseData)
153
+ {
154
+ $fakeOembed = new MockOembed(new MockHttpRequest());
155
+ $service = '\Embera\Providers\\' . $service;
156
+
157
+ foreach ($validUrls as $url) {
158
+ $test = new $service($url, array('fake' => array(), 'params' => array()), $fakeOembed);
159
+ $response = $test->fakeResponse();
160
+
161
+ $this->assertTrue((count($response) > 2), 'Invalid Fake Response for ' . $url . ' - Debug: ' . print_r($response, true));
162
+ $this->assertContains($fakeResponseData['html'], $response['html'], 'Response is not ' . $fakeResponseData['html']. ' in ' . $url);
163
+ $this->assertEquals($fakeResponseData['type'], $response['type'], 'Response type is not ' . $fakeResponseData['type'] . ' on ' . $url);
164
+
165
+ // Do a real test and comparition
166
+ $oembed = new \Embera\Oembed(new \Embera\HttpRequest());
167
+ $test = new $service($url, array('oembed' => true, 'fake' => array(), 'params' => array()), $oembed);
168
+ $result1 = $test->getInfo();
169
+
170
+ if (!isset($result1['embera_using_fake'])) {
171
+ $this->markTestIncomplete($service . ': Embera_using_fake index not defined on ' . $url . ' - Probably the response took too long');
172
+ return ;
173
+ }
174
+
175
+ $this->assertTrue(isset($result1['html']), 'Funky response (no html) from ' . $url);
176
+ $this->assertTrue($result1['embera_using_fake'] == 0, 'Using fake on ' . $url);
177
+ $this->assertTrue(!empty($result1['html']), 'Empty Html on ' . $url);
178
+
179
+ $this->assertContains($fakeResponseData['html'], $result1['html'], 'Response is not ' . $fakeResponseData['html']. ' in ' . $url);
180
+ $this->assertEquals($fakeResponseData['type'], $result1['type'], 'Response type is not ' . $fakeResponseData['type'] . ' on ' . $url);
181
+
182
+ $oembed = new \Embera\Oembed(new \Embera\HttpRequest());
183
+ $test = new $service($url, array('oembed' => false, 'fake' => array(), 'params' => array()), $oembed);
184
+ $result2 = $test->getInfo();
185
+
186
+ $this->assertTrue($result2['embera_using_fake'] == 1, 'Not Using fake on ' . $url);
187
+ $this->assertTrue(!empty($result2['html']), 'Empty Html on ' . $url);
188
+
189
+ similar_text($result1['html'], $result2['html'], $percent);
190
+ $this->assertTrue($percent >= 70, 'The Fake/Real response for ' . $url . ' seem a little off | %' . $percent);
191
+
192
+ $this->assertTrue(isset($result1['type']), 'No type response on ' . $url);
193
+ $this->assertEquals(strtolower($result1['type']), strtolower($fakeResponseData['type']), 'Funky type response from ' . $url);
194
+ }
195
+ }
196
+
197
+ /**
198
+ * Validate urls that have a private response
199
+ * @large
200
+ */
201
+ protected function validatePrivateUrlResponse($service, array $privateUrls)
202
+ {
203
+ $oembed = new \Embera\Oembed(new \Embera\HttpRequest());
204
+ $service = '\Embera\Providers\\' . $service;
205
+
206
+ foreach ($privateUrls as $url) {
207
+ $test = new $service($url, array('oembed' => true, 'fake' => array(), 'params' => array()), $oembed);
208
+ $this->assertEmpty($test->getInfo(), $service . ': Invalid response from a private url ' . print_r($test->getInfo(), true));
209
+ }
210
+ }
211
+
212
+ /**
213
+ * Validates a response from an invalid url for the current service
214
+ * @large
215
+ */
216
+ protected function validateWrongUrlResponse($service, array $urls)
217
+ {
218
+ $service = '\Embera\Providers\\' . $service;
219
+ $oembed = new MockOembed(new MockHttpRequest());
220
+
221
+ foreach ($urls as $url) {
222
+ try {
223
+ new $service($url, array(
224
+ 'oembed' => true,
225
+ 'fake' => array(),
226
+ 'params' => array()
227
+ ), $oembed);
228
+
229
+ $this->assertTrue(false, $service . ': The url ' . $url . ' doesnt seem to be invalid');
230
+ } catch (InvalidArgumentException $e) {
231
+ // just keep the count
232
+ $this->assertTrue(true);
233
+ }
234
+ }
235
+ }
236
+ }
237
+ ?>
library/ostraining/embera/Tests/TestServiceAmCharts.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceAmCharts.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceAmCharts extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://live.amcharts.com/NkMTE/',
20
+ 'http://live.amcharts.com/NjEwN',
21
+ 'http://live.amcharts.com/c1MGE/',
22
+ 'http://live.amcharts.com/hlOWI',
23
+ 'http://live.amcharts.com/TY1Yj/',
24
+ 'http://live.amcharts.com/zkyZm/edit/',
25
+ 'https://live.amcharts.com/YjRlZ/edit/',
26
+ 'http://live.amcharts.com/GIyNz/edit',
27
+ 'http://live.amcharts.com/DdmMD/',
28
+ ),
29
+ 'invalid' => array(
30
+ 'http://live.amcharts.com/new/',
31
+ 'http://live.amcharts.com/new/edit',
32
+ 'http://live.amcharts.com/',
33
+ ),
34
+ 'normalize' => array(
35
+ 'http://live.amcharts.com/hlOWI' => 'http://live.amcharts.com/hlOWI/',
36
+ 'http://live.amcharts.com/TY1Yj/' => 'http://live.amcharts.com/TY1Yj/',
37
+ 'http://live.amcharts.com/zkyZm/edit/' => 'http://live.amcharts.com/zkyZm/',
38
+ 'http://live.amcharts.com/TY1Yj/edit/stuff' => 'http://live.amcharts.com/TY1Yj/',
39
+ ),
40
+ 'fake' => array(
41
+ 'type' => 'rich',
42
+ 'html' => '<iframe'
43
+ )
44
+ );
45
+
46
+ public function testProvider() { $this->validateProvider('AmCharts'); }
47
+ }
48
+ ?>
library/ostraining/embera/Tests/TestServiceAnimatron.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceAnimatron.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceAnimatron extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://www.animatron.com/project/a1088356812e5254b05d1023',
20
+ 'https://www.animatron.com/project/acd24255d9c69b385efb1c45/',
21
+ 'http://www.animatron.com/project/6b893756fd1da93aa77abe74',
22
+ 'https://animatron.com/project/06bb635611ad737928c260ce',
23
+ 'http://animatron.com/project/c33f8155b859bb1ad1227590',
24
+ 'https://www.animatron.com/project/a12f59553432998d2950592f?query=string',
25
+ ),
26
+ 'invalid' => array(
27
+ 'https://www.animatron.com/',
28
+ 'http://www.animatron.com/not/project/6b893756fd1da93aa77abe74',
29
+ ),
30
+ );
31
+
32
+ /**
33
+ * @large
34
+ */
35
+ public function testProvider() { $this->validateProvider('Animatron'); }
36
+ }
37
+ ?>
library/ostraining/embera/Tests/TestServiceAnimoto.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceAnimoto.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceAnimoto extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://animoto.com/play/JzwsBn5FRVxS0qoqcBP5zA',
20
+ 'http://animoto.com/play/JzwsBn5FRVxS0qoqcBP5zA/',
21
+ 'http://www.animoto.com/play/JzwsBn5FRVxS0qoqcBP5zA/',
22
+ 'http://animoto.com/play/tH6T0044UCwFiALmCxbjgA',
23
+ 'http://www.animoto.com/play/tH6T0044UCwFiALmCxbjgA',
24
+ 'http://animoto.com/play/WafRFTXfiG1e7FueGwgm2w/',
25
+ 'http://www.animoto.com/play/9jR5D89nw7Cw61laPFhpsQ/'
26
+ ),
27
+ 'invalid' => array(
28
+ 'http://animoto.com/features',
29
+ 'http://animoto.com/#examples',
30
+ 'http://www.animoto.com/play/JzwsBn5FRVxS0qoqcBP5zA/other-stuff',
31
+ 'http://animoto.com/',
32
+ ),
33
+ );
34
+
35
+ /**
36
+ * @large
37
+ */
38
+ public function testProvider() { $this->validateProvider('Animoto'); }
39
+ }
40
+ ?>
library/ostraining/embera/Tests/TestServiceAolOn.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceAolOn.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceAolOn extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://on.aol.com/video/plans-to-clone-john-lennon-using-one-of-his-teeth-517906689?icid=OnHomepageL1_Tag',
20
+ 'http://on.aol.com/video/three-good-news-stories-to-brighten-your-day-517906768',
21
+ 'https://on.aol.com/video/kid-president-meets-beyonc--517906781/',
22
+ 'http://on.aol.com/video/obama-comes-out-against-dog-breed-specific-legislation-517905316/',
23
+ 'http://on.aol.com/video/colo--lawmakers-ousted-over-gun-control-support-517929948?icid=OnHomepageC3_New_Img',
24
+ 'http://www.5min.com/video/obama-comes-out-against-dog-breed-specific-legislation-517905316',
25
+ 'http://5min.com/video/obama-comes-out-against-dog-breed-specific-legislation-517905316',
26
+ ),
27
+ 'invalid' => array(
28
+ 'http://5min.com/obama-comes-out-against-dog-breed-specific-legislation-517905316',
29
+ 'http://on.aol.com/video/',
30
+ 'http://on.aol.com/channel/parenting',
31
+ 'http://on.aol.com/originals',
32
+ 'http://on.aol.com/show/CandidlyNicole-517742769',
33
+ 'http://on.aol.com/bubble/omg/1',
34
+ 'http://on.aol.com',
35
+ ),
36
+ 'normalize' => array(
37
+ 'http://5min.com/video/obama-comes-out-against-dog-breed-specific-legislation-517905316' => 'http://on.aol.com/video/obama-comes-out-against-dog-breed-specific-legislation-517905316',
38
+ 'https://5min.com/video/obama-comes-out-against-dog-breed-specific-legislation-517905316' => 'http://on.aol.com/video/obama-comes-out-against-dog-breed-specific-legislation-517905316',
39
+ 'http://on.aol.com/video/plans-to-clone-john-lennon-using-one-of-his-teeth-517906689?icid=OnHomepageL1_Tag' => 'http://on.aol.com/video/plans-to-clone-john-lennon-using-one-of-his-teeth-517906689',
40
+ 'http://on.aol.com/video/plans-to-clone-john-lennon-using-one-of-his-teeth-517906689/' => 'http://on.aol.com/video/plans-to-clone-john-lennon-using-one-of-his-teeth-517906689',
41
+ ),
42
+ 'fake' => array(
43
+ 'type' => 'video',
44
+ 'html' => '<iframe'
45
+ )
46
+ );
47
+
48
+ public function testProvider() { $this->validateProvider('AolOn'); }
49
+ }
50
+ ?>
library/ostraining/embera/Tests/TestServiceAppNet.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceAppNet.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceAppNet extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://alpha.app.net/lesechos/post/9152136',
20
+ 'http://alpha.app.net/popsugar/post/9145139',
21
+ //'https://alpha.app.net/breakingnews/post/9141658/',
22
+ //'https://photos.app.net/8244279/1',
23
+ ),
24
+ 'invalid' => array(
25
+ 'https://unknown.app.net/breakingnews/post/9141658/',
26
+ 'https://aplpha.app.net/breakingnews/post/string/',
27
+ 'https://aplpha.app.net/post/9141658/',
28
+ 'https://aplpha.app.net/breakingnews/9141658/',
29
+ 'https://aplpha.app.net',
30
+ ),
31
+ );
32
+
33
+ public function testProvider() { $this->validateProvider('AppNet'); }
34
+ }
35
+ ?>
library/ostraining/embera/Tests/TestServiceAudioSnaps.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceAudioSnaps.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceAudioSnaps extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://audiosnaps.com/k/1qbt/',
20
+ 'http://audiosnaps.com/k/1oqz',
21
+ 'http://audiosnaps.com/k/2uld/',
22
+ 'http://audiosnaps.com/k/1qen',
23
+ 'http://audiosnaps.com/k/1qey/',
24
+ 'http://audiosnaps.com/k/1qf5',
25
+ 'http://audiosnaps.com/k/1qf2/',
26
+ ),
27
+ 'invalid' => array(
28
+ 'http://audiosnaps.com/',
29
+ 'http://audiosnaps.com/about/faq/',
30
+ 'http://audiosnaps.com/about/contact/',
31
+ ),
32
+ 'normalize' => array(
33
+ 'http://audiosnaps.com/k/1qf2/' => 'http://audiosnaps.com/k/1qf2/',
34
+ 'http://audiosnaps.com/k/1qf2' => 'http://audiosnaps.com/k/1qf2/',
35
+ ),
36
+ 'fake' => array(
37
+ 'type' => 'rich',
38
+ 'html' => '<iframe'
39
+ )
40
+ );
41
+
42
+ public function testProvider() { $this->validateProvider('AudioSnaps'); }
43
+ }
44
+ ?>
library/ostraining/embera/Tests/TestServiceBambuser.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceBambuser.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceBambuser extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://bambuser.com/v/3853413',
20
+ 'http://bambuser.com/v/3828591/',
21
+ 'http://bambuser.com/channel/peterpstuttgart',
22
+ 'http://www.bambuser.com/v/3828416',
23
+ 'http://bambuser.com/v/3847370',
24
+ 'http://bambuser.com/v/3901540',
25
+ ),
26
+ 'invalid' => array(
27
+ 'http://bambuser.com/broadcasts',
28
+ 'http://bambuser.com/premium',
29
+ 'http://bambuser.com/tag/Business',
30
+ 'http://bambuser.com/tag/TMSO',
31
+ 'http://bambuser.com/',
32
+ ),
33
+ 'normalize' => array(
34
+ 'http://www.bambuser.com/v/3847370/' => 'http://bambuser.com/v/3847370',
35
+ 'http://www.bambuser.com/v/3847370' => 'http://bambuser.com/v/3847370',
36
+ 'http://bambuser.com/channel/peterpstuttgart/broadcast/3847370' => 'http://bambuser.com/v/3847370',
37
+ 'http://bambuser.com/channel/peterpstuttgart/broadcast/3847370/other/stuff' => 'http://bambuser.com/v/3847370',
38
+ ),
39
+ 'fake' => array(
40
+ 'type' => 'video',
41
+ 'html' => '<embed'
42
+ )
43
+ );
44
+
45
+ public function testProvider() { $this->validateProvider('Bambuser'); }
46
+ }
47
+ ?>
library/ostraining/embera/Tests/TestServiceBlipTv.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceBlipTv.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceBlipTv extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://a.blip.tv/laurainthekitchen/veggie-burger-recipe-6615471',
20
+ 'http://a.blip.tv/fnetwork/julien-fournie-paris-haute-couture-fall-winter-2013-fashion-network-6629497',
21
+ 'http://blip.tv/nostalgiacritic/nostalgia-critic-sailor-moon-6625851/',
22
+ 'http://blip.tv/phelous/deadly-friend-6617287',
23
+ 'http://blip.tv/v8tv/muscle-car-of-the-week-video-8-34-2-mile-1970-chevelle-ss-ls6-6623905',
24
+ 'http://blip.tv/askaninja/ask-a-ninja-question-34-the-bloodys-4441669',
25
+ 'http://blip.tv/nostalgia-chick/nostalgia-chick-lord-of-the-rings-return-of-the-king-part-1-6513810',
26
+ ),
27
+ 'invalid' => array(
28
+ 'http://blip.tv/drama-videos',
29
+ 'http://blip.tv/askaninja/ask-a-ninja-question-34-the-bloodys', // Doesnt end with number id
30
+ 'http://blip.tv/muscle-car-of-the-week-video-8-34-2-mile-1970-chevelle-ss-ls6-6623905',
31
+ 'http://blip.tv/nostalgia-chick/nostalgia-chick-lord-of-the-rings-return-of-the-king-part-1-6513810/other-stuff',
32
+ 'http://blip.tv',
33
+ ),
34
+ );
35
+
36
+ public function testProvider() { $this->validateProvider('BlipTv'); }
37
+ }
38
+ ?>
library/ostraining/embera/Tests/TestServiceCacoo.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceCacoo.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceCacoo extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://cacoo.com/diagrams/m9uZtizE5I2GkFR6',
20
+ 'http://cacoo.com/diagrams/eQe99LVxlYdVCvHA/',
21
+ 'https://www.cacoo.com/diagrams/9mG2aVxsBqoH69Qh',
22
+ 'https://cacoo.com/diagrams/z4IixDJR44iCqIYw/',
23
+ 'http://cacoo.com/diagrams/6NbKDcInDTisv2vU',
24
+ 'https://www.cacoo.com/diagrams/ZQ4rgdwXvTZFGQX8',
25
+ 'https://cacoo.com/diagrams/zN0Uen7DE0OyCuBC',
26
+ 'https://www.cacoo.com/diagrams/dbIT1zRnPJw8lCfj',
27
+ 'https://cacoo.com/diagrams/6NbKDcInDTisv2vU/other/stuff',
28
+ ),
29
+ 'invalid' => array(
30
+ 'https://cacoo.com/lang/en/?ref=logo',
31
+ 'https://cacoo.com/lang/en/tour?ref=header',
32
+ 'https://cacoo.com/lang/en/faq',
33
+ 'https://cacoo.com/signup',
34
+ 'https://cacoo.com/',
35
+ ),
36
+ 'normalize' => array(
37
+ 'https://www.cacoo.com/diagrams/9mG2aVxsBqoH69Qh' => 'https://cacoo.com/diagrams/9mG2aVxsBqoH69Qh',
38
+ 'http://www.cacoo.com/diagrams/9mG2aVxsBqoH69Qh/' => 'https://cacoo.com/diagrams/9mG2aVxsBqoH69Qh',
39
+ 'https://cacoo.com/diagrams/9mG2aVxsBqoH69Qh/' => 'https://cacoo.com/diagrams/9mG2aVxsBqoH69Qh',
40
+ 'https://cacoo.com/diagrams/9mG2aVxsBqoH69Qh/view?w=40&h=80' => 'https://cacoo.com/diagrams/9mG2aVxsBqoH69Qh',
41
+ ),
42
+ 'fake' => array(
43
+ 'type' => 'rich',
44
+ 'html' => '<iframe'
45
+ )
46
+ );
47
+
48
+ public function testProvider() { $this->validateProvider('Cacoo'); }
49
+ }
50
+ ?>
library/ostraining/embera/Tests/TestServiceChartblocks.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceChatblocks.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceChatblocks extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://public.chartblocks.com/c/54271427c9a61d8e0c8b4567/',
20
+ 'http://public.chartblocks.com/c/54276401c9a61d9b168b4567/',
21
+ 'http://public.chartblocks.com/c/542711b8c9a61d110c8b4567',
22
+ 'http://public.chartblocks.com/c/54286c66c9a61d252ed5c969/',
23
+ 'http://public.chartblocks.com/c/54267c1ec9a61d5a7d8b4567/',
24
+ 'http://public.chartblocks.com/c/54290b36c9a61de63ad5c969',
25
+ 'http://public.chartblocks.com/c/54268e52c9a61dcd7e8b4567',
26
+ ),
27
+ 'invalid' => array(
28
+ 'http://public.chartblocks.com/',
29
+ 'http://public.chartblocks.com/latest/',
30
+ 'http://www.chartblocks.com/en/',
31
+ ),
32
+ 'fake' => array(
33
+ 'type' => 'rich',
34
+ 'html' => '<iframe'
35
+ )
36
+ );
37
+
38
+ public function testProvider() { $this->validateProvider('Chartblocks'); }
39
+ }
40
+ ?>
library/ostraining/embera/Tests/TestServiceChirbit.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceChirbit.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceChirbit extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://chirb.it/w3gGKr',
20
+ 'http://chirb.it/gJDBHO',
21
+ 'http://chirb.it/wtJs5e/',
22
+ 'http://www.chirb.it/185err',
23
+ 'http://chirb.it/x0sw0k',
24
+ 'http://chirb.it/zGt9tG',
25
+ ),
26
+ 'invalid' => array(
27
+ 'http://chirbit.it/top-50-chirbits-this-week.php',
28
+ 'http://www.chirbit.com/top-50-chirbits-this-week.php',
29
+ 'http://www.chirbit.com/',
30
+ 'http://chirb.it',
31
+ ),
32
+ 'normalize' => array(
33
+ 'http://chirb.it/wp/wtJs5e/' => 'http://chirb.it/wtJs5e',
34
+ 'http://chirb.it/wp/wtJs5e/other/stuff' => 'http://chirb.it/wtJs5e',
35
+ 'http://chirb.it/wp/wtJs5e' => 'http://chirb.it/wtJs5e',
36
+ ),
37
+ 'fake' => array(
38
+ 'type' => 'rich',
39
+ 'html' => '<iframe'
40
+ )
41
+ );
42
+
43
+ public function testProvider() { $this->validateProvider('Chirbit'); }
44
+ }
45
+ ?>
library/ostraining/embera/Tests/TestServiceCircuitLab.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceCircuitLab.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceCircuitLab extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://www.circuitlab.com/circuit/e38756/555-timer-as-astable-multivibrator-oscillator/',
20
+ 'https://www.circuitlab.com/circuit/fby849/bjt-cascoded-active-load-differential-amplifier-with-cmfb',
21
+ 'https://circuitlab.com/circuit/4da864/diode-half-wave-rectifier/',
22
+ 'https://circuitlab.com/circuit/z79rqm/leds-with-resistor-biasing',
23
+ 'https://www.circuitlab.com/circuit/42475b/mosfet-and-resistor-nand-gate/',
24
+ 'https://www.circuitlab.com/circuit/4da864/embed_target/?width=540',
25
+ 'https://circuitlab.com/cz79rqm/',
26
+ 'https://circuitlab.com/cz79rqm',
27
+ ),
28
+ 'invalid' => array(
29
+ 'https://www.circuitlab.com/',
30
+ 'https://www.circuitlab.com/forums/',
31
+ 'https://www.circuitlab.com/circuit/z79rqm/leds-with-resistor-biasing/other/stuff',
32
+ ),
33
+ 'normalize' => array(
34
+ 'https://circuitlab.com/circuit/4da864/diode-half-wave-rectifier/' => 'https://www.circuitlab.com/circuit/4da864/diode-half-wave-rectifier/',
35
+ 'https://circuitlab.com/circuit/z79rqm/leds-with-resistor-biasing' => 'https://www.circuitlab.com/circuit/z79rqm/leds-with-resistor-biasing',
36
+ 'https://circuitlab.com/cz79rqm' => 'https://www.circuitlab.com/circuit/z79rqm/',
37
+ 'https://circuitlab.com/cz79rqm/' => 'https://www.circuitlab.com/circuit/z79rqm/',
38
+ 'https://www.circuitlab.com/circuit/4da864/embed_target/?width=540' => 'https://www.circuitlab.com/circuit/4da864/embed_target/',
39
+ ),
40
+ 'fake' => array(
41
+ 'type' => 'rich',
42
+ 'html' => '<iframe'
43
+ )
44
+ );
45
+
46
+ public function testProvider() { $this->validateProvider('CircuitLab'); }
47
+ }
48
+ ?>
library/ostraining/embera/Tests/TestServiceClyp.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceClyp.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceClyp extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://clyp.it/s43cav2h',
20
+ 'http://clyp.it/qtbwbkk0',
21
+ 'http://clyp.it/ucknjpgc/',
22
+ 'http://clyp.it/playlist/1kmfioze',
23
+ 'http://clyp.it/xe5rm1ie',
24
+ ),
25
+ 'invalid' => array(
26
+ 'http://clyp.it/rebrand',
27
+ 'http://clyp.it/ucknjpgc/other/stuff',
28
+ 'http://clyp.it/stuff/xe5rm1ie',
29
+ )
30
+ );
31
+
32
+ public function testProvider() { $this->validateProvider('Clyp'); }
33
+ }
34
+ ?>
library/ostraining/embera/Tests/TestServiceCodepoints.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceCodepoints.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceCodepoints extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://codepoints.net/U+FEB9',
20
+ 'https://codepoints.net/U+27F4/',
21
+ 'https://www.codepoints.net/U+2425',
22
+ 'https://codepoints.net/U+20B4',
23
+ 'http://codepoints.net/U+1E46',
24
+ ),
25
+ 'invalid' => array(
26
+ 'http://codepoints.net/',
27
+ 'https://codepoints.net/basic_multilingual_plane',
28
+ 'https://codepoints.net/scripts',
29
+ ),
30
+ 'fake' => array(
31
+ 'type' => 'rich',
32
+ 'html' => '<iframe'
33
+ )
34
+ );
35
+
36
+ public function testProvider() { $this->validateProvider('Codepoints'); }
37
+ }
38
+ ?>
library/ostraining/embera/Tests/TestServiceCollegeHumor.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceCollegeHumor.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceCollegeHumor extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.collegehumor.com/video/6830834/mitt-romney-style-gangnam-style-parody',
20
+ 'http://www.collegehumor.com/embed/6897735/dogs-come-1-by-1-for-treats-theres-a-cat-and-oh-also-a-duck/',
21
+ 'http://www.collegehumor.com/video/6897575/',
22
+ 'http://www.collegehumor.com/embed/6897394',
23
+ 'http://www.collegehumor.com/video/6182447/kid-farm',
24
+ 'http://collegehumor.com/video/6643191/batman-chooses-his-voice',
25
+ 'http://collegehumor.com/video/6621074',
26
+ 'http://www.collegehumor.com/video/6817857/the-dark-knight-meets-the-avengers',
27
+ ),
28
+ 'invalid' => array(
29
+ 'http://www.collegehumor.com/embedVideo/6897394', // wrong path
30
+ 'http://www.collegehumor.com/embed/6buaksui4', // Not numeric
31
+ 'http://www.collegehumor.com/videos/6897394',
32
+ 'http://www.collegehumor.com/6897394'
33
+ ),
34
+ 'fake' => array(
35
+ 'type' => 'video',
36
+ 'html' => '<iframe'
37
+ )
38
+ );
39
+
40
+ public function testProvider() { $this->validateProvider('CollegeHumor'); }
41
+ }
42
+ ?>
library/ostraining/embera/Tests/TestServiceCoub.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceCoub.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceCoub extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://coub.com/view/2gik7tu6',
20
+ 'http://coub.com/view/1i2na5tm',
21
+ 'http://www.coub.com/view/2oa3zbsr',
22
+ 'http://coub.com/embed/20v82p5j',
23
+ 'http://coub.com/embed/omwe0oe/',
24
+ 'http://coub.com/view/2m7mett8/',
25
+ 'http://coub.com/embed/29zkqoco',
26
+ ),
27
+ 'invalid' => array(
28
+ 'http://coub.com/explore/art-design',
29
+ 'http://coub.com/view/2m7mett8/other-stuff/',
30
+ 'http://coub.com/explore/girls',
31
+ 'http://coub.com/embed/',
32
+ 'http://coub.com/view/',
33
+ 'http://coub.com/',
34
+ ),
35
+ 'normalize' => array(
36
+ 'http://coub.com/view/231nevc?small_suggest_place=3' => 'http://coub.com/view/231nevc',
37
+ 'http://coub.com/view/231nevc/?small_suggest_place=3&stuff=hihi-hi' => 'http://coub.com/view/231nevc',
38
+ 'http://www.coub.com/view/231nevc?small_suggest_place=3&stuff=hihi-hi' => 'http://coub.com/view/231nevc',
39
+ ),
40
+ 'fake' => array(
41
+ 'type' => 'video',
42
+ 'html' => '<iframe'
43
+ )
44
+ );
45
+
46
+ public function testProvider() { $this->validateProvider('Coub'); }
47
+ }
48
+ ?>
library/ostraining/embera/Tests/TestServiceCrowdRanking.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceCrowdRanking.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceCrowdRanking extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://crowdranking.com/crowdrankings/t470g0--best-tea',
20
+ 'http://crowdranking.com/crowdrankings/t272g0--tv-serien/',
21
+ 'http://crowdranking.com/crowdrankings/t485g0--what-makes-you-want-to-live-longer',
22
+ 'http://crowdranking.com/crowdrankings/t573g0--top-tourismusregionen-in-oesterreich',
23
+ 'http://www.crowdranking.com/crowdrankings/t537g0--die-besten-premium-kompaktkameras-2013',
24
+ 'http://crowdranking.com/crowdrankings/t564g0--was-mich-am-meisten-nervt',
25
+ 'http://c9ng.com/r/t537g0',
26
+ 'http://c9ng.com/r/t470g0',
27
+ ),
28
+ 'invalid' => array(
29
+ 'http://crowdranking.com/groups/0',
30
+ 'http://crowdranking.com/groups/0?cat=creativity-diy',
31
+ 'http://crowdranking.com/groups/0?cat=people-celebrities',
32
+ 'http://crowdranking.com',
33
+ 'http://crowdranking.com/login',
34
+ ),
35
+ 'normalize' => array(
36
+ 'http://c9ng.com/r/t470g0' => 'http://crowdranking.com/r/t470g0',
37
+ 'http://c9ng.com/r/t470g0/' => 'http://crowdranking.com/r/t470g0',
38
+ 'http://crowdranking.com/crowdrankings/t573g0--top-tourismusregionen-in-oesterreich' => 'http://crowdranking.com/crowdrankings/t573g0--top-tourismusregionen-in-oesterreich',
39
+ 'http://www.crowdranking.com/crowdrankings/t537g0--die-besten-premium-kompaktkameras-2013' => 'http://crowdranking.com/crowdrankings/t537g0--die-besten-premium-kompaktkameras-2013',
40
+ ),
41
+ 'fake' => array(
42
+ 'type' => 'rich',
43
+ 'html' => '<iframe'
44
+ )
45
+ );
46
+
47
+ public function testProvider() { $this->validateProvider('CrowdRanking'); }
48
+ }
49
+ ?>
library/ostraining/embera/Tests/TestServiceDailyMile.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceDailyMile.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceDailyMile extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.dailymile.com/people/EddieJ3/entries/24776213',
20
+ 'http://www.dailymile.com/people/JessicaP30/entries/24791047',
21
+ 'http://www.dailymile.com/people/JimF3/entries/24684863',
22
+ 'http://www.dailymile.com/people/JimF3/entries/24623801/',
23
+ 'http://dailymile.com/people/JimF3/entries/24447986',
24
+ 'http://dailymile.com/people/IANH17/entries/24533363/',
25
+ 'http://www.dailymile.com/people/IANH17/entries/24444266',
26
+ ),
27
+ 'invalid' => array(
28
+ 'http://www.dailymile.com/people/EddieJ3',
29
+ 'http://www.dailymile.com/',
30
+ 'http://www.dailymile.com/signup',
31
+ 'http://www.dailymile.com/people/K_P_S',
32
+ ),
33
+ );
34
+
35
+ public function testProvider() { $this->validateProvider('DailyMile'); }
36
+ }
37
+ ?>
library/ostraining/embera/Tests/TestServiceDailyMotion.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceDailyMotion.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceDailyMotion extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.dailymotion.com/video/xxwxe1_harlem-shake-de-los-simpsons_fun',
20
+ 'http://dailymotion.com/video/xp30q9_bmw-serie3-2012-en-mexico_auto',
21
+ 'http://www.dailymotion.com/video/xzva95_jacob-jones-and-the-bigfoot-mystery-launch-trailer_videogames',
22
+ 'http://www.dailymotion.com/video/xzx4m4_balotelli-au-prochain-cri-raciste-je-quitte-le-terrain_sport?from=rss',
23
+ 'http://www.dailymotion.com/video/xzse1m_casanova-tout-reste-possible-pour-l-om_sport/stuff/here/',
24
+ 'http://www.dailymotion.com/embed/video/xzv0cd/',
25
+ 'http://dai.ly/xzse1m',
26
+ 'http://games.dailymotion.com/video/xq3p3u',
27
+ 'http://games.dailymotion.com/video/x2gfjhs',
28
+ 'http://games.dailymotion.com/live/x15gjhi',
29
+ ),
30
+ 'invalid' => array(
31
+ 'http://www.dailymotion.com',
32
+ 'http://dailymotion.com',
33
+ 'http://www.dailymotion.com/channel/stuff/',
34
+ 'http://www.dailymotion.com/stuff/',
35
+ 'http://www.dailymotion.com/video/'
36
+ ),
37
+ 'normalize' => array(
38
+ 'http://www.dailymotion.com/video/xxwxe1_harlem-shake-de-los-simpsons_fun' => 'http://www.dailymotion.com/video/xxwxe1_harlem-shake-de-los-simpsons_fun',
39
+ 'http://dailymotion.com/video/xp30q9_bmw-serie3-2012-en-mexico_auto' => 'http://www.dailymotion.com/video/xp30q9_bmw-serie3-2012-en-mexico_auto',
40
+ 'http://www.dailymotion.com/video/xzxtaf_red-bull-400-alic-y-stadlober-ganan-en-eslovenia_sport/' => 'http://www.dailymotion.com/video/xzxtaf_red-bull-400-alic-y-stadlober-ganan-en-eslovenia_sport',
41
+ 'http://www.dailymotion.com/embed/video/xzxfpu' => 'http://www.dailymotion.com/video/xzxfpu',
42
+ 'http://www.dailymotion.com/video/xzx4m4_balotelli-au-prochain-cri-raciste-je-quitte-le-terrain_sport?from=rss' => 'http://www.dailymotion.com/video/xzx4m4_balotelli-au-prochain-cri-raciste-je-quitte-le-terrain_sport',
43
+ 'http://www.dailymotion.com/embed/video/xzv0cd/' => 'http://www.dailymotion.com/video/xzv0cd',
44
+ 'http://www.dailymotion.com/video/xzse1m_casanova-tout-reste-possible-pour-l-om_sport/stuff/here/' => 'http://www.dailymotion.com/video/xzse1m_casanova-tout-reste-possible-pour-l-om_sport',
45
+ 'http://dai.ly/xzv0cd/' => 'http://www.dailymotion.com/video/xzv0cd',
46
+ 'http://dai.ly/xzv0cd' => 'http://www.dailymotion.com/video/xzv0cd',
47
+ 'http://games.dailymotion.com/live/xq3p3u' => 'http://www.dailymotion.com/video/xq3p3u',
48
+ ),
49
+ 'fake' => array(
50
+ 'type' => 'video',
51
+ 'html' => '<iframe'
52
+ )
53
+ );
54
+
55
+ public function testProvider() { $this->validateProvider('DailyMotion'); }
56
+ }
57
+ ?>
library/ostraining/embera/Tests/TestServiceDeviantart.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceDeviantart.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceDeviantart extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://wordofchen.deviantart.com/art/Pressure-379617958/',
20
+ 'http://sarahharas1.deviantart.com/art/Purple-haze-379565213/',
21
+ 'http://m-eralp.deviantart.com/art/After-rain-bomb-379561772',
22
+ 'http://fav.me/d69yyh3/',
23
+ 'http://fav.me/d67maku',
24
+ ),
25
+ 'invalid' => array(
26
+ 'http://lieveheersbeestje.deviantart.com/art/house/Heart-of-gold-378848984',
27
+ 'http://wordofchen.deviantart.com/soup/Pressure-379617958',
28
+ 'http://sarahharas1.deviantart.com/class/379565213',
29
+ 'http://fav.me/d69yyh3/stuff/',
30
+ 'http://sta.sh/',
31
+ 'http://fav.me/',
32
+ ),
33
+ 'private' => array(
34
+ 'http://sooper-deviant.deviantart.com/art/Brand-New-Day-1769-376513535'
35
+ )
36
+ );
37
+
38
+ public function testProvider() { $this->validateProvider('Deviantart'); }
39
+ }
40
+ ?>
library/ostraining/embera/Tests/TestServiceDipity.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceDipity.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceDipity extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ //'http://www.dipity.com/BIRN/Albania-Local-Elections-2011/',
20
+ 'http://www.dipity.com/StevePro/Skype-from-startup-to-8-5-billion-sale',
21
+ 'http://www.dipity.com/ibmzrl/Nanotechnology-at-IBM-Research/',
22
+ 'http://dipity.com/StevePro/2010-in-Review/',
23
+ 'http://www.dipity.com/timeline/Nba-Finals/',
24
+ ),
25
+ 'invalid' => array(
26
+ 'http://www.dipity.com/timeline/Nba-Finals/other/stuff',
27
+ 'http://www.dipity.com/',
28
+ 'http://www.dipity.com/premium',
29
+ 'http://www.dipity.com/timetube',
30
+ 'http://www.dipity.com/join',
31
+ ),
32
+ 'normalize' => array(
33
+ 'http://dipity.com/StevePro/2010-in-Review/' => 'http://dipity.com/StevePro/2010-in-Review/',
34
+ 'http://dipity.com/StevePro/2010-in-Review/?cuaccuac=cuac' => 'http://dipity.com/StevePro/2010-in-Review/',
35
+ ),
36
+ 'fake' => array(
37
+ 'type' => 'rich',
38
+ 'html' => '<iframe'
39
+ )
40
+ );
41
+
42
+ public function testProvider() { $this->validateProvider('Dipity'); }
43
+ }
44
+ ?>
library/ostraining/embera/Tests/TestServiceDotSub.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceDotSub.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceDotSub extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://dotsub.com/view/f2a85663-d9eb-4d92-bb61-fd960c401b23',
20
+ 'http://dotsub.com/view/0ebc725c-a805-4486-a1df-c1e7dccf8c6e/',
21
+ 'http://www.dotsub.com/view/dcef6c2a-3fb7-4ab1-9bc8-fd621b2c3972',
22
+ 'http://dotsub.com/media/b7a2859d-69a3-45f2-8e4e-88f2f15b3f97',
23
+ 'http://dotsub.com/view/85897135-c6ee-4c93-acdd-d7e7f4d08b6e',
24
+ 'http://dotsub.com/view/99eaba09-787a-40a9-9125-27a729de71db',
25
+ 'http://dotsub.com/view/99eaba09-787a-40a9-9125-27a729de71db/other/stuff',
26
+ ),
27
+ 'invalid' => array(
28
+ 'http://dotsub.com/view/xxx-xxx-xxxx-xxxx-xxxxx', // It seems that dotsub uses base 64 only as id
29
+ 'http://dotsub.com/view/',
30
+ 'http://dotsub.com/view/?',
31
+ 'http://dotsub.com/view/mostviewed',
32
+ 'http://dotsub.com/view/language/both/dug',
33
+ 'http://dotsub.com',
34
+ ),
35
+ 'normalize' => array(
36
+ 'http://www.dotsub.com/media/396b2b58-9a9c-42f3-b7cb-4a282964b11c/embed/' => 'http://dotsub.com/view/396b2b58-9a9c-42f3-b7cb-4a282964b11c',
37
+ 'http://www.dotsub.com/media/396b2b58-9a9c-42f3-b7cb-4a282964b11c/e/c?width=500&height=300' => 'http://dotsub.com/view/396b2b58-9a9c-42f3-b7cb-4a282964b11c',
38
+ 'http://dotsub.com/media/5af2ea32-1aa1-4fa7-9d36-b3a01e841ca2/embed/' => 'http://dotsub.com/view/5af2ea32-1aa1-4fa7-9d36-b3a01e841ca2',
39
+ ),
40
+ 'fake' => array(
41
+ 'type' => 'video',
42
+ 'html' => '<iframe'
43
+ )
44
+ );
45
+
46
+ public function testProvider() { $this->validateProvider('DotSub'); }
47
+ }
48
+ ?>
library/ostraining/embera/Tests/TestServiceEdocr.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceEdocr.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceEdocr extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.edocr.com/doc/146834/glossary-pdf-terminology',
20
+ 'http://www.edocr.com/doc/145567/tax-returns-outsourcing-debt-collection-outsourcing',
21
+ 'http://edocr.com/doc/141258/ecopowersupplies-riello-sentinel-dual-ups',
22
+ 'http://www.edocr.com/doc/120039/why-what-and-how-supplier-management/',
23
+ 'http://www.edocr.com/doc/8/uk-visa-application-form-vaf1/',
24
+ 'http://www.edocr.com/doc/8/uk-visa-application-form-guidance-notes?string=stuff',
25
+ 'http://www.edocr.com/doc/8/eye-colombo-inspector-general-police-jayantha-wickramaratna',
26
+ 'http://www.edocr.com/doc/3773/invest-nottingham-brochure-2',
27
+ ),
28
+ 'invalid' => array(
29
+ 'http://www.edocr.com/',
30
+ 'http://www.edocr.com/explore',
31
+ 'http://www.edocr.com/doc/not-numeric/other-stuff-here',
32
+ 'http://www.edocr.com/search/node/cuac',
33
+ 'http://www.edocr.com/publish',
34
+ 'http://www.edocr.com/organisation',
35
+ 'http://www.edocr.com/build-your-brand',
36
+ ),
37
+ );
38
+
39
+ public function testProvider() { $this->validateProvider('Edocr'); }
40
+ }
41
+ ?>
library/ostraining/embera/Tests/TestServiceEgliseInfo.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceEgliseInfo.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceEgliseInfo extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://egliseinfo.catholique.fr/horaires/paris',
20
+ 'http://egliseinfo.catholique.fr/a-proximite/paris',
21
+ ),
22
+ 'invalid' => array(
23
+ 'http://egliseinfo.catholique.fr/'
24
+ ),
25
+ );
26
+
27
+ public function testProvider() { $this->validateProvider('EgliseInfo'); }
28
+ }
29
+ ?>
library/ostraining/embera/Tests/TestServiceFacebook.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceFacebook.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceFacebook extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ /**
20
+ * FIXME:
21
+ * Could not find valid public urls with the following formats:
22
+ * - https://www.facebook.com/questions/{question-id}
23
+ * - https://www.facebook.com/{username}/activity/{activity-id}
24
+ * - https://www.facebook.com/video.php?id={video-id}
25
+ * - https://www.facebook.com/photos/{photo-id}
26
+ *
27
+ * I found examples for this type of urls, but it seems that is not supported
28
+ * and since we know Facebook sucks at mantaining API's, is not a surprise
29
+ * - https://www.facebook.com/media/set?set={set-id}
30
+ * https://facebook.com/media/set/?set=a.396848117509.174735.184651592509
31
+ * https://www.facebook.com/media/set/?set=a.334300020471.345441.296274160471&type=3
32
+ */
33
+ 'https://www.facebook.com/nopegida/posts/1117276211625055',
34
+ 'https://www.facebook.com/nopegida/posts/1117045234981486/',
35
+ 'https://www.facebook.com/notes/nopegida/netiquette/920088871343791',
36
+ 'https://facebook.com/coca-cola/photos/a.99394368305.88399.40796308305/10154703575238306/?type=3',
37
+ 'https://www.facebook.com/photo.php?fbid=10151025976302510&set=a.10150992587227510.445966.184651592509&type=1&relevant_count=1',
38
+ 'http://www.facebook.com/permalink.php?story_fbid=660811664028467&id=282562525186718',
39
+ 'https://www.facebook.com/4jonnhart/videos/838982552851199/',
40
+ 'https://www.facebook.com/video.php?v=10153482090911661',
41
+ ),
42
+ 'invalid' => array(
43
+ 'https://www.facebook.com/',
44
+ 'https://facebook.com/docs/plugins/oembed-endpoints',
45
+ 'https://www.facebook.com/about/privacy',
46
+ 'https://www.facebook.com/login.php',
47
+ 'https://www.facebook.com/lite/',
48
+ 'https://www.facebook.com/nopegida/',
49
+ 'https://www.facebook.com/photo.php?bad_order=1&fbid=10151025976302510&set=a.10150992587227510.445966.184651592509',
50
+ ),
51
+ );
52
+
53
+ public function testProvider() { $this->validateProvider('Facebook'); }
54
+ }
55
+ ?>
library/ostraining/embera/Tests/TestServiceFlickr.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceFlickr.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceFlickr extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.flickr.com/photos/22134962@N03/8738306577/in/explore-2013-05-14',
20
+ 'http://flic.kr/p/9gAMbM',
21
+ 'http://www.flickr.com/photos/reddragonflydmc/5427387397/',
22
+ 'http://www.flickr.com/photos/bees/8597283706/in/photostream',
23
+ 'http://www.flickr.com/photos/bees/8537962055/?noise=noise',
24
+ 'http://flic.kr/p/9gAMbM/',
25
+ 'http://www.flickr.com/photos/bees/8429256478'
26
+ ),
27
+ 'invalid' => array(
28
+ 'http://www.flickr.com/22134962@N03/8738306577/',
29
+ 'http://www.flickr.com',
30
+ 'http://www.flickr.com/stuff/8429256478/',
31
+ 'http://www.flickr.com/noise/8429256478/',
32
+ 'http://www.flickr.com//8429256478/'
33
+ ),
34
+ 'normalize' => array(
35
+ 'http://www.flickr.com/photos/22134962@N03/8738306577/in/explore-2013-05-14' => 'http://www.flickr.com/photos/22134962@N03/8738306577/',
36
+ 'http://flic.kr/p/9gAMbM' => 'http://flic.kr/p/9gAMbM',
37
+ 'http://www.flickr.com/photos/reddragonflydmc/5427387397/?noise=noise' => 'http://www.flickr.com/photos/reddragonflydmc/5427387397/',
38
+ 'http://www.flickr.com/photos/bees/8597283706/in/photostream' => 'http://www.flickr.com/photos/bees/8597283706/',
39
+ 'http://flic.kr/p/9gAMbM/' => 'http://flic.kr/p/9gAMbM/',
40
+ 'http://www.flickr.com/photos/bees/8429256478' => 'http://www.flickr.com/photos/bees/8429256478/',
41
+ 'http://www.flickr.com/photos/bees/8429256478/' => 'http://www.flickr.com/photos/bees/8429256478/',
42
+ )
43
+ );
44
+
45
+ public function testProvider() { $this->validateProvider('Flickr'); }
46
+ }
47
+ ?>
library/ostraining/embera/Tests/TestServiceFunnyOrDie.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceFunnyOrDie.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceFunnyOrDie extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.funnyordie.com/videos/a1738b0a3f/i-hate-california-lake-tahoe',
20
+ 'http://funnyordie.com/videos/8b2b588243/tom-brady-s-best-friend',
21
+ 'http://www.funnyordie.com/videos/6b0b308f41/coming-soon-from-funny-or-die-with-will-ferrell/',
22
+ 'http://funnyordie.com/videos/c4d450418e/magician-vs-wild',
23
+ 'http://funnyordie.com/embed/c4d450418e/magician-vs-wild',
24
+ 'http://funnyordie.com/embed/c4d450418e',
25
+ 'http://www.funnyordie.com/videos/bc5f676260/tony-hale-s-acting-process',
26
+ 'http://www.funnyordie.com/videos/bc5f676260/tony-hale-s-acting-process/other/stuff',
27
+ ),
28
+ 'invalid' => array(
29
+ 'http://www.funnyordie.com/#search-menu',
30
+ 'http://www.funnyordie.com/pictures/2d8a7b4876/get-the-look-miley-cyrus', // Pictures dont allow oembed
31
+ 'http://www.funnyordie.com/drunkhistory',
32
+ 'http://www.funnyordie.com/browse/videos/all/all/most_viewed/this_week',
33
+ 'http://www.funnyordie.com/support/widget',
34
+ 'http://www.funnyordie.com/marion_cotillard',
35
+ ),
36
+ 'normalize' => array(
37
+ 'http://www.funnyordie.com/embed/6b0b308f41/coming-soon-from-funny-or-die-with-will-ferrell/' => 'http://www.funnyordie.com/videos/6b0b308f41/coming-soon-from-funny-or-die-with-will-ferrell',
38
+ 'http://www.funnyordie.com/embed/6b0b308f41/' => 'http://www.funnyordie.com/videos/6b0b308f41',
39
+ 'http://www.funnyordie.com/embed/6b0b308f41/?query=string' => 'http://www.funnyordie.com/videos/6b0b308f41',
40
+ ),
41
+ 'fake' => array(
42
+ 'type' => 'video',
43
+ 'html' => '<iframe'
44
+ )
45
+ );
46
+
47
+ public function testProvider() { $this->validateProvider('FunnyOrDie'); }
48
+ }
49
+ ?>
library/ostraining/embera/Tests/TestServiceGeographCI.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceGeographCI.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceGeographCI extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://channel-islands.geographs.org/photo/1166',
20
+ 'http://channel-islands.geographs.org/photo/952',
21
+ 'http://channel-islands.geographs.org/photo/1231',
22
+ 'http://channel-islands.geographs.org.je/photo/961',
23
+ 'http://channel-islands.geographs.org.gg/photo/984',
24
+ 'http://channel-islands.geographs.org/photo/656',
25
+ ),
26
+ 'invalid' => array(
27
+ 'http://channel-islands.geographs.org/discuss/',
28
+ 'http://channel-islands.geographs.org/submit.php',
29
+ 'http://channel-islands.geographs.org/submit.php',
30
+ 'http://channel-islands.geographs.org/list.php',
31
+ ),
32
+ );
33
+
34
+ public function testProvider() { $this->validateProvider('GeographCI'); }
35
+ }
36
+ ?>
library/ostraining/embera/Tests/TestServiceGeographDe.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceGeographDe.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceGeographDe extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://geo-en.hlipp.de/photo/36058',
20
+ 'http://geo-en.hlipp.de/photo/22092/',
21
+ 'http://geo.hlipp.de/photo/35233',
22
+ 'http://geo.hlipp.de/photo/30213',
23
+ 'http://germany.geograph.org/photo/40426',
24
+ 'http://germany.geograph.org/photo/36058',
25
+ ),
26
+ 'invalid' => array(
27
+ 'http://geo-en.hlipp.de/discuss/',
28
+ 'http://geo-en.hlipp.de/latlong.php',
29
+ 'http://geo-en.hlipp.de/gallery/historische_bauten_historic_buildings_127',
30
+ 'http://geo.hlipp.de/photo/35233/more-stuff',
31
+ ),
32
+ );
33
+
34
+ public function testProvider() { $this->validateProvider('GeographDe'); }
35
+ }
36
+ ?>
library/ostraining/embera/Tests/TestServiceGeographUk.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceGeographUk.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceGeographUk extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.geograph.org.uk/photo/3619867',
20
+ 'http://www.geograph.org.uk/photo/2308394/',
21
+ 'http://www.geograph.org.uk/photo/1449749',
22
+ 'http://www.geograph.co.uk/photo/292839',
23
+ 'http://www.geograph.ie/photo/353656',
24
+ 'http://www.geograph.org.uk/photo/1146430',
25
+ 'http://www.geograph.ie/photo/973235',
26
+ ),
27
+ 'invalid' => array(
28
+ 'http://www.geograph.ie/gallery.php',
29
+ 'http://www.geograph.org/gallery.php?tab=highest',
30
+ 'http://www.geograph.org.uk/photo/2000063/other/stuff',
31
+ 'http://www.geograph.org.uk/photo/words',
32
+ ),
33
+ );
34
+
35
+ public function testProvider() { $this->validateProvider('GeographUk'); }
36
+ }
37
+ ?>
library/ostraining/embera/Tests/TestServiceGettyImages.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceGettyImages.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceGettyImages extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.gettyimages.com/detail/photo/dog-in-car-royalty-free-image/a0200-000024?suri=1',
20
+ 'http://www.gettyimages.com/detail/photo/chocolate-labrador-retriever-rolling-on-lawn-royalty-free-image/73117582',
21
+ 'http://www.gettyimages.com/detail/photo/two-underwater-female-nude-dancers-high-res-stock-photography/160002618',
22
+ 'http://gty.im/482126281',
23
+ 'http://gty.im/137700196/',
24
+ 'http://www.gettyimages.com/detail/photo/friends-toasting-with-cocktails-in-nightclub-royalty-free-image/139801239',
25
+ ),
26
+ 'invalid' => array(
27
+ 'http://www.gettyimages.com/detail/photo/friends-toasting-with-cocktails-in-nightclub-royalty-free-image/139801239/other-stuff',
28
+ 'http://gty.im/137700196/other',
29
+ 'http://www.gettyimages.com/',
30
+ 'http://www.gettyimages.com/editorialimages/news',
31
+ 'http://www.gettyimages.com/EditorialFootage/Recentevents?parentEventId=150825084&isource=USA_NewsRot_ElectionVideo',
32
+ ),
33
+ 'normalize' => array(
34
+ 'http://www.gettyimages.com/detail/photo/dog-in-car-royalty-free-image/a0200-000024?suri=1' => 'http://gty.im/a0200-000024',
35
+ 'http://www.gettyimages.com/detail/photo/chocolate-labrador-retriever-rolling-on-lawn-royalty-free-image/73117582' => 'http://gty.im/73117582',
36
+ 'http://www.gettyimages.com/detail/photo/two-underwater-female-nude-dancers-high-res-stock-photography/160002618/' => 'http://gty.im/160002618',
37
+ ),
38
+ );
39
+
40
+ public function testProvider() { $this->validateProvider('GettyImages'); }
41
+ }
42
+ ?>
library/ostraining/embera/Tests/TestServiceGfycat.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceGfycat.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceGfycat extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://gfycat.com/SerpentineScientificJenny',
20
+ 'https://gfycat.com/FloweryAnnualArchaeopteryx',
21
+ 'http://www.gfycat.com/IckyDemandingHorse',
22
+ 'https://gfycat.com/DesertedSleepyBluetickcoonhound/',
23
+ 'http://gfycat.com/MadeupFarflungHoiho/?query=string',
24
+ 'http://gfycat.com/MiniatureCautiousDuiker',
25
+ ),
26
+ 'invalid' => array(
27
+ 'http://gfycat.com/',
28
+ 'http://gfycat.com/search/dfsdfsdf',
29
+ 'http://gfycat.com/stuff/MiniatureCautiousDuiker',
30
+ 'http://gfycat.com/terms',
31
+ 'http://gfycat.com/dmca',
32
+ 'http://gfycat.com/api',
33
+ ),
34
+ 'fake' => array(
35
+ 'type' => 'video',
36
+ 'html' => '<iframe'
37
+ )
38
+ );
39
+
40
+ public function testProvider() { $this->validateProvider('Gfycat'); }
41
+ }
42
+ ?>
library/ostraining/embera/Tests/TestServiceGithubGist.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceGithubGist.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceGithubGist extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://gist.github.com/mpratt/3177700',
20
+ 'https://gist.github.com/mpratt/5671743/',
21
+ 'https://gist.github.com/nad2000/6547920',
22
+ 'https://gist.github.com/mojavelinux/6547924#file-git-user-manual-adoc',
23
+ 'https://gist.github.com/callaght/6547921#file-issueviewcontroller-m',
24
+ 'https://gist.github.com/callaght/6547921#file-logonviewcontroller-h',
25
+ 'https://gist.github.com/ashaw/6308796',
26
+ 'https://gist.github.com/mpratt/3177700#file-database-txt'
27
+ ),
28
+ 'invalid' => array(
29
+ 'https://gist.github.com/mpratt',
30
+ 'https://gist.github.com/',
31
+ 'https://gist.github.com/discover/',
32
+ ),
33
+ 'normalize' => array(
34
+ 'https://gist.github.com/mpratt/3177700' => 'https://gist.github.com/3177700',
35
+ 'https://gist.github.com/733951' => 'https://gist.github.com/733951',
36
+ 'https://gist.github.com/LJPH/6308712#file-comet_-idea_description-html' => 'https://gist.github.com/6308712',
37
+ ),
38
+ 'fake' => array(
39
+ 'type' => 'rich',
40
+ 'html' => '<script'
41
+ )
42
+ );
43
+
44
+ public function testProvider()
45
+ {
46
+ $this->markTestIncomplete('The Github-Gist Oembed Provider, is down at the time of this test');
47
+
48
+ $this->validateProvider('GithubGist');
49
+ }
50
+ }
51
+ ?>
library/ostraining/embera/Tests/TestServiceGmep.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceGmep.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceGmep extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://gmep.org/media/14769',
20
+ 'https://gmep.org/media/14767/',
21
+ 'https://www.gmep.org/media/14763',
22
+ 'https://gmep.org/media/14740',
23
+ 'https://gmep.org/media/14725',
24
+ 'https://gmep.org/media/14714/',
25
+ ),
26
+ 'invalid' => array(
27
+ 'https://gmep.org/media/14714/other/stuff',
28
+ 'https://gmep.org/media?query=%5Bbroad+complex+tachycardia%5D',
29
+ 'https://gmep.org/media',
30
+ 'https://gmep.org/about',
31
+ 'https://gmep.org/',
32
+ ),
33
+ 'normalize' => array(
34
+ 'http://www.gmep.org/media/14714/' => 'https://gmep.org/media/14714',
35
+ 'http://gmep.org/media/14714' => 'https://gmep.org/media/14714',
36
+ 'http://www.gmep.org/media/14714' => 'https://gmep.org/media/14714',
37
+ 'http://gmep.org/media/14714?hi=you' => 'https://gmep.org/media/14714',
38
+ )
39
+ );
40
+
41
+ public function testProvider() { $this->validateProvider('Gmep'); }
42
+ }
43
+ ?>
library/ostraining/embera/Tests/TestServiceHq23.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceHq23.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceHq23 extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.23hq.com/brinjal/photo/13305971',
20
+ 'http://www.23hq.com/Dan-Tuyet/photo/13301964/',
21
+ 'http://23hq.com/gap_mike/photo/13287796',
22
+ 'http://www.23hq.com/Bo-Tina/photo/13259658',
23
+ 'http://www.23hq.com/euzmar/photo/13254262',
24
+ ),
25
+ 'invalid' => array(
26
+ 'http://www.23hq.com/23/just-in?world=1&limit=70',
27
+ 'http://www.23hq.com/photogroup',
28
+ 'http://www.23hq.com/23/signup',
29
+ 'http://www.23hq.com/',
30
+ ),
31
+ );
32
+
33
+ public function testProvider() { $this->validateProvider('Hq23'); }
34
+ }
35
+ ?>
library/ostraining/embera/Tests/TestServiceHuffduffer.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceHuffDuffer.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceHuffDuffer extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://huffduffer.com/jxpx777/125342',
20
+ 'http://huffduffer.com/Jozh/124683/',
21
+ 'http://huffduffer.com/shawnpwalsh/124687',
22
+ 'http://www.huffduffer.com/erichaberkorn/124686',
23
+ 'http://huffduffer.com/bulkorder/124688',
24
+ 'http://huffduffer.com/tfehr/124690',
25
+ 'http://huffduffer.com/jasonmklug/124719',
26
+ ),
27
+ 'invalid' => array(
28
+ 'http://huffduffer.com/tags/productivity',
29
+ 'http://huffduffer.com/tags/weekly+security+audio+column',
30
+ 'http://huffduffer.com/signup/',
31
+ 'http://huffduffer.com/',
32
+ ),
33
+ );
34
+
35
+ public function testProvider() { $this->validateProvider('HuffDuffer'); }
36
+ }
37
+ ?>
library/ostraining/embera/Tests/TestServiceHulu.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceHulu.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceHulu extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.hulu.com/watch/20807/late-night-with-conan-obrien-wed-may-21-2008',
20
+ 'http://hulu.com/watch/501126',
21
+ 'http://www.hulu.com/watch/440265/',
22
+ 'http://hulu.com/watch/476621',
23
+ 'http://www.hulu.com/watch/331822/stuff/here',
24
+ 'http://www.hulu.com/watch/416223?playlist_id=1787&asset_scope=movies',
25
+ 'http://hulu.com/watch/493032/'
26
+ ),
27
+ 'invalid' => array(
28
+ 'http://www.hulu.com/stuff/440265',
29
+ 'http://www.hulu.com/watch/abduej/2344657', // Not numeric
30
+ 'http://hulu.com/450265',
31
+ 'http://www.hulu.com/watch/44ui65/'
32
+ ),
33
+ 'normalize' => array(
34
+ 'http://www.hulu.com/watch/20807/late-night-with-conan-obrien-wed-may-21-2008' => 'http://www.hulu.com/watch/20807',
35
+ 'http://www.hulu.com/watch/440265/' => 'http://www.hulu.com/watch/440265',
36
+ 'http://www.hulu.com/watch/416223?playlist_id=1787&asset_scope=movies' => 'http://www.hulu.com/watch/416223',
37
+ 'http://hulu.com/watch/331822/stuff/here' => 'http://www.hulu.com/watch/331822',
38
+ 'http://hulu.com/watch/501126' => 'http://www.hulu.com/watch/501126',
39
+ )
40
+ );
41
+
42
+ public function testProvider() { $this->validateProvider('Hulu'); }
43
+ }
44
+ ?>
library/ostraining/embera/Tests/TestServiceIFTTT.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceIFTTT.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceIFTTT extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://ifttt.com/recipes/112989',
20
+ 'https://www.ifttt.com/recipes/111063',
21
+ 'https://ifttt.com/recipes/113633/',
22
+ 'https://www.ifttt.com/recipes/109983/',
23
+ ),
24
+ 'invalid' => array(
25
+ 'https://ifttt.com/recipes',
26
+ 'https://ifttt.com/',
27
+ 'https://ifttt.com/recipes/search?q=gmail',
28
+ 'https://ifttt.com/recipes/search',
29
+ ),
30
+ 'fake' => array(
31
+ 'type' => 'rich',
32
+ 'html' => '<script'
33
+ )
34
+ );
35
+
36
+ public function testProvider() { $this->validateProvider('IFTTT'); }
37
+ }
38
+ ?>
library/ostraining/embera/Tests/TestServiceIFixIt.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceIFixIt.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceIFixIt extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.ifixit.com/Guide/Replacing+iPad+4+CDMA+Logic+Board/16458',
20
+ 'http://www.ifixit.com/Guide/Repairing+IBM+ThinkPad+T41+BIOS+Battery/2916/1',
21
+ 'http://www.ifixit.com/Teardown/Plastic+Chair+Teardown/5989/1',
22
+ 'http://ifixit.com/Teardown/iPad+2+3G+GSM+%26+CDMA+Teardown/5127/1/',
23
+ 'http://www.ifixit.com/Teardown/AirPort+Extreme+A1521+Teardown/15044/',
24
+ ),
25
+ 'invalid' => array(
26
+ 'http://www.ifixit.com/User/18/Walter+Galan',
27
+ 'http://www.ifixit.com/Guide',
28
+ 'http://www.ifixit.com/',
29
+ 'http://www.ifixit.com/Guide/login/register',
30
+ 'http://www.ifixit.com/Guide/login',
31
+ ),
32
+ 'fake' => array(
33
+ 'type' => 'rich',
34
+ 'html' => '<script'
35
+ )
36
+ );
37
+
38
+ public function testProvider() { $this->validateProvider('IFixIt'); }
39
+ }
40
+ ?>
library/ostraining/embera/Tests/TestServiceInfogram.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceInfogram.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceInfogram extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://infogr.am/4feb214cdf29-5349',
20
+ 'https://infogr.am/top_10_eu_tech_exits_in_q1_2015_ranked_by_acquisition_size__ipo_valuation_in_euros',
21
+ 'https://infogr.am/da0b4c76-26be-4169-9550-992fc499e3d9',
22
+ 'http://infogr.am/12saeimas-velesanu-rezume?query-string',
23
+ 'https://infogr.am/the-2014-creative-jobs-report-fact-sheet/',
24
+ ),
25
+ 'invalid' => array(
26
+ 'https://infogr.am/featured',
27
+ 'https://infogr.am',
28
+ 'https://infogr.am/demo/the-2014-creative-jobs-report-fact-sheet',
29
+ 'https://infogr.am/brands',
30
+ 'https://infogr.am/brands',
31
+ ),
32
+ );
33
+
34
+ public function testProvider() { $this->validateProvider('Infogram'); }
35
+ }
36
+ ?>
library/ostraining/embera/Tests/TestServiceInstagram.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceInstagram.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceInstagram extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://instagram.com/p/TCg0AoLjoH/#',
20
+ 'https://instagram.com/p/Q8fPYGLjtB',
21
+ 'http://instagram.com/p/Rqlny2Ljk7/',
22
+ 'http://instagr.am/p/TCg0AoLjoH/#',
23
+ 'http://instagr.am/p/V8UMy0LjpX',
24
+ 'https://instagram.com/p/sdS_ptrDnD/',
25
+ 'https://instagram.com/p/5jY1-grDiq/',
26
+ ),
27
+ 'invalid' => array(
28
+ 'http://instagram.com/stuff/Rqlny2Ljk7/',
29
+ 'http://instagram.com/p/Rqlny2Ljk7/other/stuff',
30
+ 'http://instagram.com',
31
+ 'http://instagr.am',
32
+ ),
33
+ 'normalize' => array(
34
+ 'http://instagram.com/p/TCg0AoLjoH/#' => 'http://instagram.com/p/TCg0AoLjoH/',
35
+ 'http://instagram.com/p/TCg0AoLjoH#' => 'http://instagram.com/p/TCg0AoLjoH',
36
+ )
37
+ );
38
+
39
+ public function testProvider() { $this->validateProvider('Instagram'); }
40
+ }
41
+ ?>
library/ostraining/embera/Tests/TestServiceIssuu.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceIssuu.php
4
+ *
5
+ * @package Tests
6
+ * @author Rob Taylor <rob@uxblondon.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ require_once 'TestProviders.php';
13
+
14
+ class TestServiceIssuu extends TestProviders
15
+ {
16
+ protected $urls = array(
17
+ 'valid' => array(
18
+ 'http://issuu.com/adidasoutdoormag/docs/h10373_ou_outdoor_ss15-terrex_magaz',
19
+ 'https://issuu.com/adidasoutdoormag/docs/h10373_ou_outdoor_ss15-terrex_magaz',
20
+ ),
21
+ 'invalid' => array(
22
+ 'https://issuu.com/',
23
+ 'http://issuu.com/?e=0/9134577',
24
+ ),
25
+ );
26
+
27
+ public function testProvider() { $this->validateProvider('Issuu'); }
28
+ }
29
+ ?>
library/ostraining/embera/Tests/TestServiceIssuuFakeResponse.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceIssuu.php
4
+ *
5
+ * @package Tests
6
+ * @author Rob Taylor <rob@uxblondon.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ require_once 'TestProviders.php';
13
+
14
+ class TestServiceIssuuFakeResponse extends TestProviders
15
+ {
16
+ protected $urls = array(
17
+ 'valid' => array(
18
+ 'https://issuu.com/tennisaustralia/docs/ao___aos_2015_ticket_guide?e=0/9134577',
19
+ 'http://issuu.com/marmotmountaineurope/docs/katalog_f14_en?e=0/10148346',
20
+ 'https://issuu.com/marmotmountaineurope/docs/katalog_f14_en?e=0/10148346',
21
+ ),
22
+ 'invalid' => array(
23
+ 'https://issuu.com/',
24
+ 'http://issuu.com/?e=0/9134577',
25
+ ),
26
+ 'fake' => array(
27
+ 'type' => 'rich',
28
+ 'html' => '<script'
29
+ )
30
+ );
31
+
32
+ public function testProvider() { $this->validateProvider('Issuu'); }
33
+ }
34
+ ?>
library/ostraining/embera/Tests/TestServiceKickstarter.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceKickstarter.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceKickstarter extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.kickstarter.com/projects/1330686256/americas-candy-all-natural-vegan-and-allergy-frien?ref=home_popular',
20
+ 'http://www.kickstarter.com/projects/yonder/dino-pet-a-living-bioluminescent-night-light-pet?ref=home_popular',
21
+ 'http://www.kickstarter.com/projects/762504755/apparitions-from-the-inferno?ref=home_location',
22
+ 'http://kickstarter.com/projects/1093644807/and-the-meek-shall-inherit',
23
+ 'http://www.kickstarter.com/projects/940737263/a-very-special-new-stripped-down-sea-wolf-album',
24
+ 'http://www.kickstarter.com/projects/DaveRyan/owlgirls',
25
+ 'http://www.kickstarter.com/projects/lenswithaview/standing-in-the-stars-the-peter-mayhew-story',
26
+ ),
27
+ 'invalid' => array(
28
+ 'http://www.kickstarter.com/discover',
29
+ 'http://www.kickstarter.com/start',
30
+ 'http://www.kickstarter.com/',
31
+ 'http://www.kickstarter.com/DaveRyan/owlgirls',
32
+ 'http://www.kickstarter.com/projects/DaveRyan',
33
+ ),
34
+ 'normalize' => array(
35
+ 'http://www.kickstarter.com/projects/1330686256/americas-candy-all-natural-vegan-and-allergy-frien?ref=home_popular' => 'http://www.kickstarter.com/projects/1330686256/americas-candy-all-natural-vegan-and-allergy-frien',
36
+ 'http://www.kickstarter.com/projects/1330686256/americas-candy-all-natural-vegan-and-allergy-frien?ref=home_popular&other=stuff-yeah' => 'http://www.kickstarter.com/projects/1330686256/americas-candy-all-natural-vegan-and-allergy-frien',
37
+ 'http://www.kickstarter.com/projects/1330686256/americas-candy-all-natural-vegan-and-allergy-frien' => 'http://www.kickstarter.com/projects/1330686256/americas-candy-all-natural-vegan-and-allergy-frien',
38
+ 'http://kickstarter.com/projects/1330686256/americas-candy-all-natural-vegan-and-allergy-frien' => 'http://www.kickstarter.com/projects/1330686256/americas-candy-all-natural-vegan-and-allergy-frien',
39
+ 'https://kickstarter.com/projects/1330686256/americas-candy-all-natural-vegan-and-allergy-frien' => 'https://www.kickstarter.com/projects/1330686256/americas-candy-all-natural-vegan-and-allergy-frien',
40
+ ),
41
+ 'fake' => array(
42
+ 'type' => 'rich',
43
+ 'html' => '<iframe'
44
+ )
45
+ );
46
+
47
+ /**
48
+ *@large
49
+ */
50
+ public function testProvider()
51
+ {
52
+ if (getenv('TRAVIS')) {
53
+ $this->markTestSkipped('Travis-ci seems to have problems testing this provider. Test it locally instead! It usually works!');
54
+ return ;
55
+ }
56
+
57
+ $this->validateProvider('Kickstarter');
58
+ }
59
+ }
60
+ ?>
library/ostraining/embera/Tests/TestServiceLearningApps.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceLearningApps.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceLearningApps extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://learningapps.org/1453543',
20
+ 'http://learningapps.org/58598/',
21
+ 'http://learningapps.org/1156943?query=string',
22
+ ),
23
+ 'invalid' => array(
24
+ 'http://learningapps.org/index.php?overview&s=&category=0&tool=',
25
+ 'http://learningapps.org/index.php',
26
+ 'http://learningapps.org/',
27
+ 'http://learningapps.org/58598/other-stuff',
28
+ 'http://learningapps.org/index.php?category=14&s=',
29
+ ),
30
+ );
31
+
32
+ public function testProvider() { $this->validateProvider('LearningApps'); }
33
+ }
34
+ ?>
library/ostraining/embera/Tests/TestServiceMeetup.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceMeetup.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceMeetup extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.meetup.com/PHPColMeetup/events/126690622/',
20
+ 'http://www.meetup.com/PHPColMeetup/photos/',
21
+ 'http://meetup.com/PHPColMeetup/events/calendar/?scroll=true',
22
+ 'http://www.meetup.com/PHPColMeetup/events/calendar/',
23
+ 'http://www.meetup.com/PHPColMeetup/',
24
+ ),
25
+ 'invalid' => array(
26
+ 'http://www.meetup.com/',
27
+ 'http://meetu.ps/17GDWn/other/stuff',
28
+ ),
29
+ 'normalize' => array(
30
+ 'http://www.meetup.com/PHPColMeetup/?scroll=true' => 'http://www.meetup.com/PHPColMeetup/',
31
+ 'http://www.meetup.com/PHPColMeetup/' => 'http://www.meetup.com/PHPColMeetup/',
32
+ )
33
+ );
34
+
35
+ /**
36
+ * @large
37
+ */
38
+ public function testProvider() { $this->validateProvider('Meetup'); }
39
+ }
40
+ ?>
library/ostraining/embera/Tests/TestServiceMixCloud.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceMixCloud.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceMixCloud extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.mixcloud.com/quietmusic/quietmusic-august-18-hour-1-excerpt/',
20
+ 'http://www.mixcloud.com/sub88/mental-place-25/',
21
+ 'http://www.mixcloud.com/FluidRadio/casual-curses-a-mixtape-by-cooper-cult/',
22
+ 'http://mixcloud.com/aboveandbeyond/above-beyond-abgt-041/',
23
+ 'http://www.mixcloud.com/CarlCox/carl-cox-ibiza-the-revolution-unites-week-6',
24
+ 'http://www.mixcloud.com/TechnoLiveSets/josephcapriati-live-aquasella-festival-2013-spain-02-08-2013/',
25
+ 'http://www.mixcloud.com/truthoughts/tru-thoughts-presents-unfold-180813/',
26
+ ),
27
+ 'invalid' => array(
28
+ 'http://www.mixcloud.com/truthoughts/',
29
+ 'http://www.mixcloud.com/categories/ambient-chillout/',
30
+ 'http://www.mixcloud.com/categories/comedy/',
31
+ 'http://www.mixcloud.com/about/',
32
+ 'http://www.mixcloud.com/upload/',
33
+ 'http://www.mixcloud.com/advertise/create/',
34
+ 'http://www.mixcloud.com/developers/documentation/',
35
+ ),
36
+ );
37
+
38
+ public function testProvider() { $this->validateProvider('MixCloud'); }
39
+ }
40
+ ?>
library/ostraining/embera/Tests/TestServiceMobyPicture.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceMobyPicture.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceMobyPicture extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.mobypicture.com/user/Henk_Voermans/view/15880044',
20
+ 'http://moby.to/89cw01',
21
+ 'http://www.mobypicture.com/user/mjjeje_cojjee/view/15880072',
22
+ 'http://www.mobypicture.com/user/Chino_Sanchez/view/15880070/',
23
+ 'http://mobypicture.com/user/oskrsal71/view/15880066',
24
+ 'http://www.mobypicture.com/user/4/view/15877052',
25
+ 'http://moby.to/be1e30',
26
+ ),
27
+ 'invalid' => array(
28
+ 'http://www.mobypicture.com/user/kakhiel2',
29
+ 'http://www.mobypicture.com/groups',
30
+ 'http://www.mobypicture.com/',
31
+ 'http://moby.to/',
32
+ 'http://moby.to/other/stuff/',
33
+ 'http://mobypicture.com/user/oskrsal71/view/15880066/other/stuff',
34
+ ),
35
+ );
36
+
37
+ public function testProvider() { $this->validateProvider('MobyPicture'); }
38
+ }
39
+ ?>
library/ostraining/embera/Tests/TestServiceNFB.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceNFB.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceNFB extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.nfb.ca/film/abegweit_en',
20
+ 'http://nfb.ca/film/act_of_dishonour',
21
+ 'http://www.nfb.ca/film/after_axe/',
22
+ 'http://nfb.ca/film/alexis_tremblay_habitant_en',
23
+ 'http://nfb.ca/film/the_animal_movie/',
24
+ 'http://www.nfb.ca/film/anniversary',
25
+ 'http://www.nfb.ca/film/anniversary/embed/player',
26
+ ),
27
+ 'invalid' => array(
28
+ 'http://www.nfb.ca/explore-all-directors/tom-jackson/',
29
+ 'http://www.nfb.ca',
30
+ 'http://www.nfb.ca/film/',
31
+ 'http://nfb.ca/film/',
32
+ 'http://www.nfb.ca/explore-all-films/',
33
+ ),
34
+ 'normalize' => array(
35
+ 'http://www.nfb.ca/film/anniversary/embed/player' => 'http://www.nfb.ca/film/anniversary',
36
+ ),
37
+ 'fake' => array(
38
+ 'type' => 'video',
39
+ 'html' => '<iframe'
40
+ )
41
+ );
42
+
43
+ public function testProvider() { $this->validateProvider('NFB'); }
44
+ }
45
+ ?>
library/ostraining/embera/Tests/TestServiceOfficeMix.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceOfficemix.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceOfficemix extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://mix.office.com/watch/1x2i2ff1bla5w?lcid=1033',
20
+ 'https://mix.office.com/watch/1138kyipqqcog',
21
+ 'http://mix.office.com/watch/hgagc38i8wx9?lcid=1033',
22
+ 'https://mix.office.com/embed/q3xhljonccyo',
23
+ ),
24
+ 'invalid' => array(
25
+ 'https://mix.office.com',
26
+ 'https://mix.office.com/gallery/category/featured',
27
+ 'https://mix.office.com/stuff/watch/q3xhljonccyo',
28
+ ),
29
+ 'fake' => array(
30
+ 'type' => 'rich',
31
+ 'html' => '<iframe'
32
+ )
33
+ );
34
+
35
+ public function testProvider() { $this->validateProvider('Officemix'); }
36
+ }
37
+ ?>
library/ostraining/embera/Tests/TestServiceOfficialFM.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceOfficialFM.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceOfficialFM extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://official.fm/playlists/cxBp?from=homepage&track_id=5dtD',
20
+ 'http://official.fm/playlists/Dztx',
21
+ 'http://official.fm/tracks/CLZo',
22
+ 'http://official.fm/tracks/2u3X',
23
+ 'http://official.fm/tracks/2eUw',
24
+ ),
25
+ 'invalid' => array(
26
+ 'http://official.fm/login',
27
+ 'http://official.fm/join',
28
+ 'http://official.fm/',
29
+ 'http://official.fm/developers',
30
+ 'http://official.fm/privacy',
31
+ ),
32
+ 'normalize' => array(
33
+ 'http://official.fm/playlists/Dztx?from=homepage&track_id=9rk1' => 'http://official.fm/playlists/Dztx',
34
+ 'http://www.official.fm/playlists/Dztx?from=homepage&track_id=9rk1' => 'http://official.fm/playlists/Dztx',
35
+ 'http://www.official.fm/playlists/Dztx' => 'http://official.fm/playlists/Dztx',
36
+ 'http://official.fm/tracks/Dztx?from=homepage&track_id=9rk1' => 'http://official.fm/tracks/Dztx',
37
+ ),
38
+ 'fake' => array(
39
+ 'type' => 'rich',
40
+ 'html' => '<iframe'
41
+ )
42
+ );
43
+
44
+ public function testProvider() { $this->validateProvider('OfficialFM'); }
45
+ }
46
+ ?>
library/ostraining/embera/Tests/TestServiceOumy.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceOumy.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceOumy extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://www.oumy.com/v/0rdiVajPP9b7pQjs18Lv7H7',
20
+ 'https://oumy.com/v/01BgyjAsCtC80d1vGDw4uOr1',
21
+ 'https://www.oumy.com/v/0UG9iWZqccZ88VXqIaNHIe5?query=string',
22
+ 'http://www.oumy.com/v/016SQZ9MrzE6nL6s5a32pz5',
23
+ 'http://oumy.com/v/0w7TvZ9e9Vs9gs4MznydO71',
24
+ ),
25
+ 'invalid' => array(
26
+ 'https://www.oumy.com',
27
+ 'https://oumy.com/features',
28
+ 'http://www.oumy.com/v/other/016SQZ9MrzE6nL6s5a32pz5',
29
+ 'http://www.oumy.com/r/016SQZ9MrzE6nL6s5a32pz5',
30
+ ),
31
+ 'fake' => array(
32
+ 'type' => 'video',
33
+ 'html' => '<iframe'
34
+ )
35
+ );
36
+
37
+ public function testProvider() { $this->validateProvider('Oumy'); }
38
+ }
39
+ ?>
library/ostraining/embera/Tests/TestServicePastery.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServicePastery.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServicePastery extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://www.pastery.net/api/',
20
+ 'https://www.pastery.net/about/'
21
+ ),
22
+ 'invalid' => array(
23
+ 'https://www.pastery.net/',
24
+ 'https://www.pastery.net/about/other-stuff',
25
+ ),
26
+ );
27
+
28
+ /**
29
+ * @large
30
+ */
31
+ public function testProvider() { $this->validateProvider('Pastery'); }
32
+ }
33
+ ?>
library/ostraining/embera/Tests/TestServicePollDaddy.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServicePollDaddy.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServicePollDaddy extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://polldaddy.com/poll/7012505/',
20
+ 'http://polldaddy.com/s/ADF2AB9E60258D2A/',
21
+ 'http://polldaddy.com/ratings/39/',
22
+ 'http://polldaddy.com/poll/6976912/',
23
+ 'https://polldaddy.com/poll/7205026/',
24
+ 'http://www.polldaddy.com/poll/7012505',
25
+ 'http://mpcimageartist.polldaddy.com/s/emotions',
26
+ 'http://theguy1979.polldaddy.com/s/growing-up-biracial-in-america-being-of-mixed-race-descent-in-2013',
27
+ ),
28
+ 'invalid' => array(
29
+ 'https://polldaddy.com/features/',
30
+ 'http://polldaddy.com',
31
+ 'https://polldaddy.com/pricing/',
32
+ 'https://polldaddy.com/poll/7205026/other-stuff',
33
+ ),
34
+ 'normalize' => array(
35
+ 'https://www.polldaddy.com/poll/6976912/' => 'http://polldaddy.com/poll/6976912/',
36
+ 'http://www.polldaddy.com/poll/6976912/' => 'http://polldaddy.com/poll/6976912/',
37
+ 'http://polldaddy.com/poll/6976912/' => 'http://polldaddy.com/poll/6976912/',
38
+ 'https://polldaddy.com/poll/7205026/' => 'http://polldaddy.com/poll/7205026/',
39
+ ),
40
+ /*'fake' => array(
41
+ 'type' => 'rich',
42
+ 'html' => '<script'
43
+ )*/
44
+ );
45
+
46
+ public function testProvider() { $this->validateProvider('PollDaddy'); }
47
+ }
48
+ ?>
library/ostraining/embera/Tests/TestServicePollEverywhere.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServicePollEverywhere.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServicePollEverywhere extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.polleverywhere.com/free_text_polls/LTk2NTg4NDI4MQ',
20
+ 'http://www.polleverywhere.com/free_text_polls/NDk3OTE0ODgy/',
21
+ 'http://polleverywhere.com/multiple_choice_polls/LTQxNTU4OTUx',
22
+ 'http://www.polleverywhere.com/multiple_choice_polls/LTE5NTcwMzU0MjA/',
23
+ ),
24
+ 'invalid' => array(
25
+ 'https://www.polleverywhere.com/login',
26
+ 'http://www.polleverywhere.com/plans',
27
+ 'http://www.polleverywhere.com',
28
+ )
29
+ );
30
+
31
+ public function testProvider() { $this->validateProvider('PollEveryWhere'); }
32
+ }
33
+ ?>
library/ostraining/embera/Tests/TestServicePortfolium.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServicePortfolium.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServicePortfolium extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://portfolium.com/entry/first-engineering-experience',
20
+ 'https://portfolium.com/entry/stephanie_lowlight-photography',
21
+ 'http://portfolium.com/entry/flora',
22
+ 'https://www.portfolium.com/entry/fresh-reds',
23
+ 'https://portfolium.com/entry/the-joker-painting/',
24
+ 'https://portfolium.com/entry/silver?querystring=stuff&yes=1',
25
+ ),
26
+ 'invalid' => array(
27
+ 'https://portfolium.com/entries',
28
+ 'https://portfolium.com/',
29
+ 'https://portfolium.com/entries/category/art-design',
30
+ 'https://portfolium.com/entry/the-joker-painting/other-stuff-on-address',
31
+ )
32
+ );
33
+
34
+ public function testProvider()
35
+ {
36
+ $this->validateProvider('Portfolium');
37
+ }
38
+ }
39
+ ?>
library/ostraining/embera/Tests/TestServiceRapidengage.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceRapidengage.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceRapidengage extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://rapidengage.com/s/6b1faa05',
20
+ 'https://www.rapidengage.com/s/6b1faa05',
21
+ 'http://www.rapidengage.com/s/6b1faa05/'
22
+ ),
23
+ 'invalid' => array(
24
+ 'https://rapidengage.com/s/6b1faa05/other-stuff',
25
+ 'https://rapidengage.com/developer/docs#oembed',
26
+ 'https://rapidengage.com/live/demo',
27
+ 'http://rapidengage.com/'
28
+ ),
29
+ );
30
+
31
+ public function testProvider() { $this->validateProvider('Rapidengage'); }
32
+ }
33
+ ?>
library/ostraining/embera/Tests/TestServiceRdio.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceRdio.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceRdio extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://rd.io/x/Q1IjXC8s',
20
+ 'http://www.rdio.com/artist/The_Black_Keys/album/Brothers/',
21
+ 'http://www.rdio.com/artist/Nine_Inch_Nails/album/The_Downward_Spiral_1/track/Hurt/',
22
+ 'http://rdio.com/people/Pitchfork/playlists/13082/Top_Singles_of_2000-2004/',
23
+ 'http://www.rdio.com/artist/Washed_Out/album/Paracosm_1/',
24
+ 'http://www.rdio.com/artist/Earl_Sweatshirt/album/Doris/',
25
+ 'http://www.rdio.com/artist/Marre/album/Sombras_De_Luz_1',
26
+ ),
27
+ 'invalid' => array(
28
+ 'http://rd.io/Q1IjXC8s',
29
+ 'http://www.rdio.com/artist/The_Black_Keys/',
30
+ 'http://www.rdio.com',
31
+ 'http://www.rdio.com/browse/new',
32
+ 'http://www.rdio.com/browse/charts/albums',
33
+ ),
34
+ );
35
+
36
+ public function testProvider() { $this->validateProvider('Rdio'); }
37
+ }
38
+ ?>
library/ostraining/embera/Tests/TestServiceReleaseWire.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceReleaseWire.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceReleaseWire extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.releasewire.com/press-releases/release-600961.htm',
20
+ 'http://releasewire.com/press-releases/release-600742.htm',
21
+ 'http://www.releasewire.com/press-releases/release-600657.htm?query=string',
22
+ 'http://www.rwire.com/600657',
23
+ 'http://rwire.com/600681/?query=string',
24
+ 'http://rwire.com/600775?query=string',
25
+ ),
26
+ 'invalid' => array(
27
+ 'http://www.releasewire.com/media-engagement-process/create/',
28
+ 'http://www.releasewire.com/about/',
29
+ 'http://media.releasewire.com/photos/show/?id=85997',
30
+ 'http://www.releasewire.com/company/jonathan-w-mcconnell-89768.htm',
31
+ 'http://www.rwire.com/notnumeric',
32
+ ),
33
+ 'normalize' => array(
34
+ 'http://www.releasewire.com/press-releases/release-600961.htm' => 'http://rwire.com/600961',
35
+ 'http://www.releasewire.com/press-releases/release-600657.htm?query=string' => 'http://rwire.com/600657',
36
+ ),
37
+ );
38
+
39
+ public function testProvider() { $this->validateProvider('ReleaseWire'); }
40
+ }
41
+ ?>
library/ostraining/embera/Tests/TestServiceRepubHub.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceRepubHub.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceRepubHub extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://repubhub.icopyright.net/freePost.act?tag=3.7212?icx_id=/content/thestar/news/gta/2015/10/30/how-toronto-kids-dressed-for-halloween-in-1929&urs=REPUBHUB',
20
+ 'https://repubhub.icopyright.net/freePost.act?tag=3.13278?icx_id=despite-reform-high-cost-living-puts-many-chinese-having-second-child-2163109&urs=REPUBHUB',
21
+ 'http://repubhub.icopyright.net/freePost.act?tag=3.15511?icx_id=60555313&urs=REPUBHUB',
22
+ 'https://repubhub.icopyright.net/freePost.act?tag=3.7280?icx_id=/news/2015/oct/30/senate-passes-debt-and-spending-hike-dead-night/&urs=REPUBHUB',
23
+ ),
24
+ 'invalid' => array(
25
+ 'http://repubhub.icopyright.net/other-stuff/freePost.act?tag=3.15511?icx_id=60555313&urs=REPUBHUB',
26
+ 'http://repubhub.icopyright.net/other-stuff/freePost.act?',
27
+ ),
28
+ );
29
+
30
+ public function testProvider() { $this->validateProvider('RepubHub'); }
31
+ }
32
+ ?>
library/ostraining/embera/Tests/TestServiceReverbnation.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceReverbnation.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceReverbnation extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.reverbnation.com/oscarattack/song/12175154-asdasd',
20
+ 'https://www.reverbnation.com/monogem',
21
+ 'https://reverbnation.com/blackoutparty',
22
+ 'https://www.reverbnation.com/umphreysmcgee/song/23964777-bad-friday',
23
+ 'https://reverbnation.com/umphreysmcgee/songs/23964733-no-diablo',
24
+ 'http://www.reverbnation.com/barbarianus',
25
+ ),
26
+ 'invalid' => array(
27
+ 'https://www.reverbnation.com/band-promotion',
28
+ 'https://www.reverbnation.com/main/charts',
29
+ 'https://reverbnation.com/copyright',
30
+ 'https://www.reverbnation.com/',
31
+ 'http://www.reverbnation.com/industryprofessionals',
32
+ 'https://www.reverbnation.com/page_object/page_object_photos/artist_151144?sel_photo_id=19161456',
33
+ )
34
+ );
35
+
36
+ public function testProvider() { $this->validateProvider('Reverbnation'); }
37
+ }
38
+ ?>
library/ostraining/embera/Tests/TestServiceRevision3.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceRevision3.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceRevision3 extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://revision3.com/sesslerssomething/e3-2013-preview',
20
+ 'http://revision3.com/tbhs/wire-we-here',
21
+ 'http://www.revision3.com/technobuffalo/ask-the-buffalo-380-nokia-lumia-running-android',
22
+ 'http://revision3.com/sidescrollers/bosnian-bear-wrestling/',
23
+ 'http://revision3.com/rev3gamespreviews/watchdogs-new-interview',
24
+ 'http://revision3.com/screwattackhardnewsclip/fat-cat'
25
+ ),
26
+ 'invalid' => array(
27
+ 'http://revision3.com/host/anthony-carboni',
28
+ 'http://revision3.com/host/adam-sessler/',
29
+ 'http://revision3.com/host/tara-long',
30
+ 'http://revision3.com/network/games/',
31
+ 'http://revision3.com/network/sharkweek',
32
+ 'http://www.revision3.com/tbhs/',
33
+ 'http://revision3.com/anniesbits',
34
+ 'http://revision3.com/where',
35
+ 'http://revision3.com/advertise/contact/'
36
+ ),
37
+ 'normalize' => array(
38
+ 'http://revision3.com/sesslerssomething/e3-2013-preview' => 'http://revision3.com/sesslerssomething/e3-2013-preview',
39
+ 'http://www.revision3.com/technobuffalo/ask-the-buffalo-380-nokia-lumia-running-android' => 'http://www.revision3.com/technobuffalo/ask-the-buffalo-380-nokia-lumia-running-android',
40
+ )
41
+ );
42
+
43
+ public function testProvider() { $this->validateProvider('Revision3'); }
44
+ }
45
+ ?>
library/ostraining/embera/Tests/TestServiceRoomshare.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceRoomshare.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceRoomshare extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://roomshare.jp/en/post/137453',
20
+ 'http://roomshare.jp/post/137453',
21
+ 'http://roomshare.jp/en/post/137393/',
22
+ 'http://www.roomshare.jp/post/137393',
23
+ ),
24
+ 'invalid' => array(
25
+ 'http://roomshare.jp/en/post?region=1',
26
+ 'http://roomshare.jp/en/',
27
+ 'http://roomshare.jp/keywords',
28
+ 'http://roomshare.jp',
29
+ ),
30
+ );
31
+
32
+ public function testProvider() { $this->validateProvider('Roomshare'); }
33
+ }
34
+ ?>
library/ostraining/embera/Tests/TestServiceRutube.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceRutube.php
4
+ *
5
+ * @package Tests
6
+ * @author dotzero <mail@dotzero.ru>
7
+ * @link http://www.dotzero.ru/
8
+ */
9
+
10
+ require_once 'TestProviders.php';
11
+
12
+ class TestServiceRutube extends TestProviders
13
+ {
14
+ protected $urls = array(
15
+ 'valid' => array(
16
+ 'http://rutube.ru/video/51b5b6ebeb1ce0a1344f323dc45201be/',
17
+ 'http://rutube.ru/video/51b5b6ebeb1ce0a1344f323dc45201be',
18
+ 'http://rutube.ru/video/cbcd2e76af0ad61fedff1a87eb2e5e74/',
19
+ 'http://rutube.ru/video/cbcd2e76af0ad61fedff1a87eb2e5e74',
20
+ ),
21
+ 'invalid' => array(
22
+ 'http://rutube.ru/metainfo/tv/27/',
23
+ 'http://rutube.ru/metainfo/tv/27/#!/season1',
24
+ 'http://rutube.ru/video/person/953339/',
25
+ ),
26
+ 'normalize' => array(
27
+ 'http://rutube.ru/video/51b5b6ebeb1ce0a1344f323dc45201be' => 'http://rutube.ru/video/51b5b6ebeb1ce0a1344f323dc45201be/',
28
+ 'http://www.rutube.ru/video/51b5b6ebeb1ce0a1344f323dc45201be' => 'http://rutube.ru/video/51b5b6ebeb1ce0a1344f323dc45201be/',
29
+ ),
30
+ );
31
+
32
+ public function testProvider() { $this->validateProvider('Rutube'); }
33
+ }
library/ostraining/embera/Tests/TestServiceSapo.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceSapo.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceSapo extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://videos.sapo.pt/1z2ieEQvWVZ6af0nQZFN',
20
+ 'http://videos.sapo.pt/ZpO1SNwJwjjjmuOlDqGN/',
21
+ 'http://videos.sapo.pt/2VA8L9zp3eSUn0HTsG3G',
22
+ 'http://videos.sapo.pt/R3wmOAGyjZFRkwdRbmHs',
23
+ 'http://videos.sapo.pt/R5Y9lJteSAzyf5V5uAhD',
24
+ 'http://videos.sapo.pt/sk9LmQAH0PQ4Pz1iupkV',
25
+ 'http://videos.sapo.pt/HAUithzZK3SShqIRGQBA',
26
+ 'http://videos.sapo.pt/eFdSRwoVzYQQ4NVEtGF6',
27
+ ),
28
+ 'invalid' => array(
29
+ 'http://videos.sapo.pt/top.html',
30
+ 'http://www.sapo.pt/',
31
+ 'http://videos.sapo.pt/tag.html?insanospt',
32
+ 'http://videos.sapo.pt/categorias.html',
33
+ 'http://videos.sapo.pt/sapotv.html',
34
+ ),
35
+ 'fake' => array(
36
+ 'type' => 'video',
37
+ 'html' => '<iframe'
38
+ )
39
+ );
40
+
41
+ public function testProvider() { $this->validateProvider('Sapo'); }
42
+ }
43
+ ?>
library/ostraining/embera/Tests/TestServiceScreenr.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceScreenr.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceScreenr extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.screenr.com/eJvs',
20
+ 'http://www.screenr.com/5xfs/',
21
+ 'http://screenr.com/mkus',
22
+ 'http://www.screenr.com/js0H',
23
+ ),
24
+ 'invalid' => array(
25
+ 'http://www.screenr.com/',
26
+ 'http://www.screenr.com/record',
27
+ 'http://www.screenr.com/stream',
28
+ 'http://www.screenr.com/help',
29
+ 'http://www.screenr.com/T80H/other/stuff',
30
+ 'http://www.screenr.com/T80H/other',
31
+ ),
32
+ 'fake' => array(
33
+ 'type' => 'video',
34
+ 'html' => '<iframe'
35
+ )
36
+ );
37
+
38
+ public function testProvider() { $this->validateProvider('Screenr'); }
39
+ }
40
+ ?>
library/ostraining/embera/Tests/TestServiceScribd.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceScribd.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceScribd extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.scribd.com/doc/155739836/The-Time-Travel-Megapack-26-Modern-and-Classic-Science-Fiction-Stories',
20
+ 'http://www.scribd.com/doc/155740115/Daughter-of-the-Amazon-The-Golden-Amazon-Saga-Book-Five/',
21
+ 'http://scribd.com/doc/155740472/Alien-Abduction-The-Wiltshire-Revelations?=hey',
22
+ 'http://scribd.com/doc/119667881/Lessons-in-Lingerie/',
23
+ 'http://www.scribd.com/doc/115726071/10-Practical-Tools-for-a-Resilient-Local-Economy',
24
+ 'http://www.scribd.com/doc/14850258/Research-Motives-of-Vinyl-Use-Author-Robert-Arndt',
25
+ ),
26
+ 'invalid' => array(
27
+ 'http://www.scribd.com/explore',
28
+ 'http://www.scribd.com/explore/Types/Featured?p=0',
29
+ 'http://scribd.com/doc/Lessons-in-Lingerie/',
30
+ 'http://scribd.com/119667881/Lessons-in-Lingerie/',
31
+ 'http://scribd.com/doc/119667881/Lessons-in-Lingerie/other-stuff',
32
+ ),
33
+ 'fake' => array(
34
+ 'type' => 'rich',
35
+ 'html' => '<iframe'
36
+ )
37
+ );
38
+
39
+ public function testProvider() { $this->validateProvider('Scribd'); }
40
+ }
41
+ ?>
library/ostraining/embera/Tests/TestServiceShortNote.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceShortNote.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceShortNote extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://www.shortnote.jp/view/notes/AAzbJ67b',
20
+ 'https://shortnote.jp/view/notes/AEKcSEt9/',
21
+ 'http://www.shortnote.jp/view/notes/ANAUuNRF',
22
+ 'http://shortnote.jp/view/notes/ANe9OZT6',
23
+ ),
24
+ 'invalid' => array(
25
+ 'https://www.shortnote.jp/',
26
+ 'http://www.shortnote.jp/view/notes/ANAUuNRF/embed',
27
+ 'http://shortnote.jp/help/',
28
+ 'http://shortnote.jp/',
29
+ ),
30
+ 'fake' => array(
31
+ 'type' => 'rich',
32
+ 'html' => '<iframe'
33
+ )
34
+ );
35
+
36
+ public function testProvider() { $this->validateProvider('ShortNote'); }
37
+ }
38
+ ?>
library/ostraining/embera/Tests/TestServiceShoudio.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceShoudio.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceShoudio extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://shoudio.com/user/sowa',
20
+ 'http://www.shoudio.com/user/shoister/',
21
+ 'http://shoudio.com/user/sowa/status/8171',
22
+ 'http://shoudio.com/user/sowa/status/8169',
23
+ 'http://shoudio.com/channel/streetmusic',
24
+ 'http://shoudio.com/venue/1246/hemlock-tavern.html',
25
+ 'http://shoudio.com/venue/1240/park-g-ell.html',
26
+ 'http://touch.shoud.io/3862',
27
+ ),
28
+ 'invalid' => array(
29
+ 'http://shoudio.com/signup',
30
+ 'http://shoudio.com',
31
+ 'http://touch.shoud.io/3862/other-stuff',
32
+ 'http://shoudio.com/collections',
33
+ 'http://shoudio.com/venues',
34
+ ),
35
+ 'normalize' => array(
36
+ 'http://shoudio.com/user/sowa/status/8169' => 'http://shoudio.com/user/sowa/status/8169',
37
+ 'http://www.shoudio.com/user/sowa/status/8169' => 'http://shoudio.com/user/sowa/status/8169',
38
+ 'http://shoudio.com/user/sowa/status/8169/' => 'http://shoudio.com/user/sowa/status/8169',
39
+ )
40
+ );
41
+
42
+ public function testProvider() { $this->validateProvider('Shoudio'); }
43
+ }
44
+ ?>
library/ostraining/embera/Tests/TestServiceShowTheWay.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceShowtheway.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceShowtheway extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://showtheway.io/to/48.85837,2.294481?name=Eiffel%20Tower',
20
+ 'http://showtheway.io/to/4.710989,-74.072092?name=Bogot%26aacute%3B',
21
+ 'https://www.showtheway.io/to/33.812092,-117.918974?name=Disneyland%20Park',
22
+ ),
23
+ 'invalid' => array(
24
+ 'https://showtheway.io/',
25
+ 'https://showtheway.io/share',
26
+ 'https://showtheway.io/not/to/33.812092,-117.918974?name=Disneyland%20Park',
27
+ ),
28
+ );
29
+
30
+ /**
31
+ * @large
32
+ */
33
+ public function testProvider() { $this->validateProvider('Showtheway'); }
34
+ }
35
+ ?>
library/ostraining/embera/Tests/TestServiceSilk.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceSilk.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceSilk extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://world.silk.co/explore/map/collection/country/numeric/total%20life%20expectancy/location/title/on/silk.co/pin/filter/matches/region/Africa',
20
+ 'https://women-in-film.silk.co/s/embed/stackchart/collection/bechdel-test-results-through-time/numeric/less-than-two-named-women-in-it/numeric/two-or-more-women-but-who-don%27t-talk-to-each-other/numeric/the-two-or-more-women-who-talk-to-each-other-but-only-discuss-men/numeric/passed',
21
+ 'http://russia-strikes-syria.silk.co/explore/iYgyzI7',
22
+ 'https://century-of-migration.silk.co/explore/wy1C01d',
23
+ 'http://lake-champlain-data.silk.co/explore/YNjH3nk',
24
+ 'http://tesla-superchargers.silk.co/explore/map/collection/tesla-superchargers\'-stations/column/city-us-state-country/column/superchargers-times/column/address/column/phone/numeric/superchargers/location/city-us-state-country/pin/filter/equals/us-state/California/suggestion/filter/equals/superchargers-times/suggestion/filter/equals/country/slice/0/1000'
25
+ ),
26
+ 'invalid' => array(
27
+ 'https://www.silk.co/signin',
28
+ 'https://www.silk.co/',
29
+ 'https://silk.co/pricing',
30
+ 'https://uziel-862601.silk.co/',
31
+ 'https://docker.silk.co/page/Alejandro-Bonilla-116814562',
32
+ ),
33
+ 'fake' => array(
34
+ 'type' => 'rich',
35
+ 'html' => '<iframe'
36
+ )
37
+ );
38
+
39
+ public function testProvider() { $this->validateProvider('Silk'); }
40
+ }
41
+ ?>
library/ostraining/embera/Tests/TestServiceSketchfab.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceSketchfab.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceSketchfab extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://sketchfab.com/show/lRyoY4ZsPRUMPlSiz03ORxTIXXK',
20
+ 'https://sketchfab.com/models/4e6urv5wnV8hxfhD2xUnSrvLNss',
21
+ 'https://sketchfab.com/show/s0eX1riDqEY6bT0uBtCjxC4V7OA',
22
+ 'https://sketchfab.com/show/lwVPifecIahu0rtGqlzZosBPFOC',
23
+ 'https://sketchfab.com/show/9lVs96AuFUAjKjwvsMG0Uf7Yy7b',
24
+ 'https://sketchfab.com/models/9afc7ce5f32b43a692e8861d6692ec2c',
25
+ 'https://sketchfab.com/models/30abb37327074983b43e9e6687126486',
26
+ 'https://sketchfab.com/models/e1cbf443e14c494883ac4bfe0321b4a9',
27
+ 'https://sketchfab.com/d3mobile-m_world_league/folders/fbebdc3958ac4acb9734d72fd80ad393',
28
+ 'https://sketchfab.com/freedee/folders/aa34319b1809428d9f8a85249f2d4412',
29
+ 'https://sketchfab.com/incenptive/folders/511829a4256a4e0b87e2396ccc0188d9',
30
+ 'https://sketchfab.com/barker_js/folders/c07b36bc1e764c9b8b347d34d54f57a3',
31
+ 'https://sketchfab.com/makerpoint/folders/bb15a149166e49cdbae2647a6575ec20',
32
+ ),
33
+ 'invalid' => array(
34
+ 'https://sketchfab.com/browse/',
35
+ 'https://sketchfab.com/browse/faved',
36
+ 'https://sketchfab.com/show/9lVs96AuFUAjKjwvsMG0Uf7Yy7b/other/crap',
37
+ 'https://sketchfab.com/order',
38
+ 'https://sketchfab.com/show/',
39
+ 'https://sketchfab.com/dashboard/upload',
40
+ 'https://sketchfab.com/models/',
41
+ 'https://sketchfab.com/show/',
42
+ ),
43
+ 'normalize' => array(
44
+ 'https://www.sketchfab.com/show/9lVs96AuFUAjKjwvsMG0Uf7Yy7b' => 'https://sketchfab.com/models/9lVs96AuFUAjKjwvsMG0Uf7Yy7b',
45
+ 'https://sketchfab.com/show/9lVs96AuFUAjKjwvsMG0Uf7Yy7b' => 'https://sketchfab.com/models/9lVs96AuFUAjKjwvsMG0Uf7Yy7b',
46
+ 'https://sketchfab.com/show/9lVs96AuFUAjKjwvsMG0Uf7Yy7b/' => 'https://sketchfab.com/models/9lVs96AuFUAjKjwvsMG0Uf7Yy7b',
47
+ 'https://www.sketchfab.com/models/9lVs96AuFUAjKjwvsMG0Uf7Yy7b/' => 'https://sketchfab.com/models/9lVs96AuFUAjKjwvsMG0Uf7Yy7b',
48
+ 'https://sketchfab.com/models/e1cbf443e14c494883ac4bfe0321b4a9/embed' => 'https://sketchfab.com/models/e1cbf443e14c494883ac4bfe0321b4a9',
49
+ 'https://sketchfab.com/models/e1cbf443e14c494883ac4bfe0321b4a9/embed/' => 'https://sketchfab.com/models/e1cbf443e14c494883ac4bfe0321b4a9',
50
+ 'https://sketchfab.com/models/e1cbf443e14c494883ac4bfe0321b4a9' => 'https://sketchfab.com/models/e1cbf443e14c494883ac4bfe0321b4a9',
51
+ ),
52
+ 'fake' => array(
53
+ 'type' => 'rich',
54
+ 'html' => '<iframe'
55
+ )
56
+ );
57
+
58
+ public function testProvider() { $this->validateProvider('Sketchfab'); }
59
+ }
60
+ ?>
library/ostraining/embera/Tests/TestServiceSlideshare.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceSlideShare.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceSlideShare extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.slideshare.net/shvmdhwn/personal-branding-do-it-yourself',
20
+ 'http://slideshare.net/robinhbchan/project-bbx',
21
+ 'http://www.slideshare.net/CNTMAN216/5linxbusinessopppresentation/',
22
+ 'http://es.slideshare.net/appsfire/app-score-report-july-2012',
23
+ 'http://www.slideshare.net/RobertGonzalez11/intelligent-onlinemarketingformedical/',
24
+ 'http://www.slideshare.net/andreasklinger/startup-metrics-a-love-story',
25
+ 'http://www.slideshare.net/FiratDemirel/hyperloop-alpha-elon-musk',
26
+ ),
27
+ 'invalid' => array(
28
+ 'http://www.slideshare.net/newlist/popular/language/de',
29
+ 'http://www.slideshare.net/newlist/popular/week',
30
+ 'http://www.slideshare.net/newlist/popular',
31
+ 'http://www.slideshare.net/FiratDemirel',
32
+ 'http://www.slideshare.net',
33
+ 'http://www.slideshare.net/search/slideshow?searchfrom=header&q=start',
34
+ ),
35
+ );
36
+
37
+ public function testProvider() { $this->validateProvider('SlideShare'); }
38
+ }
39
+ ?>
library/ostraining/embera/Tests/TestServiceSoundCloud.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceSoundCloud.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceSoundCloud extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://soundcloud.com/lospetitfellas/ser-libre-ft-alejandro-cole',
20
+ 'https://www.soundcloud.com/lospetitfellas/1150pm/',
21
+ 'https://soundcloud.com/lospetitfellas/sets/queridofrankie/',
22
+ 'https://soundcloud.com/smodco/babbleon-136',
23
+ 'https://m.soundcloud.com/smodco/isellcomics-93',
24
+ 'https://soundcloud.com/groups/rap-hiphop/',
25
+ 'https://soundcloud.com/groups/house-dj-sets',
26
+ 'https://soundcloud.com/tyrantofdeath/injection-remastered-2013/',
27
+ 'https://soundcloud.com/fernandomeira',
28
+ 'https://soundcloud.com/whatsonot/what-so-not-touched',
29
+ 'https://soundcloud.com/martingarrix/martin-garrix-jay-hardway-19',
30
+ 'https://soundcloud.com/guardianscienceweekly/science-weekly-podcast-the-25',
31
+ 'http://m.soundcloud.com/ricardobufalo/the-beatles-tomorrow-never',
32
+ ),
33
+ 'invalid' => array(
34
+ 'https://soundcloud.com/explore',
35
+ 'https://soundcloud.com/groups',
36
+ 'https://soundcloud.com',
37
+ ),
38
+ );
39
+
40
+ public function testProvider() { $this->validateProvider('SoundCloud'); }
41
+ }
42
+ ?>
library/ostraining/embera/Tests/TestServiceSpeakerDeck.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceSpeakerdeck.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceSpeakerdeck extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://speakerdeck.com/sva_1981/zhi-zhi-ju-tesuto',
20
+ 'http://www.speakerdeck.com/librarianavenger/librarian-avengers-film-rating-system',
21
+ 'http://speakerdeck.com/vinull/quest-for-fun',
22
+ 'https://speakerdeck.com/denniskardys/the-straight-up-how-to-draw-better-workshop',
23
+ ),
24
+ 'invalid' => array(
25
+ 'https://speakerdeck.com/p/featured',
26
+ 'https://speakerdeck.com/c/programming',
27
+ 'https://speakerdeck.com/signup',
28
+ 'https://speakerdeck.com/',
29
+ 'https://speakerdeck.com/search?q=what+up',
30
+ 'https://speakerdeck.com/jamesclay/what-do-you-mean-someone-made-them-up/other-stuff',
31
+ ),
32
+ );
33
+
34
+ public function testProvider() { $this->validateProvider('Speakerdeck'); }
35
+ }
36
+ ?>
library/ostraining/embera/Tests/TestServiceSpotify.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceSpotify.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceSpotify extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://play.spotify.com/album/4YQsbhCYkpmueqKC4aEn7f/0FHTJAMXhBhEnoEiMwxzO1',
20
+ 'https://play.spotify.com/album/4FCuyUjOkT28PnFo6A6vkf/4K4sc36DCTp9YJNVu5zV09',
21
+ 'https://play.spotify.com/track/0Wm3w3YiMe7YiS8erpKbOl',
22
+ 'https://play.spotify.com/album/2r4a3PREYIRF2QdbcPnrEO/4wsxtmLm89JBwWWAMKLxf2',
23
+ 'https://play.spotify.com/track/5DutiJxznQmcV5a5a1zfRW',
24
+ 'https://play.spotify.com/user/spotifycolombia/playlist/3zIzQMHvOlw3ukDhRKR2jO',
25
+ ),
26
+ 'invalid' => array(
27
+ 'https://play.spotify.com/stuff/3zIzQMHvOlw3ukDhRKR2jO',
28
+ ),
29
+ 'normalize' => array(
30
+ 'https://play.spotify.com/album/4YQsbhCYkpmueqKC4aEn7f/0FHTJAMXhBhEnoEiMwxzO1' => 'https://play.spotify.com/album/4YQsbhCYkpmueqKC4aEn7f',
31
+ 'https://play.spotify.com/track/4YQsbhCYkpmueqKC4aEn7f/0FHTJAMXhBhEnoEiMwxzO1' => 'https://play.spotify.com/track/4YQsbhCYkpmueqKC4aEn7f',
32
+ 'https://play.spotify.com/track/4YQsbhCYkpmueqKC4aEn7f/' => 'https://play.spotify.com/track/4YQsbhCYkpmueqKC4aEn7f',
33
+ 'https://play.spotify.com/album/4YQsbhCYkpmueqKC4aEn7f/' => 'https://play.spotify.com/album/4YQsbhCYkpmueqKC4aEn7f',
34
+ 'https://play.spotify.com/track/4YQsbhCYkpmueqKC4aEn7f' => 'https://play.spotify.com/track/4YQsbhCYkpmueqKC4aEn7f',
35
+ ),
36
+ 'fake' => array(
37
+ 'type' => 'rich',
38
+ 'html' => '<iframe'
39
+ )
40
+ );
41
+
42
+ /**
43
+ * @large
44
+ */
45
+ public function testProvider()
46
+ {
47
+ $this->validateProvider('Spotify');
48
+ }
49
+ }
50
+ ?>
library/ostraining/embera/Tests/TestServiceSway.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceSway.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceSway extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://sway.com/making_of_wildcat_sculpture',
20
+ 'https://www.sway.com/dBheQgVZ1RQBfiQU',
21
+ 'https://sway.com/nLa7rrYhdCmzRyQd/',
22
+ 'http://sway.com/universe_cheatsheet',
23
+ ),
24
+ 'invalid' => array(
25
+ 'https://sway.com',
26
+ 'https://sway.com/s/making_of_wildcat_sculpture/embed',
27
+ ),
28
+ 'fake' => array(
29
+ 'type' => 'rich',
30
+ 'html' => '<iframe'
31
+ )
32
+ );
33
+
34
+ public function testProvider() { $this->validateProvider('Sway'); }
35
+ }
36
+ ?>
library/ostraining/embera/Tests/TestServiceTed.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceTed.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceTed extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.ted.com/talks/david_gallo_shows_underwater_astonishments.html',
20
+ 'http://www.ted.com/talks/michael_dickinson_how_a_fly_flies.html',
21
+ 'http://www.ted.com/talks/jon_ronson_strange_answers_to_the_psychopath_test.html',
22
+ 'http://www.ted.com/talks/lang/da/jill_bolte_taylor_s_powerful_stroke_of_insight.html',
23
+ 'http://www.ted.com/talks/lang/fa/jill_bolte_taylor_s_powerful_stroke_of_insight.html',
24
+ ),
25
+ 'invalid' => array(
26
+ 'http://www.ted.com/',
27
+ 'http://www.ted.com/playlists/5/insects_are_awesome.html',
28
+ 'http://www.ted.com/tedx',
29
+ 'http://www.ted.com/talks',
30
+ ),
31
+ 'fake' => array(
32
+ 'type' => 'video',
33
+ 'html' => '<iframe'
34
+ )
35
+ );
36
+
37
+ public function testProvider() { $this->validateProvider('Ted'); }
38
+ }
39
+ ?>
library/ostraining/embera/Tests/TestServiceTheySaidSo.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceTheySaidSo.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceTheySaidSo extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://theysaidso.com/i/f5XZNjeYgxdZOSnYWQAHbQeF',
20
+ 'https://theysaidso.com/quote/Ox8voVa3kvS8upOHPmuWUweF#',
21
+ 'https://theysaidso.com/quote/QaFPskqQUabgcmOWVREIdAeF?query=string',
22
+ 'https://theysaidso.com/i/e798C8EEnAycJesx_MWDJAeF/',
23
+ 'http://theysaidso.com/i/f5XZNjeYgxdZOSnYWQAHbQeF',
24
+ 'https://www.theysaidso.com/i/GuLDqbvqaibMX_2Rl2sR4weF',
25
+ ),
26
+ 'invalid' => array(
27
+ 'https://theysaidso.com/qod#',
28
+ 'https://theysaidso.com',
29
+ 'https://theysaidso.com/i/image/GuLDqbvqaibMX_2Rl2sR4weF',
30
+ 'https://theysaidso.com/c/1#',
31
+ 'http://theysaidso.com/i/f5XZNjeYgxdZOSnYWQAHbQeF/other-path',
32
+ )
33
+ );
34
+
35
+ /**
36
+ * @large
37
+ */
38
+ public function testProvider() { $this->validateProvider('TheySaidSo'); }
39
+ }
40
+ ?>
library/ostraining/embera/Tests/TestServiceTwitter.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceTwitter.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceTwitter extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://twitter.com/ThatKevinSmith/status/361972660344856576',
20
+ 'https://twitter.com/RalphGarman/status/363749205367472129/',
21
+ 'https://twitter.com/RalphGarman/status/363354457351782401',
22
+ 'http://twitter.com/#!RalphGarman/status/363326025834299393',
23
+ 'https://twitter.com/#!RalphGarman/status/362589356495605762/',
24
+ 'https://twitter.com/#!RalphGarman/status/362279899639197696'
25
+ ),
26
+ 'invalid' => array(
27
+ 'https://twitter.com/RalphGarman/statuses/363354457351782401',
28
+ 'https://twitter.com/#!RalphGarman/status/wordswordswords/',
29
+ 'https://twitter.com/status/363749205367472129/',
30
+ 'https://twitter.com/RalphGarman/363749205367472129/',
31
+ 'https://twitter.com/#!363749205367472129/',
32
+ 'https://twitter.com/363749205367472129/',
33
+ 'https://twitter.com/',
34
+ ),
35
+ 'normalize' => array(
36
+ 'https://twitter.com/#!RalphGarman/status/362589356495605762/' => 'https://twitter.com/RalphGarman/status/362589356495605762',
37
+ 'https://twitter.com/#!RalphGarman/status/362589356495605762' => 'https://twitter.com/RalphGarman/status/362589356495605762'
38
+ )
39
+ );
40
+
41
+ public function testProvider() { $this->validateProvider('Twitter'); }
42
+ }
43
+ ?>
library/ostraining/embera/Tests/TestServiceUstream.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceUstream.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceUstream extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.ustream.tv/channel/americatv2oficial',
20
+ 'http://www.ustream.tv/usbc',
21
+ 'http://www.ustream.tv/creativelive-3',
22
+ 'http://www.ustream.tv/creativeLIVE-rebroadcast',
23
+ 'https://www.ustream.tv/creativeLIVE-rebroadcast',
24
+ 'http://www.ustream.tv/channel/cbc-tv',
25
+ 'http://ustream.com/KTNKENYALIVE',
26
+ 'http://www.ustream.tv/channel/radio-unilatina-en-vivo',
27
+ ),
28
+ 'invalid' => array(
29
+ 'http://ustre.am/142lz',
30
+ 'http://www.ustream.tv',
31
+ 'http://www.ustream.tv/channel/radio-unilatina-en-vivo/other-stuff',
32
+ 'https://www.ustream.tv/platform/pro#itm_source=footer&itm_medium=pro_link&itm_content=Pro Broadcasting&itm_campaign=footer',
33
+ 'https://www.ustream.tv/platform/plans',
34
+ 'http://www.ustream.tv/howto',
35
+ 'http://www.ustream.com/howto',
36
+ ),
37
+ );
38
+
39
+ public function testProvider() { $this->validateProvider('Ustream'); }
40
+ }
41
+ ?>
library/ostraining/embera/Tests/TestServiceVerse.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceVerse.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceVerse extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://verse.media/stories/112-connected-to-the-top/arrival-at-base-camp',
20
+ 'https://www.verse.media/stories/112-connected-to-the-top/',
21
+ 'http://verse.media/stories/112-connected-to-the-top/up-the-icefall/',
22
+ 'http://verse.media/stories/112-connected-to-the-top/reaching-for-the-top/interview-with-sam-elias',
23
+ ),
24
+ 'invalid' => array(
25
+ 'http://verse.media',
26
+ 'http://verse.media/not/stories/112-connected-to-the-top/reaching-for-the-top/interview-with-sam-elias',
27
+ ),
28
+ 'fake' => array(
29
+ 'type' => 'video',
30
+ 'html' => '<iframe'
31
+ )
32
+ );
33
+
34
+ public function testProvider() { $this->validateProvider('Verse'); }
35
+ }
36
+ ?>
library/ostraining/embera/Tests/TestServiceViddler.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceViddler.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceViddler extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.viddler.com/v/a695c468',
20
+ 'http://www.viddler.com/v/a695c468/lightbox?autoplay=1',
21
+ 'http://www.viddler.com/v/528b194c/otherStuff/lightbox',
22
+ 'http://viddler.com/embed/4c57d97a/lightbox',
23
+ 'http://viddler.com/v/4c57d97a/lightbox',
24
+ 'http://viddler.com/v/c83cacd4'
25
+ ),
26
+ 'invalid' => array(
27
+ 'http://viddler.com/invalidstuff/a695c468',
28
+ 'http://www.viddler.com/v/zxsdg9',
29
+ 'http://www.viddler.com/player/528b194c/otherStuff/lightbox',
30
+ 'http://viddler.com/v/',
31
+ ),
32
+ 'normalize' => array(
33
+ 'http://www.viddler.com/v/a695c468' => 'http://www.viddler.com/v/a695c468',
34
+ 'http://www.viddler.com/v/a695c468/' => 'http://www.viddler.com/v/a695c468',
35
+ 'http://www.viddler.com/v/528b194c/otherStuff/lightbox' => 'http://www.viddler.com/v/528b194c',
36
+ 'http://viddler.com/embed/4c57d97a/lightbox' => 'http://www.viddler.com/v/4c57d97a',
37
+ 'http://viddler.com/embed/4c57d97a/' => 'http://www.viddler.com/v/4c57d97a',
38
+ ),
39
+ 'fake' => array(
40
+ 'type' => 'video',
41
+ 'html' => '<iframe'
42
+ )
43
+ );
44
+
45
+ public function testProvider() { $this->validateProvider('Viddler'); }
46
+ }
47
+ ?>
library/ostraining/embera/Tests/TestServiceVideoFork.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceVideoFork.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceVideoFork extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://videofork.com/play/1655979',
20
+ 'http://videofork.com/play/1655970/',
21
+ 'http://videofork.com/play/1656128/other/stuff',
22
+ 'http://videofork.com/oembed/1656122',
23
+ 'http://videofork.com/oembed/1656113/',
24
+ 'http://videofork.com/play/1656101',
25
+ ),
26
+ 'invalid' => array(
27
+ 'http://videofork.com/?q=',
28
+ 'http://videofork.com/',
29
+ 'http://videofork.com/technology',
30
+ 'http://videofork.com/forks/new',
31
+ '',
32
+ ),
33
+ 'fake' => array(
34
+ 'type' => 'video',
35
+ 'html' => '<object'
36
+ )
37
+ );
38
+
39
+ public function testProvider() { $this->validateProvider('VideoFork'); }
40
+ }
41
+ ?>
library/ostraining/embera/Tests/TestServiceVideoJug.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceVideoJug.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceVideoJug extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://www.videojug.com/film/how-to-use-your-ipod-click-wheel',
20
+ 'http://www.videojug.com/interview/vehicle-speed',
21
+ 'http://videojug.com/film/how-to-get-music-onto-your-ipod-from-a-cd',
22
+ 'http://www.videojug.com/film/how-to-make-a-line-graph-in-excel/',
23
+ 'http://www.videojug.com/film/how-to-fix-a-scratched-xbox-360-game',
24
+ 'http://www.videojug.com/film/how-to-change-a-car-battery-2',
25
+ ),
26
+ 'invalid' => array(
27
+ 'http://www.videojug.com/tag/video-games-and-consoles',
28
+ 'http://www.videojug.com/tag/technology-and-cars',
29
+ 'http://www.videojug.com/film/technology-and-cars/other/stuff',
30
+ 'http://www.videojug.com',
31
+ ),
32
+ );
33
+
34
+ public function testProvider() { $this->validateProvider('VideoJug'); }
35
+ }
36
+ ?>
library/ostraining/embera/Tests/TestServiceVimeo.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceVimeo.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceVimeo extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://vimeo.com/channels/staffpicks/66252440',
20
+ 'http://vimeo.com/channels/staffpicks/65535198/',
21
+ 'http://vimeo.com/groups/shortfilms/videos/66185763',
22
+ 'https://vimeo.com/groups/shortfilms/videos/63313811/',
23
+ 'http://vimeo.com/47360546',
24
+ 'http://vimeo.com/39892335/',
25
+ 'https://player.vimeo.com/video/65297606',
26
+ 'https://player.vimeo.com/video/25818086/'
27
+ ),
28
+ 'invalid' => array(
29
+ 'http://vimeo.com/groups/shortfilms/videos/66185763/stuff/here',
30
+ 'http://vimeo.com/47360546/other/stuff/',
31
+ 'http://vimeo.com/groups/shortfilms/123',
32
+ 'http://vimeo.com/groups/shortfilms',
33
+ 'http://vimeo.com/',
34
+ 'http://vimeo.com/groups/stuff/?autoplay=1'
35
+ ),
36
+ 'normalize' => array(
37
+ 'http://vimeo.com/channels/staffpicks/66252440' => 'http://vimeo.com/66252440',
38
+ 'http://vimeo.com/channels/staffpicks/65535198/' => 'http://vimeo.com/65535198',
39
+ 'https://player.vimeo.com/video/65297606' => 'http://vimeo.com/65297606',
40
+ 'http://vimeo.com/groups/shortfilms/videos/63313811/' => 'http://vimeo.com/63313811',
41
+ 'http://vimeo.com/47360546' => 'http://vimeo.com/47360546',
42
+ 'http://vimeo.com/39892335/' => 'http://vimeo.com/39892335',
43
+ ),
44
+ 'fake' => array(
45
+ 'type' => 'video',
46
+ 'html' => '<iframe'
47
+ )
48
+ );
49
+
50
+ public function testProvider() { $this->validateProvider('Vimeo'); }
51
+ }
52
+ ?>
library/ostraining/embera/Tests/TestServiceVine.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceVine.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceVine extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://vine.co/v/OZQ61X9KWwB',
20
+ 'https://vine.co/v/OzPtPEPOwVI/',
21
+ 'http://vine.co/v/MEDKjeFnx2B',
22
+ 'http://vine.co/v/MUq1itKiPhQ/',
23
+ ),
24
+ 'invalid' => array(
25
+ 'https://vine.co/editors-picks',
26
+ 'http://vine.co/v/MUq1itKiPhQ/other-stuff',
27
+ 'https://vine.co/search/asdas',
28
+ ),
29
+ 'fake' => array(
30
+ 'type' => 'video',
31
+ 'html' => '<iframe'
32
+ )
33
+ );
34
+
35
+ /**
36
+ * @large
37
+ */
38
+ public function testProvider()
39
+ {
40
+ $this->validateProvider('Vine');
41
+ }
42
+ }
43
+ ?>
library/ostraining/embera/Tests/TestServiceWordpressTV.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceWordpressTV.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceWordpressTV extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://wordpress.tv/2013/08/25/andy-hayes-website-critiques-how-to-decide-what-works-and-what-to-ditch/',
20
+ 'http://wordpress.tv/2013/05/09/understanding-the-add-new-link-screen-and-xfn-link-relationships/',
21
+ 'http://wordpress.tv/2013/04/20/kimanzi-constable-the-power-of-your-story-through-wordpress/',
22
+ 'http://wordpress.tv/2013/04/12/jayvie-canono-designing-for-development',
23
+ 'http://blog.wordpress.tv/2013/08/08/state-of-the-word-retrospective/',
24
+ 'http://blog.wordpress.tv/2010/06/21/wordpress-3-0-videos/'
25
+ ),
26
+ 'invalid' => array(
27
+ 'http://wordpress.tv/tag/plugins/',
28
+ 'http://wordpress.tv/get-involved/',
29
+ 'http://wordpress.tv/category/how-to/',
30
+ ),
31
+ );
32
+
33
+ public function testProvider() { $this->validateProvider('WordpressTV'); }
34
+ }
35
+ ?>
library/ostraining/embera/Tests/TestServiceYFrog.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceYFrog.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceYFrog extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'http://yfrog.us/jukynnj',
20
+ 'http://twitter.yfrog.com/es3r8kzj',
21
+ 'http://twitter.yfrog.com/hws60ilj?sa=0',
22
+ 'http://yfrog.com/odxklwraj',
23
+ 'http://yfrog.com/odxklwraj?sa=0',
24
+ 'http://twitter.yfrog.com/h835endj',
25
+ 'http://yfrog.us/mryll1j',
26
+ 'http://twitter.yfrog.com/kex9kulj?sa=0',
27
+ ),
28
+ 'invalid' => array(
29
+ 'http://twitter.yfrog.com/user/IsabelVRuys/profile',
30
+ 'http://yfrog.com/about',
31
+ 'http://twitter.yfrog.com/',
32
+ 'http://yfrog.com/',
33
+ 'http://twitter.yfrog.com/page/faq',
34
+ 'http://blog.yfrog.com/jobs/',
35
+ 'http://twitter.yfrog.com/page/api',
36
+ ),
37
+ 'normalize' => array(
38
+ 'http://twitter.yfrog.com/hws60ilj?sa=0' => 'http://twitter.yfrog.com/hws60ilj',
39
+ 'http://twitter.yfrog.com/hws60ilj?sa=1' => 'http://twitter.yfrog.com/hws60ilj',
40
+ 'http://twitter.yfrog.com/hws60ilj?sa=0&stuff=stuff' => 'http://twitter.yfrog.com/hws60ilj',
41
+ )
42
+ );
43
+
44
+ public function testProvider() { $this->validateProvider('YFrog'); }
45
+ }
46
+ ?>
library/ostraining/embera/Tests/TestServiceYandex.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceYandex.php
4
+ *
5
+ * @package Tests
6
+ * @author dotzero <mail@dotzero.ru>
7
+ * @link http://www.dotzero.ru/
8
+ */
9
+
10
+ require_once 'TestProviders.php';
11
+
12
+ class TestServiceYandex extends TestProviders
13
+ {
14
+ protected $urls = array(
15
+ 'valid' => array(
16
+ 'http://video.yandex.ru/users/ya-events/view/2620/',
17
+ 'http://video.yandex.ru/users/ya-events/view/2620',
18
+ 'https://video.yandex.ru/users/ya-events/view/2620/',
19
+ 'https://video.yandex.ru/users/ya-events/view/2620',
20
+ ),
21
+ 'invalid' => array(
22
+ 'https://video.yandex.ru/view/ya-events/view/2620/',
23
+ 'https://video.yandex.ru/ya-events/view/2620/',
24
+ 'https://video.yandex.ru/users/ya-events/view/',
25
+ ),
26
+ 'normalize' => array(
27
+ 'http://video.yandex.ru/users/ya-events/view/2620' => 'http://video.yandex.ru/users/ya-events/view/2620/',
28
+ 'http://www.video.yandex.ru/users/ya-events/view/2620' => 'http://video.yandex.ru/users/ya-events/view/2620/',
29
+ ),
30
+ );
31
+
32
+ public function testProvider() { $this->validateProvider('Yandex'); }
33
+ }
library/ostraining/embera/Tests/TestServiceYoutube.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestServiceYoutube.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ require_once 'TestProviders.php';
14
+
15
+ class TestServiceYoutube extends TestProviders
16
+ {
17
+ protected $urls = array(
18
+ 'valid' => array(
19
+ 'https://www.youtube.com/watch?v=9bZkp7q19f0',
20
+ 'http://youtube.com/watch?v=J---aiyznGQ',
21
+ 'https://www.youtube.com/watch?v=xVrJ8DxECbg&list=PLwnD0jwK0yymXOCl82nqdTdxe0ykVDcPW&index=1',
22
+ 'http://youtube.com/watch?v=xVrJ8DxECbg&list=PLwnD0jwK0yymXOCl82nqdTdxe0ykVDcPW',
23
+ 'http://www.youtube.com/watch?v=WtPiGYsllos&index=1',
24
+ 'https://m.youtube.com/watch?v=mghhLqu31cQ',
25
+ 'https://m.youtube.com/watch?v=wB3sjAIARIY',
26
+ 'http://youtube.com/embed/mghhLqu31cQ',
27
+ 'http://www.youtube.com/embed/mghhLqu31cQ',
28
+ 'http://youtu.be/8aGEb_yUpMs'
29
+ ),
30
+ 'invalid' => array(
31
+ 'http://youtube.com/watch?list=hi',
32
+ 'http://youtube.com /watch?video=J---aiyznGQ',
33
+ 'http://www.youtu.be.com/watch?lol=no',
34
+ 'http://www.youtube.com/hi#ho',
35
+ 'http://youtube.com/',
36
+ 'http://www.youtube.com/?id=ho'
37
+ ),
38
+ 'normalize' => array(
39
+ 'http://youtu.be/9bZkp7q19f0/werwer' => 'http://www.youtube.com/watch?v=9bZkp7q19f0',
40
+ 'http://www.youtube.com/watch?v=9bZkp7q19f0' => 'http://www.youtube.com/watch?v=9bZkp7q19f0',
41
+ 'http://youtube.com/watch?v=xVrJ8DxECbg&list=PLwnD0jwK0yymXOCl82nqdTdxe0ykVDcPW&index=1' => 'http://www.youtube.com/watch?v=xVrJ8DxECbg',
42
+ 'http://youtu.be/8aGEb_yUpMs' => 'http://www.youtube.com/watch?v=8aGEb_yUpMs',
43
+ 'http://youtube.com/watch?v=J---aiyznGQ&index=1' => 'http://www.youtube.com/watch?v=J---aiyznGQ',
44
+ 'http://youtube.com/watch?v=mghhLqu31cQ' => 'http://www.youtube.com/watch?v=mghhLqu31cQ',
45
+ 'http://youtube.com/embed/mghhLqu31cQ' => 'http://www.youtube.com/watch?v=mghhLqu31cQ',
46
+ ),
47
+ 'fake' => array(
48
+ 'type' => 'video',
49
+ 'html' => '<iframe'
50
+ )
51
+ );
52
+
53
+ public function testProvider() { $this->validateProvider('Youtube'); }
54
+ }
55
+ ?>
library/ostraining/embera/Tests/TestUrl.php ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * TestUrl.php
4
+ *
5
+ * @package Tests
6
+ * @author Michael Pratt <pratt@hablarmierda.net>
7
+ * @link http://www.michael-pratt.com/
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ class TestUrl extends PHPUnit_Framework_TestCase
14
+ {
15
+ public function testInvalidPattern()
16
+ {
17
+ $url = new \Embera\Url('http://www.hablarmierda.net/path/stuff/');
18
+ $url->invalidPattern('\.net/path/(?:[^/]+)/');
19
+ $this->assertEmpty((string) $url);
20
+
21
+ $url = new \Embera\Url('http://www.hablarmierda.net');
22
+ $url->invalidPattern('\.net/hi/');
23
+ $this->assertEquals('http://www.hablarmierda.net', (string) $url);
24
+ }
25
+
26
+ public function testStripQueryString()
27
+ {
28
+ $url = new \Embera\Url('http://www.hablarmierda.net/path/?hi=why&id=8');
29
+ $url->stripQueryString();
30
+ $this->assertEquals('http://www.hablarmierda.net/path/', (string) $url);
31
+
32
+ $url = new \Embera\Url('http://www.hablarmierda.net/path?hi=why&id=8');
33
+ $url->stripQueryString();
34
+ $this->assertEquals('http://www.hablarmierda.net/path', (string) $url);
35
+
36
+ $url = new \Embera\Url('http://www.hablarmierda.net/path/#hi');
37
+ $url->stripQueryString();
38
+ $this->assertEquals('http://www.hablarmierda.net/path/', (string) $url);
39
+
40
+ $url = new \Embera\Url('http://www.hablarmierda.net/path/#hi&ho=80');
41
+ $url->stripQueryString();
42
+ $this->assertEquals('http://www.hablarmierda.net/path/', (string) $url);
43
+
44
+ $url = new \Embera\Url('http://www.hablarmierda.net/path/');
45
+ $url->stripQueryString();
46
+ $this->assertEquals('http://www.hablarmierda.net/path/', (string) $url);
47
+ }
48
+
49
+ public function testDiscardChanges()
50
+ {
51
+ $url = new \Embera\Url('http://www.hablarmierda.net/path/?hi=why&id=8');
52
+ $url->stripQueryString();
53
+ $url->stripLastSlash();
54
+ $this->assertEquals('http://www.hablarmierda.net/path', (string) $url);
55
+
56
+ $url->discardChanges();
57
+ $this->assertEquals('http://www.hablarmierda.net/path/?hi=why&id=8', (string) $url);
58
+ }
59
+
60
+ public function testStripLastSlash()
61
+ {
62
+ $url = new \Embera\Url('http://www.hablarmierda.net/path/');
63
+ $url->stripLastSlash();
64
+ $this->assertEquals('http://www.hablarmierda.net/path', (string) $url);
65
+
66
+ $url = new \Embera\Url('http://www.hablarmierda.net/path////');
67
+ $url->stripLastSlash();
68
+ $this->assertEquals('http://www.hablarmierda.net/path', (string) $url);
69
+
70
+ $url = new \Embera\Url('http://www.hablarmierda.net/path');
71
+ $url->stripLastSlash();
72
+ $this->assertEquals('http://www.hablarmierda.net/path', (string) $url);
73
+ }
74
+
75
+ public function testStripWWW()
76
+ {
77
+ $url = new \Embera\Url('http://www.hablarmierda.net/path/');
78
+ $url->stripWWW();
79
+ $this->assertEquals('http://hablarmierda.net/path/', (string) $url);
80
+
81
+ $url = new \Embera\Url('https://www.hablarmierda.net/path/');
82
+ $url->stripWWW();
83
+ $this->assertEquals('https://hablarmierda.net/path/', (string) $url);
84
+
85
+ $url = new \Embera\Url('http://hablarmierda.www.net/path/');
86
+ $url->stripWWW();
87
+ $this->assertEquals('http://hablarmierda.www.net/path/', (string) $url);
88
+
89
+ $url = new \Embera\Url('http://hablarmierda.net/path/');
90
+ $url->stripWWW();
91
+ $this->assertEquals('http://hablarmierda.net/path/', (string) $url);
92
+
93
+ $url = new \Embera\Url('http://hablarmierda.net/path/www.');
94
+ $url->stripWWW();
95
+ $this->assertEquals('http://hablarmierda.net/path/www.', (string) $url);
96
+ }
97
+
98
+ public function testAddWWW()
99
+ {
100
+ $url = new \Embera\Url('http://www.hablarmierda.net/path/');
101
+ $url->addWWW();
102
+ $this->assertEquals('http://www.hablarmierda.net/path/', (string) $url);
103
+
104
+ $url = new \Embera\Url('http://hablarmierda.net/path/');
105
+ $url->addWWW();
106
+ $this->assertEquals('http://www.hablarmierda.net/path/', (string) $url);
107
+
108
+ $url = new \Embera\Url('https://hablarmierda.net/path/');
109
+ $url->addWWW();
110
+ $this->assertEquals('https://www.hablarmierda.net/path/', (string) $url);
111
+ }
112
+
113
+ public function testConvertToHttp()
114
+ {
115
+ $url = new \Embera\Url('http://www.hablarmierda.net/path/');
116
+ $url->convertToHttp();
117
+ $this->assertEquals('http://www.hablarmierda.net/path/', (string) $url);
118
+
119
+ $url = new \Embera\Url('https://hablarmierda.net/path/');
120
+ $url->convertToHttp();
121
+ $this->assertEquals('http://hablarmierda.net/path/', (string) $url);
122
+
123
+ $url = new \Embera\Url('https://www.hablarmierda.net/path/');
124
+ $url->convertToHttp();
125
+ $this->assertEquals('http://www.hablarmierda.net/path/', (string) $url);
126
+ }
127
+
128
+ public function testConvertToHttps()
129
+ {
130
+ $url = new \Embera\Url('http://www.hablarmierda.net/path/');
131
+ $url->convertToHttps();
132
+ $this->assertEquals('https://www.hablarmierda.net/path/', (string) $url);
133
+
134
+ $url = new \Embera\Url('https://hablarmierda.net/path/');
135
+ $url->convertToHttps();
136
+ $this->assertEquals('https://hablarmierda.net/path/', (string) $url);
137
+
138
+ $url = new \Embera\Url('http://www.hablarmierda.net/path/');
139
+ $url->convertToHttps();
140
+ $this->assertEquals('https://www.hablarmierda.net/path/', (string) $url);
141
+ }
142
+
143
+ public function testEmbed()
144
+ {
145
+ $url = new \Embera\Url('embed://www.hablarmierda.net/path/');
146
+ $this->assertEquals('http://www.hablarmierda.net/path/', (string) $url);
147
+
148
+ $url = new \Embera\Url('embed://www.hablarmierda.net/path/');
149
+ $url->convertToHttps();
150
+ $this->assertEquals('https://www.hablarmierda.net/path/', (string) $url);
151
+ }
152
+ }
153
+
154
+ ?>
library/ostraining/embera/composer.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "ostraining/embera",
3
+ "type": "library",
4
+ "description": "Oembed consumer library, that gives information about urls. It helps you replace urls to 60+ sites like youtube or vimeo, with their html embed code.",
5
+ "keywords": ["Embed", "Oembed", "Auto embed", "Embed Text", "Url Embed", "Youtube", "Vimeo", "Vine", "Twitter", "Instagram"],
6
+ "homepage": "https://github.com/OSTraining/Embera",
7
+ "license": "MIT",
8
+ "authors": [
9
+ {
10
+ "name": "Michael Pratt",
11
+ "email": "pratt@hablarmierda.net",
12
+ "homepage": "http://www.michael-pratt.com",
13
+ "role": "Author/Developer"
14
+ }
15
+ ],
16
+ "require": {
17
+ "php": ">=5.3"
18
+ },
19
+ "autoload": {
20
+ "psr-0": {"Embera": "Lib/"}
21
+ }
22
+ }
library/ostraining/embera/phpdoc.xml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <phpdoc>
3
+ <parser>
4
+ <target>Docs/</target>
5
+ <markers>
6
+ <item>TODO</item>
7
+ <item>FIXME</item>
8
+ </markers>
9
+ <extensions>
10
+ <extension>php</extension>
11
+ </extensions>
12
+ </parser>
13
+ <transformer>
14
+ <target>Docs/</target>
15
+ </transformer>
16
+ <files>
17
+ <directory>.</directory>
18
+ <ignore>Tests/*</ignore>
19
+ <ignore>Toolkit/*</ignore>
20
+ <ignore>vendor/*</ignore>
21
+ </files>
22
+ </phpdoc>
library/ostraining/embera/phpunit.full-urls.xml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <phpunit strict="true"
2
+ backupGlobals="false"
3
+ backupStaticAttributes="false"
4
+ syntaxCheck="false"
5
+ timeoutForSmallTests="200"
6
+ timeoutForMediumTests="300"
7
+ timeoutForLargeTests="360"
8
+ bootstrap="Tests/Autoload.php">
9
+ <testsuites>
10
+ <testsuite name="Library Check">
11
+ <directory suffix=".php">Tests/</directory>
12
+ </testsuite>
13
+ </testsuites>
14
+ <filter>
15
+ <blacklist>
16
+ <directory suffix=".php">vendor/</directory>
17
+ <directory suffix=".php">Tests/</directory>
18
+ </blacklist>
19
+ </filter>
20
+ <logging>
21
+ <log type="coverage-html" target="Tests/Coverage" charset="UTF-8" yui="true" highlight="false" lowUpperBound="35" highLowerBound="70"/>
22
+ </logging>
23
+ <php>
24
+ <const name="FULL_TEST" value="1"/>
25
+ </php>
26
+ </phpunit>
library/ostraining/embera/phpunit.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <phpunit strict="true"
2
+ backupGlobals="false"
3
+ backupStaticAttributes="false"
4
+ syntaxCheck="false"
5
+ timeoutForSmallTests="100"
6
+ timeoutForMediumTests="200"
7
+ timeoutForLargeTests="300"
8
+ bootstrap="Tests/Autoload.php">
9
+ <testsuites>
10
+ <testsuite name="Library Check">
11
+ <directory suffix=".php">Tests/</directory>
12
+ </testsuite>
13
+ </testsuites>
14
+ <filter>
15
+ <blacklist>
16
+ <directory suffix=".php">vendor/</directory>
17
+ <directory suffix=".php">Tests/</directory>
18
+ </blacklist>
19
+ </filter>
20
+ <logging>
21
+ <log type="coverage-html" target="Tests/Coverage" charset="UTF-8" yui="true" highlight="false" lowUpperBound="35" highLowerBound="70"/>
22
+ </logging>
23
+ </phpunit>
library/ostraining/index.html ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>403 Forbidden</title>
5
+ </head>
6
+ <body>
7
+ <p>Directory access is forbidden.</p>
8
+ </body>
9
+ </html>
providers.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
3
+
4
+ /**
5
+ * Declare an associative array that is responsible for mapping additional service providers to its urls.
6
+ * The key must match the class placed in ./EmbedPress/Providers/ folder, and the values must be a string or
7
+ * another array listing all url patterns in which the key (a.k.a. the service provider you're adding)
8
+ * should be triggered.
9
+ *
10
+ * @package EmbedPress
11
+ * @author PressShack <help@pressshack.com>
12
+ * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
13
+ * @license GPLv2 or later
14
+ * @since 1.0
15
+ */
16
+
17
+ $additionalServiceProviders = array(
18
+ 'GoogleMaps' => array("google.com", "google.com.*", "maps.google.com"),
19
+ 'GoogleDocs' => array("docs.google.com")
20
+ );
readme.txt ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === EmbedPress ===
2
+ Contributors: PressShack
3
+ Tags: embed, embera, embedding, pressshack, ostraining
4
+ Requires at least: 4.0
5
+ Tested up to: 4.5.2
6
+ Stable tag: 1.0
7
+ License: GPLv2 or later
8
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
+
10
+ EmbedPress - Embed anything in WordPress! But now, you can enhance your embeds by passing custom parameters to each one of them.
11
+
12
+ == Description ==
13
+ EmbedPress makes embedding super-easy. All you need is the URL and you can embed almost anything into a WordPress site! You can even pass custom attributes to the generated html.
14
+
15
+ Even if you are not an experienced developer, with EmbedPress, you can easily embed content to your WordPress site from over 60 sources including these:
16
+ Facebook, YouTube, Vimeo, DailyMotion, Instagram, SoundCloud, Twitter, Slideshare, Flickr, Hulu, Kickstarter, Vine, Getty Images and [many more](https://github.com/OSTraining/EmbedPress/blob/master/PROVIDERS.md)!
17
+
18
+ == Installation ==
19
+ There're two ways to install EmbedPress plugin:
20
+
21
+ **Through your WordPress site's admin**
22
+
23
+ 1. Go to your site's admin page;
24
+ 2. Access the "Plugins" page;
25
+ 3. Click on the "Add New" button;
26
+ 4. Search for "EmbedPress";
27
+ 5. Install EmbedPress plugin;
28
+ 6. Activate the EmbedPress plugin.
29
+
30
+ **Manually uploading the plugin to your repository**
31
+
32
+ 1. Download the EmbedPress plugin zip file;
33
+ 2. Upload the plugin to your site's repository under the *"/wp-content/plugins/"* directory;
34
+ 3. Go to your site's admin page;
35
+ 4. Access the "Plugins" page;
36
+ 5. Activate the EmbedPress plugin.
37
+
38
+ == Usage ==
39
+ - Once the plugin is active, you can go on the editor and paste any URL as you normally would.
40
+ - To pass custom parameters to an embed you can hover on the preview and click on the "Pencil" button. Optionally you can set custom parameters directly using short-codes like:
41
+
42
+ `
43
+ // This will render the iframe (if there's one. Some services may use other tags) having its dimensions fixed to 460x300px.
44
+ [embed width="460" height="300" responsive="false"]your-link[/embed]
45
+
46
+ // This will render the html-embed having an additional html property data-foo="this is awesome".
47
+ [embed foo="this is awesome"]your-other-link[/embed]
48
+
49
+ // This will render the html-embed having the class "cool-embed".
50
+ [embed class="cool-embed"]your-other-link[/embed]
51
+ `
52
+
53
+ == Changelog ==
54
+ = 1.0 =
55
+ Release Date: 2016-07-27
56
+
57
+ * Initial release.