Created
October 5, 2017 10:01
-
-
Save thecotne/31e374d42c80d89a244b9da24012d39b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* MHP1138 Mobile Player v.3.1.0 | |
*/ | |
MHP1138.skinsMarkup['html'] = "<template class=mhp1138_logo_tube8><svg class=mhp1138_tube8 viewBox='1968 3562 2355 860'><path d='m4251 3994c0 202-164 367-367 367-202 0-367-164-367-367 0-202 164-367 367-367 202 0 367 164 367 367z' fill=#ccc /><circle cy=3994 cx=3884 r=349 fill=#fff /><path d='m4211 3994c0 180-146 327-327 327-180 0-327-146-327-327 0-180 146-327 327-327 180 0 327 146 327 327z' fill=#231F20 /><g opacity=.35><radialGradient id=a1_ gradientUnits=userSpaceOnUse cy=4736 cx=9218.8 gradientTransform='matrix(.4116 0 0 -.4116 0 588)' r=1019.6><stop stop-color=#fff offset=0 /><stop offset=.8681 /></radialGradient><path d='m4211 3994c0 180-146 327-327 327-180 0-327-146-327-327 0-180 146-327 327-327 180 0 327 146 327 327z' fill=url(#a1_) /></g><path d='m3810 4205c-114 0-206-91-206-203s92-203 206-203 206 91 206 203-92 203-206 203z' fill=#fff /><path d='m3810 3792c116 0 211 93 211 209s-94 209-211 209-211-93-211-209 95-209 211-209m0 11c-111 0-201 89-201 198s91 199 201 199 201-89 201-198-90-199-201-199z' fill=#231F20 /><path d='m1986 3816h345v91h-116v277h-114v-277h-116l1-91z' fill=#fff /><path d='m2331 3816v91h-116v277h-114v-277h-116v-91h346m0-19h-345c-10 0-19 8-19 19v91c0 10 8 19 19 19h98v258c0 10 8 19 18 19h114c10 0 19-8 19-19v-258h98c10 0 18-8 18-19v-91c-2-11-10-19-20-19z' fill=#231F20 /><path d='m2613 3816h113v219c0 22-3 42-10 61s-17 36-32 51c-14 14-30 25-45 30-22 8-49 12-79 12-18 0-37-1-58-4-21-2-39-7-53-15-14-7-27-18-39-32s-20-28-24-42c-7-23-11-44-11-62v-219h113v224c0 20 5 36 16 47s26 17 46 17 35-5 46-16 16-27 16-47l1-224z' fill=#fff /><path d='m2726 3816v219c0 22-3 42-10 61s-17 36-32 51c-14 14-30 25-45 30-22 8-49 12-79 12-18 0-37-1-58-4-21-2-39-7-53-15-14-7-27-18-39-32s-20-28-24-42c-7-23-11-44-11-62v-219h113v224c0 20 5 36 16 47s26 17 46 17 35-5 46-16 16-27 16-47v-224h114m0-19h-113c-10 0-19 8-19 19v224c0 16-4 27-11 34s-19 11-33 11c-15 0-26-4-33-12-8-8-12-19-12-34v-224c0-10-8-19-18-19h-113c-10 0-18 8-18 19v219c0 20 4 42 11 67 5 17 14 33 28 49 13 15 28 28 44 36 16 9 36 14 59 17 22 2 42 4 61 4 33 0 62-5 86-14 18-7 36-19 52-35s28-36 36-58c7-21 11-44 11-67v-219c0-9-8-17-18-17z' fill=#231F20 /><path d='m2792 3816h212c35 0 63 9 81 26 19 18 28 39 28 65 0 22-7 40-20 56-9 10-22 19-40 25 26 6 46 17 58 33s19 35 19 58c0 19-5 36-13 51-9 15-21 27-36 36-9 5-24 9-43 12-26 3-42 5-51 5h-196v-367h1zm115 144h49c18 0 30-3 37-9s10-15 10-26-3-19-10-25-19-9-36-9h-50v69zm0 144h58c19 0 33-3 41-10s12-16 12-28c0-11-4-20-12-26s-22-10-42-10h-58v74h1z' fill=#fff /><path d='m3005 3816c35 0 63 9 81 26 19 18 28 39 28 65 0 22-7 40-20 56-9 10-22 19-40 25 26 6 46 17 58 33s19 35 19 58c0 19-5 36-13 51-9 15-21 27-36 36-9 5-24 9-43 12-26 3-42 5-51 5h-196v-367h213m-98 144h49c18 0 30-3 37-9s10-15 10-26-3-19-10-25-19-9-36-9h-50v69m0 144h58c19 0 33-3 41-10s12-16 12-28c0-11-4-20-12-26s-22-10-42-10h-58v74m99-307h-212c-10 0-18 8-18 19v367c0 10 8 19 18 19h196c9 0 27-2 53-5 22-3 38-7 50-14 18-10 33-25 43-43s16-38 16-61c0-28-8-51-23-70-8-9-17-18-29-24 4-3 7-6 10-9 16-19 25-42 25-68 0-31-12-58-34-79-24-21-55-32-95-32zm-80 111h32c18 0 23 4 24 5 2 2 4 5 4 11 0 9-3 12-4 13s-6 5-25 5h-31v-34zm0 140h40c21 0 28 5 30 6 4 3 5 7 5 12 0 8-3 12-6 14-2 2-9 6-29 6h-40v-38z' fill=#231F20 /><path d='m3182 3816h304v79h-191v58h177v75h-177v72h196v83h-309v-367z' fill=#fff /><path d='m3486 3816v79h-191v58h177v75h-177v72h196v83h-309v-367h304m0-19h-304c-10 0-18 8-18 19v367c0 10 8 19 18 19h309c10 0 19-8 19-19v-83c0-10-8-19-19-19h-177v-36h158c10 0 19-8 19-18v-75c0-10-8-19-19-19h-158v-22h172c10 0 19-8 19-19v-79c0-8-8-16-19-16z' fill=#231F20 /><g fill=none><path d='m3788 4021h-3c-3 0-5 1-9 3-4 3-7 7-9 16 0 2-1 4-1 6 0 5 1 7 3 11 4 5 6 7 10 8h2c2 0 5-1 9-4 5-3 7-7 9-15 0-2 1-5 1-6 0-5-1-8-3-11-2-6-4-7-9-8z'/><path d='m3809 3917h-4c-2 0-4 0-6 2s-4 3-5 8v4c0 3 0 4 2 6s3 4 9 5h3c2 0 3 0 5-2s3-3 5-8v-4c0-3 0-4-2-6-1-2-2-4-7-5z'/></g><path d='m3734 3969c-10-8-17-17-21-26-5-12-7-24-4-37 4-22 18-38 42-48 18-7 41-9 67-4 35 7 60 19 74 35 14 17 19 35 15 56-2 12-8 22-16 31-7 7-16 12-28 18 13 9 22 21 26 33 5 13 6 26 3 40-2 13-8 25-16 35s-17 18-28 22c-10 5-22 7-35 7-14 0-28-1-43-4-28-5-49-13-62-22-14-9-23-21-28-35s-6-29-3-45c3-15 9-28 19-37 9-10 22-16 38-19zm17 67c-2 12 0 22 5 30 6 9 13 14 22 16s17 0 26-7c8-6 14-15 16-26 2-12 1-22-5-30-5-9-13-14-22-16s-18 0-26 6c-9 6-14 14-16 27zm26-113c-2 9 0 17 4 23 5 7 12 11 21 13 8 2 16 0 22-4s11-11 12-20c2-9 0-17-4-24-5-7-11-11-20-13s-16 0-23 4c-7 6-11 13-12 21z' fill=#231F20 /><path d='m4323 4203c-6-43-43-72-75-90-6-3-12-7-17-9-8-4-16-7-21-10-1 0-2-1-3-1-13 3-21 18-11 34 1 1 2 1 2 2 6 4 13 8 20 11 3 2 6 3 9 5 2 1 5 3 8 5 23 13 51 31 53 58 2 31-21 55-40 63-23 10-62 9-97 7-9-1-17-1-25-2-2 0-5 0-7-1-6-1-14-2-24-2-56-6-159-19-199-20-103-1-117 36-121 63-16-2-20-7-28-19 2 9 5 19 7 27 2 9 5 18 7 27 2 7 3 14 5 22 3 15 5 31 7 51 5-18 11-32 17-44 3-6 7-12 10-17 5-7 10-14 15-20 6-7 14-14 21-21-18 5-22 5-38 1 7-42 64-48 120-45 65 3 103 11 147 19 10 2 21 4 32 5 8 1 17 2 26 4 2 0 3 0 5 1 42 5 88 7 125-4 31-13 75-38 70-100z' fill=#981a20 /><path d='m4151 3562s13 57 4 79c0 0-3 27-67 52 0 0 25 54 72 65 0 0 38-46 32-100 0 0-3-42-41-96z' fill=#981a20 /><path d='m3614 3562s-13 57-3 79c0 0 3 27 67 52 0 0-24 55-72 66 0 0-38-46-33-100 0-1 4-43 41-97z' fill=#981a20 /></svg></template><template class=mhp1138_logo_youporn><svg class=mhp1138_youporn viewBox='0 0 6000 1039'><path d='m2394 60c-24-27-57-41-96-41-40 0-72 14-96 41-25 27-37 61-37 101v499c0 47-21 70-62 70-43 0-64-23-64-70v-499c0-40-12-74-37-101s-57-41-96-41c-40 0-72 14-96 41-25 27-37 61-37 101v529c0 85 27 152 80 202s120 75 202 75c49 0 91-8 125-24 20 51 59 76 119 76 39 0 72-14 96-41s37-61 37-101v-716c-1-40-14-74-38-101z' fill=#EC7895 /><polygon points='3859 322 3818 448 3690 486 3798 565 3794 698 3902 620 4027 664 3987 537 4068 432 3935 432' fill=#EC7895 /><path d='m4243 149c-86-93-206-143-346-143-137 0-261 51-349 144-90 96-138 227-138 380 0 147 46 274 132 366 42 45 93 80 150 104 59 24 123 37 191 37h2c135 0 257-48 343-136 94-95 143-229 143-390 0-144-44-270-128-362zm-352 58c78 0 143 33 189 96 41 56 64 135 64 216 0 89-24 170-68 228-45 60-110 92-186 92h-1c-75 0-139-32-185-93-43-57-67-135-67-219-2-159 77-320 254-320z' fill=#777 /><path d='m5917 148c-54-50-122-75-206-75-50 0-93 8-128 24-20-52-61-78-122-78-40 0-73 14-98 42-26 28-38 63-38 104v708c0 41 13 76 38 104 26 28 58 42 98 42 41 0 73-14 99-42 25-28 38-63 38-104v-485c0-48 21-72 63-72 44 0 66 24 66 72v485c0 41 13 76 38 104 26 28 58 42 98 42 41 0 73-14 99-42 25-28 38-63 38-104v-515c0-87-28-157-83-210z' fill=#777 /><path d='m550 61c-26-28-60-42-98-42-39 0-74 15-99 43-24 27-37 61-37 103v254h-45v-254c0-42-13-77-38-103-26-28-60-42-98-42-39 0-74 15-99 43-24 26-36 60-36 102v380c0 41 12 76 37 103 25 28 60 43 99 43h181v63c0 8-1 13-1 16h-9c-74 0-120 47-120 122 0 48 22 127 170 127 68 0 124-23 167-67s65-105 65-181v-606c-1-42-14-77-39-104z' fill=#EC7895 /><polygon points='1156 299 1114 426 987 464 1094 542 1090 675 1198 597 1324 642 1283 515 1364 410 1231 409' fill=#EC7895 /><path d='m1532 142c-86-93-205-142-345-142-137 0-260 51-348 144-90 95-137 226-137 379 0 147 45 273 131 365 42 45 93 80 150 104 58 24 123 37 191 37h2c134 0 256-48 343-135 93-94 143-229 143-389-1-146-46-271-130-363zm-605 378c0-159 79-320 254-320 173 0 252 161 252 311 0 89-24 170-67 227-45 60-110 91-186 91h-1c-75 0-139-32-185-92-43-56-67-134-67-217z' fill=#EC7895 /><path d='m3350 421c-3-177-147-319-325-319h-180c-24-55-67-83-128-83-42 0-76 14-101 43-26 29-39 64-39 107v699c0 43 13 78 39 107s60 43 101 43c42 0 76-14 101-43 26-29 39-64 39-107v-116h167c34 0 66-5 96-15 132-41 228-164 228-310 2-2 2-4 2-6zm-346 155h-159v-240h159c66 0 120 54 120 120s-54 120-120 120z' fill=#777 /><path d='m5091 679c75-60 123-151 123-254v-10c-6-175-149-315-325-315h-167c-24-54-66-80-125-80-41 0-74 14-99 42s-38 63-38 104v708c0 41 13 76 38 104s58 42 99 42 73-14 99-42c25-28 38-63 38-104v-141c10 5 20 11 32 16 15 7 32 15 50 23 35 46 90 119 125 165 50 54 97 82 144 82 41 0 74-15 101-45 26-28 39-60 39-98-1-42-59-126-134-197zm-214-112h-159v-240h159c66 0 120 54 120 120s-54 120-120 120z' fill=#777 /></svg></template><template class=mhp1138_logo_redtube><svg class=mhp1138_redtube viewBox='0 0 2949 577'><g fill=#fff><path d='m1349 0h367v49h-157v514h-54v-514h-157v-49z'/><path d='m2127 380c0 129-62 197-187 197s-187-68-187-197v-380h54v379c0 110 49 149 134 149s134-40 134-149v-379h54v380z'/><path d='m2174 0h202c149 0 168 100 168 132 0 74-32 112-103 126v2c83 8 123 73 123 147 0 81-54 157-183 157h-208v-564zm53 237h133c82 0 130-33 130-95 0-70-41-93-125-93h-137v188zm0 277h155c92 0 128-54 128-108 0-71-52-120-147-120h-136v228z'/><path d='m2600 0h332v49h-278v199h98v49h-98v217h295v49h-349v-563z'/></g><path d='m501 0h366v98h-260v128h124v94h-124v146h281v98h-387v-564z' fill=#AE2024 /><path d='m939 0h156c195 0 277 120 277 282 0 184-89 282-257 282h-176v-564zm106 465h55c104 0 161-38 161-184 0-111-48-184-164-184h-52v368z' fill=#AE2024 /><path d='m339 336c27-10 112-40 112-166 0-99-70-170-190-170h-199l134 93h35c74 0 108 33 108 85 0 53-39 85-93 85h-52l-132 91v209h107v-207h64l109 207h123l-126-227z' fill=#AE2024 /><polygon points='0 41 195 178 0 314' fill=#AE2024 /><defs><filter id=Adobe_OpacityMaskFilter height=563 width=1372 y=0 x=0 filterUnits=userSpaceOnUse><feColorMatrix values='1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0' type=matrix /></filter></defs><mask id=a1_ height=563 width=1372 y=0 x=0 maskUnits=userSpaceOnUse><g filter=url(#Adobe_OpacityMaskFilter)><radialGradient id=a2_ gradientUnits=userSpaceOnUse cy=-37.753 cx=.7542 gradientTransform='matrix(.9447 -.869 1.3413 1.4581 85.667 44.719)' r=501.25><stop stop-color=#fff offset=0 /><stop stop-color=#EFEFEF offset=.043581 /><stop stop-color=#A8A8A8 offset=.2516 /><stop stop-color=#6C6C6C offset=.4476 /><stop stop-color=#3D3D3D offset=.6259 /><stop stop-color=#1C1C1C offset=.7831 /><stop stop-color=#070707 offset=.9131 /><stop offset=1 /></radialGradient><path d='m831-545c371 404 460 926 199 1166-262 241-775 108-1146-295-371-404-460-926-199-1167 262-240 775-108 1146 296z' fill=url(#a2_) /></g></mask><g fill=#C97175 mask=url(#a1_)><polygon points='501 0 868 0 868 98 607 98 607 226 732 226 732 320 607 320 607 465 888 465 888 563 501 563'/><path d='m1095 0h-156v563h176c168 0 257-98 257-282 0-161-82-281-277-281zm5 465h-55v-367h52c115 0 164 73 164 184 0 145-57 183-161 183z'/><path d='m339 336c27-10 112-40 112-166 0-99-70-170-190-170h-199l134 93h35c74 0 108 33 108 85 0 53-39 85-93 85h-52l-132 91v209h107v-207h64l109 207h123l-126-227z'/><polygon points='0 314 195 178 0 41'/></g></svg></template><template class=mhp1138_logo_pornhub><svg class=mhp1138_pornhub viewBox='725 3310 4666 1308'><path d='m5295 3310h-1898c-59 7-92 43-97 109v1091c5 66 38 102 96 109h1899c59-7 91-43 96-109v-1092c-5-65-38-101-96-108z' fill=#f90 /><path d='m3960 3812c-15-20-35-37-63-50-25-11-54-18-84-19h-2c-63-3-145 15-184 52v-257h-151v790h151v-287c0-48 5-85 14-109s24-43 44-55 42-18 67-18c22 0 41 5 55 15 15 9 24 22 31 38s8 54 8 114v302h151v-336c0-51-2-90-8-114-5-23-15-46-29-66z'/><path d='m4455 3998c0 82-4 133-11 155-8 21-21 39-42 53-21 15-44 21-70 21-23 0-41-5-56-16s-25-25-31-43c-5-18-8-67-8-148v-263h-151v363c0 54 7 96 21 127s36 54 67 71c31 17 65 25 103 25 6 0 11 0 17-1h1c96-3 147-47 172-76v63h141v-573h-151l-2 242z'/><path d='m5190 3819c-32-36-76-58-122-69-14-4-29-6-46-7-62-5-142 19-180 50l9-256h-151v790h140v-44c32 26 85 57 164 57h9 6c67 0 123-27 170-80s70-129 70-226c-1-92-24-164-69-215zm-123 361c-24 28-52 43-86 43-44 0-78-20-105-60-18-28-28-72-28-132 0-57 12-100 36-129 24-28 54-42 90-42 37 0 67 15 91 44s36 77 36 142c2 60-10 104-34 134z'/><g fill=#fff><path d='m1194 3495c-31-8-98-12-200-12h-269v832h168v-314h109c76 0 134-4 174-12 30-6 59-20 87-40s52-47 70-82c18-34 28-78 28-129 0-66-16-120-48-162-32-41-71-69-119-81zm-24 310c-13 18-30 32-53 41-22 8-67 13-133 13h-92v-236h81c60 0 101 2 121 5 28 5 50 17 67 37 18 20 27 44 27 75 1 25-5 46-18 65z'/><path d='m1706 3698c-59 0-112 13-160 39s-85 64-111 113c-26 50-39 101-39 154 0 69 13 128 39 176s64 85 114 109c50 25 103 37 158 37 90 0 163-30 222-90s88-135 88-226c0-90-29-165-87-224s-132-88-224-88zm106 452c-28 32-63 47-105 47-41 0-77-16-105-47-28-32-43-77-43-137s15-106 43-137c28-32 63-47 105-47s76 16 105 47c28 32 42 77 42 136 0 60-14 106-42 138z'/><path d='m2356 3700c-47 6-93 44-112 68v-57h-148v602h159v-186c0-103 5-170 13-202 9-32 21-54 37-67s34-18 57-18c23 0 48 8 75 26l50-139c-34-20-69-30-105-30-9 1-17 1-26 3z'/><path d='m3116 3832c-6-25-16-47-31-67s-37-36-66-48c-29-13-61-19-96-19-63-4-168 21-198 70v-57h-148v602h159v-273c0-67 4-113 12-138s23-45 45-60 47-23 74-23c21 0 40 5 55 16s27 25 33 44c7 19 10 61 10 126v308h159v-374c0-46-2-82-8-107z'/></g></svg></template><template class=mhp1138_logo_thumbzilla><svg class=mhp1138_thumbzilla viewBox='725 3310 4666 1308'><path d='m5295 3310h-1898c-59 7-92 43-97 109v1091c5 66 38 102 96 109h1899c59-7 91-43 96-109v-1092c-5-65-38-101-96-108z' fill=#f90 /><path d='m3960 3812c-15-20-35-37-63-50-25-11-54-18-84-19h-2c-63-3-145 15-184 52v-257h-151v790h151v-287c0-48 5-85 14-109s24-43 44-55 42-18 67-18c22 0 41 5 55 15 15 9 24 22 31 38s8 54 8 114v302h151v-336c0-51-2-90-8-114-5-23-15-46-29-66z'/><path d='m4455 3998c0 82-4 133-11 155-8 21-21 39-42 53-21 15-44 21-70 21-23 0-41-5-56-16s-25-25-31-43c-5-18-8-67-8-148v-263h-151v363c0 54 7 96 21 127s36 54 67 71c31 17 65 25 103 25 6 0 11 0 17-1h1c96-3 147-47 172-76v63h141v-573h-151l-2 242z'/><path d='m5190 3819c-32-36-76-58-122-69-14-4-29-6-46-7-62-5-142 19-180 50l9-256h-151v790h140v-44c32 26 85 57 164 57h9 6c67 0 123-27 170-80s70-129 70-226c-1-92-24-164-69-215zm-123 361c-24 28-52 43-86 43-44 0-78-20-105-60-18-28-28-72-28-132 0-57 12-100 36-129 24-28 54-42 90-42 37 0 67 15 91 44s36 77 36 142c2 60-10 104-34 134z'/><g fill=#fff><path d='m1194 3495c-31-8-98-12-200-12h-269v832h168v-314h109c76 0 134-4 174-12 30-6 59-20 87-40s52-47 70-82c18-34 28-78 28-129 0-66-16-120-48-162-32-41-71-69-119-81zm-24 310c-13 18-30 32-53 41-22 8-67 13-133 13h-92v-236h81c60 0 101 2 121 5 28 5 50 17 67 37 18 20 27 44 27 75 1 25-5 46-18 65z'/><path d='m1706 3698c-59 0-112 13-160 39s-85 64-111 113c-26 50-39 101-39 154 0 69 13 128 39 176s64 85 114 109c50 25 103 37 158 37 90 0 163-30 222-90s88-135 88-226c0-90-29-165-87-224s-132-88-224-88zm106 452c-28 32-63 47-105 47-41 0-77-16-105-47-28-32-43-77-43-137s15-106 43-137c28-32 63-47 105-47s76 16 105 47c28 32 42 77 42 136 0 60-14 106-42 138z'/><path d='m2356 3700c-47 6-93 44-112 68v-57h-148v602h159v-186c0-103 5-170 13-202 9-32 21-54 37-67s34-18 57-18c23 0 48 8 75 26l50-139c-34-20-69-30-105-30-9 1-17 1-26 3z'/><path d='m3116 3832c-6-25-16-47-31-67s-37-36-66-48c-29-13-61-19-96-19-63-4-168 21-198 70v-57h-148v602h159v-273c0-67 4-113 12-138s23-45 45-60 47-23 74-23c21 0 40 5 55 16s27 25 33 44c7 19 10 61 10 126v308h159v-374c0-46-2-82-8-107z'/></g></svg></template><template class=mhp1138_logo_xtube><svg class=mhp1138_xtube viewBox='0 0 518.9 263.4'><defs><linearGradient id=a x1=193.3 x2=193.9 y1=206 y2=206 gradientTransform='matrix(1 0 0 -1 0 598)' gradientUnits=userSpaceOnUse><stop offset=0 stop-color=#e5654a /><stop offset=1 stop-color=#c1222a /></linearGradient><linearGradient id=b x1=219.1 x2=222.3 y1=213.4 y2=213.4 xlink:href=#a /><linearGradient id=c x1=161.5 x2=391.1 y1=300.5 y2=300.5 xlink:href=#a /></defs><path fill=url(#a) d='M193.3 392c.4.4.5.2.6 0s-.5-.4-1 0z' transform='translate(-161.5 -165.8)'/><path fill=url(#b) d='M219 386.6c1.2 0 3-2.7 3.4-4-1.7 0-3.2 2-3.3 4z' transform='translate(-161.5 -165.8)'/><path fill=url(#c) d='M201.7 334a2.3 2.3 0 0 1 .4-2c-1.6 1.3-3.6 3-3.2 5a.4.4 0 0 0-.5 0h.3q-.7-.4-.6.4c-1-.2-5 5.6-5.3 6.4s.3.4.8.3l-4.6 4c3.5 1 0 1 .5 1s-4.4 1-2.2 3q-3.2.8-2 3c.4-.5.7-1.4 1.4-1-1.5 3.3-4.4 2-6.4 4 .5 1 1.7 0 2.6.6s-1.7 0-2.3.8.6 0 1.2.3q-1.7 4.7-3.8 2.2c.8 1 .3 2.5-1.2 4-1-.4.7-1.4-1-1.6l-7.5 8.6a101.8 101.8 0 0 1-6.7 9.3c4 .7 5-7 9.2-7.8q-8 4-3.2 7c-2 .5-2.7 1.7-4.3 3 1.8 0 2.4-1.4 3.6-2.5 2.7 4.8-2.6 3.6 5 5.7 1.4-5 7.4 0 8.4 1.2-.6 0-.7-1-1.2-1s1 1.4 2 2.2 6.5 2 6.5 2c-4.7.8 6 5 4 0-.5.3 3.3-.3 3.2-.3s-.4 0-.5 0l9.2-8.2s.4 1 1 1.6-1-2 1-.8q4-1.5 2.2-4.5c.7.7 0 .4 0 1 6-1.6 9.7.3 14-6.7q-1.4.5-2-.4a3 3 0 0 1-.6 1.5 2.4 2.4 0 0 1 .4-2 12.6 12.6 0 0 0 3 .2l-.2-.3c.6.2 1.2-2 1.7-1-1.3 3-24.6 22-22 24.6 1.7-1.3 5.7-5.6 8-5.4v.2l.7-.3a1.8 1.8 0 0 1-1-.3 8 8 0 0 0 3-3.2l-1.5 2.8q2 .4 2.8-2c2 5 5.2-1 4.6-2s-.8 1.5-1.7 1.6c-.3-2.4 3-3.5 2-5.7-.5.3-.2 1-.7.8s1-1.8 1.5-1.6a1 1 0 0 0 .4 1s5.3-6 2.4-6.3q.6 3.6-3.4 3.6c2.4-2.8 2.6-4.4 5-6.4a2.5 2.5 0 0 1-1 3.6c.5-.2 3.5-2.3 2.5-3.4 1 .2 1.6.6 1.4 2q6.6-3.7 4-8.4-.4 2.4-3.3 3.3c-2.2-1.4 8.7-8.3 8.5-12-.4 1-1 1-1.3.5 2.6-.8 9.3-14 9.3-13.2s0 .7.4 1c0-1.6.7-4 2-4-.2.4-1.4 1.2-1 1.6s5.3-3.7 4.5-4-.4 2-1 .5a14 14 0 0 1 1.7-3.5c-.3-1-.8 1-1.2.4s17-20.7 15.7-21.4-1 1.6-1 2.2c3.3-2 8-11.8 11.6-14.8.6 6.5 16.5 22.4 19.3 25.7l-2-1c-1.5 2 2.8 3 3.2 2.6l-.3-.5c1.4 1.5 2.7 2.7 3 5-.3.3-.6-.4-1-.6s8 12.8 9 13.6-.6-1 .2-1a7.3 7.3 0 0 1 1.4 2c.5-.3 0-.6 0-1s3.7 2 2 1.3c1.3-.8-2.6-4.6-2.6-5.5s-.3-.5-.5-1l-.4.3c-.3-.4 0-1-.3-1.2v-.2a3.3 3.3 0 0 1 0-1.3c.2.2 1 1.7 1.8.2h.3a2 2 0 0 0-.5.5q.7.3.6 0c2 5 24.4 39.5 29.8 39a.4.4 0 0 1 0-.5c-.4-.8 1-.3 1-1.3s1.2 1 .6 2.4q3-2.2-2.4-5v.5l-1.7-1a6.3 6.3 0 0 0 .5 1.6c-6-.8.6-3.4 0-3 .8 2-2-4.2-2-1.6-1-2-1-2-1.5 0a16 16 0 0 1-2-2.7 4.4 4.4 0 0 1 3 0s-3.2-3-3.3-2.8a1.4 1.4 0 0 1 .6.6q-1.4 1.5-1.4-.6a1.4 1.4 0 0 0 .7 1c0-1-.7-2.5-1.5-1.8l.5.4c-.8.4-1.2-.8-1.2-1.7s.7 0 .6-.3.4 0 1 .4-.5 0-.4.5 0 1.3.7.2-12-21-15-20c0 .7.6.8.5 1.8a6 6 0 0 1-2.8-3.2c.4-.5.6.4 1 0-1.5-1-4.5-2.4-3.7-4a.3.3 0 0 0 0 .3q.5 0 .2-.3l.2.3c.4-.5 1 .3 1 .2l.2.2c0 .2-.3.5 0 .7s.3 0 0-.4l.3.3c1-1-1-3-.8-4.4a1.5 1.5 0 0 0 .2.5c.4-.4 0-.4.6 0a3.7 3.7 0 0 0 1 1l.2-.4a1 1 0 0 0 .3.5c2.6-3 1.3 0 2.4 2.8 1.4-1 .5-.8 1.3 1 .7-.4.6-.3.6-.7s0 1.5 1 .8-3 1-2.5 0a1 1 0 0 1 .8 1.3c-.4 0-.6-1-1 0 1.8 2.4 5 4 4.7 7 .7-.4-1-3.3 0-4a.8.8 0 0 1-.7-.8v-.2a2.4 2.4 0 0 0 1.4 1 1.6 1.6 0 0 0 0-.4 2.8 2.8 0 0 0 1.5 1.5c0-1.5-1.8-1.3-2-2.7a1.6 1.6 0 0 0 .3 1.2q-1.7-.7-.5-2c2.6 2.2 1.5 5.7 3.7 5.3-.3 1 .4 1 1.2 1a4 4 0 0 0 1.4 4 .5.5 0 0 0-.7-.2v.2c.4.3-1-3.3-1-1.5a.8.8 0 0 0-.4.6c.4 0-1-2.6-1-1.7s4.7 2.7 3 4.8c.2.8.7.6 1 .7a1.5 1.5 0 0 0-.2-1c.7-.4.4-.8.3-1s.6 1.3 1 1.8-.3-.6-.6-.3a10.8 10.8 0 0 0 2 6c-.3-1 .4-.7.2-2 .5 1-1.5 3 1.2 3a1 1 0 0 1 0-1c1.7 2.3 2.8 4.4 4 6l.5-.5a2 2 0 0 1 .4 1.7c.7-.3 0-.8 0-1.2l.8 1.2.5-.6a2 2 0 0 1 .3 1.8c.7-.5-.3-1 0-1.5q7.6 4 4 7c2.6-.4 2 4 1.8 4.4s.3 2 1.2 1.4a2.2 2.2 0 0 1-.4-1.5c.8-.3.5.3 1 .7-2 1 4.8 6.6 4.8 7 4.4 1.4 1-1 1.4 1q6.6-.8 8 8.7c0-.5-1-1-.8-1.6a11.6 11.6 0 0 0 2.4 2.7c-.2-.6-1-1.2-.8-1.7s.5.3.7 0q-4.8-2-2.3-4a33.5 33.5 0 0 1 3 5.5c-.2-.5-.5-.7-1-.4a2.8 2.8 0 0 1 1.3 3 .5.5 0 0 1 0-.7 3.4 3.4 0 0 1 1.6 1.6 1.4 1.4 0 0 1 0-.5c1.4 2.3 8.3 13 9 12.5v-.3c1 .3 2 2.4 3.2 3a5.7 5.7 0 0 1-.8 0c1.6 3.3 6.4 12 8.3 11 0-.7-.7-1.4-.3-2s.2.8 1 .6a5.5 5.5 0 0 0-2-4.3 2 2 0 0 0 .3 2.8c-2-1.2 1-6.7 2-8.5v-.7c.4.2 1.5 2 2 2a.5.5 0 0 1-.2-.5 1 1 0 0 1 1 1 1.6 1.6 0 0 0 2.2 0 7.7 7.7 0 0 1-1.7-3 3 3 0 0 0-.5 1.5 2.7 2.7 0 0 1-.6-2 .5.5 0 0 1-.2.5c0-.7-.6-1.4-1-2l-.5 1c.8-6.7-2.7.7.6-1.4 0-2-1.5-3.3-2.2-4.8l-.5.6a14.4 14.4 0 0 1-1-1.6v.2a5 5 0 0 1-.3-1.2c.5.2.4.8 1.2.4-1.3-2-1-2.7-2.8-4.6a3 3 0 0 1 2.2 1 3 3 0 0 1-.7-2c0 .8 1 2.3 1.6 2.4s-2.2-4-2.7-4a2.5 2.5 0 0 0-.3 2 1.6 1.6 0 0 1-.2-1.6c-.6.6-3.8-7-3.8-7s1-.7 0-1.3a2.7 2.7 0 0 0-.2 1q-.7-1 0-1c-1-1.6-3-3.2-3-4.2s-1.3-1.4-1.4-1.6a.6.6 0 0 1 1 0c.3-.6-.7-.2-.3-1s.4 0 .6.5.3-1 0-1.4l-.5-.5-.5.3-.2-.4c.5.2.3-1 .8 0a.5.5 0 0 1 .5-.2c-1.7-1.5-4.3-12.2-6.6-7.4l-1-1.6h.2a4.2 4.2 0 0 1-1-3.3 14.6 14.6 0 0 0 1.2 2c1.7-1-.3-4.7-1.7-4.2v-.2q-.3.4-.5-.2a7 7 0 0 1 .8-.2c-.6-.3-.7.2-.6-1a2 2 0 0 0-.3 1c-.3-1.2-5-6.7-5-6.7a1.8 1.8 0 0 1 0 1c-1.3-1.2 1-2.4-.3-4-.7.4.2 1-.3 1.3s-2.4-6.4-3.4-7.2-1 1-.3 0-1.6 0-2-.8.3 0 .5-.2a.5.5 0 0 1-.4-.5c0 .3-1 .4-.8 0s-1 0-.7-1l-.2.5c0-.4.8-2 .5-2s.5.5 1 .2-1.6-1.6-2.5-.2a1.4 1.4 0 0 0 0-1c.2.4.5.6 1 .3s.3-1.2-.2-2L350 347q-1-1.6.6-1.6c2-.6 0-4.2-.8-3.7l-.4-.6.5.5c0-1-1-2.4-2-3a2.5 2.5 0 0 0 0 1 4.7 4.7 0 0 0-1.4-1.8 2.5 2.5 0 0 0 0 1 2 2 0 0 0-1.2-.8c-1.6-.8-1.8-1.5-1.7-1.4s2 1.8 1.4 1-2-9-5-8c0 .3-1.5-3.2-1.6-2.5s-.8 0-1.2-1a.7.7 0 0 1 .2 1q-1.4-1 .2-1.5a2.4 2.4 0 0 1-1-1.5 13.8 13.8 0 0 1-.2 1.7c-1.5-2-1.3-2.8-5-6.7a.5.5 0 0 0 .5 0c-.5 0-2-.5-1.6-1s-.6-.4-.4-1 .6 1 1 .7-1-4.4-1.5-3.8 1 0 0 .6-1.4-2-1.5-2 .7.3.3 1c-2-2.5-5-9-7.6-12.2 2-1.2-28.7-27.6-21-31.8-3-2 4-8 5-10a2 2 0 0 1 0 .5c2.7-3.7-1.4 1 3.4-6a1.3 1.3 0 0 1-.2 1.7 2 2 0 0 1 .5-1 1 1 0 0 0 .3 1.2c.4-.5 1.6-3 1-3.8a2.8 2.8 0 0 1-.3.8c-1-1 1-1.5.6-2 0-2.6 4.4-10 6-10.3h-.3c.5-.6 1.3-2.3 2-3.3.3-.8 1.7-4 1.4-2-.2.2 2.3-3.4 2-3.5s-.2.3 0 .5a11.8 11.8 0 0 1 1-2.5v.4a1.2 1.2 0 0 1 .2-1 1.6 1.6 0 0 1 0 .5c-.5.6 2-4 2-3s0 0-.4 0 .2-.6.4 0a18 18 0 0 1 2.5-4.5 1.7 1.7 0 0 1 0 .5c.6-1 3-3.4 3.3-4.5.3 1-2 7.5-2.6 8.4.6-1 1-2 1.6-2.5s-1 1.2-.7 1.8a32.2 32.2 0 0 0 2.3-4.6c.2.3-.4.7 0 1a42 42 0 0 0 3.6-9 1.2 1.2 0 0 1-1.3.8 1.4 1.4 0 0 0 .3-.7s-1.5 1-1 1.6a2 2 0 0 1 .6-.7c0 .3-.5 1-.5 1.4a2.5 2.5 0 0 0-2 1.3c1-2.8 2.3-6 4.6-7q-.4.2-.3-.3v.3q-.5-.7.4-1c-.4-.8 5-8.8 5.6-9.6s.7 0 .7.5 2-6 3-7.5.7 1.4 2-1.5l-.6.2c-.6-.7.4-1 1-1.4v.4q-.3-3.4 2.5-3.5c-.7.7-1.5 1.6-1 2 3-3 1.7-5.2 2-7.7-18.3 7.7 4.7 11.3-5 .3-1.2.2-.2 2-1.4 3-.8-1 1.6-2 0-3 0 .5-.6.7-1.2 1a28.7 28.7 0 0 0 3.2-6.4c-.8-.2-1.3.4-2.3-.4-.3.7.8.5.7 1.3-2 1-2.5-4-3.4 5.8.5 0 .7-.6 1.3-.3a6 6 0 0 1-.3 3c-1-.6-.3-1.2 0-2s-5 2-1.8-.7c-.7-.7-.8 0-1 .3-3.7-3 8.3-7.4 2.7-10.4.2.6-.5 1 .6 1.7s-1.3-.3-1-.7-7 5.8-8.6 7.2 0-.7-.7-1l-1.6 2.8c1.4.2 1-1 1.7-1.7 1 1 0 1.6-.5 2.4q-5.5-2 1.4-7.8c1.4-1-4 4-3 .7-.5-.3-.6.6-1 .8s0-1.6 1-1.3a1.2 1.2 0 0 1-.2-1.7c-7 10.7-9 11.8-15.6 8 0 1.4-1.3 1.7-1.3 3-.7-2 1.2-3.4 2-5.5-1-.5-1 .3-1.5.4s1-1 0-1.8a1.2 1.2 0 0 1-1 1.3c-.4-.2 0-.4 0-.6a3.5 3.5 0 0 0-3 3.5q.2-1.7-1-1.3c1.2-2.4 7.8-12 5-15.3-1.6 0-2.6 1.7-3.3 3.7l.6-1q0 1 .7.7a1.4 1.4 0 0 0-.2.5h.7a.8.8 0 0 0-.3 1l-2.7 4.6c-2.5-1.7-2.3 6.2-4.3 6a2 2 0 0 0-.2-1.2c-2.3 2-1.5 3.5-1 3.8s.4.8-.2.8.5.7-.2 1.2-.5-1-.4-1.2-3 8-3.4 8.5-1.5-.5-1.7.4.6-.6 1 0-2.7 0-2.2 2c-2-1 2-1.7.8-3.3 0 .5-3 3.2-1.2 4q-1-.4-1.5 1.5 1-.3.8 1a1 1 0 0 1 1-.7c0 .7-7 2.7-4.2 4s2.4 4.4.6 4c0-.8 1-.8.7-1.6-2 .2-1.3 3-3.6 2.7 0-.5.8-.4.4-.7s-.8 1.3-.5 1.6a1 1 0 0 1 1 0c0 .2-2.3 5.5-4 3.2q3.2-.2 1.3-3.3c-1.2 2.4-2.4 3-3 5.3a1.8 1.8 0 0 0 2.6-1.4q-3.7 3 .6 3.3c-2.5 2.2-5.2 10-9.4 11a.6.6 0 0 0-.5-1.2c.3 2-6 10-6.4 10.3a2.7 2.7 0 0 1 1 0c-1.4.4-3 1.6-2.3 2.7s.4-1.4 1-1-.2 4-.7 4.4a1 1 0 0 1-.6-1q-.4.3-.5-.7a3 3 0 0 1-1.4 2.7c-.7 0-.2-.4 0-.7h.3c0-.6-.5-1.2-1-.6s-1.4.3-2.2-1.6l-4-4.4v.5c-1-.7-.2-1.7-.5-2.2s-.5 1-1 .6h.2c0-.3-3-3-2-3.5s.6 1 1 .7a7.8 7.8 0 0 0-4.8-2.6c.3-.4 1 0 1.5-1s-1.2.5-1.6 0 .3-.3.7-.5-2.5-1.5-2.3-2-1.7-2.4-2-2.6 0 .6 0 1c-1-3-4.7-5-7-7h.3l-1.7-1c1-.8 1.3.7 2.6.6-4-5-9.8-9-15-13q2.8-1-2-3.6c-.5-.7-1-1.3-1.7-1s0 1.2.4 2.2-.5-1-1-.4 3 2.6 1.6 5c-4.2.7-3.7-3.5-4.3-5.7 1.2-1 1.3.8 0-.5a2.5 2.5 0 0 1 0-.6c-.3.4-.4-1-.8-.8a9.2 9.2 0 0 1-2-2h-1.7a1 1 0 0 1 1.2-.3c-.3-.4-.5-1.5-1-.7s3 4.6.6 4a1.6 1.6 0 0 0-.3 1c-.2-1-.3-1.7-1-2a.8.8 0 0 1-1 1c.4-1-3-1.6-3.7-2s0 1 0 1.3-.5-2-1.5-2.4a9.3 9.3 0 0 1-.2 1.4 8.4 8.4 0 0 0-2.5-1c.2 6.5.5.4-1.5 2.3-.3.7 1 .6.6 1.2s-1-.4-1 .2c1 1.8 1 1.8 3 3.3q-2 0-1.5 1-9-3.2-11.2-14.2a8.4 8.4 0 0 0 0 1l-1.5-2q2.4 2 0 2.5a1.2 1.2 0 0 1 .6 2c-.5-.7-6.5-7-4.8-5.7a6.6 6.6 0 0 1 .8 1.6 14.3 14.3 0 0 0-2.3-2.5c.6.8 1.4 1.8.6 3a.8.8 0 0 0-.8-.8 9.6 9.6 0 0 1 1.4 3.7c-.4-.4-4.6-6.6-6-5.7v.3c-.6-.5-1.2-1.5-1.5-1.3 16 40 1 5.3 2 10.8a77.4 77.4 0 0 0 2 12.8c-1 0-.5-.8-1-.8l-.8 1.5c-.5-1-1-1.7-1.6-1.5 3.8 5.2-2.2-.8-1.5-1 5.4 7.6 2 21.2 2.2 25q0 2 1 1.5a3.3 3.3 0 0 0 2 3 1.7 1.7 0 0 0 0-.5c2.3 3.3 1.6.7 1.3-.4s.8 0 1.3-.3c-1.6-1.5-2-1.5-3-3.3.4-.6.6.5 1-.3s-1-.3-.5-1c2-2 1.7 4 1.5-2.3.5-.4 2.3 1.5 2.5.8a1.2 1.2 0 0 0 .7.5 1.5 1.5 0 0 0 .2-.8c.3.7.3 1.6 1.3 1.8 1.2-1.4.6-1.3 1.5 0 2-1.5.4-.7 1.5 1a1.4 1.4 0 0 0 .5-.7 2.2 2.2 0 0 0 .4 1l.6-1a9.3 9.3 0 0 0 .8 2l1-1.7c0-.4 0 3.5 1.2 2.4s3 4.8 5.8 4.3c1.5-2.5-2.2-3.4-1.5-5s.5 0 .8.4 0-1-.5-2q2.5 2 .6 2.5c5.3 4 11 8 15 13-10 1.2-4.5-9.5-10-5.6.5-1-1-.6-.5-1.4l1.2.6q-1 .6 1 1.6c.2-.8-1-.5-.8-1.3 3.6 1.5 6 5.6 7.3 8s-.4-2 1.6 1l5 5c1-.4-.4-1 .4-1.4a2 2 0 0 1 1 2.5.5.5 0 0 0 .5-.4 2.7 2.7 0 0 1 0 1.4c.2-.4 0-.7.5-1a1.4 1.4 0 0 1 1 2c1.6-1.5.6.3.6.7s1.3-.5 1.7.3-1.6 0-1.8 1.2l2.2 1.3c-1.5 1 2.4 1.4 1 0 1.3 0 .7.7.2 1.2s.4 1.2.7.8 0-.6 0-.6a4.4 4.4 0 0 0 1.3.5q-1.4 1.4 1 1.8s.7.7.8.5c-.2 0 .5 1 1.3 1.4s.2 1 .3.2v.2c-.4.6.4 1.2.7.7 8.2 9.2-11 24.4-16 33a8.2 8.2 0 0 0 1 0c-1.4 2-2.5 3-4 5.3a1 1 0 0 0 1-.7 1 1 0 0 0-.4.6 1 1 0 0 1 1 0c-.3.8-2 2-2.6 1.7a1.5 1.5 0 0 0 .5-.5c-1.5-.6-1 1-1.5 1-2.3.3-6 6.2-6.5 8a.8.8 0 0 0-.8 1c-.6.6-2.3 2-1 1.5s-1.8 2.4-2 2.4.3-.6.5-.5a6.4 6.4 0 0 0-1.5 1.4h.3a.7.7 0 0 0-.5.3h.3c.3-1-2 2.3-1.6 2s0-.3 0-.4-.4.2 0 .3a10.5 10.5 0 0 0-2.4 2.7h.2c-.4.7-1.6 3.5-2.2 3.8 1 0 1-1 2-1m-2 3.7c-.7.7-1 1.5-2 1.5a.8.8 0 0 0 0-1.2s-.2.6-.4.5 0-1.5 1-1a1 1 0 0 0-.5.4m127-110.5a1 1 0 0 1 1-1.5l-1 1.4s.3-.7 0 0zm-142.8 8c0-.3-.5-1 0-1.2s1 1 0 1.5 0-.4 0 0zm36 14.7v-.2q.2 0 0 .2zm14.7 15.4a1.4 1.4 0 0 1-1-1c.5 0 1.5 1 1 1zm-.6-52.7c0 .2-2-.5-2.4-.7 2-1.7 7.4 2 8.2 6-2-2-4.3-3.3-5.7-5.6-.3.4 1.2 2.4 0 .2zM198.6 337c0 .3-.3 0-.5 0s.6 0 .6 0zm-1.2 1a.2.2 0 0 1-.3 0zm15-19.3l8-9.4s0 .5-.4.5.4-.5.5-.3zm172 94.3a1.2 1.2 0 0 1 .3 1.3c-.5 0-.4-.7 0-1.3s-.4.5 0 0zm-1 .7zm-.3-6.4l-.5-1a2 2 0 0 1 .7 1zM376 392q.8.5.4 1t-.4-1c.2.3 0 0 0 0zm-3-6.8l-.4.6-.6-.5a3 3 0 0 1 1 0c-.2.3-.4 0 0 0zm0-2a2 2 0 0 0-.2 1 6 6 0 0 1-1-2.5l1.2 1.6c0 .3-.3-.5 0 0zm-2-.8c2 2.3.5 2.5 0 1.7a.7.7 0 0 0 .7 0q-1-1-.6-1.6c.4.7 0 0 0 0zM358 359a6.5 6.5 0 0 0 .8 1q-1.4 0-.8-1c.2.3 0 0 0 0zm-.2-.6c0 .2-.4.3 0 0zm-58-22c.6-.5 1 0 1 .7a1.5 1.5 0 0 1-1-.4c.2 0 .4.3 0 0zm29.6 20a.5.5 0 0 1 .3-.6q.4.6-.3.5s.2 0 0 0zm56.8 59.2c-.5-.7-1.4-.5-2-2q.6 1.3 1.4-.3c-.5 1 .6 2 1.2 2.6a.8.8 0 0 1-.6-.7zm.8 2c-.2-.2 0-.4.3-.6a1 1 0 0 1-.2.8zm.4-1.6a1 1 0 0 0 0 .4 1 1 0 0 1-.5-1.7q1 1 0 1.2h.3z' transform='translate(-161.5 -165.8)'/><g fill=#fff><path d='M146 53.2v21.5h29v78.8l3 3a3 3 0 0 1 1.2 1l1.4 2c3.8 5 7 10.2 11 15s5.5 8.2 8 12.6l1.4 2.6 1.5 1.6V74.8H231V53.2h-85zm123.3 0v116.3c0 10.8 5.5 14.6 14.2 14.6s14.2-3.6 14.2-14.3V53.2h26V168c0 24-14 38-41 38s-41-14-41-38V53.2h27.5zM424.7 88v5c0 15.5-5.5 25.4-17.7 30.4 14.7 5 20.5 16.4 20.5 32.3V168c0 23.3-14.2 35.7-41.7 35.7h-43.3V53H384c28.5 0 40.7 11.4 40.7 34.7zM370 74.7v39.8h10.7c10.2 0 16.5-4 16.5-16V90c0-10.7-4.2-15.4-14-15.4H370zm0 61.4v46.5h15.7c9.2 0 14.2-3.7 14.2-15v-13c0-14-5.5-18.4-18-18.4h-12zM471.4 117H509v21.5h-37.6v44H519V204h-75V53.2h75v21.5h-47.6v42z'/></g></svg></template><template class=mhp1138_svg_hotspots><div class=mhp1138_hotspots><svg viewBox='0 0 1000 100' preserveAspectRatio=none><defs><clipPath id=hotspotsClip clipPathUnits=userSpaceOnUse><polygon/></clipPath></defs><g clip-path=url(#hotspotsClip)><rect class=mhp1138_hotspotsBg x=0 y=0 width=100% height=100% fill=rgba(33,29,27,0.58) /><rect class=mhp1138_hotspotsFill x=0 y=0 width=100% height=100% fill=#6d6d6d /></g></svg></div></template>"; | |
MHP1138.skinsMarkup['css'] = "@font-face{font-family:'mobile-icons';src:url(data:application/x-font-ttf;base64,AAEAAAALAIAAAwAwR1NVQiCMJXkAAAE4AAAAVE9TLzJDS00DAAABjAAAAFZjbWFwYkblTAAAAiAAAAImZ2x5ZmpX7fkAAARoAAAMzGhlYWRiSq2jAAAA4AAAADZoaGVhErIK7QAAALwAAAAkaG10eHR3//cAAAHkAAAAPGxvY2EXZBoEAAAESAAAACBtYXhwAR8BAAAAARgAAAAgbmFtZfRhMRAAABE0AAACRnBvc3QbViaIAAATfAAAAMAAAQAAB9AAAAAACuL/+f/7CucAAQAAAAAAAAAAAAAAAAAAAA8AAQAAAAEAANn5K71fDzz1AAsH0AAAAAB8JbCBAAAAAHwlsIH/+f/9CucH1wAAAAgAAgAAAAAAAAABAAAADwD0AAYAAAAAAAIAAAAKAAoAAAD/AAAAAAAAAAEAAAAKADAAPgACbGF0bgAOREZMVAAaAAQAAAAAAAAAAQAAAAQAAAAAAAAAAQAAAAFsaWdhAAgAAAABAAAAAQAEAAQAAAABAAgAAQAGAAAAAQAAAAEHxAGQAAUAAAOlBXgAAAEYA6UFeAAAA8AAYgIEAAACAAUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBmRWQAQOAB4A4H0AAAALQH1wADAAAAAQAAAAAAAAAAAAAKagAACjYAAAo3//8HzQAAB9AAAAhUAAAFcQAABpUAAAfQ//8HHAAACuL/+Qg5AAAH0AAAB9AAAAAAAAUAAAADAAAALAAAAAQAAAFuAAEAAAAAAGgAAwABAAAALAADAAoAAAFuAAQAPAAAAAQABAABAADgDv//AADgAf//AAAAAQAEAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAAABBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAC4AAAAAAAAAA4AAOABAADgAQAAAAEAAOACAADgAgAAAAIAAOADAADgAwAAAAMAAOAEAADgBAAAAAQAAOAFAADgBQAAAAUAAOAGAADgBgAAAAYAAOAHAADgBwAAAAcAAOAIAADgCAAAAAgAAOAJAADgCQAAAAkAAOAKAADgCgAAAAoAAOALAADgCwAAAAsAAOAMAADgDAAAAAwAAOANAADgDQAAAA0AAOAOAADgDgAAAA4AAAAAAAAAIgCGANgBngMGA1QDmAPIBIoFBgU6BVgGCAZmAAIAAAAACmsH0AALAA4AABEhESEDIREhESEDIQkBIQpr/bj6AfT4MAH0+v25BTUCm/rLB9D5fQFOA+j8GP6yApv8GAAABQAAAAAKNwfQAAsAEgAgAC8AOQAAExEWFxEhESEWFyERAREhNi4CAxUWFxYXFhczJicmJyYDFRYXFhcWFzMmJyYAJyYBERYXFhcWFyERmmtiCAL63C4PBbT1ygEmFx1egz9xYF8/QBTQF1xajZCp07Owb3IXzxNWU/7ssLUBQoZyb0pMGASvB9D8sg4uAr36ZWFrBzT5V/7aP4JfHQFW0BVAPl9gcamQjFtcAYDPF3Jvr7TTyLWwARRUVgKB/agYS0pwcYcEbQAE/////wo4B9AACwAQAB4ALQAAExEWFxEhESEWFyERAREhLgEDFRYXFhcWFzMmJyYnJgMVFhcWFxYXMyYnJgAnJppoZQgD+tsoFQW19ckBJhyebHFgXz9AFNAWXVqNkKnTtK9vchjOElZU/uywtQfQ/LIVKAK++mVlaAc1+Vb+2myeAYnQFEA/X2BxqZCNWl0Bf84Xcm+ws9TJtbABFFNWAAAAAAQAAAAAB8UHxgAgAEEAYQCCAAAJAQMUFjsBMjY3EyMmNTc0JyYjISIGBxUeATMhAQYUFjIJARM0JisBIgYHETMWFQcUFxYzBTI2NzUuASMhATY0LgEBAzQmKwEiBhUTASYiBhQXASEiBgcVFBYXJTI3NjUnIwEhMjY3NTQmJwUmBwYVFyMiFRMUFjsBMjY1AwEWMjY0JwU3AhICGxIfExsCAgEBAgsOEv4tExsCBB0TAST98BIjNP11/e4CGxIiEhsCAQECCw4SAdYSGwIEHRP+3AIQEyczBRcDGhUfExoE/e4TMiUSAhD+3BMdBBsVAdMVCwsCAfkfASQTHQQbFf4rDw8LAgEBAhsVIRMaBAISEzIlEgThAhH+1RMdFxIBvwEBFxcIDhsUIBUY/fASMyX+IP3yASsSHRYT/j8BARcXCA4CGxQgFRoCDhIzJgH9UAG/EhccFP7VAhESJTMS/fIYFyASGwICDgsUFwb2GBcgEhsCAgMPCxQXAv5BEhccFAEr/e8SJTMSAAAAAAQAAAAAB8UHxQBvANEA5gDzAAABJyYnNzY3Ni8BJicmBg8BJi8BLgEnJisBIgcGDwEGBycuAQcGDwEGFxYfAQYPAQ4BBwYdARQXFh8BFhcHBgcGHwEWFxY2PwEWHwEWFxY7ATI3PgE/ATY3Fx4BNzY/ATYnJi8BNj8BNjc2PQE0Jy4BBwYPAgYPARcWFwcmLwEHBg8CDgEHIyYvAiYvAQcGIyc0PwEnJi8CLgEnNTI3Nj8CNj8BJyYnNxYfATc2PwI2PwEzFBcWHwIWFxYfATc2MxcUDwEXFh8CHgEXASIHBgcGFBcWFxYyNzY3NjQnJicmAyIuATQ+ATIeARQOAQdJnREeVRsDAyFYFiIfQxmMMz0iBiQbHSB8LyMeCyk7Po4ZQh8iF1ghAwMbWhgTnR45EhMoIjKfEhdaGwMDIVgWIh9DGZA/OygLHyMveyAdGyUGIz4zixpBHyIYWCADAxpWEhubMiIoExE5HwcU5RYJGyB5DAJRBw3NPzclQzQBCQNuCAQ4QTgtP80SBlYMfR0UDhTlCRAEAQQKBeoWEBQdfQwCUQcK0j8tOEE4BggCcwIFAjNEHxAaFT/IDA1RDHkgHQkW5QoPAvydZVZUMTMzMVRWyldUMjMzMVRXZkNyQkJyhnJCQnIEoyMyQZAsLDUiWBYIBw4TVxkWnR45EhMoIjKfEyFaEQ4GBxdXITUuLJYsPiEGJRsdIHsvIx8LKDYtlywsNSJYFggHDhNcIROdMiIoExE5H6IVGloRDwcHFlghNS4rkCJIJgsfIy97Ih0bJPAIBDhBHTs8yxYHUQMGgyIcChflCA8CCBPjFBMYIoIJTAwP0z0sJUE6AggEcAMFATRDLyk90RYHUQIFhyIYExTgDxADAQQKBeoWCwcLDCF9CU4MD806PiBENAEKBAE/MzFUVspWVDEzMzFUV8lWVDEz/ZZCcoZyQkJyhnJCAAQAAP/+CFUH0QACABYAGgAsAAATCQETIg4BFQMUHgE2NwE+AS4BJwEmIwURIRElISIGFTERFBYzITI2NRE0JiN+BZX6agEePCICIjxDHgWWHB8CIhf6ax0lB1j+xQF7/kYZJSUZAboZJSUZB1P8lfyVB1MgOyL5KiI7IgITA2sTO0M4DQNpE335KgbWfSUZ+KwZJSUZB1QZJQAAAAQAAAAABWcHxQAPABMAIwAoAAABISIGFREUFjMhMjY1ETQmAyERISUhIgYVERQWMyEyNjURNCYDIREhEQH+/kwZJiUaAbQaJSVZ/sgBOANo/k4ZJiUaAbIaJSVZ/swBNgfFJBn4wholJRoHPhkk+MIGwnwkGfjCGiUlGgc+GST4wgbC+T4AAAACAAAAAAaLB8UAAgAYAAATCQETIg4BFQMUFhcWMzI3AT4BNCYnASYjiQWG+ngCIDoiAiIdGSQhIAWIGx8fG/p6ICEHSfyf/J8HPiE5Ivk+IjkREBIDYRE5QDkRA2ESAAAE/////wfTB9EAHwBAAGEAggAAARE0JisBIgYVEwEmIgYUFwEhIgYHFRQWFyUyNzY1JyMFFjMFMjY3NS4BIyEBNjQmIgcBEzQmKwEiBgcRMxYVBxQBJiMhIgYHFR4BMyEBBhQWMjcBAxQWOwEyNjcTIyY1NzQFITI2NzU0JichIgcGFRcjBhUTFBY7ATI2NQMBFjI2NCcC7RsVIBMbA/35EzMmEwIF/tgUHQMbFAHaFQoMAgECAQ0SAdoSHAEDHhP+2AIFEyYzE/35AxsTIBMbAgIBA/4ADRL+JhIcAQMeEwEo/fsTJjMTAgcDGxMgExsCAgEBAgLKASgUHQMbFP4iEBALAgEBBBsVIhMbAwIJEzMmEwUqAcUSFxwU/s8CBxMmMxP9/hkXIBMbAgMNDBQXNw0DHBQgFhoCAhMzJhP9+wExEx0XEv45AQEXFf3jDhwUIBYa/f4TMyYTAgf+zxMdFxIBxQEBGQ9jGRcgExsCEAwUFwEB/j0SFxwUAS/9/RIlMxMAAQAAAAAHFAfFAE8AAAEiBw4BBwYVFBceARcWFwcOAR8BHgE3JTM3Njc2LwEwMQMuAQ8BDgEfASMmJy4BJyY1NDc+ATc2IBceARcWFRQCBw4BHgE3NhI1JicuAScmA462p6H5RUdAPeGUmKqxEg4JBwokEQEpAhQRAwQIC7kKIxEOEAQJbAOWhoPGNjg9O9eLkAE6kIvXOz2ilBQIIDMWq7wBR0X6oacHxUdE+KGntqufmfRKTA9aCSMRDxEKCZYMChAUDhQBHhAKCAkIJxKnCkE/1IaKlZ2Qi9Y6PT061ouQnbj+vW8PMyoHEIABd9a2p6H4REcAAAAB//n//QrnB9cAGgAAAS4BBgcJAS4BDgIWFwEeATY3Njc2NwE+ASYKsyBVUx75/f1MIFVTPhcXIAMpIFVTHgUHBAEGYx4VFQegIBcXIPnwArggFhZAVVQe/NMgFhYgBQoFAgZrIFZVAAEAAAAACDoH0AAJAAAJAQMBJQkBBQEDBB0CiqwCPv0L/tn+2P0LAj6sAYj+eALkAfFBArr9RkH+D/0cAAYAAAAAB1wGBgAfAD0ASgBXAGgAdQAAASEiDgEVERQeATMhMjY3EzYyFxMeATMhMj4BNREuAhMUBiMhIiYnAy4BIgYHAw4BIyEiJjURNDYzITIWFQUiDgEUHgEyPgE0LgEDIi4BND4BMh4BFA4BASIOARUUFhcWMj4BNTQnLgEDIi4BND4BMh4BFA4BBrX6ViVCJydCJQGQLEYTdR1sHXUTRiwBkClFKAgwRhokHv5wEhoGdRJZZlkTbAYhE/5wGiEiGQWqGij7cj5nPDxne2g8PGg9JUInJ0JKQSckQQLOPmc8PDM1e2c8IB9pOSVBKChBSkEoKEEGBilFKPydKUUoMCwBIzs7/t0sMChFKQNjKUUo/AcbKBcTASQxOzsx/twSGCQfA2MaKCQeyD1rg2s9PWuDaz3+gClFUUUoKEVSRSgBgD1rQj1sHyE9a0E9NzVB/oApRVFFKChFUUUpAAADAAAAAAcgBd0AIAAuADwAAAEhIg4BFREUHgEzITI2NxM+ATIWFxMeATMhMjY1ETQmIwEiLgE0PgEyHgEUDgEjISIuATQ+ATIeARQOASMGuPpTGy4bGy8cAY0fMwxzD0FQQQ90CzMeAY0rPT0r+7MyVDExVGRVMTFVMgLwMlQxMVRkVTExVTIF3B0wHfyaHTAdJB4BISUuLiX+3x0lPiwDZiw+/SUzV2hXMzNXaFczM1doVzMzV2hXMwAAAAAAEADGAAEAAAAAAAEADAAAAAEAAAAAAAIABwAMAAEAAAAAAAMADAATAAEAAAAAAAQADAAfAAEAAAAAAAUACwArAAEAAAAAAAYADAA2AAEAAAAAAAoAKwBCAAEAAAAAAAsAEwBtAAMAAQQJAAEAGACAAAMAAQQJAAIADgCYAAMAAQQJAAMAGACmAAMAAQQJAAQAGAC+AAMAAQQJAAUAFgDWAAMAAQQJAAYAGADsAAMAAQQJAAoAVgEEAAMAAQQJAAsAJgFabW9iaWxlLWljb25zUmVndWxhcm1vYmlsZS1pY29uc21vYmlsZS1pY29uc1ZlcnNpb24gMS4wbW9iaWxlLWljb25zR2VuZXJhdGVkIGJ5IHN2ZzJ0dGYgZnJvbSBGb250ZWxsbyBwcm9qZWN0Lmh0dHA6Ly9mb250ZWxsby5jb20AbQBvAGIAaQBsAGUALQBpAGMAbwBuAHMAUgBlAGcAdQBsAGEAcgBtAG8AYgBpAGwAZQAtAGkAYwBvAG4AcwBtAG8AYgBpAGwAZQAtAGkAYwBvAG4AcwBWAGUAcgBzAGkAbwBuACAAMQAuADAAbQBvAGIAaQBsAGUALQBpAGMAbwBuAHMARwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABzAHYAZwAyAHQAdABmACAAZgByAG8AbQAgAEYAbwBuAHQAZQBsAGwAbwAgAHAAcgBvAGoAZQBjAHQALgBoAHQAdABwADoALwAvAGYAbwBuAHQAZQBsAGwAbwAuAGMAbwBtAAAAAgAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAQIBAwEEAQUBBgEHAQgBCQEKAQsBDAENAQ4BDwEQAAdhaXJwbGF5DWNocm9tZWNhc3Qtb24KY2hyb21lY2FzdAZleHBhbmQKZ2Vhci1jbGVhcgRuZXh0C3BhdXNlLWNsZWFyCnBsYXktY2xlYXIGcmVkdWNlBnJlbG9hZA5zbGltLWNoZWNrbWFyawRzdGFyCHZyLWNsZWFyAnZyAAA=) format(\"truetype\"),url(data:application/font-woff;base64,d09GRgABAAAAAA4IAAsAAAAAFDwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADsAAABUIIwleU9TLzIAAAFEAAAAQgAAAFZDS00DY21hcAAAAYgAAACJAAACJmJG5UxnbHlmAAACFAAACWoAAAzMalft+WhlYWQAAAuAAAAAMwAAADZiSq2jaGhlYQAAC7QAAAAfAAAAJBKyCu1obXR4AAAL1AAAADcAAAA8dHf/92xvY2EAAAwMAAAAIAAAACAXZBoEbWF4cAAADCwAAAAfAAAAIAEfAQBuYW1lAAAMTAAAATQAAAJG9GExEHBvc3QAAA2AAAAAhwAAAMAbViaIeJxjYGRgYOBiMGCwY2DKSSzJY+BzcfMJYZBiYGGAAJA8MpsxJzM9kYEDxgPKsYBpDiBmg4gCAClZBUgAeJxjYGQ/wjiBgZWBgXkpawUDA6MEhGY+wJDExMLAwMTAysyAFQSkuaYwODxgfMDHfgHI3cJ+nQGkkhEkBwDS2grWAAB4nO2R2w0DIQwEh4N7c1SSElJQvlJfyqGTi5dNGbE0XnkxCNnADOTgERRIbxKKV7hp+Jlj+IXn6Cnye7vvyEk56jLyFL0lXlxY2djj3knlosXhwj/qyJ9f1TQ/MyY6GaTZaDO9GM24z0Zb64tBuhqkm0G6G6SH0Tb7aZBWo9/1yyBthvYFBZQi0wAAAHicfVZrkBTVFe5ze7p7Hrsz04/p3pnZeXTP9swsu8yy0/NgHzOzs7AQCWUk7AM3GCUEWbMk4BoqGiRBqcIHYu0PIYnWSjQ/iI8qiYCFVoxVVq2FGgWDoiFYiWVIUqnEEKMpZthucm/Pqium7K66fc/jnnvOued8tylE4cc9yZ2iPJSXoniVV2m1MbpAdU+ax+vw0cUl8FHdfJbJo4fqr3Knajvhavpvcy3W0+ihuRaKYmwbRduGQMWpLqqHokReVogdWVF54NVCBtEBWSGvkUzhdyFFpZLAN0iVf3DyW05UP5fxMUc/fgWSSuSbuys333B9ZUA6pawf3zf92Okjh7dOKSfF0bXWPw4fg8E9U1tXrW5xPMWdmnvam0HP1zdtmORytTHrbOXO6yMweiowUL7+hpsfm77vG+th10llautTR0+fOHYYpOFRdIf5y5avrtp2812O71KOy/hxL7Xj8FNRavEXosjAlwbx4MQmJ13/QzrAHPv4ZUi2Prxl3nH5Otvxo09tnWp5XRgdJo4TdwNp9Jv6pk0TXL42ap3d8jDcc0oaqNjO7hu/Dn78Onb28JE3XybOrh0laXaQgZvlXsJ5rlIbqDspygW0JPdBtlAUE8l8MZdKJlSN5QJRMFRgJTnrAjGX7ADM4w05wEmKbDBYO5+BhAqFXAaAbsgDIiQ1VlLAXi/Jip4tFvKpBKhEPZdMMUmODSgJLSA2dszTIGcLuRRTRAIKCzExjBAA8ngFazGeOyIitJkXhETO3G5+gBU0ITwvhzOCLbfOIb+YMhiFDgViYshhfiBmdQH5rXNixBEOwOmAx4OgFoM2m7Y6fD4PMREOqFgbCUTb8R7irbfEiCLACwCK4vSGpXigBW9s6Fbc/BA6hIgsWpWGDBFhCHkFIwnmNfCCoLRK1luIF3RDMD9sUeLYMeT1SAr733mC9mEKWVWiCR3mv4jmwrOYpbZSb1B/of5DUYCrolgoFroAVwTrg2QXZDAPJ5fDFMulMmBPFDkG+OvFVAQkQskKx3Is+cqFCtgMkuJiGSpQKCpRKGJ2IYUNkm+xUIJcwxjCdnAJclhCKGwykexCNpVI5Sp49y6Efcjjo6ygQsX2EJufpwyyOZIVm2MoErEVQ1FQiMccrgUsypKIcna9axnIlSEbBQnvc9UMHx0J07S6TtZiy4L3GSWNbQtH4rd3JaKe9r7y/cHBmKasU2k6PN4izkR7BDGtZQ8Kyvhni6YrfWlPLNG1Ix4J62yibOwNVWNay7o4TYdGhfBDWS0t8j0xTjovu8Lx25rQGq75tUpRX5YDF/09p2NpdeniymsCO9q0MyJ5pfMuvwMcbubvsl+K7CTa7t9VFmMl1oluQQwylsf8oUDlRFPzmqbb4hGXfN7tQ3Mzm0aHuw2je3j0lbHhLJmM3bhsanBwag8ZHL9IZKvTnZ15bZ3s5LziWFD+NBZRHee9LKeMqflM54HOssrqOAE7uhIxT7qw+CefLVqvijPzsTwaCI3zPo6T1+FFHdPaV5J2ArRIuO0CCSjS1/+qzK2h2d1aq1s57/Qhp/i+JLZod7pWN/lOlzr1ai9yOrbRDOSWdbWX3sDKiLlLaxGlP/n8dCN8D+dpUne6rm7yvdZbji/PgdsBFTvC+VDHXiYT88B8kHgg9XzZco5wb1CIkqkQ1YnxD2OH5oUALUVx0UGZVDMkEwzGRB2DRKCbl2QDo0OezyUTP2L2178D0X4Naf3LosyB1hjSlPpkROfWWbOww1oR1PUgPEdGbu3c/rn93Np4n1ZbpPVpSKQnxb5lS5vpm8SdtUXsmZ168OKTtuZwUP+k15jNuNd8lEglqDTuNeLAgv3JvaX/Hx4PlrU6mNRDcDSk69daJ2ApPWFdbXOetjm/hQI32xa8+CKmQlw52HbxRfbF269k1MrYBfu+ZPdiPxDVsjA/uE+MLMkQhkmcoXuYPfVbUbwX5yISbFPjzN3hWCxc/2Fc5a6aOzh3kCurPVqtrPXwfoHewPcM9PD0Bowq9h3EncZnEKMGGvgO/JejM/N5OE9q3BV4D1deCMUrbgzmE3xXNRvf2SvxHf0zHIiLYdqsiUZSRIz1jhShwxKcDbibECBoFuCs0Ap0VLTeQYyYNESzRofFuH0f0BbVLFjJhhzS5iUiR9ynckDoFUjbBi3N7yfwjpFew9shF9mOWQSzNkifRJxt2goqZCXd3CQpxWa6VYrLIYSIqnkJusk9YPVgrA+Y73ttmWnZXnPWSfuOmAUI+jY2bPixCQCrZEN7l2liaBcpsHFdwmf8NZx9jSMoHZAwBBOY9UIMMBjrRgPml3TTGSBAHoNEMkWwPp/DmF0sxG39gITwCgLeQr4hpu9/5tAjtaGVA6X3Hvjp478SvC7O3cZDO5J42uH0POtO8F6/w7WFPrBn90uFpaW+t/dOQ+/03rf7So8+IDnjhvzEr2HlUP2RQ9zsyuUXHzn0zBMHf/bRqtW+cVeC9/Fu14Emtx8jIUT9bqfLmRIOuauVN/fcu39meu+Z3lKp98ze6Znj1vNbfcYizr8LfnAG+3Nx+UocMlyuXTbdf+Xexr1P4U5nORcevfh2ANL95MX1nXQfiY+sjdZMczX+lhUlTrcTBsM5gN0YDQS4n8cxs3YBHY/L8sDIcHTuNJ7EGTeD2Mn46Egjv85e/J/lsv9eQHcBA7Qjgu59EpVNj/V76x3Tg8pPwt3WrejP8O8qes5cUbV8ZivF2meznmVxf5SoVdQYNUFtt7EAdyEvkRInZV3IKqI9L0OezyBRYnELJFP4rHAj0F4gFMaHAtaQAwxei1diXfwv9LkrDohV0trEDrlvPydlj9VH9cFUalCH6c4V4vbIlsh2cUUnTLcPpZ1LVoTaotY2IcRuF6698VpxC6uK1raQqgWZx0PpS1Plzf39m3dM9PdPlGwbq6qptip6nbCN/I7N/fHYTT16NZ2uriIDy2KbczN4WNIJib4+693OJemhdnojYXPhtIJ/tLr7+rqtc0JLW4zeGEq3RU+UJndPluzB2tU+tGYonR76+lAadpUmB0tbYmppsloq5qufytYMtVMUbec3zryL/y8zVP8XM4uDl+dz20B9WJgSnNeFFHu8vjacCYe7WmFfzGi6xVe9pur7vseIwr6OUqnj0pHscHf38LdHurtHsujCAoI5F1kSmXsQD21RUPVMRrf+GNHLnfSNnWVTN8YmxowrBor6Hy2uu7cAAHicY2BkYGAA4ps/HpfG89t8ZeBmvwAUYahR3dAIo////P+X6zn7dSCXg4EJJAoAnYsPHgB4nGNgZGBgv8AABFyP/v/8/5vrOQMjAyrgBwCcQga4AHicY2BgYODKAmIzIDb//5/9LAMD+wUGBo4QBgbWQgYGtqkgPlBcBij/6P9PDkuIPAgDAHDnDdcAAAAAAAAiAIYA2AGeAwYDVAOYA8gEigUGBToFWAYIBmZ4nGNgZGBg4Gf4wsDGAAJMQMwFhAwM/8F8BgAiPQIgAHicdY89TsNAEIWfEyeIBCEkJETHVjQozk9BkZIi6VOkoLOddeLI9lrrTaR0HIMTcAxKjsApOAQvyxQRUnalne99nlnbAG7whQDHFeDKn8fVwgXTH7dJt8Ih+UG4gz6ehLv0z8I92hfhPidL3hCElzT3eBNu4Rrvwm36D+GQ/CncwR2+hbv0P8I9LINQuI/H4LU0SV7oQZ6aqlno9a6I7ak65aW2TW4qNY5Gp3quK21jp1cqOahmv544l6nMmlLNTOV0URhVW7PVqYs2ztXT4TATH6Wm5B8aJMhRQGPAmjJXaLBgXmNHH8Oe7Trnl8yWNfdZYYwIo7Pdc+bKT8RwrCtOJDjwbLDnV0xoHTLmjD2G9yjM/Oyxu+A2NLV/tqVJ6SNs/FSNKYbc2b/+yL+9/AXl8mo5eJxtjMsOgjAQRXuxAhZ5LPwNPmpSJkIo0EyB4N+LqYkbz+K+FlclKvJQ/6mR4AKNK1JkyHGDQYE7SlSo0aiMBvGOXqXtZZnYUljbZTa/lvLhae7Mk0la607VMx9r4WkLHAfzOYgxFe42y6e5hboquGFqbc92nEhGHVaSfP/eJLso9Qb4EC3/AA==) format(\"woff\");font-weight:normal;font-style:normal}.mhp1138_container .mhp1138_icon{font-family:'mobile-icons';speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.mhp1138_container .mhp1138_icon-airplay:before{content:\"\\E001\"}.mhp1138_container .mhp1138_icon-chromecast-on:before{content:\"\\E002\"}.mhp1138_container .mhp1138_icon-chromecast:before{content:\"\\E003\"}.mhp1138_container .mhp1138_icon-expand:before{content:\"\\E004\"}.mhp1138_container .mhp1138_icon-gear-clear:before{content:\"\\E005\"}.mhp1138_container .mhp1138_icon-next:before{content:\"\\E006\"}.mhp1138_container .mhp1138_icon-pause-clear:before{content:\"\\E007\"}.mhp1138_container .mhp1138_icon-play-clear:before{content:\"\\E008\"}.mhp1138_container .mhp1138_icon-reduce:before{content:\"\\E009\"}.mhp1138_container .mhp1138_icon-reload:before{content:\"\\E00A\"}.mhp1138_container .mhp1138_icon-slim-checkmark:before{content:\"\\E00B\"}.mhp1138_container .mhp1138_icon-star:before{content:\"\\E00C\"}.mhp1138_container .mhp1138_icon-vr-clear:before{content:\"\\E00D\"}.mhp1138_container .mhp1138_icon-vr:before{content:\"\\E00E\"}@import url(https://fonts.mhp1138_googleapis.mhp1138_com/css?family=Roboto);.mhp1138_container{height:100%;width:100%;position:relative;background:black;overflow:hidden;font-family:Arial;color:white}.mhp1138_container div,.mhp1138_container span,.mhp1138_container applet,.mhp1138_container object,.mhp1138_container iframe,.mhp1138_container h1,.mhp1138_container h2,.mhp1138_container h3,.mhp1138_container h4,.mhp1138_container h5,.mhp1138_container h6,.mhp1138_container p,.mhp1138_container blockquote,.mhp1138_container pre,.mhp1138_container a,.mhp1138_container abbr,.mhp1138_container acronym,.mhp1138_container address,.mhp1138_container big,.mhp1138_container cite,.mhp1138_container code,.mhp1138_container del,.mhp1138_container dfn,.mhp1138_container em,.mhp1138_container img,.mhp1138_container ins,.mhp1138_container kbd,.mhp1138_container q,.mhp1138_container s,.mhp1138_container samp,.mhp1138_container small,.mhp1138_container strike,.mhp1138_container strong,.mhp1138_container sub,.mhp1138_container sup,.mhp1138_container tt,.mhp1138_container var,.mhp1138_container b,.mhp1138_container u,.mhp1138_container i,.mhp1138_container center,.mhp1138_container dl,.mhp1138_container dt,.mhp1138_container dd,.mhp1138_container ol,.mhp1138_container ul,.mhp1138_container li,.mhp1138_container fieldset,.mhp1138_container form,.mhp1138_container label,.mhp1138_container legend,.mhp1138_container table,.mhp1138_container caption,.mhp1138_container tbody,.mhp1138_container tfoot,.mhp1138_container thead,.mhp1138_container tr,.mhp1138_container th,.mhp1138_container td,.mhp1138_container article,.mhp1138_container aside,.mhp1138_container canvas,.mhp1138_container details,.mhp1138_container embed,.mhp1138_container figure,.mhp1138_container figcaption,.mhp1138_container footer,.mhp1138_container header,.mhp1138_container hgroup,.mhp1138_container menu,.mhp1138_container nav,.mhp1138_container output,.mhp1138_container ruby,.mhp1138_container section,.mhp1138_container summary,.mhp1138_container time,.mhp1138_container mark,.mhp1138_container audio,.mhp1138_container video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}.mhp1138_container article,.mhp1138_container aside,.mhp1138_container details,.mhp1138_container figcaption,.mhp1138_container figure,.mhp1138_container footer,.mhp1138_container header,.mhp1138_container hgroup,.mhp1138_container menu,.mhp1138_container nav,.mhp1138_container section{display:block}.mhp1138_container ol,.mhp1138_container ul{list-style:none}.mhp1138_container blockquote,.mhp1138_container q{quotes:none}.mhp1138_container blockquote:before,.mhp1138_container blockquote:after,.mhp1138_container q:before,.mhp1138_container q:after{content:'';content:none}.mhp1138_container table{border-collapse:collapse;border-spacing:0}.mhp1138_container video{border:none}.mhp1138_container .mhp1138_videoWrapper{position:absolute;top:0;left:0;z-index:1;width:100%;height:100%}.mhp1138_container .mhp1138_videoWrapper canvas{visibility:hidden}.mhp1138_container .mhp1138_videoWrapper video,.mhp1138_container .mhp1138_videoWrapper canvas{position:absolute;top:0;left:0;z-index:0}.mhp1138_container button{overflow:visible}.mhp1138_container button::-moz-focus-inner,.mhp1138_container input::-moz-focus-inner{padding:0;border:0}.mhp1138_container *{outline:none}.mhp1138_container,.mhp1138_container *{-webkit-user-select:none;user-select:none}.mhp1138_container *::selection{background:transparent}.mhp1138_container .mhp1138_controlBar{align-items:center;background:linear-gradient(to bottom, transparent 0%, #000 100%);bottom:0;display:flex;color:#cbcbcb;position:absolute;transition:transform 0.5s ease;transform:translate3d(0, 52px, 0);width:100%;z-index:5;box-sizing:border-box}.mhp1138_container .mhp1138_controlBar .mhp1138_time_elapsed,.mhp1138_container .mhp1138_controlBar .mhp1138_time_total{justify-content:center;font-size:14px;line-height:46px;text-align:center;display:flex;flex:0 0 auto;align-items:center;margin-left:10px}.mhp1138_container .mhp1138_controlBar .mhp1138_time_elapsed{margin:0 10px 0 15px}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar{margin:0 5px;height:44px;position:relative;display:flex;flex:1 1;align-items:center}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_hotspots{position:absolute;left:0;bottom:23px;right:0;height:30px;overflow:hidden;z-index:1}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_hotspots svg{display:block;width:100%;height:100%}.mhp1138_container .mhp1138_controlBar .mhp1138_seekBar .mhp1138_hotspots .mhp1138_hotspotsFill{opacity:0.7}.mhp1138_container .mhp1138_controlBar .mhp1138_background{display:flex;height:2px;background-color:#cbcbcb;flex:1 1}.mhp1138_container .mhp1138_controlBar .mhp1138_progress{position:absolute;width:100%;left:0;top:21px;z-index:5;transform:translate3d(-100%, 0px, 0px)}.mhp1138_container .mhp1138_controlBar .mhp1138_progress.mhp1138_animated{transition:all 0.15s ease}.mhp1138_container .mhp1138_controlBar .mhp1138_handle{width:22px;height:22px;border-radius:20px;background-color:rgba(255,255,255,0.2);position:absolute;top:-10.5px;right:-10.5px}.mhp1138_container .mhp1138_controlBar .mhp1138_handle.mhp1138_hover{background-color:rgba(255,255,255,0.5)}.mhp1138_container .mhp1138_controlBar .mhp1138_handle .mhp1138_center{width:8px;height:8px;border-radius:20px;background-color:#ffffff;position:absolute;top:7px;left:7px}.mhp1138_container .mhp1138_controlBar .mhp1138_fullscreen{display:flex;align-items:center;flex:0 0 44px;height:44px;order:10}.mhp1138_container .mhp1138_controlBar .mhp1138_fullscreen.mhp1138_hover .mhp1138_icon{color:#fff;text-shadow:0 0 20px #fff}.mhp1138_container .mhp1138_controlBar .mhp1138_fullscreen .mhp1138_fullscreenOn{display:none}.mhp1138_container .mhp1138_controlBar .mhp1138_fullscreen .mhp1138_fullscreenOff{display:block}.mhp1138_container .mhp1138_controlBar .mhp1138_fullscreen.mhp1138_fullscreenState .mhp1138_fullscreenOn{display:block}.mhp1138_container .mhp1138_controlBar .mhp1138_fullscreen.mhp1138_fullscreenState .mhp1138_fullscreenOff{display:none}.mhp1138_container .mhp1138_controlBar .mhp1138_cardboard{display:none;align-items:center;flex:0 0 44px;height:44px}.mhp1138_container .mhp1138_controlBar .mhp1138_cardboard .mhp1138_icon{font-size:25px}.mhp1138_container .mhp1138_controlBar .mhp1138_cardboard.mhp1138_hover .mhp1138_icon{color:#fff;text-shadow:0 0 20px #fff}.mhp1138_container .mhp1138_controlBar .mhp1138_cardboard .mhp1138_cardboardOn{display:none}.mhp1138_container .mhp1138_controlBar .mhp1138_cardboard .mhp1138_cardboardOff{display:block}.mhp1138_container .mhp1138_controlBar .mhp1138_cardboard.mhp1138_cardboardState .mhp1138_cardboardOn{display:block}.mhp1138_container .mhp1138_controlBar .mhp1138_cardboard.mhp1138_cardboardState .mhp1138_cardboardOff{display:none}.mhp1138_container .mhp1138_controlBar .mhp1138_fullscreenOn,.mhp1138_container .mhp1138_controlBar .mhp1138_fullscreenOff,.mhp1138_container .mhp1138_controlBar .mhp1138_cardboardOn,.mhp1138_container .mhp1138_controlBar .mhp1138_cardboardOff{background-color:transparent;color:#cbcbcb;font-size:16px;line-height:44px;text-align:center;width:44px;height:45px;margin:0;border:0}.mhp1138_container .mhp1138_controlBar .mhp1138_fullscreenOn .mhp1138_icon,.mhp1138_container .mhp1138_controlBar .mhp1138_fullscreenOff .mhp1138_icon,.mhp1138_container .mhp1138_controlBar .mhp1138_cardboardOn .mhp1138_icon,.mhp1138_container .mhp1138_controlBar .mhp1138_cardboardOff .mhp1138_icon{display:block;position:relative;top:0}.mhp1138_container.mhp1138_vr .mhp1138_controlBar .mhp1138_cardboard{display:flex}.mhp1138_container.mhp1138_embedded .mhp1138_controlBar{padding-left:50px}.mhp1138_container.mhp1138_embedded .mhp1138_controlBar .mhp1138_cardboard{display:none}.mhp1138_container.mhp1138_embedded .mhp1138_controlBar .mhp1138_time_elapsed{order:2;margin:0 0 0 5px}.mhp1138_container.mhp1138_embedded .mhp1138_controlBar .mhp1138_time_elapsed:after{content:\"/\";margin-left:3px}.mhp1138_container.mhp1138_embedded .mhp1138_controlBar .mhp1138_time_total{order:3;margin:0 0 0 2px}.mhp1138_container.mhp1138_embedded .mhp1138_controlBar .mhp1138_seekBar{order:1;margin:0 10px}.mhp1138_container .mhp1138_thumbnails{position:absolute;top:0;left:0;width:100%;height:100%;background:black;z-index:3;display:none}.mhp1138_container .mhp1138_thumbnails.mhp1138_visible{display:block}.mhp1138_container .mhp1138_thumbnails .mhp1138_sprite{position:absolute;top:50%;left:50%;width:160px;height:90px;overflow:hidden;background:white;transform:translate(-50%, -50%);transform-origin:0 0}.mhp1138_container{font-family:'Roboto', Helvetica, sans-serif}.mhp1138_container .mhp1138_hidden{display:none !important}.mhp1138_container.mhp1138_chromecastV2 .mhp1138_options .mhp1138_chromecastBtn{display:block}.mhp1138_container.mhp1138_hlsStream .mhp1138_options .mhp1138_chromecastBtn,.mhp1138_container.mhp1138_dashStream .mhp1138_options .mhp1138_chromecastBtn{display:none !important}.mhp1138_container .mhp1138_videoWrapper{background:#000}.mhp1138_container .mhp1138_videoWrapper canvas{visibility:hidden}.mhp1138_container .mhp1138_videoWrapper video::-internal-media-controls-overlay-cast-button{display:none}.mhp1138_container .mhp1138_videoWrapper video::-webkit-media-controls-start-playback-button{display:none !important;-webkit-appearance:none}.mhp1138_container .mhp1138_eventCatcher{position:absolute;top:0;left:0px;width:100%;height:100%;z-index:5 !important;display:none}.mhp1138_container .mhp1138_videoErrorMessage{display:none;z-index:4;position:absolute;top:30px;left:50%;white-space:nowrap;float:left;cursor:default}.mhp1138_container .mhp1138_videoErrorMessage .mhp1138_centered{background:black;margin-left:-50%;float:left;padding:1px 7px;border-radius:3px}.mhp1138_container .mhp1138_videoErrorMessage p{margin:0;padding:2px 0 0 22px;font-size:16px;font-weight:bold;font-family:Arial, Verdana, Serif}.mhp1138_container .mhp1138_videoErrorMessage .mhp1138_icon{float:left;position:relative;top:2px;font-size:16px}.mhp1138_container .mhp1138_videoPoster{position:absolute;top:0;left:0;z-index:2;width:100%;height:100%;background-repeat:no-repeat;background-position:center;background-size:100%}.mhp1138_container .mhp1138_optionsMenu{position:absolute;z-index:3;width:260px;left:50%;top:50%;opacity:0;transform:translate(-50%, -100%);transition:all 0.5s ease;pointer-events:none}.mhp1138_container .mhp1138_optionsMenu .mhp1138_menuTabs{border-bottom:2px solid #cbcbcb;margin-bottom:20px;display:flex}.mhp1138_container .mhp1138_optionsMenu .mhp1138_menuTabs .mhp1138_menuTitle{flex:1 1 auto;max-width:40%;padding:0 2px 10px;font-size:18px;color:#cbcbcb;display:inline-block;position:relative;text-align:center;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;top:2px}.mhp1138_container .mhp1138_optionsMenu .mhp1138_menuTabs .mhp1138_menuTitle.mhp1138_active{color:#fff;border-bottom:2px solid #fff}.mhp1138_container .mhp1138_optionsMenu .mhp1138_menuPage{display:none;overflow:hidden}.mhp1138_container .mhp1138_optionsMenu .mhp1138_menuPage.mhp1138_active{display:block}.mhp1138_container .mhp1138_optionsMenu .mhp1138_optionsItem{padding:10px;font-size:16px;float:left;box-sizing:border-box;width:125px;height:42px;border-radius:5px;margin-right:10px;color:#cbcbcb;position:relative;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.mhp1138_container .mhp1138_optionsMenu .mhp1138_optionsItem:nth-child(even){margin-right:0}.mhp1138_container .mhp1138_optionsMenu .mhp1138_optionsItem.mhp1138_optionsText{padding:0 10px 10px;margin:0;float:none;width:100%;height:auto}.mhp1138_container .mhp1138_optionsMenu .mhp1138_optionsItem.mhp1138_upsell .mhp1138_icon{top:11px;right:10px;position:absolute}.mhp1138_container .mhp1138_optionsMenu .mhp1138_optionsItem.mhp1138_active{border:2px solid #fff;padding:8px 26px 8px 8px;color:#fff}.mhp1138_container .mhp1138_optionsMenu .mhp1138_optionsItem.mhp1138_active .mhp1138_icon-slim-checkmark{display:block}.mhp1138_container .mhp1138_optionsMenu .mhp1138_optionsItem .mhp1138_icon-slim-checkmark{position:absolute;font-size:12px;right:8px;top:13px;display:none}.mhp1138_container .mhp1138_optionsMenu .mhp1138_motionRates .mhp1138_optionsItem{width:80px;margin-right:10px}.mhp1138_container .mhp1138_optionsMenu .mhp1138_motionRates .mhp1138_optionsItem:last-child{margin-right:0}.mhp1138_container .mhp1138_optionsMenu .mhp1138_motionRates .mhp1138_optionsText{width:100%}.mhp1138_container .mhp1138_controls{background-color:rgba(0,0,0,0.4);position:absolute;height:100%;width:100%;top:0;z-index:3;opacity:0;transition:opacity 0.5s ease;pointer-events:none}.mhp1138_container .mhp1138_controls .mhp1138_play,.mhp1138_container .mhp1138_controls .mhp1138_pause,.mhp1138_container .mhp1138_controls .mhp1138_replay,.mhp1138_container .mhp1138_controls .mhp1138_next{position:absolute;z-index:5;font-size:35px;line-height:60px;height:60px;width:60px;text-align:center;top:50%;left:50%;padding:5px 0;margin:-30px 0 0 -30px;color:#cbcbcb;background-color:transparent;border:0;opacity:0;transition:opacity 0.5s cubic-bezier(1, 0, 1, 0);pointer-events:none;overflow:hidden}.mhp1138_container .mhp1138_controls .mhp1138_play.mhp1138_hover .mhp1138_icon,.mhp1138_container .mhp1138_controls .mhp1138_pause.mhp1138_hover .mhp1138_icon,.mhp1138_container .mhp1138_controls .mhp1138_replay.mhp1138_hover .mhp1138_icon,.mhp1138_container .mhp1138_controls .mhp1138_next.mhp1138_hover .mhp1138_icon{color:#fff;text-shadow:0 0 20px #fff}.mhp1138_container .mhp1138_controls .mhp1138_next{left:68%;font-size:25px;top:49.5%}.mhp1138_container .mhp1138_controls .mhp1138_prerollEventCatcher{display:none}.mhp1138_container .mhp1138_topBar{padding:0 15px;position:relative;z-index:10;display:none;background:linear-gradient(to bottom, rgba(0,0,0,0.8) 0%, transparent 100%);transition:transform 0.5s ease;transform:translate(0, -50px)}.mhp1138_container .mhp1138_topBar .mhp1138_content{display:flex;justify-content:space-around;align-items:flex-start;height:45px}.mhp1138_container .mhp1138_topBar .mhp1138_title{line-height:45px;display:flex;flex:1 1;order:-1;width:80%;padding-right:10px}.mhp1138_container .mhp1138_topBar .mhp1138_title span{display:block;width:100%;text-decoration:underline;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mhp1138_container .mhp1138_topBar .mhp1138_logo{display:flex;height:45px;line-height:45px;flex:0 1;flex-basis:80px}.mhp1138_container .mhp1138_topBar .mhp1138_logo svg{width:100%}.mhp1138_container.mhp1138_readyState .mhp1138_controls .mhp1138_play,.mhp1138_container.mhp1138_readyState .mhp1138_controls .mhp1138_next{opacity:1;pointer-events:auto}.mhp1138_container.mhp1138_bufferingState .mhp1138_loader{opacity:1}.mhp1138_container.mhp1138_bufferingState .mhp1138_controls .mhp1138_play,.mhp1138_container.mhp1138_bufferingState .mhp1138_controls .mhp1138_pause,.mhp1138_container.mhp1138_bufferingState .mhp1138_controls .mhp1138_replay{opacity:0;transition-duration:0.01s}.mhp1138_container.mhp1138_pausedState .mhp1138_controls .mhp1138_play,.mhp1138_container.mhp1138_pausedState .mhp1138_controls .mhp1138_next{opacity:1;transition-duration:0.2s;transition-timing-function:ease;pointer-events:none}.mhp1138_container.mhp1138_pausedState .mhp1138_controls .mhp1138_pause{transition-duration:0.2s;transition-timing-function:ease}.mhp1138_container.mhp1138_pausedState.mhp1138_showControls .mhp1138_controls .mhp1138_play,.mhp1138_container.mhp1138_pausedState.mhp1138_showControls .mhp1138_controls .mhp1138_next{pointer-events:auto}.mhp1138_container.mhp1138_replayState .mhp1138_controls .mhp1138_replay{opacity:1;pointer-events:auto}.mhp1138_container.mhp1138_replayState .mhp1138_controls .mhp1138_pause{transition-duration:0.01s}.mhp1138_container.mhp1138_playingState .mhp1138_controls .mhp1138_pause,.mhp1138_container.mhp1138_playingState .mhp1138_controls .mhp1138_next{opacity:1;pointer-events:none}.mhp1138_container.mhp1138_playingState.mhp1138_showControls .mhp1138_controls .mhp1138_pause,.mhp1138_container.mhp1138_playingState.mhp1138_showControls .mhp1138_controls .mhp1138_next{pointer-events:auto;transition-duration:0.2s;transition-timing-function:ease}.mhp1138_container.mhp1138_playingState.mhp1138_showControls .mhp1138_controls .mhp1138_play{transition-duration:0.2s;transition-timing-function:ease}.mhp1138_container.mhp1138_showControls .mhp1138_controls,.mhp1138_container.mhp1138_readyState .mhp1138_controls{pointer-events:none;opacity:1}.mhp1138_container.mhp1138_showControls .mhp1138_options,.mhp1138_container.mhp1138_readyState .mhp1138_options{transform:translate(0, 0)}.mhp1138_container.mhp1138_showControls .mhp1138_controlBar,.mhp1138_container.mhp1138_readyState .mhp1138_controlBar{transform:translate(0, 0)}.mhp1138_container.mhp1138_showControls .mhp1138_controlBar .mhp1138_hotspots,.mhp1138_container.mhp1138_readyState .mhp1138_controlBar .mhp1138_hotspots{visibility:visible}.mhp1138_container .mhp1138_hotspots{visibility:hidden}.mhp1138_container.mhp1138_showOptions .mhp1138_controls{opacity:1}.mhp1138_container.mhp1138_showOptions .mhp1138_controls .mhp1138_play,.mhp1138_container.mhp1138_showOptions .mhp1138_controls .mhp1138_pause,.mhp1138_container.mhp1138_showOptions .mhp1138_controls .mhp1138_replay,.mhp1138_container.mhp1138_showOptions .mhp1138_controls .mhp1138_next{opacity:0;pointer-events:none;transition-timing-function:cubic-bezier(0, 1, 0, 1)}.mhp1138_container.mhp1138_showOptions .mhp1138_controlBar{transform:translate(0, 52px)}.mhp1138_container.mhp1138_showOptions .mhp1138_controlBar .mhp1138_hotspots{visibility:hidden}.mhp1138_container.mhp1138_showOptions .mhp1138_optionsMenu{transform:translate(-50%, -50%);opacity:1;pointer-events:auto}.mhp1138_container.mhp1138_embedded .mhp1138_options{display:none}.mhp1138_container.mhp1138_embedded .mhp1138_topBar{display:block;transform:translate(0, 0)}.mhp1138_container.mhp1138_embedded .mhp1138_controls{height:44px;width:44px;bottom:2px;left:3px;top:auto;z-index:5;background-color:transparent}.mhp1138_container.mhp1138_embedded .mhp1138_controls .mhp1138_play,.mhp1138_container.mhp1138_embedded .mhp1138_controls .mhp1138_pause,.mhp1138_container.mhp1138_embedded .mhp1138_controls .mhp1138_replay,.mhp1138_container.mhp1138_embedded .mhp1138_controls .mhp1138_next{line-height:44px;width:44px;height:44px;margin:0;padding:0;left:0;top:0}.mhp1138_container.mhp1138_embedded .mhp1138_controls .mhp1138_play .mhp1138_icon,.mhp1138_container.mhp1138_embedded .mhp1138_controls .mhp1138_pause .mhp1138_icon,.mhp1138_container.mhp1138_embedded .mhp1138_controls .mhp1138_replay .mhp1138_icon,.mhp1138_container.mhp1138_embedded .mhp1138_controls .mhp1138_next .mhp1138_icon{font-size:22px}.mhp1138_container.mhp1138_embedded .mhp1138_controls .mhp1138_replay{top:2px}.mhp1138_container.mhp1138_embedded .mhp1138_eventCatcher{display:block;top:45px;bottom:45px;height:auto}.mhp1138_container.mhp1138_embedded .mhp1138_eventCatcher .mhp1138_bigPlay{border-radius:50%;display:none;position:absolute;font-size:35px;line-height:70px;height:60px;width:60px;text-align:center;top:50%;left:50%;margin:-30px 0 0 -30px;color:#cbcbcb;background-color:transparent;border:0;z-index:7}.mhp1138_container.mhp1138_embedded .mhp1138_eventCatcher .mhp1138_bigPlay.mhp1138_hover .mhp1138_icon{color:#fff;text-shadow:0 0 20px #fff}.mhp1138_container.mhp1138_embedded .mhp1138_eventCatcher .mhp1138_bigPlay .mhp1138_icon{font-size:35px;margin-left:7px;color:#fff}.mhp1138_container.mhp1138_embedded .mhp1138_loader{top:auto;bottom:2px;left:2px;width:40px;height:40px;margin:0}.mhp1138_container.mhp1138_embedded .mhp1138_controls{opacity:1}.mhp1138_container.mhp1138_embedded.mhp1138_pausedState .mhp1138_controls .mhp1138_play{pointer-events:auto}.mhp1138_container.mhp1138_embedded.mhp1138_playingState .mhp1138_controls .mhp1138_pause{pointer-events:auto}.mhp1138_container.mhp1138_embedded.mhp1138_readyState .mhp1138_eventCatcher .mhp1138_bigPlay{background-color:rgba(0,0,0,0.4);display:block}.mhp1138_container.mhp1138_embedded .mhp1138_controlBar{transform:translate(0, 0)}.mhp1138_container .mhp1138_options{z-index:3;transition:transform 0.5s ease;transform:translate(0, -52px);position:absolute;top:2px;right:8px}.mhp1138_container .mhp1138_options .mhp1138_qualityBtn,.mhp1138_container .mhp1138_options .mhp1138_chromecastBtn{display:block;position:relative;float:right;height:44px;line-height:1;padding:14px 7px;background-color:transparent;border:0;z-index:5;color:#cbcbcb}.mhp1138_container .mhp1138_options .mhp1138_qualityBtn.mhp1138_hover .mhp1138_icon,.mhp1138_container .mhp1138_options .mhp1138_chromecastBtn.mhp1138_hover .mhp1138_icon{color:#fff;text-shadow:0 0 20px #fff}.mhp1138_container .mhp1138_options .mhp1138_qualityBtn .mhp1138_title{font-size:16px;color:#cbcbcb}.mhp1138_container .mhp1138_options .mhp1138_qualityBtn .mhp1138_title:after{position:relative;top:-2px;padding-left:5px;font:10px sans-serif;content:'\\25BC'}.mhp1138_container .mhp1138_options .mhp1138_qualityBtn .mhp1138_icon{position:relative;top:-3px;font-size:20px}.mhp1138_container .mhp1138_options .mhp1138_chromecastBtn{width:44px;font-size:18px;padding-top:12px;display:none}.mhp1138_container .mhp1138_loader{position:absolute;z-index:4;top:50%;left:50%;width:50px;height:50px;margin:-25px 0 0 -25px;transition:opacity 0.2s ease;opacity:0;pointer-events:none}.mhp1138_container .mhp1138_loader:before{content:'';display:block;padding-top:100%}.mhp1138_container .mhp1138_circular{width:100%;height:100%;position:absolute;top:0;bottom:0;left:0;right:0;margin:auto;transform:rotate(0deg);transform-origin:center center;animation:rotate 2s linear infinite}.mhp1138_container .mhp1138_path{stroke-dasharray:1,200;stroke-dashoffset:0;stroke:#cbcbcb;animation:dash 1.5s ease-in-out infinite;stroke-linecap:round}@keyframes rotate{100%{transform:rotate(360deg)}}@keyframes dash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:89,200;stroke-dashoffset:-35px}100%{stroke-dasharray:89,200;stroke-dashoffset:-124px}}.mhp1138_container .mhp1138_preRollTitle{position:relative;z-index:2;background-color:rgba(0,0,0,0.55);border-bottom:1px solid #000000;padding:8px;font-size:14px;font-weight:bold;line-height:14px;display:none}.mhp1138_container .mhp1138_preRollSkipButton{z-index:4;position:absolute;padding:10px;background:rgba(0,0,0,0.55);border:1px solid black;right:0;top:60%;cursor:pointer;display:none}.mhp1138_container.mhp1138_preRollRunning .mhp1138_preRollTitle{display:block}.mhp1138_container.mhp1138_preRollRunning .mhp1138_actionTag{display:none !important}.mhp1138_container.mhp1138_preRollRunning .mhp1138_progress{background:#690 !important}.mhp1138_container.mhp1138_preRollRunning .mhp1138_progress:before{background:#690 !important}.mhp1138_container.mhp1138_preRollRunning .mhp1138_handleHover .mhp1138_center{background:#690 !important}.mhp1138_container.mhp1138_preRollRunning .mhp1138_chromecast{display:none !important}.mhp1138_container.mhp1138_preRollRunning .mhp1138_hotspots{display:none !important}.mhp1138_container.mhp1138_preRollRunning .mhp1138_controls .mhp1138_next,.mhp1138_container.mhp1138_preRollRunning .mhp1138_controls .mhp1138_replay{display:none !important}.mhp1138_container.mhp1138_preRollRunning .mhp1138_controlBar{transform:translate(0, 0)}.mhp1138_container.mhp1138_preRollRunning .mhp1138_controlBar .mhp1138_seekBar{overflow:hidden}.mhp1138_container.mhp1138_preRollRunning .mhp1138_controlBar .mhp1138_seekBar .mhp1138_progress{height:2px}.mhp1138_container.mhp1138_preRollRunning .mhp1138_controlBar .mhp1138_seekBar .mhp1138_progress .mhp1138_handle{display:none}.mhp1138_container.mhp1138_preRollRunning .mhp1138_prerollEventCatcher{display:block;height:100%;z-index:4;position:relative;pointer-events:auto}.mhp1138_container.mhp1138_preRollRunning .mhp1138_options{display:none}.mhp1138_container.mhp1138_noFullscreen .mhp1138_fullscreen{display:none}.mhp1138_container.mhp1138_noFullscreen .mhp1138_time_total{margin-right:10px}"; | |
/** | |
* @license Satisfy - made to satisfy CSS selectors | |
* Copyright (c) 2009 James Padolsey | |
* ------------------------------------------------------- | |
* Dual licensed under the MIT and GPL licenses. | |
* - http://www.opensource.org/licenses/mit-license.php | |
* - http://www.gnu.org/copyleft/gpl.html | |
* ------------------------------------------------------- | |
* Version: 0.3 | |
* ------------------------------------------------------- | |
* (most) Regular Expressions are Copyright (c) John Resig, | |
* from the Sizzle Selector Engine. | |
*/ | |
(function (definition) { | |
var satisfy = definition(); | |
window['satisfy'] = satisfy; | |
})(function(){ | |
var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g, | |
exprRegex = { | |
ID: /[^"]#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/, | |
CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?![^[\]]+])(?:(?!\]))/g, | |
NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/, | |
ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/g, | |
TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/, | |
CLONE: /\:(\d+)(?=$|[:[])/, | |
COMBINATOR: /^[>~+]$/ | |
}, | |
doc = document, | |
cache = {}, | |
attrMap = { | |
'for': 'htmlFor', | |
'class': 'className', | |
'html': 'innerHTML' | |
}, | |
callbackTypes = ['ID','CLASS','NAME','ATTR'], | |
exprCallback = { | |
ID: function(match, node) { | |
node.id = selectorPrefix + match[1]; | |
}, | |
CLASS: function(match, node) { | |
var cls = node.className.replace(/^\s+$/,''); | |
node.className = cls ? cls + ' ' + selectorPrefix + match[1] : selectorPrefix + match[1]; | |
}, | |
NAME: function(match, node) { | |
node.name = match[1]; | |
}, | |
ATTR: function(match, node) { | |
var attr = match[1], | |
val = match[4] || true; | |
if ( val === true || attr === 'innerHTML' || attrMap.hasOwnProperty(attr) ) { | |
node[attrMap[attr] || attr] = val; | |
} else { | |
node.setAttribute( attr, val ); | |
} | |
} | |
}, | |
selectorPrefix = ''; | |
function create(part, n) { | |
var tag = exprRegex.TAG.exec(part), | |
node = doc.createElement( tag && tag[1] !== '*' ? tag[1] : 'div' ), | |
fragment = doc.createDocumentFragment(), | |
c = callbackTypes.length, | |
match, regex, callback; | |
while (c--) { | |
regex = exprRegex[callbackTypes[c]]; | |
callback = exprCallback[callbackTypes[c]]; | |
if (regex.global) { | |
while ( (match = regex.exec(part)) !== null ) { | |
callback( match, node ); | |
} | |
continue; | |
} | |
if (match = regex.exec(part)) { | |
callback( match, node ); | |
} | |
} | |
while (n--) { | |
fragment.appendChild( node.cloneNode(true) ); | |
} | |
return fragment; | |
} | |
function multiAppend(parents, children) { | |
parents = parents.childNodes; | |
var i = parents.length, | |
parent; | |
while ( i-- ) { | |
parent = parents[i]; | |
if (parent.nodeName.toLowerCase() === 'table') { | |
/* IE requires table to have tbody */ | |
parent.appendChild(parent = doc.createElement('tbody')); | |
} | |
parent.appendChild(children.cloneNode(true)); | |
} | |
} | |
function satisfy(selector, prefix) { | |
if (selector in cache) { | |
return cache[selector].cloneNode(true).childNodes; | |
} | |
if( !__.isUndefined(prefix) ){ | |
selectorPrefix = prefix; | |
}else{ | |
selectorPrefix = ''; | |
} | |
var selectorParts = [], | |
fragment = doc.createDocumentFragment(), | |
children, | |
prevChildren, | |
curSelector, | |
nClones = 1, | |
nParts = 0, | |
isSibling = false, | |
cloneMatch, | |
m; | |
while ( (m = chunker.exec(selector)) !== null ) { | |
++nParts; | |
selectorParts.push(m[1]); | |
} | |
// We're going in reverse | |
while (nParts--) { | |
curSelector = selectorParts[nParts]; | |
if (exprRegex.COMBINATOR.test(curSelector)) { | |
isSibling = curSelector === '~' || curSelector === '+'; | |
continue; | |
} | |
// Number of clones must be an int >= 1 | |
nClones = (cloneMatch = curSelector.match(exprRegex.CLONE)) ? ~~cloneMatch[1] : 1; | |
prevChildren = children; | |
children = create(curSelector, nClones); | |
if (prevChildren) { | |
if (isSibling) { | |
children.appendChild(prevChildren); | |
isSibling = false; | |
} else { | |
multiAppend(children, prevChildren); | |
} | |
} | |
} | |
fragment.appendChild(children); | |
cache[selector] = fragment.cloneNode(true); | |
return fragment.childNodes; | |
} | |
satisfy.cache = cache; | |
return satisfy; | |
}); | |
(function(window) { | |
'use strict'; | |
var Locales = { | |
en: { | |
'%QUALITY%': 'Quality', | |
'%ON%': 'ON', | |
'%OFF%': 'OFF', | |
'%AUTO_QUALITY%': 'Auto', | |
'%ADVERTISEMENT_TITLE%': 'Advertisement: Your video will resume shortly', | |
'%SKIP_AD%': 'Skip Ad >>', | |
'%SKIP_TIMER%': 'You can skip this video in % second(s)', | |
'%HOTSPOTS%': 'Hotspots', | |
'%CONTROL_PLAYBACK%': 'Control the playback speed', | |
'%SLOWMOTION%': 'Speed', | |
'%SLOWMOTIONNORMAL%': 'Normal', | |
'%HOTSPOTS_HOT_NOT%': "See what's hot and what's not", | |
'%NOT_AVAILABLE%': 'Video is not available at the moment.', | |
'%ERROR_OCCURED%': 'An error occured, please try again later or <a href="javascript:window.location.reload()">reload</a> the page.', | |
}, | |
ru: { | |
'%QUALITY%': 'КачеÑтво', | |
'%ON%': 'Вкл', | |
'%OFF%': 'Выкл', | |
'%AUTO_QUALITY%': 'Ðвто', | |
'%ADVERTISEMENT_TITLE%': 'Реклама: Ваше видео продолжитÑÑ ÑовÑем Ñкоро', | |
'%SKIP_AD%': 'ПропуÑтить рекламу >>', | |
'%SKIP_TIMER%': 'Ð’Ñ‹ можете пропуÑтить Ñто видео через % Ñекунд', | |
'%HOTSPOTS%': 'ГорÑчее', | |
'%CONTROL_PLAYBACK%': 'Управление ÑкороÑтью воÑпроизведениÑ', | |
'%SLOWMOTION%': 'СкороÑть', | |
'%HOTSPOTS_HOT_NOT%': "Узнай, что Ñтоит Ñмотреть", | |
'%NOT_AVAILABLE%': 'Видео недоÑтупно в данный момент.', | |
'%ERROR_OCCURED%': 'Произошла ошибка. ПожалуйÑта, попробуйте позже или <a href="javascript:window.location.reload()">перезагрузите</a> Ñтраницу.', | |
}, | |
fr: { | |
'%QUALITY%': 'Qualité', | |
'%ON%': 'ON', | |
'%OFF%': 'OFF', | |
'%AUTO_QUALITY%': 'Auto', | |
'%ADVERTISEMENT_TITLE%': 'Publicité: votre vidéo reprendra sous peu', | |
'%SKIP_AD%': 'Ignorer la publicité >>', | |
'%SKIP_TIMER%': 'Vous pouvez ignorer cette vidéo dans % secondes', | |
'%HOTSPOTS%': 'Hotspots', | |
'%CONTROL_PLAYBACK%': 'Contrôlez la vitesse de lecture', | |
'%SLOWMOTION%': 'la vitesse', | |
'%HOTSPOTS_HOT_NOT%': "Voyez ce qui est chaud et ce qui ne l'est pas", | |
'%NOT_AVAILABLE%': "La vidéo n'est pas disponible pour le moment.", | |
'%ERROR_OCCURED%': 'Une erreur est survenue, réessayez ultérieurement ou <a href="javascript:window.location.reload()">rechargez</a> la page.' | |
}, | |
tk: { | |
'%QUALITY%': 'Kalite', | |
'%ON%': 'Açık', | |
'%OFF%': 'Kapalı', | |
'%AUTO_QUALITY%': 'Otomatik', | |
'%ADVERTISEMENT_TITLE%': 'Reklam: Videonuz kısa bir süre sonra devam edecektir', | |
'%SKIP_AD%': 'Reklamları Geç >>', | |
'%SKIP_TIMER%': 'Bu videoyu % saniye sonra atlayabilirsiniz', | |
'%HOTSPOTS%': 'Popüler Noktalar', | |
'%CONTROL_PLAYBACK%': 'Çalma hızını kontrol etme', | |
'%SLOWMOTION%': 'hız', | |
'%HOTSPOTS_HOT_NOT%': 'Popüler olanlar ve olmayanlar', | |
'%NOT_AVAILABLE%': 'Video şu an oynatılamıyor.', | |
'%ERROR_OCCURED%': 'Bir hata oluştu, lütfen sonra tekrar deneyiniz ya da <a href="javascript:window.location.reload()">yeniden yükleyiniz</a> yeniden yükleyiniz.' | |
}, | |
pt: { | |
'%QUALITY%': 'Qualidade', | |
'%ON%': 'Ativada', | |
'%OFF%': 'Desativada', | |
'%AUTO_QUALITY%': 'Auto', | |
'%ADVERTISEMENT_TITLE%': 'Anúncio: seu vÃdeo será retomado em breve', | |
'%SKIP_AD%': 'Pular Anúncio >>', | |
'%SKIP_TIMER%': 'Pode ignorar este vÃdeo em % segundos', | |
'%HOTSPOTS%': 'Ponto de Acesso', | |
'%CONTROL_PLAYBACK%': 'Controle a velocidade de reprodução', | |
'%SLOWMOTION%': 'Rapidez', | |
'%HOTSPOTS_HOT_NOT%': 'Veja o que é tendência e o que não é', | |
'%NOT_AVAILABLE%': 'O vÃdeo não está disponÃvel no momento.', | |
'%ERROR_OCCURED%': 'Ocorreu um erro, tente novamente mais tarde ou <a href="javascript:window.location.reload()">recarregue</a> a página.' | |
}, | |
pl: { | |
'%QUALITY%': 'Jakość', | |
'%ON%': 'Włącz', | |
'%OFF%': 'wyłącz', | |
'%AUTO_QUALITY%': 'Auto', | |
'%ADVERTISEMENT_TITLE%': 'Reklama: Twoj film wkrótce zostanie wyświetlony', | |
'%SKIP_AD%': 'Pomiń Reklamę >>', | |
'%SKIP_TIMER%': 'Mozesz wyłączyć ten filmik za % sekund', | |
'%HOTSPOTS%': 'Hotspots', | |
'%CONTROL_PLAYBACK%': 'Kontroluj prędkość odtwarzania', | |
'%SLOWMOTION%': 'Prędkość', | |
'%HOTSPOTS_HOT_NOT%': 'Co jest hot, a co nie', | |
'%NOT_AVAILABLE%': 'Film nie jest teraz dostępny.', | |
'%ERROR_OCCURED%': 'Wystąpił błąd, spróbuj ponownie później lub <a href="javascript:window.location.reload()">załaduj stronę</a> od nowa.' | |
}, | |
nl: { | |
'%QUALITY%': 'Kwaliteit', | |
'%ON%': 'Aan', | |
'%OFF%': 'Uit', | |
'%AUTO_QUALITY%': 'Auto', | |
'%ADVERTISEMENT_TITLE%': 'Advertentie: Je video zal snel hervat worden', | |
'%SKIP_AD%': 'Advertentie Overslaan >>', | |
'%SKIP_TIMER%': 'Je kunt deze video overslaan over % seconden', | |
'%HOTSPOTS%': 'Hotspots', | |
'%CONTROL_PLAYBACK%': 'Controleer de weergavesnelheid', | |
'%SLOWMOTION%': 'Snelheid', | |
'%HOTSPOTS_HOT_NOT%': "Zie wat heet is en wat niet", | |
'%NOT_AVAILABLE%': 'Video is niet beschikbaar op dit moment.', | |
'%ERROR_OCCURED%': 'Een fout deed zich voor, probeer alstublieft later opnieuw of <a href="javascript:window.location.reload()">vernieuw</a> de pagina.' | |
}, | |
jp: { | |
'%QUALITY%': '質', | |
'%ON%': 'オン', | |
'%OFF%': 'オフ', | |
'%AUTO_QUALITY%': '自動', | |
'%ADVERTISEMENT_TITLE%': '広告:ã‚ãªãŸã®ãƒ“デオãŒã¾ã‚‚ãªãå†é–‹ã•れã¾ã™', | |
'%SKIP_AD%': '広告をスã‚ップ >>', | |
'%SKIP_TIMER%': '% 秒後ã«ã“ã®ãƒ“デオをスã‚ップã§ãã¾ã™', | |
'%HOTSPOTS%': 'ホットスãƒãƒƒãƒˆã‚’', | |
'%CONTROL_PLAYBACK%': 'å†ç”Ÿé€Ÿåº¦ã‚’制御ã™ã‚‹', | |
'%SLOWMOTION%': '速度', | |
'%HOTSPOTS_HOT_NOT%': 'æœ€è¿‘ã®æµè¡Œã‚Š', | |
'%NOT_AVAILABLE%': 'ç¾åœ¨ãƒ“デオãŒåˆ©ç”¨ã§ãã¾ã›ã‚“。', | |
'%ERROR_OCCURED%': '<a href="javascript:window.location.reload()">エラーãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚後ã§ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ã«ãªã‚‹ã‹ã€ãƒšãƒ¼ã‚¸ã‚’å†èªè¾¼ã¿ã—ã¦ä¸‹ã•ã„。</a>' | |
}, | |
it: { | |
'%QUALITY%': 'Qualità ', | |
'%ON%': 'attiva', | |
'%OFF%': 'disattivata', | |
'%AUTO_QUALITY%': 'Automatico', | |
'%ADVERTISEMENT_TITLE%': 'Pubblicità : il tuo video riprenderà tra poco', | |
'%SKIP_AD%': 'Salta pubblicità >>', | |
'%SKIP_TIMER%': 'Puoi saltare questo video tra % secondi', | |
'%HOTSPOTS%': 'Hotspots', | |
'%CONTROL_PLAYBACK%': 'Controlla la velocità di riproduzione', | |
'%SLOWMOTION%': 'Velocità ', | |
'%HOTSPOTS_HOT_NOT%': 'Scopri cosa piace e cosa no', | |
'%NOT_AVAILABLE%': 'Il video in questo momento non è disponibile.', | |
'%ERROR_OCCURED%': 'Si è verificato un errore, riprova più tardi oppure <a href="javascript:window.location.reload()">ricarica</a> la pagina.' | |
}, | |
de: { | |
'%QUALITY%': 'Qualität', | |
'%ON%': 'An', | |
'%OFF%': 'Aus', | |
'%AUTO_QUALITY%': 'Auto', | |
'%ADVERTISEMENT_TITLE%': 'Werbung: Dein Video wird gleich fortgesetzt', | |
'%SKIP_AD%': 'Werbung übergehen >>', | |
'%SKIP_TIMER%': 'Du kannst dieses Video in % Sekunden überspringen', | |
'%HOTSPOTS%': 'Hotspots', | |
'%CONTROL_PLAYBACK%': 'Steuern Sie die Wiedergabegeschwindigkeit', | |
'%SLOWMOTION%': 'Geschwindigkeit', | |
'%HOTSPOTS_HOT_NOT%': 'Sieh dir an was in ist und was nicht', | |
'%NOT_AVAILABLE%': 'Video ist derzeit nicht verfügbar.', | |
'%ERROR_OCCURED%': 'Ein Fehler ist aufgetreten. Bitte versuche es später oder <a href="javascript:window.location.reload()">lade die</a> Seite erneut.' | |
}, | |
es: { | |
'%QUALITY%': 'Calidad', | |
'%ON%': 'Encendido', | |
'%OFF%': 'Apagado', | |
'%AUTO_QUALITY%': 'Auto', | |
'%ADVERTISEMENT_TITLE%': 'Publicidad: su video continuará en unos instantes.', | |
'%SKIP_AD%': 'Saltar publicidad >>', | |
'%SKIP_TIMER%': 'Puede saltar este video en % segundos.', | |
'%HOTSPOTS%': 'Hotspots', | |
'%CONTROL_PLAYBACK%': 'Control de la velocidad de reproducción', | |
'%SLOWMOTION%': 'Velocidad', | |
'%HOTSPOTS_HOT_NOT%': 'Ver que es tendencia y que no lo es', | |
'%NOT_AVAILABLE%': 'El video no está disponible en estos momentos.', | |
'%ERROR_OCCURED%': 'Ocurrió un error, por favor intente de nuevo o <a href="javascript:window.location.reload()">recargue</a> la página.' | |
}, | |
cz: { | |
'%QUALITY%': 'Kvalita', | |
'%ON%': 'Zapnuto', | |
'%OFF%': 'Vypnuto', | |
'%AUTO_QUALITY%': 'Auto', | |
'%ADVERTISEMENT_TITLE%': 'Reklama: VaÅ¡e video bude brzy pokraÄovat', | |
'%SKIP_AD%': 'PÅ™eskoÄit reklamu >>', | |
'%SKIP_TIMER%': 'Můžete pÅ™eskoÄit video za % sekund', | |
'%HOTSPOTS%': 'Hotspoty', | |
'%CONTROL_PLAYBACK%': 'Ovládejte rychlost pÅ™ehrávánÃ', | |
'%SLOWMOTION%': 'Rychlost', | |
'%HOTSPOTS_HOT_NOT%': 'PodÃvejte se, co je žhavé a co ne', | |
'%NOT_AVAILABLE%': 'Video nenà momentálně dostupné.', | |
'%ERROR_OCCURED%': 'Objevila se chyba, zkuste to prosÃm pozdÄ›ji nebo <a href="javascript:window.location.reload()">obnovte</a> stránku.' | |
} | |
}; | |
window.MHP1138 = window.MHP1138 || {}; | |
window.MHP1138.Locales = Locales; | |
})(window); | |
/** | |
* Zest (https://github.com/chjj/zest) | |
* A css selector engine. | |
* Copyright (c) 2011-2012, Christopher Jeffrey. (MIT Licensed) | |
*/ | |
// TODO | |
// - Recognize the TR subject selector when parsing. | |
// - Pass context to scope. | |
// - Add :column pseudo-classes. | |
;(function() { | |
/** | |
* Shared | |
*/ | |
var window = this | |
, document = this.document | |
, old = this.zest; | |
/** | |
* Helpers | |
*/ | |
var compareDocumentPosition = (function() { | |
if (document.compareDocumentPosition) { | |
return function(a, b) { | |
return a.compareDocumentPosition(b); | |
}; | |
} | |
return function(a, b) { | |
var el = a.ownerDocument.getElementsByTagName('*') | |
, i = el.length; | |
while (i--) { | |
if (el[i] === a) return 2; | |
if (el[i] === b) return 4; | |
} | |
return 1; | |
}; | |
})(); | |
var order = function(a, b) { | |
return compareDocumentPosition(a, b) & 2 ? 1 : -1; | |
}; | |
var next = function(el) { | |
while ((el = el.nextSibling) | |
&& el.nodeType !== 1); | |
return el; | |
}; | |
var prev = function(el) { | |
while ((el = el.previousSibling) | |
&& el.nodeType !== 1); | |
return el; | |
}; | |
var child = function(el) { | |
if (el = el.firstChild) { | |
while (el.nodeType !== 1 | |
&& (el = el.nextSibling)); | |
} | |
return el; | |
}; | |
var lastChild = function(el) { | |
if (el = el.lastChild) { | |
while (el.nodeType !== 1 | |
&& (el = el.previousSibling)); | |
} | |
return el; | |
}; | |
var unquote = function(str) { | |
if (!str) return str; | |
var ch = str[0]; | |
return ch === '"' || ch === '\'' | |
? str.slice(1, -1) | |
: str; | |
}; | |
var indexOf = (function() { | |
if (Array.prototype.indexOf) { | |
return Array.prototype.indexOf; | |
} | |
return function(obj, item) { | |
var i = this.length; | |
while (i--) { | |
if (this[i] === item) return i; | |
} | |
return -1; | |
}; | |
})(); | |
var makeInside = function(start, end) { | |
var regex = rules.inside.source | |
.replace(/</g, start) | |
.replace(/>/g, end); | |
return new RegExp(regex); | |
}; | |
var replace = function(regex, name, val) { | |
regex = regex.source; | |
regex = regex.replace(name, val.source || val); | |
return new RegExp(regex); | |
}; | |
var truncateUrl = function(url, num) { | |
return url | |
.replace(/^(?:\w+:\/\/|\/+)/, '') | |
.replace(/(?:\/+|\/*#.*?)$/, '') | |
.split('/', num) | |
.join('/'); | |
}; | |
/** | |
* Handle `nth` Selectors | |
*/ | |
var parseNth = function(param, test) { | |
var param = param.replace(/\s+/g, '') | |
, cap; | |
if (param === 'even') { | |
param = '2n+0'; | |
} else if (param === 'odd') { | |
param = '2n+1'; | |
} else if (!~param.indexOf('n')) { | |
param = '0n' + param; | |
} | |
cap = /^([+-])?(\d+)?n([+-])?(\d+)?$/.exec(param); | |
return { | |
group: cap[1] === '-' | |
? -(cap[2] || 1) | |
: +(cap[2] || 1), | |
offset: cap[4] | |
? (cap[3] === '-' ? -cap[4] : +cap[4]) | |
: 0 | |
}; | |
}; | |
var nth = function(param, test, last) { | |
var param = parseNth(param) | |
, group = param.group | |
, offset = param.offset | |
, find = !last ? child : lastChild | |
, advance = !last ? next : prev; | |
return function(el) { | |
if (el.parentNode.nodeType !== 1) return; | |
var rel = find(el.parentNode) | |
, pos = 0; | |
while (rel) { | |
if (test(rel, el)) pos++; | |
if (rel === el) { | |
pos -= offset; | |
return group && pos | |
? !(pos % group) && (pos < 0 === group < 0) | |
: !pos; | |
} | |
rel = advance(rel); | |
} | |
}; | |
}; | |
/** | |
* Simple Selectors | |
*/ | |
var selectors = { | |
'*': (function() { | |
if (function() { | |
var el = document.createElement('div'); | |
el.appendChild(document.createComment('')); | |
return !!el.getElementsByTagName('*')[0]; | |
}()) { | |
return function(el) { | |
if (el.nodeType === 1) return true; | |
}; | |
} | |
return function() { | |
return true; | |
}; | |
})(), | |
'type': function(type) { | |
type = type.toLowerCase(); | |
return function(el) { | |
return el.nodeName.toLowerCase() === type; | |
}; | |
}, | |
'attr': function(key, op, val, i) { | |
op = operators[op]; | |
return function(el) { | |
var attr; | |
switch (key) { | |
case 'for': | |
attr = el.htmlFor; | |
break; | |
case 'class': | |
// className is '' when non-existent | |
// getAttribute('class') is null | |
attr = el.className; | |
if (attr === '' && el.getAttribute('class') == null) { | |
attr = null; | |
} | |
break; | |
case 'href': | |
attr = el.getAttribute('href', 2); | |
break; | |
case 'title': | |
// getAttribute('title') can be '' when non-existent sometimes? | |
attr = el.getAttribute('title') || null; | |
break; | |
case 'id': | |
if (el.getAttribute) { | |
attr = el.getAttribute('id'); | |
break; | |
} | |
default: | |
attr = el[key] != null | |
? el[key] | |
: el.getAttribute && el.getAttribute(key); | |
break; | |
} | |
if (attr == null) return; | |
attr = attr + ''; | |
if (i) { | |
attr = attr.toLowerCase(); | |
val = val.toLowerCase(); | |
} | |
return op(attr, val); | |
}; | |
}, | |
':first-child': function(el) { | |
return !prev(el) && el.parentNode.nodeType === 1; | |
}, | |
':last-child': function(el) { | |
return !next(el) && el.parentNode.nodeType === 1; | |
}, | |
':only-child': function(el) { | |
return !prev(el) && !next(el) | |
&& el.parentNode.nodeType === 1; | |
}, | |
':nth-child': function(param, last) { | |
return nth(param, function() { | |
return true; | |
}, last); | |
}, | |
':nth-last-child': function(param) { | |
return selectors[':nth-child'](param, true); | |
}, | |
':root': function(el) { | |
return el.ownerDocument.documentElement === el; | |
}, | |
':empty': function(el) { | |
return !el.firstChild; | |
}, | |
':not': function(sel) { | |
var test = compileGroup(sel); | |
return function(el) { | |
return !test(el); | |
}; | |
}, | |
':first-of-type': function(el) { | |
if (el.parentNode.nodeType !== 1) return; | |
var type = el.nodeName; | |
while (el = prev(el)) { | |
if (el.nodeName === type) return; | |
} | |
return true; | |
}, | |
':last-of-type': function(el) { | |
if (el.parentNode.nodeType !== 1) return; | |
var type = el.nodeName; | |
while (el = next(el)) { | |
if (el.nodeName === type) return; | |
} | |
return true; | |
}, | |
':only-of-type': function(el) { | |
return selectors[':first-of-type'](el) | |
&& selectors[':last-of-type'](el); | |
}, | |
':nth-of-type': function(param, last) { | |
return nth(param, function(rel, el) { | |
return rel.nodeName === el.nodeName; | |
}, last); | |
}, | |
':nth-last-of-type': function(param) { | |
return selectors[':nth-of-type'](param, true); | |
}, | |
':checked': function(el) { | |
return !!(el.checked || el.selected); | |
}, | |
':indeterminate': function(el) { | |
return !selectors[':checked'](el); | |
}, | |
':enabled': function(el) { | |
return !el.disabled && el.type !== 'hidden'; | |
}, | |
':disabled': function(el) { | |
return !!el.disabled; | |
}, | |
':target': function(el) { | |
return el.id === window.location.hash.substring(1); | |
}, | |
':focus': function(el) { | |
return el === el.ownerDocument.activeElement; | |
}, | |
':matches': function(sel) { | |
return compileGroup(sel); | |
}, | |
':nth-match': function(param, last) { | |
var args = param.split(/\s*,\s*/) | |
, arg = args.shift() | |
, test = compileGroup(args.join(',')); | |
return nth(arg, test, last); | |
}, | |
':nth-last-match': function(param) { | |
return selectors[':nth-match'](param, true); | |
}, | |
':links-here': function(el) { | |
return el + '' === window.location + ''; | |
}, | |
':lang': function(param) { | |
return function(el) { | |
while (el) { | |
if (el.lang) return el.lang.indexOf(param) === 0; | |
el = el.parentNode; | |
} | |
}; | |
}, | |
':dir': function(param) { | |
return function(el) { | |
while (el) { | |
if (el.dir) return el.dir === param; | |
el = el.parentNode; | |
} | |
}; | |
}, | |
':scope': function(el, con) { | |
var context = con || el.ownerDocument; | |
if (context.nodeType === 9) { | |
return el === context.documentElement; | |
} | |
return el === context; | |
}, | |
':any-link': function(el) { | |
return typeof el.href === 'string'; | |
}, | |
':local-link': function(el) { | |
if (el.nodeName) { | |
return el.href && el.host === window.location.host; | |
} | |
var param = +el + 1; | |
return function(el) { | |
if (!el.href) return; | |
var url = window.location + '' | |
, href = el + ''; | |
return truncateUrl(url, param) === truncateUrl(href, param); | |
}; | |
}, | |
':default': function(el) { | |
return !!el.defaultSelected; | |
}, | |
':valid': function(el) { | |
return el.willValidate || (el.validity && el.validity.valid); | |
}, | |
':invalid': function(el) { | |
return !selectors[':valid'](el); | |
}, | |
':in-range': function(el) { | |
return el.value > el.min && el.value <= el.max; | |
}, | |
':out-of-range': function(el) { | |
return !selectors[':in-range'](el); | |
}, | |
':required': function(el) { | |
return !!el.required; | |
}, | |
':optional': function(el) { | |
return !el.required; | |
}, | |
':read-only': function(el) { | |
if (el.readOnly) return true; | |
var attr = el.getAttribute('contenteditable') | |
, prop = el.contentEditable | |
, name = el.nodeName.toLowerCase(); | |
name = name !== 'input' && name !== 'textarea'; | |
return (name || el.disabled) && attr == null && prop !== 'true'; | |
}, | |
':read-write': function(el) { | |
return !selectors[':read-only'](el); | |
}, | |
':hover': function() { | |
throw new Error(':hover is not supported.'); | |
}, | |
':active': function() { | |
throw new Error(':active is not supported.'); | |
}, | |
':link': function() { | |
throw new Error(':link is not supported.'); | |
}, | |
':visited': function() { | |
throw new Error(':visited is not supported.'); | |
}, | |
':column': function() { | |
throw new Error(':column is not supported.'); | |
}, | |
':nth-column': function() { | |
throw new Error(':nth-column is not supported.'); | |
}, | |
':nth-last-column': function() { | |
throw new Error(':nth-last-column is not supported.'); | |
}, | |
':current': function() { | |
throw new Error(':current is not supported.'); | |
}, | |
':past': function() { | |
throw new Error(':past is not supported.'); | |
}, | |
':future': function() { | |
throw new Error(':future is not supported.'); | |
}, | |
// Non-standard, for compatibility purposes. | |
':contains': function(param) { | |
return function(el) { | |
var text = el.innerText || el.textContent || el.value || ''; | |
return !!~text.indexOf(param); | |
}; | |
}, | |
':has': function(param) { | |
return function(el) { | |
return zest(param, el).length > 0; | |
}; | |
} | |
// Potentially add more pseudo selectors for | |
// compatibility with sizzle and most other | |
// selector engines (?). | |
}; | |
/** | |
* Attribute Operators | |
*/ | |
var operators = { | |
'-': function() { | |
return true; | |
}, | |
'=': function(attr, val) { | |
return attr === val; | |
}, | |
'*=': function(attr, val) { | |
return attr.indexOf(val) !== -1; | |
}, | |
'~=': function(attr, val) { | |
var i = attr.indexOf(val) | |
, f | |
, l; | |
if (i === -1) return; | |
f = attr[i - 1]; | |
l = attr[i + val.length]; | |
return (!f || f === ' ') && (!l || l === ' '); | |
}, | |
'|=': function(attr, val) { | |
var i = attr.indexOf(val) | |
, l; | |
if (i !== 0) return; | |
l = attr[i + val.length]; | |
return l === '-' || !l; | |
}, | |
'^=': function(attr, val) { | |
return attr.indexOf(val) === 0; | |
}, | |
'$=': function(attr, val) { | |
return attr.indexOf(val) + val.length === attr.length; | |
}, | |
// non-standard | |
'!=': function(attr, val) { | |
return attr !== val; | |
} | |
}; | |
/** | |
* Combinator Logic | |
*/ | |
var combinators = { | |
' ': function(test) { | |
return function(el) { | |
while (el = el.parentNode) { | |
if (test(el)) return el; | |
} | |
}; | |
}, | |
'>': function(test) { | |
return function(el) { | |
return test(el = el.parentNode) && el; | |
}; | |
}, | |
'+': function(test) { | |
return function(el) { | |
return test(el = prev(el)) && el; | |
}; | |
}, | |
'~': function(test) { | |
return function(el) { | |
while (el = prev(el)) { | |
if (test(el)) return el; | |
} | |
}; | |
}, | |
'noop': function(test) { | |
return function(el) { | |
return test(el) && el; | |
}; | |
}, | |
'ref': function(test, name) { | |
var node; | |
function ref(el) { | |
var doc = el.ownerDocument | |
, nodes = doc.getElementsByTagName('*') | |
, i = nodes.length; | |
while (i--) { | |
node = nodes[i]; | |
if (ref.test(el)) { | |
node = null; | |
return true; | |
} | |
} | |
node = null; | |
} | |
ref.combinator = function(el) { | |
if (!node || !node.getAttribute) return; | |
var attr = node.getAttribute(name) || ''; | |
if (attr[0] === '#') attr = attr.substring(1); | |
if (attr === el.id && test(node)) { | |
return node; | |
} | |
}; | |
return ref; | |
} | |
}; | |
/** | |
* Grammar | |
*/ | |
var rules = { | |
qname: /^ *([\w\-]+|\*)/, | |
simple: /^(?:([.#][\w\-]+)|pseudo|attr)/, | |
ref: /^ *\/([\w\-]+)\/ */, | |
combinator: /^(?: +([^ \w*]) +|( )+|([^ \w*]))(?! *$)/, | |
attr: /^\[([\w\-]+)(?:([^\w]?=)(inside))?\]/, | |
pseudo: /^(:[\w\-]+)(?:\((inside)\))?/, | |
inside: /(?:"(?:\\"|[^"])*"|'(?:\\'|[^'])*'|<[^"'>]*>|\\["'>]|[^"'>])*/ | |
}; | |
rules.inside = replace(rules.inside, '[^"\'>]*', rules.inside); | |
rules.attr = replace(rules.attr, 'inside', makeInside('\\[', '\\]')); | |
rules.pseudo = replace(rules.pseudo, 'inside', makeInside('\\(', '\\)')); | |
rules.simple = replace(rules.simple, 'pseudo', rules.pseudo); | |
rules.simple = replace(rules.simple, 'attr', rules.attr); | |
/** | |
* Compiling | |
*/ | |
var compile = function(sel) { | |
var sel = sel.replace(/^\s+|\s+$/g, '') | |
, test | |
, filter = [] | |
, buff = [] | |
, subject | |
, qname | |
, cap | |
, op | |
, ref; | |
while (sel) { | |
if (cap = rules.qname.exec(sel)) { | |
sel = sel.substring(cap[0].length); | |
qname = cap[1]; | |
buff.push(tok(qname, true)); | |
} else if (cap = rules.simple.exec(sel)) { | |
sel = sel.substring(cap[0].length); | |
qname = '*'; | |
buff.push(tok(qname, true)); | |
buff.push(tok(cap)); | |
} else { | |
throw new Error('Invalid selector.'); | |
} | |
while (cap = rules.simple.exec(sel)) { | |
sel = sel.substring(cap[0].length); | |
buff.push(tok(cap)); | |
} | |
if (sel[0] === '!') { | |
sel = sel.substring(1); | |
subject = makeSubject(); | |
subject.qname = qname; | |
buff.push(subject.simple); | |
} | |
if (cap = rules.ref.exec(sel)) { | |
sel = sel.substring(cap[0].length); | |
ref = combinators.ref(makeSimple(buff), cap[1]); | |
filter.push(ref.combinator); | |
buff = []; | |
continue; | |
} | |
if (cap = rules.combinator.exec(sel)) { | |
sel = sel.substring(cap[0].length); | |
op = cap[1] || cap[2] || cap[3]; | |
if (op === ',') { | |
filter.push(combinators.noop(makeSimple(buff))); | |
break; | |
} | |
} else { | |
op = 'noop'; | |
} | |
filter.push(combinators[op](makeSimple(buff))); | |
buff = []; | |
} | |
test = makeTest(filter); | |
test.qname = qname; | |
test.sel = sel; | |
if (subject) { | |
subject.lname = test.qname; | |
subject.test = test; | |
subject.qname = subject.qname; | |
subject.sel = test.sel; | |
test = subject; | |
} | |
if (ref) { | |
ref.test = test; | |
ref.qname = test.qname; | |
ref.sel = test.sel; | |
test = ref; | |
} | |
return test; | |
}; | |
var tok = function(cap, qname) { | |
// qname | |
if (qname) { | |
return cap === '*' | |
? selectors['*'] | |
: selectors.type(cap); | |
} | |
// class/id | |
if (cap[1]) { | |
return cap[1][0] === '.' | |
? selectors.attr('class', '~=', cap[1].substring(1)) | |
: selectors.attr('id', '=', cap[1].substring(1)); | |
} | |
// pseudo-name | |
// inside-pseudo | |
if (cap[2]) { | |
return cap[3] | |
? selectors[cap[2]](unquote(cap[3])) | |
: selectors[cap[2]]; | |
} | |
// attr name | |
// attr op | |
// attr value | |
if (cap[4]) { | |
var i; | |
if (cap[6]) { | |
i = cap[6].length; | |
cap[6] = cap[6].replace(/ +i$/, ''); | |
i = i > cap[6].length; | |
} | |
return selectors.attr(cap[4], cap[5] || '-', unquote(cap[6]), i); | |
} | |
throw new Error('Unknown Selector.'); | |
}; | |
var makeSimple = function(func) { | |
var l = func.length | |
, i; | |
// Potentially make sure | |
// `el` is truthy. | |
if (l < 2) return func[0]; | |
return function(el) { | |
if (!el) return; | |
for (i = 0; i < l; i++) { | |
if (!func[i](el)) return; | |
} | |
return true; | |
}; | |
}; | |
var makeTest = function(func) { | |
if (func.length < 2) { | |
return function(el) { | |
return !!func[0](el); | |
}; | |
} | |
return function(el) { | |
var i = func.length; | |
while (i--) { | |
if (!(el = func[i](el))) return; | |
} | |
return true; | |
}; | |
}; | |
var makeSubject = function() { | |
var target; | |
function subject(el) { | |
var node = el.ownerDocument | |
, scope = node.getElementsByTagName(subject.lname) | |
, i = scope.length; | |
while (i--) { | |
if (subject.test(scope[i]) && target === el) { | |
target = null; | |
return true; | |
} | |
} | |
target = null; | |
} | |
subject.simple = function(el) { | |
target = el; | |
return true; | |
}; | |
return subject; | |
}; | |
var compileGroup = function(sel) { | |
var test = compile(sel) | |
, tests = [ test ]; | |
while (test.sel) { | |
test = compile(test.sel); | |
tests.push(test); | |
} | |
if (tests.length < 2) return test; | |
return function(el) { | |
var l = tests.length | |
, i = 0; | |
for (; i < l; i++) { | |
if (tests[i](el)) return true; | |
} | |
}; | |
}; | |
/** | |
* Selection | |
*/ | |
var find = function(sel, node) { | |
var results = [] | |
, test = compile(sel) | |
, scope = node.getElementsByTagName(test.qname) | |
, i = 0 | |
, el; | |
while (el = scope[i++]) { | |
if (test(el)) results.push(el); | |
} | |
if (test.sel) { | |
while (test.sel) { | |
test = compile(test.sel); | |
scope = node.getElementsByTagName(test.qname); | |
i = 0; | |
while (el = scope[i++]) { | |
if (test(el) && !~indexOf.call(results, el)) { | |
results.push(el); | |
} | |
} | |
} | |
results.sort(order); | |
} | |
return results; | |
}; | |
/** | |
* Native | |
*/ | |
var select = (function() { | |
var slice = (function() { | |
try { | |
Array.prototype.slice.call(document.getElementsByTagName('zest')); | |
return Array.prototype.slice; | |
} catch(e) { | |
e = null; | |
return function() { | |
var a = [], i = 0, l = this.length; | |
for (; i < l; i++) a.push(this[i]); | |
return a; | |
}; | |
} | |
})(); | |
if (document.querySelectorAll) { | |
return function(sel, node) { | |
try { | |
return slice.call(node.querySelectorAll(sel)); | |
} catch(e) { | |
return find(sel, node); | |
} | |
}; | |
} | |
return function(sel, node) { | |
try { | |
if (sel[0] === '#' && /^#[\w\-]+$/.test(sel)) { | |
return [node.getElementById(sel.substring(1))]; | |
} | |
if (sel[0] === '.' && /^\.[\w\-]+$/.test(sel)) { | |
sel = node.getElementsByClassName(sel.substring(1)); | |
return slice.call(sel); | |
} | |
if (/^[\w\-]+$/.test(sel)) { | |
return slice.call(node.getElementsByTagName(sel)); | |
} | |
} catch(e) { | |
; | |
} | |
return find(sel, node); | |
}; | |
})(); | |
/** | |
* Zest | |
*/ | |
var zest = function(sel, node) { | |
try { | |
sel = select(sel, node || document); | |
} catch(e) { | |
if (window.ZEST_DEBUG) { | |
console.log(e.stack || e + ''); | |
} | |
sel = []; | |
} | |
return sel; | |
}; | |
/** | |
* Expose | |
*/ | |
zest.selectors = selectors; | |
zest.operators = operators; | |
zest.combinators = combinators; | |
zest.compile = compileGroup; | |
zest.matches = function(el, sel) { | |
return !!compileGroup(sel)(el); | |
}; | |
zest.cache = function() { | |
if (compile.raw) return; | |
var raw = compile | |
, cache = {}; | |
compile = function(sel) { | |
return cache[sel] | |
|| (cache[sel] = raw(sel)); | |
}; | |
compile.raw = raw; | |
zest._cache = cache; | |
}; | |
zest.noCache = function() { | |
if (!compile.raw) return; | |
compile = compile.raw; | |
delete zest._cache; | |
}; | |
zest.noConflict = function() { | |
window.zest = old; | |
return zest; | |
}; | |
zest.noNative = function() { | |
select = find; | |
}; | |
if (typeof module !== 'undefined') { | |
module.exports = zest; | |
} else { | |
this.zest = zest; | |
} | |
if (window.ZEST_DEBUG) { | |
zest.noNative(); | |
} else { | |
zest.cache(); | |
} | |
}).call(function() { | |
return this || (typeof window !== 'undefined' ? window : global); | |
}()); | |
(function(window) { | |
'use strict'; | |
var markup = { | |
controlBar: { | |
time_elapsed: 'span[html=00:00]', | |
seekBar: { | |
background: null, | |
progress: { | |
handle : '.center' | |
} | |
}, | |
time_total: '[html=00:00]', | |
fullscreen: '.fullscreenOff.icon.icon-expand + .fullscreenOn.icon.icon-reduce', | |
cardboard: '.cardboardOff.icon.icon-vr-clear + .cardboardOn.icon.icon-vr', | |
}, | |
thumbnails: { | |
sprite: null | |
}, | |
preRollTitle: '[html=%ADVERTISEMENT_TITLE%]', | |
preRollSkipButton: { | |
content: null | |
}, | |
eventCatcher: null, | |
controls: 'button.play i.icon.icon-play-clear + button.pause i.icon.icon-pause-clear + button.replay i.icon.icon-reload', | |
options: { | |
qualityBtn: 'i.icon.icon-gear-clear', | |
chromecastBtn: 'i.icon.icon-chromecast' | |
}, | |
optionsMenu: { | |
menuTabs: 'span.menuTitle.menuTitleQuality.active[data-tab=Quality][html=%QUALITY%] + span.menuTitle.menuTitleSpeed[data-tab=Speed][html=%SLOWMOTION%]', | |
menuPages: '.qualityList.menuPage.menuPageQuality.active + .motionRates.menuPage.menuPageSpeed > .optionsItem.optionsText[html=%CONTROL_PLAYBACK%]', | |
}, | |
loader: 'svg.circular[viewBox=25 25 50 50] circle.path[cx=50][cy=50][r=20][fill=none][stroke-width=2][stroke-miterlimit=10]', | |
topBar: { | |
content: { | |
logo: 'img.logoImg', | |
title: 'span' | |
} | |
}, | |
/*thumbnailsHolder: { | |
box: { | |
sprite: 'img.image', | |
selectedTime: 'span[html=00:00] + .background' | |
}, | |
arrow: null | |
},*/ | |
videoErrorMessage: { | |
centered: '.span.icon.icon-error + p' | |
}, | |
videoPoster: null | |
}; | |
window.MHP1138 = window.MHP1138 || {}; | |
window.MHP1138.markup = markup; | |
})(window); | |
(function() {'use strict';if(!window.PresentationRequest)return;var e,aa=function(a,b){function c(){}c.prototype=b.prototype;a.prototype=new c;a.prototype.constructor=a;for(var d in b)if(Object.defineProperties){var f=Object.getOwnPropertyDescriptor(b,d);f&&Object.defineProperty(a,d,f)}else a[d]=b[d]},ba="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(c.get||c.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[b]=c.value)},g="undefined"!=typeof window&& | |
window===this?this:"undefined"!=typeof global&&null!=global?global:this,ca=function(){ca=function(){};g.Symbol||(g.Symbol=da)},ea=0,da=function(a){return"jscomp_symbol_"+(a||"")+ea++},l=function(){ca();var a=g.Symbol.iterator;a||(a=g.Symbol.iterator=g.Symbol("iterator"));"function"!=typeof Array.prototype[a]&&ba(Array.prototype,a,{configurable:!0,writable:!0,value:function(){return fa(this)}});l=function(){}},fa=function(a){var b=0;return ga(function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}})}, | |
ga=function(a){l();a={next:a};a[g.Symbol.iterator]=function(){return this};return a},n=this,p=function(a,b,c){a=a.split(".");c=c||n;a[0]in c||!c.execScript||c.execScript("var "+a[0]);for(var d;a.length&&(d=a.shift());)a.length||void 0===b?c=c[d]?c[d]:c[d]={}:c[d]=b},ia=function(){},q=function(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"== | |
c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";else if("function"==b&&"undefined"==typeof a.call)return"object";return b},r=function(a){var b=q(a);return"array"==b||"object"==b&&"number"==typeof a.length},t=function(a){return"string"== | |
typeof a},ja="closure_uid_"+(1E9*Math.random()>>>0),ka=0,la=function(a,b,c){return a.call.apply(a.bind,arguments)},ma=function(a,b,c){if(!a)throw Error();if(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,d);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}},u=function(a,b,c){u=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?la:ma; | |
return u.apply(null,arguments)},na=function(a,b){function c(){}c.prototype=b.prototype;a.ge=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.ce=function(a,c,h){for(var d=Array(arguments.length-2),f=2;f<arguments.length;f++)d[f-2]=arguments[f];return b.prototype[c].apply(a,d)}};var chrome=chrome||window.chrome||{};chrome.cast=chrome.cast||{};chrome.cast.media=chrome.cast.media||{};chrome.cast.VERSION=[1,2];p("chrome.cast.VERSION",chrome.cast.VERSION,void 0);chrome.cast.ae=!0;p("chrome.cast.usingPresentationApi",chrome.cast.ae,void 0);chrome.cast.Error=function(a,b,c){this.code=a;this.description=b||null;this.details=c||null};p("chrome.cast.Error",chrome.cast.Error,void 0);chrome.cast.uc=function(a){this.platform=a;this.packageId=this.url=null};p("chrome.cast.SenderApplication",chrome.cast.uc,void 0);chrome.cast.Image=function(a){this.url=a;this.width=this.height=null}; | |
p("chrome.cast.Image",chrome.cast.Image,void 0);chrome.cast.Volume=function(a,b){this.level=void 0!==a?a:null;this.muted=void 0!==b?b:null};p("chrome.cast.Volume",chrome.cast.Volume,void 0);var oa=String.prototype.trim?function(a){return a.trim()}:function(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")},pa=/&/g,qa=/</g,ra=/>/g,sa=/"/g,ta=/'/g,ua=/\x00/g,va=/[\x00&<>"']/,xa=function(a,b){var c={"&":"&","<":"<",">":">",""":'"'},d;d=b?b.createElement("div"):n.document.createElement("div");return a.replace(wa,function(a,b){var f=c[a];if(f)return f;"#"==b.charAt(0)&&(b=Number("0"+b.substr(1)),isNaN(b)||(f=String.fromCharCode(b)));f||(d.innerHTML=a+" ",f=d.firstChild.nodeValue.slice(0, | |
-1));return c[a]=f})},ya=function(a){return a.replace(/&([^;]+);/g,function(a,c){switch(c){case "amp":return"&";case "lt":return"<";case "gt":return">";case "quot":return'"';default:return"#"!=c.charAt(0)||(c=Number("0"+c.substr(1)),isNaN(c))?a:String.fromCharCode(c)}})},wa=/&([^;\s<&]+);?/g,w=function(a,b){return a<b?-1:a>b?1:0};chrome.cast.bb={CUSTOM_CONTROLLER_SCOPED:"custom_controller_scoped",TAB_AND_ORIGIN_SCOPED:"tab_and_origin_scoped",ORIGIN_SCOPED:"origin_scoped",PAGE_SCOPED:"page_scoped"};p("chrome.cast.AutoJoinPolicy",chrome.cast.bb,void 0);chrome.cast.cb={CREATE_SESSION:"create_session",CAST_THIS_TAB:"cast_this_tab"};p("chrome.cast.DefaultActionPolicy",chrome.cast.cb,void 0);chrome.cast.Ca={VIDEO_OUT:"video_out",AUDIO_OUT:"audio_out",VIDEO_IN:"video_in",AUDIO_IN:"audio_in",MULTIZONE_GROUP:"multizone_group"}; | |
p("chrome.cast.Capability",chrome.cast.Ca,void 0);chrome.cast.u={CANCEL:"cancel",TIMEOUT:"timeout",API_NOT_INITIALIZED:"api_not_initialized",INVALID_PARAMETER:"invalid_parameter",EXTENSION_NOT_COMPATIBLE:"extension_not_compatible",EXTENSION_MISSING:"extension_missing",RECEIVER_UNAVAILABLE:"receiver_unavailable",SESSION_ERROR:"session_error",CHANNEL_ERROR:"channel_error",LOAD_MEDIA_FAILED:"load_media_failed"};p("chrome.cast.ErrorCode",chrome.cast.u,void 0);chrome.cast.ha={AVAILABLE:"available",UNAVAILABLE:"unavailable"}; | |
p("chrome.cast.ReceiverAvailability",chrome.cast.ha,void 0);chrome.cast.vc={CHROME:"chrome",IOS:"ios",ANDROID:"android"};p("chrome.cast.SenderPlatform",chrome.cast.vc,void 0);chrome.cast.mb={CAST:"cast",DIAL:"dial",HANGOUT:"hangout",CUSTOM:"custom"};p("chrome.cast.ReceiverType",chrome.cast.mb,void 0);chrome.cast.Zb={RUNNING:"running",STOPPED:"stopped",ERROR:"error"};p("chrome.cast.DialAppState",chrome.cast.Zb,void 0);chrome.cast.qc={CAST:"cast",STOP:"stop"}; | |
p("chrome.cast.ReceiverAction",chrome.cast.qc,void 0);chrome.cast.U={CONNECTED:"connected",DISCONNECTED:"disconnected",STOPPED:"stopped"};p("chrome.cast.SessionStatus",chrome.cast.U,void 0);chrome.cast.Xb=function(a,b,c,d,f){this.sessionRequest=a;this.sessionListener=b;this.receiverListener=c;this.autoJoinPolicy=d||chrome.cast.bb.TAB_AND_ORIGIN_SCOPED;this.defaultActionPolicy=f||chrome.cast.cb.CREATE_SESSION;this.customDialLaunchCallback=null;this.invisibleSender=!1;this.additionalSessionRequests=[]};p("chrome.cast.ApiConfig",chrome.cast.Xb,void 0);chrome.cast.bc=function(a,b){this.appName=a;this.launchParameter=b||null};p("chrome.cast.DialRequest",chrome.cast.bc,void 0); | |
chrome.cast.$b=function(a,b,c){this.receiver=a;this.appState=b;this.extraData=c||null};p("chrome.cast.DialLaunchData",chrome.cast.$b,void 0);chrome.cast.ac=function(a,b){this.doLaunch=a;this.launchParameter=b||null};p("chrome.cast.DialLaunchResponse",chrome.cast.ac,void 0);chrome.cast.wc=function(a,b,c){this.appId=a;this.capabilities="array"==q(b)?b:[chrome.cast.Ca.VIDEO_OUT,chrome.cast.Ca.AUDIO_OUT];this.requestSessionTimeout=c||chrome.cast.timeout.requestSession;this.dialRequest=this.language=null}; | |
p("chrome.cast.SessionRequest",chrome.cast.wc,void 0); | |
chrome.cast.pc=function(a,b,c,d){this.label=a;a=b;va.test(a)&&(-1!=a.indexOf("&")&&(a=a.replace(pa,"&")),-1!=a.indexOf("<")&&(a=a.replace(qa,"<")),-1!=a.indexOf(">")&&(a=a.replace(ra,">")),-1!=a.indexOf('"')&&(a=a.replace(sa,""")),-1!=a.indexOf("'")&&(a=a.replace(ta,"'")),-1!=a.indexOf("\x00")&&(a=a.replace(ua,"�")));this.friendlyName=a;this.capabilities=c||[];this.volume=d||null;this.receiverType=chrome.cast.mb.CAST;this.displayStatus=this.isActiveInput=null}; | |
p("chrome.cast.Receiver",chrome.cast.pc,void 0);chrome.cast.rc=function(a,b){this.statusText=a;this.appImages=b;this.showStop=null};p("chrome.cast.ReceiverDisplayStatus",chrome.cast.rc,void 0);chrome.cast.pb=function(){this.requestSession=6E4;this.sendCustomMessage=this.setReceiverVolume=this.stopSession=this.leaveSession=3E3};p("chrome.cast.Timeout",chrome.cast.pb,void 0);chrome.cast.timeout=new chrome.cast.pb;p("chrome.cast.timeout",chrome.cast.timeout,void 0);chrome.cast.Wb="auto-join"; | |
chrome.cast.kc="cast-session_";chrome.cast.media.gc={PAUSE:"pause",SEEK:"seek",STREAM_VOLUME:"stream_volume",STREAM_MUTE:"stream_mute"};p("chrome.cast.media.MediaCommand",chrome.cast.media.gc,void 0);chrome.cast.media.s={GENERIC:0,MOVIE:1,TV_SHOW:2,MUSIC_TRACK:3,PHOTO:4};p("chrome.cast.media.MetadataType",chrome.cast.media.s,void 0);chrome.cast.media.T={IDLE:"IDLE",PLAYING:"PLAYING",PAUSED:"PAUSED",BUFFERING:"BUFFERING"};p("chrome.cast.media.PlayerState",chrome.cast.media.T,void 0); | |
chrome.cast.media.Da={OFF:"REPEAT_OFF",ALL:"REPEAT_ALL",SINGLE:"REPEAT_SINGLE",ALL_AND_SHUFFLE:"REPEAT_ALL_AND_SHUFFLE"};p("chrome.cast.media.RepeatMode",chrome.cast.media.Da,void 0);chrome.cast.media.sc={PLAYBACK_START:"PLAYBACK_START",PLAYBACK_PAUSE:"PLAYBACK_PAUSE"};p("chrome.cast.media.ResumeState",chrome.cast.media.sc,void 0);chrome.cast.media.ob={BUFFERED:"BUFFERED",LIVE:"LIVE",OTHER:"OTHER"};p("chrome.cast.media.StreamType",chrome.cast.media.ob,void 0); | |
chrome.cast.media.ec={CANCELLED:"CANCELLED",INTERRUPTED:"INTERRUPTED",FINISHED:"FINISHED",ERROR:"ERROR"};p("chrome.cast.media.IdleReason",chrome.cast.media.ec,void 0);chrome.cast.media.Ec={TEXT:"TEXT",AUDIO:"AUDIO",VIDEO:"VIDEO"};p("chrome.cast.media.TrackType",chrome.cast.media.Ec,void 0);chrome.cast.media.Bc={SUBTITLES:"SUBTITLES",CAPTIONS:"CAPTIONS",DESCRIPTIONS:"DESCRIPTIONS",CHAPTERS:"CHAPTERS",METADATA:"METADATA"};p("chrome.cast.media.TextTrackType",chrome.cast.media.Bc,void 0); | |
chrome.cast.media.xc={NONE:"NONE",OUTLINE:"OUTLINE",DROP_SHADOW:"DROP_SHADOW",RAISED:"RAISED",DEPRESSED:"DEPRESSED"};p("chrome.cast.media.TextTrackEdgeType",chrome.cast.media.xc,void 0);chrome.cast.media.Cc={NONE:"NONE",NORMAL:"NORMAL",ROUNDED_CORNERS:"ROUNDED_CORNERS"};p("chrome.cast.media.TextTrackWindowType",chrome.cast.media.Cc,void 0); | |
chrome.cast.media.yc={SANS_SERIF:"SANS_SERIF",MONOSPACED_SANS_SERIF:"MONOSPACED_SANS_SERIF",SERIF:"SERIF",MONOSPACED_SERIF:"MONOSPACED_SERIF",CASUAL:"CASUAL",CURSIVE:"CURSIVE",SMALL_CAPITALS:"SMALL_CAPITALS"};p("chrome.cast.media.TextTrackFontGenericFamily",chrome.cast.media.yc,void 0);chrome.cast.media.zc={NORMAL:"NORMAL",BOLD:"BOLD",BOLD_ITALIC:"BOLD_ITALIC",ITALIC:"ITALIC"};p("chrome.cast.media.TextTrackFontStyle",chrome.cast.media.zc,void 0);chrome.cast.media.eb=function(){this.customData=null};p("chrome.cast.media.GetStatusRequest",chrome.cast.media.eb,void 0);chrome.cast.media.fb=function(){this.customData=null};p("chrome.cast.media.PauseRequest",chrome.cast.media.fb,void 0);chrome.cast.media.gb=function(){this.customData=null};p("chrome.cast.media.PlayRequest",chrome.cast.media.gb,void 0);chrome.cast.media.tc=function(){this.customData=this.resumeState=this.currentTime=null};p("chrome.cast.media.SeekRequest",chrome.cast.media.tc,void 0); | |
chrome.cast.media.nb=function(){this.customData=null};p("chrome.cast.media.StopRequest",chrome.cast.media.nb,void 0);chrome.cast.media.Gc=function(a){this.volume=a;this.customData=null};p("chrome.cast.media.VolumeRequest",chrome.cast.media.Gc,void 0);chrome.cast.media.fc=function(a){this.type="LOAD";this.requestId=0;this.sessionId=null;this.media=a;this.activeTrackIds=null;this.autoplay=!0;this.customData=this.currentTime=null};p("chrome.cast.media.LoadRequest",chrome.cast.media.fc,void 0); | |
chrome.cast.media.mc=function(a){this.type="PRECACHE";this.requestId=0;this.data=a};chrome.cast.media.cc=function(a,b){this.requestId=0;this.activeTrackIds=a||null;this.textTrackStyle=b||null};p("chrome.cast.media.EditTracksInfoRequest",chrome.cast.media.cc,void 0);chrome.cast.media.dc=function(){this.metadataType=this.type=chrome.cast.media.s.GENERIC;this.releaseDate=this.releaseYear=this.images=this.subtitle=this.title=null};p("chrome.cast.media.GenericMediaMetadata",chrome.cast.media.dc,void 0); | |
chrome.cast.media.ic=function(){this.metadataType=this.type=chrome.cast.media.s.MOVIE;this.releaseDate=this.releaseYear=this.images=this.subtitle=this.studio=this.title=null};p("chrome.cast.media.MovieMediaMetadata",chrome.cast.media.ic,void 0);chrome.cast.media.Fc=function(){this.metadataType=this.type=chrome.cast.media.s.TV_SHOW;this.originalAirdate=this.releaseYear=this.images=this.episode=this.episodeNumber=this.season=this.seasonNumber=this.episodeTitle=this.title=this.seriesTitle=null}; | |
p("chrome.cast.media.TvShowMediaMetadata",chrome.cast.media.Fc,void 0);chrome.cast.media.jc=function(){this.metadataType=this.type=chrome.cast.media.s.MUSIC_TRACK;this.releaseDate=this.releaseYear=this.images=this.discNumber=this.trackNumber=this.artistName=this.songName=this.composer=this.artist=this.albumArtist=this.title=this.albumName=null};p("chrome.cast.media.MusicTrackMediaMetadata",chrome.cast.media.jc,void 0); | |
chrome.cast.media.lc=function(){this.metadataType=this.type=chrome.cast.media.s.PHOTO;this.creationDateTime=this.height=this.width=this.longitude=this.latitude=this.images=this.location=this.artist=this.title=null};p("chrome.cast.media.PhotoMediaMetadata",chrome.cast.media.lc,void 0);chrome.cast.media.hc=function(a,b){this.contentId=a;this.streamType=chrome.cast.media.ob.BUFFERED;this.contentType=b;this.customData=this.textTrackStyle=this.tracks=this.duration=this.metadata=null}; | |
p("chrome.cast.media.MediaInfo",chrome.cast.media.hc,void 0);chrome.cast.media.ib=function(a){this.itemId=null;this.media=a;this.autoplay=!0;this.startTime=0;this.playbackDuration=null;this.preloadTime=0;this.customData=this.activeTrackIds=null};p("chrome.cast.media.QueueItem",chrome.cast.media.ib,void 0);chrome.cast.media.Yb="CC1AD845";p("chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID",chrome.cast.media.Yb,void 0);chrome.cast.media.timeout={}; | |
p("chrome.cast.media.timeout",chrome.cast.media.timeout,void 0);chrome.cast.media.timeout.load=0;chrome.cast.media.timeout.load=chrome.cast.media.timeout.load;chrome.cast.media.timeout.ma=0;chrome.cast.media.timeout.getStatus=chrome.cast.media.timeout.ma;chrome.cast.media.timeout.play=0;chrome.cast.media.timeout.play=chrome.cast.media.timeout.play;chrome.cast.media.timeout.pause=0;chrome.cast.media.timeout.pause=chrome.cast.media.timeout.pause;chrome.cast.media.timeout.seek=0; | |
chrome.cast.media.timeout.seek=chrome.cast.media.timeout.seek;chrome.cast.media.timeout.stop=0;chrome.cast.media.timeout.stop=chrome.cast.media.timeout.stop;chrome.cast.media.timeout.Ba=0;chrome.cast.media.timeout.setVolume=chrome.cast.media.timeout.Ba;chrome.cast.media.timeout.ka=0;chrome.cast.media.timeout.editTracksInfo=chrome.cast.media.timeout.ka;chrome.cast.media.timeout.o=0;chrome.cast.media.timeout.queue=chrome.cast.media.timeout.o; | |
chrome.cast.media.Dc=function(a,b){this.trackId=a;this.trackContentType=this.trackContentId=null;this.type=b;this.customData=this.subtype=this.language=this.name=null};p("chrome.cast.media.Track",chrome.cast.media.Dc,void 0);chrome.cast.media.Ac=function(){this.customData=this.fontStyle=this.fontGenericFamily=this.fontFamily=this.fontScale=this.windowRoundedCornerRadius=this.windowColor=this.windowType=this.edgeColor=this.edgeType=this.backgroundColor=this.foregroundColor=null}; | |
p("chrome.cast.media.TextTrackStyle",chrome.cast.media.Ac,void 0);chrome.cast.media.nc=function(a){this.type="QUEUE_LOAD";this.sessionId=this.requestId=null;this.items=a;this.startIndex=0;this.repeatMode=chrome.cast.media.Da.OFF;this.customData=null};p("chrome.cast.media.QueueLoadRequest",chrome.cast.media.nc,void 0);chrome.cast.media.hb=function(a){this.type="QUEUE_INSERT";this.sessionId=this.requestId=null;this.items=a;this.customData=this.insertBefore=null}; | |
p("chrome.cast.media.QueueInsertItemsRequest",chrome.cast.media.hb,void 0);chrome.cast.media.oc=function(a){this.type="QUEUE_UPDATE";this.sessionId=this.requestId=null;this.items=a;this.customData=null};p("chrome.cast.media.QueueUpdateItemsRequest",chrome.cast.media.oc,void 0);chrome.cast.media.ga=function(){this.type="QUEUE_UPDATE";this.customData=this.jump=this.currentItemId=this.sessionId=this.requestId=null};p("chrome.cast.media.QueueJumpRequest",chrome.cast.media.ga,void 0); | |
chrome.cast.media.lb=function(){this.type="QUEUE_UPDATE";this.customData=this.repeatMode=this.sessionId=this.requestId=null};p("chrome.cast.media.QueueSetPropertiesRequest",chrome.cast.media.lb,void 0);chrome.cast.media.jb=function(a){this.type="QUEUE_REMOVE";this.sessionId=this.requestId=null;this.itemIds=a;this.customData=null};p("chrome.cast.media.QueueRemoveItemsRequest",chrome.cast.media.jb,void 0); | |
chrome.cast.media.kb=function(a){this.type="QUEUE_REORDER";this.sessionId=this.requestId=null;this.itemIds=a;this.customData=this.insertBefore=null};p("chrome.cast.media.QueueReorderItemsRequest",chrome.cast.media.kb,void 0);var x=Array.prototype.forEach?function(a,b,c){Array.prototype.forEach.call(a,b,c)}:function(a,b,c){for(var d=a.length,f=t(a)?a.split(""):a,h=0;h<d;h++)h in f&&b.call(c,f[h],h,a)},za=function(a,b,c){for(var d=a.length,f=t(a)?a.split(""):a,h=0;h<d;h++)if(h in f&&b.call(c,f[h],h,a))return h;return-1},Aa=function(a){return Array.prototype.concat.apply(Array.prototype,arguments)},Ba=function(a){var b=a.length;if(0<b){for(var c=Array(b),d=0;d<b;d++)c[d]=a[d];return c}return[]};chrome.cast.media.a=function(a,b){this.sessionId=a;this.mediaSessionId=b;this.media=null;this.playbackRate=1;this.playerState=chrome.cast.media.T.IDLE;this.currentTime=0;this.Pa=-1;this.supportedMediaCommands=[];this.volume=new chrome.cast.Volume;this.items=this.preloadedItemId=this.loadingItemId=this.currentItemId=this.customData=this.activeTrackIds=this.idleReason=null;this.repeatMode=chrome.cast.media.Da.OFF;this.na=!1;this.da=[]};p("chrome.cast.media.Media",chrome.cast.media.a,void 0); | |
chrome.cast.media.a.prototype.ma=function(a,b,c){a||(a=new chrome.cast.media.eb);y.i(this,"MEDIA_GET_STATUS",a,b,c,chrome.cast.media.timeout.ma)};chrome.cast.media.a.prototype.getStatus=chrome.cast.media.a.prototype.ma;chrome.cast.media.a.prototype.play=function(a,b,c){this.Gb(y,a,b,c)};chrome.cast.media.a.prototype.play=chrome.cast.media.a.prototype.play;chrome.cast.media.a.prototype.Gb=function(a,b,c,d){b||(b=new chrome.cast.media.gb);a.i(this,"PLAY",b,c,d,chrome.cast.media.timeout.play)}; | |
chrome.cast.media.a.prototype.playWithContext=chrome.cast.media.a.prototype.Gb;chrome.cast.media.a.prototype.pause=function(a,b,c){this.Fb(y,a,b,c)};chrome.cast.media.a.prototype.pause=chrome.cast.media.a.prototype.pause;chrome.cast.media.a.prototype.Fb=function(a,b,c,d){b||(b=new chrome.cast.media.fb);a.i(this,"PAUSE",b,c,d,chrome.cast.media.timeout.pause)};chrome.cast.media.a.prototype.pauseWithContext=chrome.cast.media.a.prototype.Fb; | |
chrome.cast.media.a.prototype.seek=function(a,b,c){y.i(this,"SEEK",a,b,c,chrome.cast.media.timeout.seek)};chrome.cast.media.a.prototype.seek=chrome.cast.media.a.prototype.seek;chrome.cast.media.a.prototype.stop=function(a,b,c){a||(a=new chrome.cast.media.nb);y.i(this,"STOP_MEDIA",a,b,c,chrome.cast.media.timeout.stop)};chrome.cast.media.a.prototype.stop=chrome.cast.media.a.prototype.stop;chrome.cast.media.a.prototype.Ba=function(a,b,c){y.i(this,"MEDIA_SET_VOLUME",a,b,c,chrome.cast.media.timeout.Ba)}; | |
chrome.cast.media.a.prototype.setVolume=chrome.cast.media.a.prototype.Ba;chrome.cast.media.a.prototype.ka=function(a,b,c){y.i(this,"EDIT_TRACKS_INFO",a,b,c,chrome.cast.media.timeout.ka)};chrome.cast.media.a.prototype.editTracksInfo=chrome.cast.media.a.prototype.ka;chrome.cast.media.a.prototype.Ad=function(a,b,c){y.i(this,"QUEUE_INSERT",a,b,c,chrome.cast.media.timeout.o)};chrome.cast.media.a.prototype.queueInsertItems=chrome.cast.media.a.prototype.Ad; | |
chrome.cast.media.a.prototype.zd=function(a,b,c){y.i(this,"QUEUE_INSERT",new chrome.cast.media.hb([a]),b,c,chrome.cast.media.timeout.o)};chrome.cast.media.a.prototype.queueAppendItem=chrome.cast.media.a.prototype.zd;chrome.cast.media.a.prototype.Kd=function(a,b,c){y.i(this,"QUEUE_UPDATE",a,b,c,chrome.cast.media.timeout.o)};chrome.cast.media.a.prototype.queueUpdateItems=chrome.cast.media.a.prototype.Kd; | |
chrome.cast.media.a.prototype.Fd=function(a,b){var c=new chrome.cast.media.ga;c.jump=-1;y.i(this,"QUEUE_UPDATE",c,a,b,chrome.cast.media.timeout.o)};chrome.cast.media.a.prototype.queuePrev=chrome.cast.media.a.prototype.Fd;chrome.cast.media.a.prototype.Ed=function(a,b){var c=new chrome.cast.media.ga;c.jump=1;y.i(this,"QUEUE_UPDATE",c,a,b,chrome.cast.media.timeout.o)};chrome.cast.media.a.prototype.queueNext=chrome.cast.media.a.prototype.Ed; | |
chrome.cast.media.a.prototype.Bd=function(a,b,c){if(!(0>this.Na(a))){var d=new chrome.cast.media.ga;d.currentItemId=a;y.i(this,"QUEUE_UPDATE",d,b,c,chrome.cast.media.timeout.o)}};chrome.cast.media.a.prototype.queueJumpToItem=chrome.cast.media.a.prototype.Bd;chrome.cast.media.a.prototype.Jd=function(a,b,c){var d=new chrome.cast.media.lb;d.repeatMode=a;y.i(this,"QUEUE_UPDATE",d,b,c,chrome.cast.media.timeout.o)};chrome.cast.media.a.prototype.queueSetRepeatMode=chrome.cast.media.a.prototype.Jd; | |
chrome.cast.media.a.prototype.Hd=function(a,b,c){y.i(this,"QUEUE_REMOVE",a,b,c,chrome.cast.media.timeout.o)};chrome.cast.media.a.prototype.queueRemoveItems=chrome.cast.media.a.prototype.Hd;chrome.cast.media.a.prototype.Gd=function(a,b,c){0>this.Na(a)||y.i(this,"QUEUE_REMOVE",new chrome.cast.media.jb([a]),b,c,chrome.cast.media.timeout.o)};chrome.cast.media.a.prototype.queueRemoveItem=chrome.cast.media.a.prototype.Gd;chrome.cast.media.a.prototype.Id=function(a,b,c){y.i(this,"QUEUE_REORDER",a,b,c,chrome.cast.media.timeout.o)}; | |
chrome.cast.media.a.prototype.queueReorderItems=chrome.cast.media.a.prototype.Id;chrome.cast.media.a.prototype.Dd=function(a,b,c,d){var f=this.Na(a);if(!(0>f))if(0>b)d&&d(new chrome.cast.Error(chrome.cast.u.INVALID_PARAMETER));else if(f==b)c&&c();else{var h=null;b=b>f?b+1:b;b<this.items.length&&(h=this.items[b]);a=new chrome.cast.media.kb([a]);a.insertBefore=h?h.itemId:null;y.i(this,"QUEUE_REORDER",a,c,d,chrome.cast.media.timeout.o)}};chrome.cast.media.a.prototype.queueMoveItemToNewIndex=chrome.cast.media.a.prototype.Dd; | |
chrome.cast.media.a.prototype.Zd=function(a){return-1<this.supportedMediaCommands.indexOf(a)};chrome.cast.media.a.prototype.supportsCommand=chrome.cast.media.a.prototype.Zd;chrome.cast.media.a.prototype.Uc=function(){if(this.playerState==chrome.cast.media.T.PLAYING&&0<=this.Pa){var a=this.currentTime+(Date.now()-this.Pa)/1E3*this.playbackRate;this.media&&null!=this.media.duration&&a>this.media.duration&&(a=this.media.duration);0>a&&(a=0);return a}return this.currentTime}; | |
chrome.cast.media.a.prototype.getEstimatedTime=chrome.cast.media.a.prototype.Uc;chrome.cast.media.a.prototype.Ga=function(a){this.V(y,a)};chrome.cast.media.a.prototype.addUpdateListener=chrome.cast.media.a.prototype.Ga;chrome.cast.media.a.prototype.V=function(a,b){a.Ic(this,b)};chrome.cast.media.a.prototype.addUpdateListenerWithContext=chrome.cast.media.a.prototype.V;chrome.cast.media.a.prototype.Sa=function(a){this.aa(y,a)};chrome.cast.media.a.prototype.removeUpdateListener=chrome.cast.media.a.prototype.Sa; | |
chrome.cast.media.a.prototype.aa=function(a,b){y.Nd(this,b)};chrome.cast.media.a.prototype.removeUpdateListenerWithContext=chrome.cast.media.a.prototype.aa;chrome.cast.media.a.prototype.Na=function(a){return za(this.items,function(b){return b.itemId==a})};var y=null;var Ca=function(a,b,c){this.sessionId=a;this.namespaceName=b;this.message=c};var Da=function(a,b){this.type="SET_VOLUME";this.requestId=0;this.volume=a;this.expectedVolume=b||null};var Ea=function(a){this.type="STOP";this.requestId=0;this.sessionId=a||null};chrome.cast.b=function(a,b,c,d,f){this.sessionId=a;this.appId=b;this.displayName=c;this.statusText=null;this.appImages=d;this.receiver=f;this.senderApps=[];this.namespaces=[];this.media=[];this.status=chrome.cast.U.CONNECTED;this.transportId=""};p("chrome.cast.Session",chrome.cast.b,void 0);chrome.cast.b.prototype.Wd=function(a,b,c){this.Sb(y,a,b,c)};chrome.cast.b.prototype.setReceiverVolumeLevel=chrome.cast.b.prototype.Wd; | |
chrome.cast.b.prototype.Sb=function(a,b,c,d){b=new Da(new chrome.cast.Volume(b,null),this.receiver.volume);a.setReceiverVolume(this.sessionId,b,c,d)};chrome.cast.b.prototype.setReceiverVolumeLevelWithContext=chrome.cast.b.prototype.Sb;chrome.cast.b.prototype.Vd=function(a,b,c){this.Rb(y,a,b,c)};chrome.cast.b.prototype.setReceiverMuted=chrome.cast.b.prototype.Vd; | |
chrome.cast.b.prototype.Rb=function(a,b,c,d){a=new Da(new chrome.cast.Volume(null,b),this.receiver.volume);y.setReceiverVolume(this.sessionId,a,c,d)};chrome.cast.b.prototype.setReceiverMutedWithContext=chrome.cast.b.prototype.Rb;chrome.cast.b.prototype.fd=function(a,b){y.leaveSession(this.sessionId,a,b)};chrome.cast.b.prototype.leave=chrome.cast.b.prototype.fd;chrome.cast.b.prototype.stop=function(a,b){this.Ub(y,a,b)};chrome.cast.b.prototype.stop=chrome.cast.b.prototype.stop; | |
chrome.cast.b.prototype.Ub=function(a,b,c){a.Nb(new Ea(this.sessionId),b,c,chrome.cast.timeout.stopSession)};chrome.cast.b.prototype.stopWithContext=chrome.cast.b.prototype.Ub;chrome.cast.b.prototype.sendMessage=function(a,b,c,d){this.Pb(y,a,b,c,d)};chrome.cast.b.prototype.sendMessage=chrome.cast.b.prototype.sendMessage;chrome.cast.b.prototype.Pb=function(a,b,c,d,f){a.Rd(new Ca(this.sessionId,b,c),d,f)};chrome.cast.b.prototype.sendMessageWithContext=chrome.cast.b.prototype.Pb; | |
chrome.cast.b.prototype.Ga=function(a){this.V(y,a)};chrome.cast.b.prototype.addUpdateListener=chrome.cast.b.prototype.Ga;chrome.cast.b.prototype.V=function(a,b){a.Lc(this.sessionId,b)};chrome.cast.b.prototype.addUpdateListenerWithContext=chrome.cast.b.prototype.V;chrome.cast.b.prototype.Sa=function(a){this.aa(y,a)};chrome.cast.b.prototype.removeUpdateListener=chrome.cast.b.prototype.Sa;chrome.cast.b.prototype.aa=function(a,b){a.Qd(this.sessionId,b)}; | |
chrome.cast.b.prototype.removeUpdateListenerWithContext=chrome.cast.b.prototype.aa;chrome.cast.b.prototype.Jc=function(a,b){this.rb(y,a,b)};chrome.cast.b.prototype.addMessageListener=chrome.cast.b.prototype.Jc;chrome.cast.b.prototype.rb=function(a,b,c){a.Hc(this.sessionId,b,c)};chrome.cast.b.prototype.addMessageListenerWithContext=chrome.cast.b.prototype.rb;chrome.cast.b.prototype.Ea=function(a){this.qb(y,a)};chrome.cast.b.prototype.addMediaListener=chrome.cast.b.prototype.Ea; | |
chrome.cast.b.prototype.qb=function(a,b){a.Ea(this.sessionId,b)};chrome.cast.b.prototype.addMediaListenerWithContext=chrome.cast.b.prototype.qb;chrome.cast.b.prototype.Qa=function(a){this.Ib(y,a)};chrome.cast.b.prototype.removeMediaListener=chrome.cast.b.prototype.Qa;chrome.cast.b.prototype.Ib=function(a,b){a.Qa(this.sessionId,b)};chrome.cast.b.prototype.removeMediaListenerWithContext=chrome.cast.b.prototype.Ib;chrome.cast.b.prototype.Od=function(a,b){this.Jb(y,a,b)}; | |
chrome.cast.b.prototype.removeMessageListener=chrome.cast.b.prototype.Od;chrome.cast.b.prototype.Jb=function(a,b,c){a.Ld(this.sessionId,b,c)};chrome.cast.b.prototype.removeMessageListenerWithContext=chrome.cast.b.prototype.Jb;chrome.cast.b.prototype.hd=function(a,b,c){a.sessionId=this.sessionId;y.Ob(a,"LOAD",b,c)};chrome.cast.b.prototype.loadMedia=chrome.cast.b.prototype.hd;chrome.cast.b.prototype.Cd=function(a,b,c){a.sessionId=this.sessionId;y.Ob(a,"QUEUE_LOAD",b,c)}; | |
chrome.cast.b.prototype.queueLoad=chrome.cast.b.prototype.Cd;var Fa=function(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b},Ga=function(a){var b=[],c=0,d;for(d in a)b[c++]=d;return b};var z="StopIteration"in n?n.StopIteration:{message:"StopIteration",stack:""},A=function(){};A.prototype.next=function(){throw z;};A.prototype.v=function(){return this}; | |
var Ha=function(a){if(a instanceof A)return a;if("function"==typeof a.v)return a.v(!1);if(r(a)){var b=0,c=new A;c.next=function(){for(;;){if(b>=a.length)throw z;if(b in a)return a[b++];b++}};return c}throw Error("Not implemented");},B=function(a,b,c){if(r(a))try{x(a,b,c)}catch(d){if(d!==z)throw d;}else{a=Ha(a);try{for(;;)b.call(c,a.next(),void 0,a)}catch(d){if(d!==z)throw d;}}};var C=function(a,b){this.h={};this.g=[];this.fa=this.f=0;var c=arguments.length;if(1<c){if(c%2)throw Error("Uneven number of arguments");for(var d=0;d<c;d+=2)this.set(arguments[d],arguments[d+1])}else a&&this.addAll(a)};e=C.prototype;e.l=function(){this.ia();for(var a=[],b=0;b<this.g.length;b++)a.push(this.h[this.g[b]]);return a};e.B=function(){this.ia();return this.g.concat()};e.M=function(a){return D(this.h,a)};e.clear=function(){this.h={};this.fa=this.f=this.g.length=0}; | |
e.remove=function(a){return D(this.h,a)?(delete this.h[a],this.f--,this.fa++,this.g.length>2*this.f&&this.ia(),!0):!1};e.ia=function(){if(this.f!=this.g.length){for(var a=0,b=0;a<this.g.length;){var c=this.g[a];D(this.h,c)&&(this.g[b++]=c);a++}this.g.length=b}if(this.f!=this.g.length){for(var d={},b=a=0;a<this.g.length;)c=this.g[a],D(d,c)||(this.g[b++]=c,d[c]=1),a++;this.g.length=b}};e.get=function(a,b){return D(this.h,a)?this.h[a]:b}; | |
e.set=function(a,b){D(this.h,a)||(this.f++,this.g.push(a),this.fa++);this.h[a]=b};e.addAll=function(a){var b;a instanceof C?(b=a.B(),a=a.l()):(b=Ga(a),a=Fa(a));for(var c=0;c<b.length;c++)this.set(b[c],a[c])};e.forEach=function(a,b){for(var c=this.B(),d=0;d<c.length;d++){var f=c[d],h=this.get(f);a.call(b,h,f,this)}};e.clone=function(){return new C(this)}; | |
e.v=function(a){this.ia();var b=0,c=this.fa,d=this,f=new A;f.next=function(){if(c!=d.fa)throw Error("The map has changed since the iterator was created");if(b>=d.g.length)throw z;var f=d.g[b++];return a?f:d.h[f]};return f};var D=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};var Ia=function(a,b){this.requestId=a;this.$d=b;this.Vb=null};Ia.prototype.Eb=function(){};var E=function(){this.ta=new C};E.prototype.Kc=function(a){var b=this;this.ta.set(a.requestId,a);a.Vb=setTimeout(function(){return b.ud(a)},a.$d)};E.prototype.Kb=function(a){var b=this.ta.get(a);if(!b)return null;clearTimeout(b.Vb);this.ta.remove(a);return b};E.prototype.ud=function(a){this.ta.remove(a.requestId);a.Eb()};var Ja=function(a){this.ld=a},La=function(a){var b=Ka.get(a);b||(b=new Ja(a),Ka.set(a,b));return b};e=Ja.prototype;e.log=function(a,b,c){if(1<=a){"function"==typeof b&&(b=b());var d={fe:this.ld,level:a,time:Date.now(),message:b,de:c};Ma.forEach(function(a){return a(d)})}};e.error=function(a,b){this.log(3,a,b)};e.be=function(a,b){this.log(2,a,b)};e.info=function(a,b){this.log(1,a,b)};e.Bb=function(a,b){this.log(0,a,b)};var Ma=[],Ka=new Map;var F=function(){this.Ka=this.Ka;this.pd=this.pd};F.prototype.Ka=!1;F.prototype.isDisposed=function(){return this.Ka};var Na=function(a,b,c,d){d=d?d(b):b;return Object.prototype.hasOwnProperty.call(a,d)?a[d]:a[d]=c(b)};var G;a:{var Oa=n.navigator;if(Oa){var Pa=Oa.userAgent;if(Pa){G=Pa;break a}}G=""}var H=function(a){return-1!=G.indexOf(a)};var Qa=H("Opera"),I=H("Trident")||H("MSIE"),Ra=H("Edge"),J=H("Gecko")&&!(-1!=G.toLowerCase().indexOf("webkit")&&!H("Edge"))&&!(H("Trident")||H("MSIE"))&&!H("Edge"),K=-1!=G.toLowerCase().indexOf("webkit")&&!H("Edge"),Sa; | |
a:{var Ta="",Ua=function(){var a=G;if(J)return/rv\:([^\);]+)(\)|;)/.exec(a);if(Ra)return/Edge\/([\d\.]+)/.exec(a);if(I)return/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(a);if(K)return/WebKit\/(\S+)/.exec(a);if(Qa)return/(?:Version)[ \/]?(\S+)/.exec(a)}();Ua&&(Ta=Ua?Ua[1]:"");if(I){var L,Va=n.document;L=Va?Va.documentMode:void 0;if(null!=L&&L>parseFloat(Ta)){Sa=String(L);break a}}Sa=Ta} | |
var Wa=Sa,Xa={},M=function(a){return Na(Xa,a,function(){for(var b=0,c=oa(String(Wa)).split("."),d=oa(String(a)).split("."),f=Math.max(c.length,d.length),h=0;0==b&&h<f;h++){var k=c[h]||"",m=d[h]||"";do{k=/(\d*)(\D*)(.*)/.exec(k)||["","","",""];m=/(\d*)(\D*)(.*)/.exec(m)||["","","",""];if(0==k[0].length&&0==m[0].length)break;b=w(0==k[1].length?0:parseInt(k[1],10),0==m[1].length?0:parseInt(m[1],10))||w(0==k[2].length,0==m[2].length)||w(k[2],m[2]);k=k[3];m=m[3]}while(0==b)}return 0<=b})};I&&M("9");!K||M("528");J&&M("1.9b")||I&&M("8")||Qa&&M("9.5")||K&&M("528");J&&!M("8")||I&&M("9");var Ya=function(a,b,c){F.call(this);this.gd=null!=c?u(a,c):a;this.ad=b;this.Ia=u(this.vd,this);this.Ha=[]};na(Ya,F);e=Ya.prototype;e.S=!1;e.$=0;e.J=null;e.Sc=function(a){this.Ha=arguments;this.J||this.$?this.S=!0:this.La()};e.stop=function(){this.J&&(n.clearTimeout(this.J),this.J=null,this.S=!1,this.Ha=[])};e.pause=function(){this.$++};e.resume=function(){this.$--;this.$||!this.S||this.J||(this.S=!1,this.La())};e.vd=function(){this.J=null;this.S&&!this.$&&(this.S=!1,this.La())}; | |
e.La=function(){var a=this.Ia,b=this.ad;if("function"!=q(a))if(a&&"function"==typeof a.handleEvent)a=u(a.handleEvent,a);else throw Error("Invalid listener argument");this.J=2147483647<Number(b)?-1:n.setTimeout(a,b||0);this.gd.apply(null,this.Ha)};var Za=H("Safari")&&!((H("Chrome")||H("CriOS"))&&!H("Edge")||H("Coast")||H("Opera")||H("Edge")||H("Silk")||H("Android"))&&!(H("iPhone")&&!H("iPod")&&!H("iPad")||H("iPad")||H("iPod"));var N=null,$a=null,ab=J||K&&!Za||Qa||"function"==typeof n.btoa,bb=function(a,b){var c;if(ab&&!b)c=n.btoa(a);else{c=[];for(var d=0,f=0;f<a.length;f++){for(var h=a.charCodeAt(f);255<h;)c[d++]=h&255,h>>=8;c[d++]=h}if(!N)for(N={},$a={},a=0;65>a;a++)N[a]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(a),$a[a]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.".charAt(a);b=b?$a:N;a=[];for(d=0;d<c.length;d+=3){var k=c[d],m=(f=d+1<c.length)?c[d+1]:0,v=(h=d+2<c.length)? | |
c[d+2]:0,ha=k>>2,k=(k&3)<<4|m>>4,m=(m&15)<<2|v>>6,v=v&63;h||(v=64,f||(m=64));a.push(b[ha],b[k],b[m],b[v])}c=a.join("")}return c};var cb=function(a){if(a.l&&"function"==typeof a.l)return a.l();if(t(a))return a.split("");if(r(a)){for(var b=[],c=a.length,d=0;d<c;d++)b.push(a[d]);return b}return Fa(a)},db=function(a,b,c){if(a.forEach&&"function"==typeof a.forEach)a.forEach(b,c);else if(r(a)||t(a))x(a,b,c);else{var d;if(a.B&&"function"==typeof a.B)d=a.B();else if(a.l&&"function"==typeof a.l)d=void 0;else if(r(a)||t(a)){d=[];for(var f=a.length,h=0;h<f;h++)d.push(h)}else d=Ga(a);for(var f=cb(a),h=f.length,k=0;k<h;k++)b.call(c,f[k], | |
d&&d[k],a)}};var O=function(a){this.h=new C;a&&this.addAll(a)},eb=function(a){var b=typeof a;return"object"==b&&a||"function"==b?"o"+(a[ja]||(a[ja]=++ka)):b.substr(0,1)+a};e=O.prototype;e.add=function(a){this.h.set(eb(a),a)};e.addAll=function(a){a=cb(a);for(var b=a.length,c=0;c<b;c++)this.add(a[c])};e.removeAll=function(a){a=cb(a);for(var b=a.length,c=0;c<b;c++)this.remove(a[c])};e.remove=function(a){return this.h.remove(eb(a))};e.clear=function(){this.h.clear()};e.contains=function(a){return this.h.M(eb(a))}; | |
e.l=function(){return this.h.l()};e.clone=function(){return new O(this)};e.v=function(){return this.h.v(!1)};var fb=function(a,b,c,d){Ia.call(this,a,d||6E5);this.Yd=b;this.Ma=c};aa(fb,Ia);fb.prototype.Eb=function(){this.Ma(new chrome.cast.Error(chrome.cast.u.TIMEOUT))};var P=function(a,b,c,d){this.type=a;this.message=b;this.sequenceNumber=void 0!==c?c:-1;this.timeoutMillis=d||0;this.clientId=""};var Q=function(a,b){this.Ia=a;this.D=b||String(Date.now())+String(Math.floor(1E5*Math.random()));this.L=null};Q.prototype.Qb=function(a){if(!this.L)return R.error("No active session"),"No active session";a.clientId=this.D;a=JSON.stringify(a);if(32768<a.length)return R.error("Message length over limit"),"Message length over limit";R.Bb("Send "+a);this.L.send(a);return null};Q.prototype.connect=function(a){this.L=a;this.L.onmessage=u(this.qd,this);this.Qb(new P("client_connect",this.D))}; | |
Q.prototype.disconnect=function(){this.L.close();this.L=null};Q.prototype.qd=function(a){R.Bb("Receive "+a.data);a=JSON.parse(a.data);if(a.clientId==this.D)this.Ia.onMessage(a)};var R=La("mr.cast.ExtensionMessenger");var gb=/^(?:([^:/?#.]+):)?(?:\/\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\?([^#]*))?(?:#([\s\S]*))?$/,hb=function(a,b){if(a){a=a.split("&");for(var c=0;c<a.length;c++){var d=a[c].indexOf("="),f,h=null;0<=d?(f=a[c].substring(0,d),h=a[c].substring(d+1)):f=a[c];b(f,h?decodeURIComponent(h.replace(/\+/g," ")):"")}}};var S=function(a,b){this.X=this.ea=this.C="";this.P=null;this.Z=this.H="";this.m=this.ed=!1;var c;a instanceof S?(this.m=void 0!==b?b:a.m,this.Aa(a.C),this.$a(a.ea),this.xa(a.X),this.Ya(a.P),this.za(a.H),this.Za(a.w.clone()),this.ya(a.Z)):a&&(c=String(a).match(gb))?(this.m=!!b,this.Aa(c[1]||"",!0),this.$a(c[2]||"",!0),this.xa(c[3]||"",!0),this.Ya(c[4]),this.za(c[5]||"",!0),this.Za(c[6]||"",!0),this.ya(c[7]||"",!0)):(this.m=!!b,this.w=new T(null,null,this.m))};e=S.prototype; | |
e.toString=function(){var a=[],b=this.C;b&&a.push(U(b,ib,!0),":");var c=this.X;if(c||"file"==b)a.push("//"),(b=this.ea)&&a.push(U(b,ib,!0),"@"),a.push(encodeURIComponent(String(c)).replace(/%25([0-9a-fA-F]{2})/g,"%$1")),c=this.P,null!=c&&a.push(":",String(c));if(c=this.H)this.Oa()&&"/"!=c.charAt(0)&&a.push("/"),a.push(U(c,"/"==c.charAt(0)?jb:kb,!0));(c=this.Tc())&&a.push("?",c);(c=this.Z)&&a.push("#",U(c,lb));return a.join("")}; | |
e.resolve=function(a){var b=this.clone(),c=a.Yc();c?b.Aa(a.C):c=a.Zc();c?b.$a(a.ea):c=a.Oa();c?b.xa(a.X):c=a.Wc();var d=a.H;if(c)b.Ya(a.P);else if(c=a.Cb()){if("/"!=d.charAt(0))if(this.Oa()&&!this.Cb())d="/"+d;else{var f=b.H.lastIndexOf("/");-1!=f&&(d=b.H.substr(0,f+1)+d)}f=d;if(".."==f||"."==f)d="";else if(-1!=f.indexOf("./")||-1!=f.indexOf("/.")){for(var d=0==f.lastIndexOf("/",0),f=f.split("/"),h=[],k=0;k<f.length;){var m=f[k++];"."==m?d&&k==f.length&&h.push(""):".."==m?((1<h.length||1==h.length&& | |
""!=h[0])&&h.pop(),d&&k==f.length&&h.push("")):(h.push(m),d=!0)}d=h.join("/")}else d=f}c?b.za(d):c=a.Xc();c?b.Za(a.w.clone()):c=a.Vc();c&&b.ya(a.Z);return b};e.clone=function(){return new S(this)};e.Aa=function(a,b){this.F();if(this.C=b?V(a,!0):a)this.C=this.C.replace(/:$/,"");return this};e.Yc=function(){return!!this.C};e.$a=function(a,b){this.F();this.ea=b?V(a):a;return this};e.Zc=function(){return!!this.ea};e.xa=function(a,b){this.F();this.X=b?V(a,!0):a;return this};e.Oa=function(){return!!this.X}; | |
e.Ya=function(a){this.F();if(a){a=Number(a);if(isNaN(a)||0>a)throw Error("Bad port number "+a);this.P=a}else this.P=null;return this};e.Wc=function(){return null!=this.P};e.za=function(a,b){this.F();this.H=b?V(a,!0):a;return this};e.Cb=function(){return!!this.H};e.Xc=function(){return""!==this.w.toString()};e.Za=function(a,b){this.F();a instanceof T?(this.w=a,this.w.Wa(this.m)):(b||(a=U(a,mb)),this.w=new T(a,null,this.m));return this};e.Tc=function(){return this.w.toString()}; | |
e.ya=function(a,b){this.F();this.Z=b?V(a):a;return this};e.Vc=function(){return!!this.Z};e.F=function(){if(this.ed)throw Error("Tried to modify a read-only Uri");};e.Wa=function(a){this.m=a;this.w&&this.w.Wa(a);return this}; | |
var V=function(a,b){return a?b?decodeURI(a.replace(/%25/g,"%2525")):decodeURIComponent(a):""},U=function(a,b,c){return t(a)?(a=encodeURI(a).replace(b,nb),c&&(a=a.replace(/%25([0-9a-fA-F]{2})/g,"%$1")),a):null},nb=function(a){a=a.charCodeAt(0);return"%"+(a>>4&15).toString(16)+(a&15).toString(16)},ib=/[#\/\?@]/g,kb=/[\#\?:]/g,jb=/[\#\?]/g,mb=/[\#\?@]/g,lb=/#/g,T=function(a,b,c){this.f=this.c=null;this.A=a||null;this.m=!!c};e=T.prototype; | |
e.G=function(){if(!this.c&&(this.c=new C,this.f=0,this.A)){var a=this;hb(this.A,function(b,c){a.add(decodeURIComponent(b.replace(/\+/g," ")),c)})}};e.add=function(a,b){this.G();this.O();a=this.N(a);var c=this.c.get(a);c||this.c.set(a,c=[]);c.push(b);this.f+=1;return this};e.remove=function(a){this.G();a=this.N(a);return this.c.M(a)?(this.O(),this.f-=this.c.get(a).length,this.c.remove(a)):!1};e.clear=function(){this.O();this.c=null;this.f=0};e.M=function(a){this.G();a=this.N(a);return this.c.M(a)}; | |
e.B=function(){this.G();for(var a=this.c.l(),b=this.c.B(),c=[],d=0;d<b.length;d++)for(var f=a[d],h=0;h<f.length;h++)c.push(b[d]);return c};e.l=function(a){this.G();var b=[];if(t(a))this.M(a)&&(b=Aa(b,this.c.get(this.N(a))));else{a=this.c.l();for(var c=0;c<a.length;c++)b=Aa(b,a[c])}return b};e.set=function(a,b){this.G();this.O();a=this.N(a);this.M(a)&&(this.f-=this.c.get(a).length);this.c.set(a,[b]);this.f+=1;return this};e.get=function(a,b){a=a?this.l(a):[];return 0<a.length?String(a[0]):b}; | |
e.Xd=function(a,b){this.remove(a);0<b.length&&(this.O(),this.c.set(this.N(a),Ba(b)),this.f+=b.length)};e.toString=function(){if(this.A)return this.A;if(!this.c)return"";for(var a=[],b=this.c.B(),c=0;c<b.length;c++)for(var d=b[c],f=encodeURIComponent(String(d)),d=this.l(d),h=0;h<d.length;h++){var k=f;""!==d[h]&&(k+="="+encodeURIComponent(String(d[h])));a.push(k)}return this.A=a.join("&")};e.O=function(){this.A=null}; | |
e.clone=function(){var a=new T;a.A=this.A;this.c&&(a.c=this.c.clone(),a.f=this.f);return a};e.N=function(a){a=String(a);this.m&&(a=a.toLowerCase());return a};e.Wa=function(a){a&&!this.m&&(this.G(),this.O(),this.c.forEach(function(a,c){var b=c.toLowerCase();c!=b&&(this.remove(c),this.Xd(b,a))},this));this.m=a};e.extend=function(a){for(var b=0;b<arguments.length;b++)db(arguments[b],function(a,b){this.add(b,a)},this)};var ob=function(a,b,c,d,f,h,k,m,v,ha){this.Mc=a;this.D=b||null;this.tb=c||null;this.yb=d||null;this.Db=void 0!==f?f:null;this.sb=h||null;this.Ab=k||null;this.bd=m||!1;this.vb=v||null;this.ub=ha||null}; | |
ob.prototype.toString=function(){var a=new S;a.Aa("https");a.xa("google.com");a.za("/cast");var b=[];x(this.Mc,function(a){var c="__castAppId__="+a.appId;a.capabilities&&0<a.capabilities.length&&(c=c+"("+a.capabilities.join(","),c+=")");b.push(c)});this.D&&b.push("__castClientId__="+this.D);this.tb&&b.push("__castAutoJoinPolicy__="+this.tb);this.yb&&b.push("__castDefaultActionPolicy__="+this.yb);null!=this.Db&&b.push("__castLaunchTimeout__="+this.Db);this.sb&&b.push("__dialAppName__="+this.sb);this.Ab&& | |
b.push("__dialPostData__="+this.Ab);this.bd&&b.push("__castInvisibleSender__=true");this.vb&&(b.push("__castBroadcastNamespace__="+this.vb),b.push("__castBroadcastId__="+Math.random()));this.ub&&b.push("__castBroadcastMessage__="+encodeURIComponent(JSON.stringify(this.ub)));a.ya(b.join("/"));return a.toString()};var W=function(){this.R={};this.ra={}};W.prototype.Pd=function(a,b){var c=this,d=this.R[a];return d?(d.status=b,d.media.forEach(function(a){delete c.ra[a.sessionId+"#"+a.mediaSessionId]}),delete this.R[a],!0):!1}; | |
W.prototype.Rc=function(a){var b=this,c=this.R[a.sessionId];if(c)return c.statusText=a.statusText,c.namespaces=a.namespaces||[],c.receiver.volume=a.receiver.volume,c;var c=new chrome.cast.b(a.sessionId,a.appId,a.displayName,a.appImages,a.receiver),d;for(d in a)"media"==d?c.media=a.media.map(function(a){a=b.xb(a);a.ee=!1;a.na=!0;return a}):a.hasOwnProperty(d)&&(c[d]=a[d]);return this.R[a.sessionId]=c}; | |
W.prototype.xb=function(a){var b=a.sessionId+"#"+a.mediaSessionId,c=this.ra[b];c||(c=new chrome.cast.media.a(a.sessionId,a.mediaSessionId),this.ra[b]=c,(b=this.R[a.sessionId])&&b.media.push(c));b=c;b.currentItemId=null;b.loadingItemId=null;b.preloadedItemId=null;for(var d in a)"items"!=d&&a.hasOwnProperty(d)&&("volume"==d?(b.volume.level=a.volume.level,b.volume.muted=a.volume.muted):b[d]=a[d]);"currentTime"in a&&(b.Pa=Date.now());if(b.playerState==chrome.cast.media.T.IDLE&&null==b.loadingItemId)b.currentItemId= | |
null,b.loadingItemId=null,b.preloadedItemId=null,b.items=null;else if(a.hasOwnProperty("items")&&a.items){d=[];var f=b.items,h={};if(f)for(var k=0;k<f.length;k++)h[f[k].itemId]=k;a=a.items;l();a=(f=a[Symbol.iterator])?f.call(a):fa(a);for(f=a.next();!f.done;f=a.next()){f=f.value;if(!f.media){var k=f.itemId,m=b.items?b.items[h[k]]:null;m&&m.media?f.media=m.media:k==b.currentItemId&&b.media&&(f.media=b.media)}d.push(pb(f))}b.items=d}return c}; | |
W.prototype.Md=function(a){delete this.ra[a.sessionId+"#"+a.mediaSessionId];var b=this.R[a.sessionId];b&&(a=b.media.indexOf(a),-1!=a&&b.media.splice(a,1))};var pb=function(a){var b=new chrome.cast.media.ib(a.media),c;for(c in a)a.hasOwnProperty(c)&&(b[c]=a[c]);return b};var X=function(){this.Y=new Q(this);this.j=null;this.wa=new W;this.va=0;this.Ja=new E;this.ca=new C;this.Hb=!1;this.W=new C;this.qa=new C;this.ua=[];this.Pc=this.Qc.bind(this);this.I=null;this.pa=0;this.K=null;this.Oc=new Ya(this.Sd,200,this);this.zb=null},qb=function(a,b){a&&a(b)};e=X.prototype;e.ja=function(a,b,c){return new fb(this.va,a,b,c)}; | |
e.ba=function(a,b,c){b&&this.Ja.Kc(b);void 0!==c?a.sequenceNumber=c:(a.sequenceNumber=this.va,this.va=(this.va+1)%9007199254740992);c=this.Y.Qb(a);b&&c&&(a=this.Ja.Kb(a.sequenceNumber),b=new chrome.cast.Error(chrome.cast.u.INVALID_PARAMETER,c),(a=a.Ma)&&a(b))}; | |
e.oa=function(a,b){var c=this;y=this;this.j||(this.j=a,a.invisibleSender||(a=new PresentationRequest(this.la()),a.getAvailability().then(function(a){a.onchange=function(){c.Hb=!!a.value;c.j.receiverListener(a.value?chrome.cast.ha.AVAILABLE:chrome.cast.ha.UNAVAILABLE)};a.onchange()},function(){c.j.receiverListener(chrome.cast.ha.AVAILABLE)}),a.onconnectionavailable=function(a){c.sa(a.connection)},this.zb=(n.navigator||null).presentation.defaultRequest=a,a.reconnect(chrome.cast.Wb).then(function(a){c.sa(a)}, | |
ia)));b&&b(void 0)};e.Xa=function(a){a.navigator.presentation.defaultRequest=this.zb};e.sa=function(a,b){b=void 0===b?null:b;var c=this;a.onclose=function(a){c.I=null;switch(a.reason){case "closed":c.od();break;case "error":b&&(a=new chrome.cast.Error(chrome.cast.u.SESSION_ERROR),b&&b(a))}};a.onterminate=function(){c.td()};"connected"==a.state?this.Y.connect(a):a.onconnect=function(){c.Y.connect(a)}}; | |
e.Nc=function(a,b){"urn:x-cast:com.google.cast.media"!=a?Y.error("Unsupported broadcast message namespace - "+a):rb.has(b.type)?this.Hb&&(this.K?(b.sessionId=this.K,this.Va(null,b.type,b,function(){Y.info("Send Broadcast directly succeeded")},function(a){Y.error("Send Broadcast directly failed with code "+a.code)})):this.Oc.Sc(this.la(void 0,a,b))):Y.error("Unsupported broadcast message type - "+b.type)}; | |
e.Sd=function(a){Y.info("Broadcast request "+a);(a=(new PresentationRequest(a)).getAvailability())?a.then(function(){Y.info("Broadcast succeeded")},function(){Y.be("Broadcast failed")}):Y.error("presentationRequest.getAvailability return undefined")}; | |
e.requestSession=function(a,b,c){var d=this;this.I?qb(b,new chrome.cast.Error(chrome.cast.u.INVALID_PARAMETER,"Already requesting session")):(c=this.la(c),this.I=a,(new PresentationRequest(c.toString())).start().then(function(a){d.sa(a,b)}).catch(function(a){d.I=null;a=new chrome.cast.Error("AbortError"==a.name||"NotAllowedError"==a.name?chrome.cast.u.CANCEL:chrome.cast.u.SESSION_ERROR);b&&b(a)}))}; | |
e.la=function(a,b,c){var d=null,f=null,h=a||this.j.sessionRequest,k=h.dialRequest;k&&(d=k.appName,(f=k.launchParameter)&&!f.match(sb)&&(f=bb(f)));var m=[];m.push({appId:h.appId,capabilities:h.capabilities});a||x(this.j.additionalSessionRequests,function(a){m.push({appId:a.appId,capabilities:a.capabilities})});return(new ob(m,this.Y.D,this.j.autoJoinPolicy,this.j.defaultActionPolicy,h.requestSessionTimeout,d,f,this.j.invisibleSender,b,c)).toString()}; | |
e.Ob=function(a,b,c,d){var f=this;this.pa++;this.Va(null,b,a,function(a){f.pa--;a.na=!0;c&&c(a)},function(a){f.pa--;d(a)},chrome.cast.media.timeout.load)};e.i=function(a,b,c,d,f,h){var k=this;this.Va(a,b,c,function(a){k.wb(a);d&&d(void 0)},f,h)};e.Va=function(a,b,c,d,f,h){c.type=b;null!=a&&(c.mediaSessionId=a.mediaSessionId,c.sessionId=a.sessionId);this.Nb(c,function(a){a.status&&1==a.status.length?d&&d(a.status[0]):(a=new chrome.cast.Error(chrome.cast.u.SESSION_ERROR),f&&f(a))},f,h)}; | |
e.setReceiverVolume=function(a,b,c,d){b.sessionId=a;this.ba(new P("v2_message",b,void 0,chrome.cast.timeout.setReceiverVolume),this.ja(c,d,chrome.cast.timeout.sendCustomMessage))};e.Ta=function(a){var b=this;(new PresentationRequest(this.la())).reconnect(chrome.cast.kc+a).then(function(a){b.sa(a)},ia)};e.leaveSession=function(a,b,c){this.ba(new P("leave_session",a,void 0,chrome.cast.timeout.leaveSession),this.ja(b,c,chrome.cast.timeout.leaveSession))}; | |
e.Rd=function(a,b,c){this.ba(new P("app_message",a,void 0,chrome.cast.timeout.sendCustomMessage),this.ja(b,c,chrome.cast.timeout.sendCustomMessage))};e.Nb=function(a,b,c,d){this.ba(new P("v2_message",a,void 0,d),this.ja(b,c,d))};var tb=function(a,b,c){var d=a.get(b);d||(d=new O,a.set(b,d));d.add(c)};e=X.prototype;e.Lc=function(a,b){tb(this.ca,a,b)};e.Qd=function(a,b){(a=this.ca.get(a))&&a.remove(b)};e.Fa=function(a){this.ua.push(a)};e.Ra=function(a){a=this.ua.indexOf(a);0<=a&&this.ua.splice(a,1)}; | |
e.Hc=function(a,b,c){var d=this.W.get(a);d||(d=new C,this.W.set(a,d));a=d.get(b);a||(a=new O,d.set(b,a));a.add(c)};e.Ld=function(a,b,c){(a=this.W.get(a))&&(b=a.get(b))&&b.remove(c)};e.Ea=function(a,b){tb(this.qa,a,b)};e.Qa=function(a,b){(a=this.qa.get(a))&&a.remove(b)};e.Ic=function(a,b){-1==a.da.indexOf(b)&&a.da.push(b)};e.Nd=function(a,b){b=a.da.indexOf(b);-1!=b&&a.da.splice(b,1)};e.cd=function(a){var b=this.Ja.Kb(a.sequenceNumber);b&&(b="error"==a.type?b.Ma:b.Yd)&&b(a.message)}; | |
e.dd=function(a){return a.playerState!=chrome.cast.media.T.IDLE||null!=a.loadingItemId};e.wb=function(a){if(a.na){var b=this.dd(a);a.da.forEach(function(a){a(b)});b||this.wa.Md(a)}else if(!(0<this.pa)){a.na=!0;var c=this.qa.get(a.sessionId);c&&B(c.v(),function(b){b(a)})}};e.Qc=function(a){return this.wa.xb(a)};e.kd=function(a){switch(a.type){case "new_session":case "update_session":a.message=this.wa.Rc(a.message);break;case "v2_message":(a=a.message)&&"MEDIA_STATUS"==a.type&&a.status&&(a.status=a.status.map(this.Pc))}}; | |
e.Lb=function(a){if(this.K){var b=this.K;this.K=null;this.Y.disconnect();var c=a!=chrome.cast.U.STOPPED;this.wa.Pd(b,a)&&(this.W.remove(b),this.qa.remove(b),a=this.ca.get(b))&&(this.ca.remove(b),B(a.v(),function(a){a(c)}))}}; | |
e.onMessage=function(a){this.kd(a);this.cd(a);var b=a.message;if(b)switch(a.type){case "receiver_action":this.sd(b);break;case "new_session":this.rd(b);break;case "update_session":this.wd(b);break;case "app_message":this.md(b);break;case "v2_message":this.xd(b);break;case "custom_dial_launch":this.nd(a.sequenceNumber,b)}};e.rd=function(a){this.K=a.sessionId;this.I?(this.I(a),this.I=null):this.j&&this.j.sessionListener(a)};e.wd=function(a){(a=this.ca.get(a.sessionId))&&B(a.v(),function(a){a(!0)})}; | |
e.sd=function(a){this.ua.forEach(function(b){b(a.receiver,a.action)})};e.od=function(){this.Lb(chrome.cast.U.DISCONNECTED)};e.td=function(){this.Lb(chrome.cast.U.STOPPED)};e.md=function(a){var b=this.W.get(a.sessionId);b&&(b=b.get(a.namespaceName))&&B(b.v(),function(b){b(a.namespaceName,a.message)})};e.xd=function(a){"MEDIA_STATUS"==a.type&&a.status.forEach(this.wb.bind(this))};e.Ua=function(a,b){this.ba(new P("custom_dial_launch",b,void 0,chrome.cast.timeout.sendCustomMessage),null,a)}; | |
e.nd=function(a,b){var c=this;this.j.customDialLaunchCallback?this.j.customDialLaunchCallback(b).then(function(b){c.Ua(a,b)},function(){c.Ua(a)}):this.Ua(a)};var sb=/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,rb=new Set(["PRECACHE"]),Z=new X,Y=La("mr.cast.Api");chrome.cast.oa=function(a,b,c){Z.oa(a,b,c)};p("chrome.cast.initialize",chrome.cast.oa,void 0);chrome.cast.$c=function(a,b,c){var d=new X;d.oa(a,b,c);return d};p("chrome.cast.initializeWithContext",chrome.cast.$c,void 0);chrome.cast.Xa=function(a){Z.Xa(a)};p("chrome.cast.setPageContext",chrome.cast.Xa,void 0);chrome.cast.requestSession=function(a,b,c){Z.requestSession(a,b,c)};p("chrome.cast.requestSession",chrome.cast.requestSession,void 0); | |
chrome.cast.yd=function(a){Z.Nc("urn:x-cast:com.google.cast.media",new chrome.cast.media.mc(a))};p("chrome.cast.precache",chrome.cast.yd,void 0);chrome.cast.Ta=function(a){chrome.cast.Mb(Z,a)};p("chrome.cast.requestSessionById",chrome.cast.Ta,void 0);chrome.cast.Mb=function(a,b){a.Ta(b)};p("chrome.cast.requestSessionByIdWithContext",chrome.cast.Mb,void 0);chrome.cast.Fa=function(a){Z.Fa(a)};p("chrome.cast.addReceiverActionListener",chrome.cast.Fa,void 0);chrome.cast.Ra=function(a){Z.Ra(a)}; | |
p("chrome.cast.removeReceiverActionListener",chrome.cast.Ra,void 0);chrome.cast.jd=function(){};p("chrome.cast.logMessage",chrome.cast.jd,void 0);chrome.cast.Td=function(a,b){b()};p("chrome.cast.setCustomReceivers",chrome.cast.Td,void 0);chrome.cast.Ud=function(a,b){b()};p("chrome.cast.setReceiverDisplayStatus",chrome.cast.Ud,void 0);chrome.cast.unescape=function(a){return-1!=a.indexOf("&")?"document"in n?xa(a):ya(a):a};p("chrome.cast.unescape",chrome.cast.unescape,void 0); | |
chrome.cast.isAvailable=!1;p("chrome.cast.isAvailable",chrome.cast.isAvailable,void 0);chrome.cast.Tb=!1;chrome.cast.ab=function(){if(!chrome.cast.Tb){chrome.cast.Tb=!0;chrome.cast.isAvailable=!0;var a=window.__onGCastApiAvailable;a&&"function"==typeof a&&a(!0)}};"complete"==document.readyState?chrome.cast.ab():(window.addEventListener("load",chrome.cast.ab,!1),window.addEventListener("DOMContentLoaded",chrome.cast.ab,!1));}).call(window); | |
(function(window, _) { | |
'use strict'; | |
var xest = _.xest; | |
var SeekBarController = function(skin, player, elements, subscribeToEvent) { | |
var container, progress, handle, seekBarZoneOffset, touchX; | |
// initialize selectors | |
container = xest(elements.container); | |
progress = xest(elements.progress); | |
handle = xest(elements.handle); | |
function addEventHandlers() { | |
var mouseDown, mouseMove; | |
// calculate it initially for mouse events | |
container.addEventListener('mousedown', function(e) { | |
seekBarZoneOffset = container.getBoundingClientRect(); | |
}); | |
container.addEventListener('touchstart', function(e) { | |
mouseDown = true; | |
//we set this bool to true but it does not mean it's true, but if the "touchmove" events don't set it to false | |
//then we will know it was only a touch event when we reach the "touchend" event. | |
//we only calculate the bounding zone on the initial mousedown event to save cpu ressources | |
//calculating it on every pixel during the mousemove event could use a lot of ressources for nothing. | |
seekBarZoneOffset = container.getBoundingClientRect(); | |
touchX = e.touches[0].pageX; | |
//self.trackSeekBarMousePosition(e); | |
_.addClass(handle, 'hover'); | |
skin.clearAutoHideControls(); | |
if (player.videoStarted) { | |
player.pauseTimeWhenSeekPegHold(true); | |
e.stopPropagation(); | |
e.preventDefault(); | |
} | |
}); | |
container.addEventListener('touchmove', function(e){ | |
trackMousePosition(e); | |
if (!player.videoStarted) { | |
mouseMove = true; | |
} | |
e.stopPropagation(); | |
e.preventDefault(); //just in case, to prevent the page from scrolling when the user is moving is finger on the player seekbar. | |
}); | |
this.seekBarElement.addEventListener('touchend', function(e){ | |
self.seekBarMouseDown = false; | |
player.pauseTimeWhenSeekPegHold(false); | |
//if (self.player.videoStarted) { //commented because unable to seek before play | |
self.trackSeekBarMousePosition(e); | |
e.stopPropagation(); | |
e.preventDefault(); | |
//} | |
__.removeClass(self.seekBarHandle, 'hover'); | |
}); | |
// emulated click on seekbar when video is not played yet | |
this.seekBarElement.addEventListener('click', function(e) { | |
self.seekBarMouseDown = false; | |
self.trackSeekBarMousePosition(e); | |
}); | |
// deferred seek will be done right after the first 'play' click | |
// reposition the progress mark and timer | |
if (this.settings.startOffset && player.mainRoll.duration) { | |
this.setSeekBarPosition(this.settings.startOffset, player.mainRoll.duration); | |
player.updateCurrentTime(this.settings.startOffset); | |
} | |
} | |
function listenPlayerEvents() { | |
} | |
addEventHandlers(); | |
listenPlayerEvents(); | |
return { | |
} | |
} | |
window.MHP1138 = window.MHP1138 || {}; | |
window.MHP1138.SeekBarController = SeekBarController; | |
})(window, __); | |
__.mixin({ | |
ajaxLoader: function(path, callback, error) { | |
var xmlhttp; | |
xmlhttp = new XMLHttpRequest(); | |
//xmlhttp.timeout = 10000; // 10sec | |
if (__.isFunction(callback)) { | |
xmlhttp.onreadystatechange = function() { | |
if (xmlhttp.readyState == XMLHttpRequest.DONE) { | |
if (xmlhttp.status == 200) { | |
callback(xmlhttp.responseText, xmlhttp.responseXML); | |
} | |
if (__.isFunction(error)) { | |
if (xmlhttp.status == 500 || xmlhttp.status == 404) { | |
error(); | |
} | |
} | |
} | |
} | |
} | |
xmlhttp.open("GET", path, true); | |
xmlhttp.send(); | |
} | |
}); | |
__.mixin({ | |
// we use zest lib to resolve selectors, but in most cases | |
// we dont need an array of elements, but just the first one | |
// xest is a macro for those calls, saves us some bytes | |
xest: function(sel) { | |
return zest(sel)[0]; | |
}, | |
fireEvent: function(player, eventName, additionalOptions) { | |
var options = { | |
playerType: player.playerType, | |
element: player.playerContainerElement | |
}; | |
__.extend(options, additionalOptions); | |
MHP1138.player.fireEvent(eventName, player.playerId, options); | |
} | |
}) | |
// Creating a Delay for any actions or events | |
__.mixin({ | |
debounce: function(func, wait, immediate) { | |
var timeout; | |
return function() { | |
var context = this, args = arguments; | |
var later = function() { | |
timeout = null; | |
if (!immediate) func.apply(context, args); | |
}; | |
var callNow = immediate && !timeout; | |
clearTimeout(timeout); | |
timeout = setTimeout(later, wait); | |
if (callNow) func.apply(context, args); | |
}; | |
} | |
}); | |
//innerHTML don't run script, so this extract them so they can be appended to the document in a different way. | |
//it also add the class prefix to every class. | |
var mhp_cssClassRegex = /\.-?[_a-zA-Z]+[_a-zA-Z0-9-]*(?=[^}]*\{)(?!.*\*\/)/g; //http://regexr.com/3b877 | |
__.mixin({ | |
colorLuminance: function(hex, lum){ | |
// validate hex string | |
hex = String(hex).replace(/[^0-9a-f]/gi, ''); | |
if (hex.length < 6) { | |
hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2]; | |
} | |
lum = lum || 0; | |
// convert to decimal and change luminosity | |
var rgb = "#", c, i; | |
for (i = 0; i < 3; i++) { | |
c = parseInt(hex.substr(i*2,2), 16); | |
c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16); | |
rgb += ("00"+c).substr(c.length); | |
} | |
return rgb; | |
}, | |
addPrefixToSkinElements: function(originalObject, prefix, playerId){ | |
var newObject = {}; | |
__.each(originalObject, function(value, key){ | |
if( __.isObject(value) ){ | |
newObject[key] = __.addPrefixToSkinElements(value, prefix, playerId); | |
}else{ | |
newObject[key] = '#' + playerId + ' ' + value.replace(/\./g, '.' + prefix + '_'); | |
} | |
}); | |
return newObject; | |
}, | |
addPrefixAndColorToSkinThemeCss: function(originalObject, prefix, playerId, themeColor){ | |
var newObject = []; | |
__.each(originalObject, function(css, key){ | |
//add prefix to classes | |
var css = css.replace(mhp_cssClassRegex, function(string){ | |
return '.' + prefix + '_' + string.substring(1); | |
}); | |
//add player id before css declaration | |
css = '#' + playerId + ' ' + css; | |
//change "themeColor(number)" in the css to the theme color.. if (number) is present after it modify the color luminosity | |
//http://regexr.com/3bh7g | |
css = css.replace(/themeColor(\(([\d-\.]+)\))?/, function(){ | |
if( !__.isUndefined(arguments[2]) && !__.isNaN(arguments[2]) ){ | |
return __.colorLuminance(themeColor, arguments[2]); | |
}else{ | |
return themeColor; | |
} | |
}); | |
newObject.push(css); | |
}); | |
return newObject; | |
} | |
}); | |
__.mixin({ | |
toMarkup: function(markup, prefix){ | |
var finalMarkup = ''; | |
__.each(markup, function(code, key) { | |
if ( __.isObject(code)) { | |
var attributes = code['_attributes'] || ''; | |
delete code['_attributes']; | |
finalMarkup += satisfy('.'+ key + attributes + '[html='+ __.toMarkup(code, prefix) +']', prefix)[0].outerHTML; | |
} else { | |
var elements = ''; | |
if (!__.isNull(code)) | |
__.each(satisfy(code, prefix), function(item){ | |
elements += item.outerHTML; | |
}); | |
finalMarkup += satisfy('.' + key + ((elements.length) ? '[html='+ elements +']' : ''), prefix)[0].outerHTML; | |
} | |
}); | |
return finalMarkup; | |
} | |
}); | |
__.mixin({ | |
secondToTime: function(time, separator){ | |
separator = separator || ':'; | |
var hours = Math.floor(time / 3600); | |
time = time - hours * 3600; | |
var minutes = Math.floor(time / 60); | |
var seconds = Math.floor(time % 60); | |
hours = (hours > 0 && hours < 10) ? '0' + hours : hours; | |
minutes = (minutes < 10) ? '0' + minutes : minutes; | |
seconds = (seconds < 10) ? '0' + seconds : seconds; | |
return ((hours) ? hours + separator : '') + minutes + separator + seconds; | |
} | |
}); | |
//Will check the z-index of an element and all it's children and return the highest z-index found. | |
//Usefull to be sure an element that catch events is over it's childrens whitout having to set a ridiculous z-index. | |
//Will return 0 in case of negative value. | |
__.mixin({ | |
getTopIndex: function(element){ | |
var topIndex = 0; | |
var thisIndex = parseInt(window.getComputedStyle(element).zIndex); | |
if( !__.isNaN(thisIndex) && thisIndex > topIndex ) | |
topIndex = parseInt(thisIndex); | |
if( element.childNodes.length ){ | |
__.each(element.childNodes, function(el){ | |
var childrenTopIndex = __.getTopIndex(el); | |
if( childrenTopIndex > topIndex ) | |
topIndex = childrenTopIndex; | |
}); | |
} | |
return topIndex; | |
} | |
}); | |
__.mixin({ | |
getElementsByClassName: function(node, classname){ | |
if(node.querySelectorAll){ | |
var a = [], | |
x = node.querySelectorAll('.' + classname); | |
if(x.length){ | |
for(var i = 0, ln = x.length; i < ln; i++){ | |
a.push(x[i]); | |
} | |
} | |
return a; | |
} else { | |
var a = []; | |
var re = new RegExp('(^| )'+classname+'( |$)'); | |
var els = node.getElementsByTagName("*"); | |
for(var i=0,j=els.length; i<j; i++) | |
if(re.test(els[i].className))a.push(els[i]); | |
return a; | |
} | |
} | |
}); | |
//Building simple hash from string | |
__.mixin({ | |
hashString: function(str) { | |
var hash = 0; | |
if (str.length === 0) return hash; | |
for (var i = 0, l = str.length; i < l; i++) { | |
var character = str.charCodeAt(i); | |
hash = ((hash<<5)-hash)+character; | |
hash = hash & hash; // Convert to 32bit integer | |
} | |
return Math.abs(hash); | |
} | |
}); | |
(function(window) { | |
'use strict'; | |
var selectors = { | |
controls: { | |
container: '.controls', | |
play: '.play', | |
pause: '.pause', | |
replay: '.replay', | |
time: { | |
elapsed: '.time_elapsed', | |
total: '.time_total' | |
}, | |
seekBar: { | |
container: '.seekBar', | |
progress: '.progress', | |
handle: '.handle' | |
}, | |
fullscreen: { | |
button: '.fullscreen', | |
}, | |
cardboard: { | |
button: '.cardboard', | |
}, | |
options: { | |
container: '.options', | |
qualityBtn: '.qualityBtn', | |
chromecastBtn: '.chromecastBtn', | |
chromecastIcon: '.chromecastBtn .icon', | |
menu: { | |
container: '.optionsMenu', | |
optionTabsContainer: '.menuTabs', | |
optionTabs: '.menuTitle', | |
optionTabActive: '.menuTitle.active', | |
optionTabHotspots: '.menuTitle.menuTitleHotspots', | |
qualityList: '.qualityList', // first tab | |
qualityItems: '.qualityList .optionsItem', | |
motionRates: '.motionRates', // second tab | |
hotspotsSwitch: '.hotspotsSwitch', // third tab | |
page: '.menuPage', | |
pages: '.menuPages', | |
pageActive: '.menuPage.active' | |
} | |
} | |
}, | |
hotspots: { | |
container: '.seekBar .hotspots', | |
svg: '.hotspots svg', | |
polygon: '.hotspots polygon', | |
progress: '.hotspots .hotspotsFill' | |
}, | |
topBar: { | |
container: '.topBar', | |
title: '.topBar .title span', | |
logo: '.topBar .logo' | |
}, | |
thumbnails: { | |
container: '.thumbnails', | |
sprite: '.thumbnails .sprite' | |
}, | |
preRollTitle: '.preRollTitle', | |
preRollSkipButton: '.preRollSkipButton', | |
eventCatcher: '.eventCatcher', | |
loading: '.loader', | |
videoErrorMessage: { | |
container: '.videoErrorMessage', | |
text: '.videoErrorMessage p' | |
} | |
}; | |
window.MHP1138 = window.MHP1138 || {}; | |
window.MHP1138.selectors = selectors; | |
})(window); | |
MHP1138.vast = function() { | |
return { | |
videoReady: false, | |
cachedFiles: {}, | |
status: 'empty', | |
errorUrl: '', | |
version: 0, | |
errorCode: 0, | |
linearAds: [], | |
nonLinearAds: [], | |
companionAds: [], | |
init: function(player, settings, rollType) { | |
this.player = player; | |
this.playerSettings = player.settings; | |
this.settings = settings; | |
this.rollType = rollType; | |
if (__.isString(settings.xml)) { | |
this.createXmlDom(settings.xml); | |
} | |
}, | |
createXmlDom: function(xmlData) { | |
var parser = new DOMParser(); | |
this.xml = parser.parseFromString(xmlData, "text/xml"); | |
if ((new XMLSerializer()).serializeToString(this.xml).indexOf('parsererror') != -1) { | |
this.errorParsingXml(); | |
} else { | |
this.status = 'created'; | |
this.parseData(); | |
} | |
}, | |
parseData: function() { | |
var root = this.xml.documentElement; | |
this.version = parseFloat(root.getAttribute('version')) || 0; | |
this.parseErrorTracking(root); | |
this.parseAds(root); | |
this.checkUnsupportedVastFeatures(root); | |
this.rootNode = root; | |
this.status = 'parsed'; | |
}, | |
parseAds: function(root) { | |
var self = this, | |
ads = root.getElementsByTagName('Ad') | |
this.rolls = []; | |
this.overlays = []; | |
__.each(ads, function(ad) { | |
self.checkUnsupportedAdFeatures(ad); | |
// converting 'HTMLCollections' returned by 'getElementsByTagName' to regular arrays | |
// (to use Array.concat method later) | |
var linears = [].slice.call(ad.getElementsByTagName('Linear')), | |
nonLinears = [].slice.call(ad.getElementsByTagName('NonLinear')), | |
companions = [].slice.call(ad.getElementsByTagName('Companion')), | |
impression = [].slice.call(ad.getElementsByTagName('Impression')), | |
arrString = ''; | |
if(__.isArray(impression)) { | |
arrString = impression.map(function(el){ | |
return el.textContent; | |
}).join('|'); | |
} else { | |
arrString = impression[0].textContent; | |
} | |
// HACKERY | |
// apply impression (trackUrl) to each video roll object because it is located in the upper Ad structure | |
// (not inside Linear node) | |
if (impression.length) { | |
__.each(linears, function(ad) { | |
ad.setAttribute('impression', arrString) | |
}); | |
} | |
// regular video ad rolls | |
self.linearAds = self.linearAds.concat(linears); | |
// non linear ads will become overlays | |
self.nonLinearAds = self.nonLinearAds.concat(nonLinears); | |
// storing them for future generations | |
self.companionAds = self.companionAds.concat(companions); | |
}); | |
__.each(this.linearAds, function(ad) { | |
var roll = self.parseLinearAd(ad); | |
if (roll) { | |
self.rolls.push(roll); | |
} | |
}); | |
__.each(this.nonLinearAds, function(ad) { | |
var banner = self.parseNonLinearAd(ad); | |
if (banner) { | |
self.overlays.push(banner); | |
} | |
}); | |
}, | |
parseLinearAd: function(ad) { | |
var durationNodes = ad.getElementsByTagName('Duration'), | |
skipDelay = this.parseTimeToSeconds(ad.getAttribute('skipoffset') || ''), | |
videoUrl = this.getMediaSrcByQuality(ad, this.player.selectedResolution); | |
if (!__.isPath(videoUrl)) return false; | |
// merged settings | |
var roll = __.deepExtend({}, this.playerSettings.defaultRollObject, this.settings.rollSettings) | |
// fill default object with data from xml | |
roll.vastParser = true; | |
roll.timing = this.rollType; | |
roll.videoUrl = videoUrl; | |
// parseClickTracking methid returns the same roll with | |
// created or updated clickUrl and clickTrackUrl fields | |
roll.campaign = __.hashString(roll.campaignName).toString(); | |
roll = this.parseClickTracking(ad, roll); | |
roll = this.parseImpressionTracking(ad, roll); | |
roll.tracking = this.parseTrackingEvents(ad); | |
// use skipDelay from VAST config | |
// could be dangerous | |
if (this.settings.vastSkipDelay && | |
skipDelay > 0 | |
) { | |
roll.skipDelay = skipDelay; | |
} | |
if (durationNodes.length) { | |
roll.duration = this.parseTimeToSeconds(String(durationNodes[0].textContent).trim()); | |
} | |
return roll; | |
}, | |
parseNonLinearAd: function(ad) { | |
// IframeResource and HTMLResource are basically the same entities | |
var imageNodes = ad.getElementsByTagName('StaticResource'), | |
htmlNodes = ad.getElementsByTagName('HTMLResource'), | |
iframeNodes = ad.getElementsByTagName('IFrameResource'), | |
overlay = { | |
hCentered: true, | |
border: true, | |
closeButton: true, | |
top: '10px', | |
width: ad.getAttribute('width') || 0 + 'px', | |
height: ad.getAttribute('height') || 0 + 'px', | |
time: 0, | |
duration: this.parseTimeToSeconds(ad.getAttribute('minSuggestedDuration') || '24:00:00') | |
}, | |
imageUrl, iframeUrl, clickUrl, trackingUrl; | |
// check the nodes | |
if (imageNodes.length) { | |
imageUrl = String(imageNodes[0].textContent).trim(); | |
} else if (htmlNodes.length) { | |
iframeUrl = String(htmlNodes[0].textContent).trim(); | |
} else if (iframeNodes.length) { | |
iframeUrl = String(iframeNodes[0].textContent).trim(); | |
} else { | |
return false; | |
} | |
// check the data | |
if (__.isPath(imageUrl)) { | |
overlay.imageUrl = imageUrl | |
// extract more fields for static banner | |
overlay = this.parseClickTracking(ad, overlay, 'NonLinear'); | |
} else if (__.isPath(iframeUrl)) { | |
overlay.iframeUrl = iframeUrl; | |
} else { | |
return false; | |
} | |
// check the player dimensions to place the banner | |
// TODO: refactoring needed. Cant do this at this point, since player container is not initialized yet | |
// | |
// if (!this.checkOverlayDimensions(overlay)) { | |
// this.reportError(501); | |
// return false; | |
// } | |
return overlay; | |
}, | |
checkOverlayDimensions: function(overlay) { | |
var container = this.player.playerContainerElement; | |
if (container.clientWidth < overlay.width || | |
container.clientHeight < overlay.height | |
) { | |
return false; | |
} | |
return true; | |
}, | |
parseTimeToSeconds: function(time) { | |
var parts = String(time).split(':'), | |
seconds = 0; | |
if (parts.length) { | |
seconds = parseInt(parts[parts.length-1]); | |
if (parts.length > 1) { | |
seconds += parseInt(parts[parts.length-2])*60; | |
} | |
if (parts.length > 2) { | |
seconds += parseInt(parts[parts.length-3])*60*60 | |
} | |
} else { | |
seconds = parseInt(time); | |
} | |
return seconds; | |
}, | |
getMediaSrcByQuality: function(ad, quality) { | |
var medias = ad.getElementsByTagName('MediaFile'), | |
mp4Medias = [], | |
mp4MediasQualities = [], | |
bestBiggerQuality = null; | |
if (medias.length) { | |
__.each(medias, function(media) { | |
if (media.getAttribute('type') == 'video/mp4') { | |
var height = media.getAttribute('height'); | |
mp4Medias[height] = media.textContent; | |
} | |
}); | |
if (mp4Medias.length) { | |
if(typeof mp4Medias[quality] !== 'undefined'){ | |
return String(mp4Medias[quality]).trim(); | |
} else { | |
mp4MediasQualities = __.keys(mp4Medias); | |
bestBiggerQuality = parseInt(mp4MediasQualities[mp4MediasQualities.length - 1]); | |
quality = parseInt(quality); | |
__.each(mp4MediasQualities, function(mediaQuality, index) { | |
mediaQuality = parseInt(mediaQuality); | |
// Get best bigger quality | |
if((quality - mediaQuality) < 0 && Math.abs(quality - mediaQuality) <= Math.abs(quality - bestBiggerQuality)){ | |
bestBiggerQuality = mediaQuality; | |
} | |
}); | |
return String(mp4Medias[bestBiggerQuality]).trim(); | |
} | |
} else { | |
this.reportError(403); | |
return false; | |
} | |
} else { | |
// Couldn’t find MediaFile that is supported by this video player, | |
// based on the attributes of the MediaFile element. | |
this.reportError(403); | |
return false; | |
} | |
}, | |
parseErrorTracking: function(root) { | |
var error = root.getElementsByTagName('Error'); | |
if (error.length) { | |
this.errorUrl = error[0].textContent || ''; | |
} | |
}, | |
parseImpressionTracking: function(ad, roll) { | |
var impressionUrl = String(ad.getAttribute('impression') || '').trim(), | |
defaultTrackUrl = this.playerSettings.htmlSettings.adsTrackUrl; | |
impressionUrl = (impressionUrl.indexOf('|') > -1) ? impressionUrl.split('|') : impressionUrl; | |
if (__.isArray(impressionUrl)) { | |
roll.impressionUrl = impressionUrl; | |
roll.impressionUrl.push(defaultTrackUrl); | |
} else { | |
roll.impressionUrl = [impressionUrl, defaultTrackUrl]; | |
} | |
return roll; | |
}, | |
parseClickTracking: function(ad, roll, prefix) { | |
var defaultTrackUrl = this.playerSettings.htmlSettings.adsTrackUrl, | |
prefix = prefix || '', | |
clickNodes = ad.getElementsByTagName(prefix + 'ClickThrough'), | |
clickUrl = (clickNodes.length ? clickNodes[0].textContent : ''), | |
customClickNodes = ad.getElementsByTagName(prefix + 'CustomClick'), | |
clickTrackingNodes = [].slice.call(ad.getElementsByTagName(prefix + 'ClickTracking')); | |
if (customClickNodes.length || | |
clickTrackingNodes.length | |
) { | |
if (!clickUrl) { | |
clickUrl = '#'; // emulate url to be able to track clicks | |
} | |
roll.clickTrackUrl = []; | |
if (customClickNodes.length) { | |
roll.clickTrackUrl.push(String(customClickNodes[0].textContent).trim()); | |
} | |
if (clickTrackingNodes.length) { | |
__.each(clickTrackingNodes, function(node) { | |
roll.clickTrackUrl.push(String(node.textContent).trim()); | |
}); | |
} | |
roll.clickTrackUrl.push(defaultTrackUrl); | |
} | |
roll.clickUrl = clickUrl; | |
return roll; | |
}, | |
parseTrackingEvents: function(ad) { | |
var tracking = {}, | |
trackingNodes = ad.getElementsByTagName('Tracking'); | |
__.each(trackingNodes, function(node) { | |
var event = node.getAttribute('event'), | |
url = node.textContent; | |
if (event && __.isPath(url)) { | |
if (__.isUndefined(tracking[event])) { | |
tracking[event] = [url]; | |
} else { | |
tracking[event].push(url); | |
} | |
} | |
}); | |
return tracking; | |
}, | |
track: function(action) { | |
}, | |
checkUnsupportedVastFeatures: function(root) { | |
if (root.getElementsByTagName('Wrapper').length) { | |
this.errorUnsupportedFeature('Wrapper', 300); // General Wrapper error. | |
} | |
if (root.getElementsByTagName('Extension').length) { | |
this.errorUnsupportedFeature('Extension'); | |
} | |
if (root.getElementsByTagName('AdVerifications').length || | |
root.getElementsByTagName('Verification').length | |
) { | |
this.errorUnsupportedFeature('AdVerifications'); | |
} | |
if (root.getElementsByTagName('CompanionAds').length || | |
root.getElementsByTagName('Companion').length | |
) { | |
this.errorUnsupportedFeature('CompanionAds', 600); // General CompanionAds error. | |
} | |
}, | |
checkUnsupportedAdFeatures: function(ad) { | |
if (parseInt(ad.getAttribute('sequence')) > 0) { | |
this.errorUnsupportedFeature('Ad Pods'); | |
} | |
if (ad.getAttribute('conditionalAd')) { | |
this.errorUnsupportedFeature('Conditional Ads'); | |
} | |
if (ad.getElementsByTagName('Icons').length || | |
ad.getElementsByTagName('Icon').length | |
) { | |
this.errorUnsupportedFeature('Icon'); | |
} | |
}, | |
reportError: function(code) { | |
if (!code) { | |
code = 900; // Unidentified error | |
} | |
if (this.errorUrl) { | |
__.ajaxLoader(this.errorUrl.replace('[ERRORCODE]', code)); | |
} | |
// store last fired error code for debugging purposes | |
this.errorCode = code; | |
}, | |
errorLoadingXml: function() { | |
console.warn('VAST Parser: error loading XML file, player continues to work without "' + this.rollType + 'Roll" data'); | |
this.status = 'error'; | |
}, | |
errorParsingXml: function() { | |
console.warn('VAST Parser: error parsing XML file, player continues to work without "' + this.rollType + 'Roll" data'); | |
this.reportError(100); // XML parsing error | |
this.status = 'error'; | |
}, | |
errorUnsupportedFeature: function(featureName, code) { | |
console.warn('VAST Parser: No "' + featureName + '" support yet'); | |
if (code) { | |
this.reportError(code); | |
} | |
} | |
} | |
}; | |
(function(window, _) { | |
'use strict'; | |
var xest = _.xest; | |
/** | |
* Shows blurred thumbnail on top of the video for timestamp | |
* | |
* @param {HTMLElement} playerContainer | |
* @param {object} elements | |
* @param {function} subscribeToEvent | |
* @param {function} getThumbnail | |
* @param {float} blurLevel | |
*/ | |
var ThumbnailsController = function(playerContainer, elements, subscribeToEvent, getThumbnail, blurLevel) { | |
var container, image, thumbnail, spritesheet, disabled; | |
// initialize selectors | |
container = xest(elements.container); | |
image = xest(elements.sprite); | |
function hide() { | |
_.removeClass(container, 'visible'); | |
} | |
function show(seconds) { | |
if (disabled) return; | |
getThumbnail(seconds, function(thumb, sheet) { | |
_.addClass(container, 'visible'); | |
setImage(thumb, sheet); | |
// save latest values; | |
thumbnail = thumb; | |
spritesheet = sheet; | |
}); | |
} | |
function disable() { | |
disabled = true; | |
} | |
function enable() { | |
disabled = false; | |
} | |
function setImage(thumb, sheet) { | |
if (image.style.backgroundImage.indexOf(sheet.url) == -1) { | |
image.style.backgroundImage = 'url(' + sheet.url + ')'; | |
image.style.width = sheet.thumbWidth + 'px'; | |
image.style.height = sheet.thumbHeight + 'px'; | |
setContainerScale(sheet); | |
} | |
image.style.backgroundPosition = thumb.cssLeft + ' ' + thumb.cssTop; | |
// save them globally | |
thumbnail = thumb; | |
spritesheet = sheet; | |
} | |
function setBlur(value) { | |
var blur = ''; | |
if (value > 0) { | |
blur = 'blur(' + parseInt(value) + 'px)'; | |
} | |
image.style.filter = blur; | |
image.style.webkitBackdropFilter = blur; //some verion of ios doesn't support filter | |
} | |
function setContainerScale(sheet) { | |
var vScale = playerContainer.clientWidth / sheet.thumbWidth, | |
hScale = playerContainer.clientHeight / sheet.thumbHeight, | |
scaleFactor = Math.min(vScale, hScale); | |
container.style.transform = 'scale(' + scaleFactor + ')'; | |
} | |
function listenPlayerEvents() { | |
subscribeToEvent('onPlay', function() { | |
if (disabled) return; | |
hide(); | |
}); | |
subscribeToEvent('onPause', function(i,e,player) { | |
if (!player.videoStarted) return; | |
if (disabled) return; | |
hide(); | |
}); | |
} | |
function listenWindowEvents() { | |
// recalculate container dimensions after phone was rotated | |
// using the last saved spritesheet | |
window.addEventListener('orientationchange', function() { | |
if (spritesheet) { | |
setContainerScale(spritesheet); | |
} | |
}); | |
window.addEventListener('resize', function() { | |
if (spritesheet) { | |
setContainerScale(spritesheet); | |
} | |
}); | |
} | |
listenPlayerEvents(); | |
listenWindowEvents(); | |
hide(); | |
if (blurLevel) { | |
setBlur(blurLevel); | |
} | |
return { | |
disable: disable, | |
enable: enable, | |
hide: hide, | |
show: show, | |
thumbnail: thumbnail, | |
spritesheet: spritesheet, | |
setBlur: setBlur | |
}; | |
}; | |
window.MHP1138 = window.MHP1138 || {}; | |
window.MHP1138.ThumbnailsController = ThumbnailsController; | |
})(window, __); | |
(function(window) { | |
'use strict'; | |
var chrome = window.chrome; | |
var Chromecast = function(player, fireEvent) { | |
var session = null, | |
castTimeupdateDelay = 250, | |
castTimeInterval = null, | |
castFinished = false, | |
seeking = false; | |
/** | |
* Main function to initiate the necessary component to start the Chromecast API | |
*/ | |
function initChromecast() { | |
var initialized = false; | |
/** | |
* Main Setup function to start the API | |
*/ | |
function initializeCastApi() { | |
// do this only once | |
if (initialized) return false; | |
var sessionRequest = new chrome.cast.SessionRequest(chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID); | |
var apiConfig = new chrome.cast.ApiConfig(sessionRequest, | |
sessionListener, | |
receiverListener | |
); | |
chrome.cast.initialize(apiConfig, onInitSuccess, onError); | |
initialized = true; | |
} | |
if (window.chrome && chrome.cast && chrome.cast.isAvailable) { | |
initializeCastApi(); | |
} else { | |
setTimeout(function() { | |
if (window.chrome && chrome.cast && chrome.cast.isAvailable) { | |
initializeCastApi(); | |
} | |
}, 1000); | |
} | |
/** | |
* Listens to receivers being available or not through the API. When a wep page loads, this will always turn negative. | |
* It will return AVAILABLE only if there's at least one CHROMECAST device available | |
* | |
* @param {object} e - Gives the receiver availability, given by the API Config | |
*/ | |
function receiverListener(e) { | |
if (e === chrome.cast.ReceiverAvailability.AVAILABLE) { | |
fireEvent('chromecastAvailable', { available: true }); | |
} else { | |
fireEvent('chromecastAvailable', { available: false }); | |
} | |
} | |
/** | |
* Found existing session on init | |
*/ | |
function sessionListener(e) { | |
session = e; | |
if (session.media.length !== 0) { | |
//onMediaDiscovered('onRequestSessionSuccess', session.media[0]); | |
} | |
} | |
/** | |
* Fires when the API is succesfully initiated | |
*/ | |
function onInitSuccess() { | |
//When API is initiated | |
} | |
/** | |
* Fires when the API is not succesfully initiated | |
*/ | |
function onError() { | |
//TO DO: Send a warning message in console or do a thing | |
} | |
} | |
/** | |
* Sets a regulated interval to ask Chromecast for synchronizing time | |
*/ | |
function setTimeUpdateInterval() { | |
var self = this; | |
clearInterval(castTimeInterval); | |
function updateSenderAppTime() { | |
player.updateCurrentTime(self.media.getEstimatedTime()); | |
} | |
castTimeInterval = setInterval(updateSenderAppTime, castTimeupdateDelay); | |
} | |
initChromecast(); | |
return { | |
available: false, | |
active: false, | |
media: null, | |
/** | |
* Main function that requests a Chromecast session once the API is setup | |
*/ | |
requestSession: function(){ | |
var self = this; | |
/** | |
* This fires if the session is correctly requested. | |
* The function will pause the video and request the media to be loaded on the established session | |
* | |
* @param {object} e - Stores the chromecast session object | |
*/ | |
function onRequestSessionSuccess(e) { | |
session = e; | |
/** | |
* Adds an update listner to the newly established session. | |
* Whenever the session send an update, we can check if the Chromecast is still connected. | |
* We can then send the appropriate response to the ORION depending of the current state of the video. | |
*/ | |
session.addUpdateListener(function() { | |
if (session.status !== chrome.cast.SessionStatus.CONNECTED) { | |
if (!castFinished) { | |
// we could also get session disconnect event without media initialized | |
if (this.media) { | |
//Sets Player current time to what time was on the chromecast | |
player.playing = false; | |
player.playAfterSeek = false; | |
player.playerElement.currentTime = this.media.getEstimatedTime(); | |
} | |
//Sets the player in pause mode | |
fireEvent('onPause'); | |
} | |
self.setActiveState(false); | |
} | |
}); | |
player.pause(); | |
self.runMedia(player.videoSources[player.selectedResolution].videoUrl); | |
} | |
/** | |
* If the session cannot launch correctly, it fires and tells the error | |
*/ | |
function onLaunchError() { | |
self.setActiveState(false); | |
//TO DO: Set up a warning console error if session doesn't fire | |
} | |
/** | |
* Requests the session based of the api and the selected device prior to this. | |
*/ | |
chrome.cast.requestSession(onRequestSessionSuccess, onLaunchError); | |
}, | |
/** | |
* Handles the media request, sets listeners and events based of the media load or not | |
* | |
* @param {string} mediaLink - Optional setting, you can chose to submit the media link to be requested. Mostly used for quality selection. | |
*/ | |
runMedia: function(mediaUrl) { | |
var mediaInfo = new chrome.cast.media.MediaInfo(mediaUrl); | |
mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata(); | |
mediaInfo.metadata.title = player.settings.mainRoll.title; | |
mediaInfo.metadata.subtitle = player.selectedResolution + 'p'; | |
// var poster = new chrome.cast.Image(player.settings.mainRoll.poster); | |
// mediaInfo.metadata.images = [poster]; | |
var request = new chrome.cast.media.LoadRequest(mediaInfo), | |
self = this; | |
/** | |
* Show spinner before init | |
*/ | |
fireEvent('onWaiting'); | |
clearInterval(castTimeInterval); | |
this.videoChange = true; | |
/** | |
* Loads media and depnding on the success or not, will return appropriate response | |
* | |
* @param {object} request - Request object containing the information about the media | |
* @param {function} sucessCallback - Callback function for when the media has been properly loaded | |
* @param {function} failureCallback - Callback function for when the media fails to load | |
*/ | |
session.loadMedia( | |
request, | |
onMediaDiscovered.bind(this, 'loadMedia'), | |
onMediaError | |
); | |
/** | |
* Update listener when the media updates on Play, Stop, Pause, Buffer and a variety of other elements. | |
* In this particular case, we check if the chromecast player is idle and if so, has the playback finshed we stop the session and revert the controls back to the player. | |
*/ | |
function onMediaStatusUpdate() { | |
var state = self.media.playerState; | |
if (state === 'PLAYING') { | |
// do not fire play / pause events while seeking | |
if (seeking) return; | |
player.seeking = false; | |
player.playing = true; | |
fireEvent('onPlay'); | |
setTimeUpdateInterval.call(self); | |
self.videoChange = false; | |
} else if (state === 'PAUSED') { | |
// do not fire play / pause events while seeking | |
if (seeking) return; | |
// do not react on paused events while changing media stream | |
// the cake is a lie | |
if (self.videoChange) return; | |
player.playing = false; | |
fireEvent('onPause'); | |
clearInterval(castTimeInterval); | |
} else if (state === 'BUFFERING') { | |
fireEvent('onWaiting'); | |
// chromecast fires several play / pause events before _actual_ seek (for unknown reasons), | |
// only buffering state is the true signal it actually seeked to somewhere | |
// the right time to remove the flag | |
if (seeking === true) { | |
seeking = false; | |
} | |
} else if (state === 'IDLE') { | |
if (self.media.idleReason === "FINISHED") { | |
self.stopSession(); | |
fireEvent('onEnd'); | |
} | |
} | |
} | |
/** | |
* Sets a lot of things in motion for when the media is successfully loaded upon the chromecast | |
* Player behavior and timer initiation are such example. | |
* | |
* @param {object} how - No idea what that thing does, but it do. | |
* @param {object} media - Contains the Chromecast media object returned on successful callback | |
*/ | |
function onMediaDiscovered(how, media) { | |
self.setActiveState(true); | |
media.addUpdateListener(onMediaStatusUpdate); | |
self.media = media; | |
setTimeUpdateInterval.call(self); | |
//Resets the value if the user finished the video once | |
castFinished = false; | |
if (player.videoStarted) { | |
var duration = player.duration, | |
currentPos = player.skin.currentSeekBarPosition; | |
self.seek(currentPos * duration / 100); | |
} | |
player.videoStarted = true; | |
} | |
/** | |
* Callback function if the media is not loaded properly | |
*/ | |
function onMediaError(error) { | |
window.console.log(error); | |
self.setActiveState(false); | |
} | |
}, | |
seek: function(seekTime, playAfter) { | |
var self = this, | |
request = new chrome.cast.media.SeekRequest(); | |
function onSeekSuccess() { | |
player.updateCurrentTime(self.media.getEstimatedTime()); | |
if (playAfter) { | |
self.media.play(); | |
} else { | |
self.media.pause(); | |
} | |
setTimeout(function() { | |
seeking = false; | |
}, 500); | |
} | |
function onSeekError(error) { | |
window.console.log(error); | |
} | |
seeking = true; | |
fireEvent('onSeek'); | |
request.currentTime = seekTime; | |
this.media.seek(request, onSeekSuccess, onSeekError); | |
}, | |
setActiveState: function(flag) { | |
fireEvent('onCasting', { chromecast: flag }); | |
this.active = flag; | |
}, | |
stopSession: function() { | |
castFinished = true; | |
this.pause(); | |
this.setActiveState(false); | |
clearInterval(castTimeInterval); | |
player.seek(this.media.getEstimatedTime(), false); | |
fireEvent('onSeek'); | |
session.stop(); | |
}, | |
startVideo: function() { this.requestSession(); }, | |
play: function() { | |
this.media.play(); | |
}, | |
pause: function() { | |
this.media.pause(); | |
} | |
}; | |
}; | |
window.MHP1138 = window.MHP1138 || {}; | |
window.MHP1138.Chromecast = Chromecast; | |
})(window); | |
function mhp1138_skin() { | |
var l; | |
var ss = function(selector) { | |
selector = selector.replace(/\.(\S+?)/g, ".mhp1138_$1"); | |
return satisfy(selector); | |
}; | |
var s = function(selector) { | |
return ss(selector)[0]; | |
}; | |
return { | |
/*the key in elementsClassName should never be changed, only the value | |
should be changed.*/ | |
seekBarHandleWidth: 24, | |
thumbnailsPreview: {}, | |
controlsBarVisible: true, | |
//INIT THE SKIN | |
init: function(player, callback) { | |
var self = this; | |
this.player = player; | |
this.settings = player.settings; | |
this.container = player.playerContainerElement; | |
l = player.l10n.localize; | |
// localizing + proxifying global function | |
this.subscribeToEvent = function(eventName, callback) { | |
return MHP1138.player.subscribeToEvent(eventName, player.playerId, callback); | |
} | |
//this.setPlayerState('buffering'); | |
//this.setPlayerState('ready'); | |
this.subscribeToPlayerEvents(); | |
this.initTimeLabels(); | |
this.initPlaybackControls(); | |
this.initNextVideoBtn(); | |
this.initShowControlsOnTouch(); | |
this.initFullscreenBtn(); | |
this.initCardboardBtn(); | |
this.initChromecastBtn(); | |
if (MHP1138.ThumbnailsController && player.thumbnails && player.settings.features.seekPreview) { | |
this.thumbnailsController = new MHP1138.ThumbnailsController( | |
player.playerContainerElement, // player container | |
this.elements.thumbnails, // thumbnails markup selectors | |
this.subscribeToEvent, // method to subscribe on player events | |
player.thumbnails.get, // method to retrieve thumbnail info, | |
player.settings.features.seekPreviewBlur // default blur value from config | |
); | |
} | |
this.initSeekBar(); | |
this.initTopBar(); | |
this.initEventCatcher(); | |
this.initBigPlayBtn(); | |
if (this.settings.hotspots.enabled){ | |
this.initHotspotsElements(); | |
this.createHotspotsOptionTab(); | |
this.createHotspotsGraph(); | |
} | |
this.createMotionRateTab(); | |
this.createQualityMenu(); | |
this.initOptionsTabs(); | |
this.initStartOffset(); | |
// some buttons are created dynamically, init hovers after all that | |
this.initButtonHoversOnTouch(); | |
this.initIosControls(); | |
callback(); | |
}, | |
//TOP BAR | |
initTopBar: function() { | |
if(!this.player.settings.features.topControlBar) return; | |
var player = this.player, | |
self = this, | |
topBar = this.elements.topBar, | |
embeds = this.settings.embeds, | |
redirect = embeds.redirect.logoUrl, | |
logoNode = __.xest(topBar.logo), | |
topBarTitleNode = __.xest(topBar.title), | |
logoTemplate = __.xest( | |
'#mhp1138_skin' + | |
' .mhp1138_logo_'+ this.settings.quickSetup | |
); | |
if (!__.isUndefined(logoTemplate)) { | |
logoNode.innerHTML = logoTemplate.innerHTML; | |
} | |
if (player.mainRoll.title.length) { | |
topBarTitleNode.innerHTML = player.mainRoll.title; | |
__.addClass(topBarTitleNode, 'isLink'); | |
} | |
var changeEmbedURL = function(url, str){ | |
return player.addUTM(player.addCurrentTimeToUrl(url), 'embed-mobile', 'embed-' + str + '-html5'); | |
} | |
if (__.isPath(redirect)) { | |
this.addClickEvent(topBarTitleNode, function(e) { | |
e.preventDefault(); | |
e.stopPropagation(); | |
player.openRedirectWindow((embeds.enabled && embeds.utmRedirect.title) ? changeEmbedURL(redirect, 'title') : redirect); | |
if (!player.seeking) { | |
player.pause(); | |
} else { | |
self.checkPageVisibilityAndPause(); | |
} | |
}); | |
this.addClickEvent(logoNode, function(e) { | |
e.preventDefault(); | |
e.stopPropagation(); | |
player.openRedirectWindow((embeds.enabled && embeds.utmRedirect.title) ? changeEmbedURL(redirect, 'logo') : redirect); | |
if (!player.seeking) { | |
player.pause(); | |
} else { | |
self.checkPageVisibilityAndPause(); | |
} | |
}); | |
} | |
}, | |
// proxy function to duplicate mouse touch event handlers | |
addClickEvent: function(el, func) { | |
var touchStartY, fingerMoved; | |
el.addEventListener('touchstart', function(e) { | |
touchStartY = e.touches[0].screenY; | |
fingerMoved = false; | |
}); | |
el.addEventListener('touchmove', function(e) { | |
if (Math.abs(touchStartY - e.changedTouches[0].screenY) > 10) { | |
fingerMoved = true; | |
} | |
}); | |
el.addEventListener('touchend', function(e) { | |
if (!fingerMoved) { | |
func.call(this, e); | |
} | |
}); | |
el.addEventListener('mouseup', func); | |
}, | |
subscribeToPlayerEvents: function() { | |
var self = this, | |
player = this.player, | |
settings = this.settings, | |
subscribeToEvent = this.subscribeToEvent, | |
// playback was started by seek action | |
// need to hide controls instantly in this case | |
firstTimePlaying = true, | |
readySource = false; | |
subscribeToEvent('onVideoReady', function() { | |
self.setPlayerState('ready'); | |
if (player.hlsSource) { | |
__.addClass(player.playerContainerElement, 'hlsStream'); | |
} else { | |
__.removeClass(player.playerContainerElement, 'hlsStream'); | |
} | |
if (player.dashSource) { | |
__.addClass(player.playerContainerElement, 'dashStream'); | |
} else { | |
__.removeClass(player.playerContainerElement, 'dashStream'); | |
} | |
}); | |
subscribeToEvent('onPlay', function(i,e,o) { | |
self.setPlayerState('playing'); | |
// wait 2 seconds before hiding controls after seek | |
if (!firstTimePlaying && o.playAfterSeek || settings.embeds.enabled) { | |
self.autoHideControls(); | |
// but hide them instantly on direct action | |
} else { | |
self.hideControls(); | |
} | |
// initial seek generates two onPlay events because of bug in core logic, | |
// need to disable firstTimePlaying flag only after that | |
setTimeout(function() { | |
firstTimePlaying = false; | |
}, 100); | |
self.hideOptionsMenu(); | |
}); | |
subscribeToEvent('onPause', function() { | |
// ignore pause events if the user started to drag the peg. | |
// UI should stay in exactly the same state as before we started drag | |
if (settings.features.seekPreview && self.seekBarMouseDown) return; | |
self.setPlayerState('paused'); | |
self.hideOptionsMenu(); | |
self.showControls(); | |
}); | |
subscribeToEvent('onSeek', function(i,e,o) { | |
self.setPlayerState('buffering'); | |
// show controls and spinner all time we seek | |
// no 2sec autohide | |
self.showControls(true); | |
}); | |
subscribeToEvent('onWaiting', function() { | |
self.setPlayerState('buffering'); | |
}); | |
subscribeToEvent('onQualityChange', function() { | |
self.setPlayerState('buffering'); | |
self.hideOptionsMenu(); | |
// show controls and spinner all time we change quality / stream | |
// no 2sec autohide | |
self.showControls(true); | |
}); | |
subscribeToEvent('onDurationChange', function(i,e,o) { | |
self.durationTime.innerHTML = __.secondToTime(o.duration); | |
}); | |
subscribeToEvent('onTimeChange', function(i,e,o) { | |
self.currentTime.innerHTML = __.secondToTime(o.time); | |
if (self.seekBarMouseDown) return false; | |
self.seekPosition = (o.time * 100 / player.duration); | |
self.updateSeekBarPosition(); | |
}); | |
subscribeToEvent('onEnd', function() { | |
self.setPlayerState('replay'); | |
// no 2sec autohide | |
self.showControls(true); | |
}); | |
subscribeToEvent('onFullscreen', function(i,e,o) { | |
self.setFullscreenState(o.fullscreen); | |
if (!o.fullscreen && | |
self.settings.isVr | |
) { | |
self.setCardboardState(false); | |
} | |
self.showControls(); | |
}); | |
subscribeToEvent('chromecastAvailable', function(i,e,o) { | |
if (o.available) { | |
__.addClass(self.container, 'chromecastV2'); | |
} else { | |
__.removeClass(self.container, 'chromecastV2'); | |
} | |
}); | |
subscribeToEvent('onCasting', function(i,e,o) { | |
self.setChromecastState(o.chromecast); | |
if (!o.chromecast) { | |
// reset loading spinner | |
self.setPlayerState('paused'); | |
} | |
}); | |
subscribeToEvent('onHotspotsStateChange', function(i,e,o) { | |
self.setHotspotsState(o.hotspotsState); | |
self.toggleHotspotsGraphVisibility(); | |
}); | |
subscribeToEvent('onSlowMotionChange', function(i,e,o) { | |
self.toggleMotionSpeed(o.motionRate); | |
}); | |
subscribeToEvent('hideRoll', function() { | |
self.showSeekPeg(); | |
}); | |
}, | |
videoNotAvailable: function() { | |
var elements = this.elements, | |
videoErrorMessage = elements.videoErrorMessage; | |
__.xest(videoErrorMessage.container).style.display = 'block'; | |
var message = this.player.mainRoll.videoUnavailableMessage || this.settings.htmlSettings.notAvailableMessage; | |
message = l(this.settings.htmlSettings.notAvailableMessage); | |
__.xest(videoErrorMessage.text).textContent = message; | |
}, | |
setPlayerState: function(state) { | |
var container = this.container, | |
playerStates = ['ready', 'buffering', 'playing', 'paused', 'replay']; | |
if (playerStates.indexOf(state) != -1) { | |
__.each(playerStates, function(state) { | |
__.removeClass(container, state + 'State'); | |
}) | |
__.addClass(container, state + 'State'); | |
this.playerState = state; | |
} | |
}, | |
setFullscreenState: function(state) { | |
this.setButtonState(state, this.fullscreenBtn, 'fullscreenState'); | |
}, | |
setCardboardState: function(state) { | |
this.setButtonState(state, this.cardboardBtn, 'cardboardState'); | |
}, | |
setChromecastState: function(state) { | |
if (state) { | |
__.removeClass(this.chromecastIcon, 'icon-chromecast'); | |
__.addClass(this.chromecastIcon, 'icon-chromecast-on'); | |
} else { | |
__.removeClass(this.chromecastIcon, 'icon-chromecast-on'); | |
__.addClass(this.chromecastIcon, 'icon-chromecast'); | |
} | |
}, | |
setButtonState: function(state, element, className) { | |
if (state) { | |
__.addClass(element, className); | |
} else { | |
__.removeClass(element, className); | |
} | |
}, | |
//SEEK BAR | |
initSeekBar: function() { | |
var self = this, | |
player = this.player, | |
seekBar = this.elements.controls.seekBar; | |
this.seekBarElement = __.xest(seekBar.container); | |
this.seekBarProgressElement = __.xest(seekBar.progress); | |
this.seekBarHandle = __.xest(seekBar.handle); | |
if(this.player.preRoll.enabled) { | |
__.addClass(this.seekBarHandle, 'hidden'); | |
} | |
// calculate it initially for mouse events | |
this.seekBarElement.addEventListener('mousedown', function(e){ | |
self.seekBarZoneOffset = self.seekBarElement.getBoundingClientRect(); | |
}); | |
this.seekBarElement.addEventListener('touchstart', function(e){ | |
self.seekBarMouseDown = true; | |
//we set this bool to true but it does not mean it's true, but if the "touchmove" events don't set it to false | |
//then we will know it was only a touch event when we reach the "touchend" event. | |
//we only calculate the bounding zone on the initial mousedown event to save cpu ressources | |
//calculating it on every pixel during the mousemove event could use a lot of ressources for nothing. | |
self.seekBarZoneOffset = self.seekBarElement.getBoundingClientRect(); | |
self.touchX = e.touches[0].pageX; | |
//self.trackSeekBarMousePosition(e); | |
__.addClass(self.seekBarHandle, 'hover'); | |
self.clearAutoHideControls(); | |
if (self.player.videoStarted) { | |
if (self.settings.features.seekPreview && !self.player.preRoll.enabled) { | |
player.pause(); | |
} | |
player.pauseTimeWhenSeekPegHold(true); | |
e.stopPropagation(); | |
e.preventDefault(); | |
} | |
}); | |
this.seekBarElement.addEventListener('touchmove', function(e){ | |
self.trackSeekBarMousePosition(e); | |
if (!self.player.videoStarted) { | |
self.mouseMove = true; | |
} | |
e.stopPropagation(); | |
e.preventDefault(); //just in case, to prevent the page from scrolling when the user is moving is finger on the player seekbar. | |
}); | |
this.seekBarElement.addEventListener('touchend', function(e){ | |
self.seekBarMouseDown = false; | |
player.pauseTimeWhenSeekPegHold(false); | |
//if (self.player.videoStarted) { //commented because unable to seek before play | |
self.trackSeekBarMousePosition(e); | |
e.stopPropagation(); | |
e.preventDefault(); | |
//} | |
__.removeClass(self.seekBarHandle, 'hover'); | |
}); | |
// emulated click on seekbar when video is not played yet | |
this.seekBarElement.addEventListener('click', function(e) { | |
self.seekBarMouseDown = false; | |
self.trackSeekBarMousePosition(e); | |
}); | |
}, | |
showSeekPeg: function() { | |
__.removeClass(this.seekBarHandle, 'hidden'); | |
}, | |
initStartOffset: function() { | |
// deferred seek will be done right after the first 'play' click | |
// reposition the progress mark and timer | |
if (!this.player.preRoll.enabled && this.settings.startOffset && this.player.mainRoll.duration) { | |
this.setSeekBarPosition(this.settings.startOffset, this.player.mainRoll.duration); | |
this.player.updateCurrentTime(this.settings.startOffset); | |
} | |
}, | |
setSeekBarPosition: function(time, duration) { | |
this.seekPosition = time * 100 / duration; | |
this.updateSeekBarPosition(); | |
}, | |
//Repeats Desktop version | |
seekBarAddAnimation: function() { | |
//__.addClass(this.seekBarElement, 'animated'); | |
}, | |
//Repeats Desktop version | |
seekBarRemoveAnimation: function() { | |
//__.removeClass(this.seekBarElement, 'animated'); | |
}, | |
trackSeekBarMousePosition: function(e){ | |
var position = this.calculateSeekbarMousePositionFromEvent(e, this.seekBarZoneOffset), | |
previousSeekPosition = this.seekPosition, | |
duration = this.player.playerElement.duration; | |
if (this.player.preRoll.enabled) return false; | |
this.seekPosition = this.pixelToPercent(position.position, position.range); | |
if (!duration) { | |
duration = this.player.duration; | |
} | |
var seconds = this.seekPosition * duration / 100; | |
if (this.seekPosition !== previousSeekPosition) { | |
this.updateSeekBarPosition(); | |
if (this.thumbnailsController) { | |
this.thumbnailsController.show(seconds); | |
} | |
this.player.updateCurrentTime(seconds); | |
} | |
if (!this.seekBarMouseDown) { | |
if (this.mouseMove) { | |
this.player.seek(seconds, false); | |
this.mouseMove = false; | |
} else { | |
this.player.seek(seconds, true); | |
} | |
} | |
}, | |
updateSeekBarPosition: function() { | |
var add = parseFloat(-100) + parseFloat(this.seekPosition); | |
var cssTranslate = 'translate3d('+ (add + '%')+',0,0)'; | |
this.seekBarProgressElement.style.webkitTransform = cssTranslate; | |
this.seekBarProgressElement.style.mozTransform = cssTranslate; | |
this.seekBarProgressElement.style.transform = cssTranslate; | |
if (!__.isUndefined(this.hotspotsProgress) && !__.isNaN(this.seekPosition)) { | |
this.hotspotsProgress.setAttribute('transform', 'translate(' + (1000/100*this.seekPosition-1000) + ')'); | |
} | |
}, | |
percentToCurrentTime: function(percent){ | |
return Math.round(percent * this.player.duration / 100); | |
}, | |
//has it's own function since multiple thing use this calculation. | |
calculateSeekbarMousePositionFromEvent: function(e, seekbarBound) { | |
if (e.clientX) { | |
var pageX = e.clientX; | |
} else if (e.touches && e.touches.length) { | |
var pageX = e.touches[0].clientX; | |
} else if (e.changedTouches && e.changedTouches.length) { | |
var pageX = e.changedTouches[0].clientX; | |
} | |
var position = pageX - (seekbarBound.left + window.pageXOffset); | |
var range = seekbarBound.width; | |
if( position > range ) position = range; | |
if( position < 0 ) position = 0; | |
return { | |
position: position, | |
range: range | |
}; | |
}, | |
initTimeLabels: function() { | |
var self = this, | |
time = this.elements.controls.time; | |
this.currentTime = __.xest(time.elapsed); | |
this.durationTime = __.xest(time.total) | |
}, | |
initButtonHoversOnTouch: function() { | |
var self = this, | |
icons = zest('#' + this.player.playerId + ' .mhp1138_icon'); | |
__.each(icons, function(icon) { | |
var btn = icon.parentNode; | |
btn.addEventListener('touchstart', function(e) { | |
__.addClass(btn, 'hover'); | |
}); | |
btn.addEventListener('touchend', function(e) { | |
__.removeClass(btn, 'hover'); | |
}); | |
}); | |
}, | |
initPlaybackControls: function() { | |
var self = this, | |
player = this.player, | |
controls = this.elements.controls; | |
this.playBtn = __.xest(controls.play); | |
this.replayBtn = __.xest(controls.replay); | |
this.pauseBtn = __.xest(controls.pause); | |
this.addClickEvent(this.replayBtn, function(e) { | |
// .play() doesnt work here | |
player.seek(0, true); | |
e.stopPropagation(); | |
e.preventDefault(); | |
}); | |
this.addClickEvent(this.pauseBtn, function(e) { | |
player.pause(); | |
e.stopPropagation(); | |
e.preventDefault(); | |
}); | |
this.addClickEvent(this.playBtn, function(e) { | |
player.play(); | |
e.preventDefault(); | |
e.stopPropagation(); | |
}); | |
var div = s('.prerollEventCatcher'), | |
controlsDiv = __.xest(controls.container); | |
controlsDiv.appendChild(div); | |
this.addClickEvent(div, function(e) { | |
var roll = player.adsRoll(); | |
if (roll && __.isPath(roll.clickUrl) && player.videoStarted) { | |
player.adsRollTracking(roll, 'click'); | |
player.openRedirectWindow(roll.clickUrl); | |
player.pause(); | |
return false; | |
} | |
}); | |
}, | |
initNextVideoBtn: function() { | |
var player = this.player, | |
controls = this.elements.controls, | |
nextVideoSection = this.settings.nextVideo; | |
if(__.isPath(nextVideoSection.nextUrl) && !this.settings.embeds.enabled) { | |
var controlsDiv = __.xest(controls.container), | |
nextVideo = nextVideoSection.nextUrl ? nextVideoSection.nextUrl : ''; | |
var nextBtn = s('button.next'); | |
var nextButtonIcon = s('i.icon.icon-next'); | |
nextBtn.appendChild(nextButtonIcon); | |
controlsDiv.appendChild(nextBtn); | |
this.addClickEvent(nextBtn, function(e) { | |
player.openRedirectWindow(nextVideo, true); | |
e.preventDefault(); | |
e.stopPropagation(); | |
}); | |
} | |
}, | |
initBigPlayBtn: function() { | |
var player = this.player; | |
if (player.settings.embeds.enabled) { | |
var bigPlayBtn = s('.bigPlay'), | |
bigPlayIcon = s('i.icon.icon-play-clear'), | |
eventCatcherDiv = __.xest(this.elements.eventCatcher); | |
bigPlayBtn.appendChild(bigPlayIcon); | |
eventCatcherDiv.appendChild(bigPlayBtn); | |
this.addClickEvent(bigPlayBtn, function(e) { | |
e.preventDefault(); | |
e.stopPropagation(); | |
if (!player.videoStarted) { | |
player.play(); | |
} | |
}); | |
} | |
}, | |
initShowControlsOnTouch: function() { | |
var self = this; | |
this.addClickEvent(this.player.playerContainerElement, function(e) { | |
if (self.optionsVisible) { | |
self.hideOptionsMenu(); | |
} else { | |
self.toggleControls(); | |
} | |
e.stopPropagation(); | |
e.preventDefault(); | |
}); | |
}, | |
initFullscreenBtn: function() { | |
var self = this, | |
player = this.player, | |
controls = this.elements.controls, | |
embeds = this.settings.embeds, | |
features = this.settings.features, | |
redirect = embeds.redirect, | |
logoUrl = redirect.logoUrl; | |
this.fullscreenBtn = __.xest(controls.fullscreen.button); | |
if(!features.fullscreen) { | |
__.addClass(this.container, 'noFullscreen'); | |
return; | |
} | |
this.addClickEvent(this.fullscreenBtn, function(e) { | |
if (embeds.enabled && | |
__.isPath(logoUrl) && | |
redirect.onFullscreen | |
) { | |
var url = player.addUTM(player.addCurrentTimeToUrl(logoUrl), 'embed-mobile', 'embed-fullscreen-html5'); | |
player.pause(); | |
player.openRedirectWindow(url); | |
} else { | |
// if (player.playing) self.resetControlTimer(); | |
player.fullscreen.toggle(); | |
} | |
e.preventDefault(); | |
e.stopPropagation(); | |
}); | |
if(('orientation' in screen) && !player.settings.embeds.enabled) { | |
screen.orientation.addEventListener('change', function (e) { | |
if (screen.orientation.type === 'landscape-primary' || screen.orientation.type === 'landscape-secondary') { | |
player.fullscreen.enter(); | |
} else { | |
player.fullscreen.exit(); | |
} | |
e.preventDefault(); | |
e.stopPropagation(); | |
}); | |
} | |
}, | |
initCardboardBtn: function() { | |
var self = this, | |
player = this.player; | |
this.cardboardBtn = __.xest(this.elements.controls.cardboard.button); | |
this.addClickEvent(this.cardboardBtn, function(e) { | |
if (player.vrPlayer) { | |
if (player.vrPlayer.isStereoView()) { | |
player.vrPlayer.setStereoView(false); | |
self.setCardboardState(false); | |
} else { | |
player.vrPlayer.launchStereoView(); | |
self.setCardboardState(true); | |
} | |
} | |
e.preventDefault(); | |
}); | |
}, | |
initChromecastBtn: function() { | |
var self = this, | |
options = this.elements.controls.options; | |
this.chromecastBtn = __.xest(options.chromecastBtn); | |
this.chromecastIcon = __.xest(options.chromecastIcon); | |
this.addClickEvent(this.chromecastBtn, function(e) { | |
self.player.toggleChromecast(); | |
if (!self.player.chromecast.active) { | |
// no 2sec autohide | |
self.showControls(true); | |
} | |
e.preventDefault(); | |
e.stopPropagation(); | |
}); | |
}, | |
initEventCatcher: function(){ | |
var player = this.player, | |
embeds = this.settings.embeds, | |
catcher = __.xest(this.elements.eventCatcher), | |
redirect = embeds.redirect.logoUrl, | |
startTouchPoint, | |
self = this; | |
if (!embeds.enabled) return; | |
this.addClickEvent(catcher, function(e) { | |
var url = player.addCurrentTimeToUrl(redirect); | |
if (embeds.utmRedirect.videoArea) { | |
var url = player.addUTM(url, 'embed-mobile', 'embed-html5'); | |
e.preventDefault(); | |
e.stopPropagation(); | |
player.openRedirectWindow(url); | |
if (!player.seeking) { | |
player.pause(); | |
} else { | |
self.checkPageVisibilityAndPause(); | |
} | |
return false; | |
} | |
}); | |
}, | |
checkPageVisibilityAndPause : function() { | |
var hidden, visibilityChange, | |
player = this.player; | |
if (typeof document.hidden !== "undefined") { | |
hidden = "hidden"; | |
visibilityChange = "visibilitychange"; | |
} else if (typeof document.msHidden !== "undefined") { | |
hidden = "msHidden"; | |
visibilityChange = "msvisibilitychange"; | |
} else if (typeof document.webkitHidden !== "undefined") { | |
hidden = "webkitHidden"; | |
visibilityChange = "webkitvisibilitychange"; | |
} | |
document.addEventListener(visibilityChange, function(){ | |
player.seeking = false; | |
player.playAfterSeek = false; | |
player.deferredSeek = false; | |
if (document[hidden]) { | |
player.playerElement.onpause(); | |
} | |
}); | |
}, | |
createQualityMenu: function() { | |
var self = this, | |
player = this.player, | |
options = this.elements.controls.options, | |
settings = this.settings; | |
this.qualityBtn = __.xest(options.qualityBtn); | |
this.qualityMenu = __.xest(options.menu.container); | |
this.qualityMenuList = __.xest(options.menu.qualityList); | |
this.addClickEvent(this.qualityBtn, function(e) { | |
self.toggleOptionsMenu(); | |
e.preventDefault(); | |
e.stopPropagation(); | |
}); | |
// mouse events support | |
this.qualityBtn.addEventListener('click', function(e) { | |
e.stopPropagation(); | |
}) | |
__.each(player.videoResolutions, function(resolution) { | |
var newItem = s('.optionsItem'), | |
resolutionName = String(resolution).replace('_', 'p'); | |
if (resolutionName.indexOf('p') == -1) { | |
resolutionName += 'p'; | |
} | |
if (parseInt(resolution) >= settings.minUHDQuality) { | |
resolutionName += ' <b>4K</b>'; | |
} else if (parseInt(resolution) >= settings.minHDQuality) { | |
resolutionName += ' <b>HD</b>'; | |
} | |
if (resolution == 'hls' || resolution == 'dash') { | |
resolutionName = l('%AUTO_QUALITY%'); | |
__.addClass(newItem, 'adaptive'); | |
} | |
newItem.innerHTML = resolutionName; | |
newItem.rel = resolution; | |
if (resolution == player.selectedResolution) { | |
__.addClass(newItem, 'active'); | |
} | |
if (player.videoSources[resolution].format == 'upsell') { | |
__.addClass(newItem, 'upsell'); | |
newItem.innerHTML += ' <i class="mhp1138_icon mhp1138_icon-star"></i>'; | |
} else { | |
newItem.innerHTML += ' <i class="mhp1138_icon mhp1138_icon-slim-checkmark"></i>'; | |
} | |
self.qualityMenuList.appendChild(newItem); | |
}); | |
this.qualityMenuListItems = zest(options.menu.qualityItems); | |
__.each(this.qualityMenuListItems, function(item) { | |
self.addClickEvent(item, function(e) { | |
var resolution = item.rel; | |
//already selected | |
if (resolution == self.player.selectedResolution) { | |
return; | |
} | |
if (self.player.videoSources[resolution].format == 'upsell') { | |
//is upsell | |
self.player.fireUpsellEvent(); | |
} else { | |
//change quality | |
self.player.setQuality(resolution, function() { | |
__.each(self.qualityMenuListItems, function(item2) { | |
__.removeClass(item2, 'active'); | |
}); | |
__.addClass(item, 'active'); | |
}); | |
} | |
e.stopPropagation(); | |
e.preventDefault(); | |
}); | |
}); | |
}, | |
/*----------------Motion rate---------------------*/ | |
createMotionRateTab: function(){ | |
var self = this, | |
player = this.player, | |
options = this.elements.controls.options, | |
settings = this.settings; | |
this.speedMenuList = __.xest(options.menu.motionRates); | |
//__.addClass(this.speedMenuList, 'menuPage'); | |
//__.addClass(this.speedMenuList, ''); | |
this.switch05X = s('.optionsItem.optionsItem05X[html="0.5x"] i.icon.icon-slim-checkmark'); | |
this.switch1X = s('.optionsItem.optionsItem1X.active[html=1.0x] i.icon.icon-slim-checkmark'); | |
this.switch20X = s('.optionsItem.optionsItem20X[html="2.0x"] i.icon.icon-slim-checkmark'); | |
this.speedMenuList.appendChild(this.switch05X); | |
this.speedMenuList.appendChild(this.switch1X); | |
this.speedMenuList.appendChild(this.switch20X); | |
this.addClickEvent(this.switch05X, function(e) { | |
e.preventDefault(); | |
e.stopPropagation(); | |
player.setMotionRate(0.5); | |
self.hideOptionsMenu(); | |
}); | |
this.addClickEvent(this.switch1X, function(e) { | |
e.preventDefault(); | |
e.stopPropagation(); | |
player.setMotionRate(1); | |
self.hideOptionsMenu(); | |
}); | |
this.addClickEvent(this.switch20X, function(e) { | |
e.preventDefault(); | |
e.stopPropagation(); | |
player.setMotionRate(2.0); | |
self.hideOptionsMenu(); | |
}); | |
}, | |
toggleMotionSpeed : function(speed) { | |
switch(speed) { | |
case 0.5 : | |
__.addClass(this.switch05X, 'active'); | |
__.removeClass(this.switch1X, 'active'); | |
__.removeClass(this.switch20X, 'active'); | |
break; | |
case 2.0 : | |
__.addClass(this.switch20X, 'active'); | |
__.removeClass(this.switch1X, 'active'); | |
__.removeClass(this.switch05X, 'active'); | |
break; | |
default : | |
__.addClass(this.switch1X, 'active'); | |
__.removeClass(this.switch05X, 'active'); | |
__.removeClass(this.switch20X, 'active'); | |
} | |
}, | |
/*----------------Motion rate end---------------------*/ | |
showControls: function(disableAutohide) { | |
this.clearAutoHideControls(); | |
this.controlsVisible = true; | |
__.addClass(this.container, 'showControls'); | |
if (!disableAutohide) { | |
this.autoHideControls(); | |
} | |
}, | |
hideControls: function() { | |
this.clearAutoHideControls(); | |
// all-time visible controls when using phone as remote | |
if (this.player.chromecast.active) return false; | |
// do not hide controls at the end of the video | |
if (this.playerState == 'replay') return false; | |
this.controlsVisible = false; | |
__.removeClass(this.container, 'showControls'); | |
}, | |
toggleControls: function() { | |
if (this.controlsVisible) { | |
this.hideControls(); | |
} else { | |
this.showControls(); | |
} | |
}, | |
showOptionsMenu: function() { | |
this.optionsVisible = true; | |
__.addClass(this.container, 'showOptions'); | |
this.clearAutoHideControls(); | |
}, | |
hideOptionsMenu: function() { | |
this.optionsVisible = false; | |
__.removeClass(this.container, 'showOptions'); | |
this.autoHideControls(); | |
}, | |
initOptionsTabs: function(){ | |
var self = this, | |
menu = this.elements.controls.options.menu; | |
optionTabs = zest(menu.optionTabs); | |
optionPages = zest(menu.page); | |
if (optionTabs.length === 1) { | |
__.removeClass(optionTabs[0], 'active'); | |
return; | |
} | |
this.normalizeOptionPagesHeight(optionPages); | |
__.each(optionTabs, function(tab) { | |
self.addClickEvent(tab, function(e) { | |
e.preventDefault(); | |
e.stopPropagation(); | |
//already selected | |
if (__.hasClass(tab, 'active')) { | |
return; | |
} | |
var activeTab = __.xest(menu.optionTabActive), | |
activePage = __.xest(menu.pageActive), | |
tabTitle = tab.getAttribute('data-tab'), | |
page = __.xest(menu.page + tabTitle); | |
__.removeClass(activeTab, 'active'); | |
__.removeClass(activePage, 'active'); | |
__.addClass(tab, 'active'); | |
__.addClass(page, 'active'); | |
}); | |
}); | |
}, | |
normalizeOptionPagesHeight: function(optionPages) { | |
var maxHeight = 0; | |
__.each(optionPages, function(page) { | |
__.addClass(page, 'active'); | |
var pageHeight = page.clientHeight; | |
if (maxHeight < pageHeight) { | |
maxHeight = pageHeight; | |
} | |
}); | |
__.each(optionPages, function(page) { | |
page.style.height = maxHeight + 'px'; | |
__.removeClass(page,'active'); | |
}); | |
__.addClass(optionPages[0], 'active'); | |
}, | |
toggleOptionsMenu: function() { | |
if (this.optionsVisible) { | |
this.hideOptionsMenu(); | |
} else { | |
this.showOptionsMenu(); | |
} | |
}, | |
autoHideControls: function() { | |
var self = this; | |
this.clearAutoHideControls(); | |
// user is able to show/hide controls on tap while video is paused, | |
// but no automatic hiding in this state | |
if (this.playerState == 'paused') return false; | |
this.hideControlTimer = setTimeout(function() { | |
self.hideControls(); | |
}, this.settings.features.hideControlsTimeout * 1000); | |
}, | |
clearAutoHideControls: function() { | |
clearTimeout(this.hideControlTimer); | |
}, | |
//UTILITY | |
pixelToPercent: function(pixel, range) { | |
return ((pixel * 100) / range).toFixed(2); | |
}, | |
percentToPixel: function(percentage, range) { | |
return Math.round((percentage * range) / 100); | |
}, | |
// -------------------- Hotspots -------------------- | |
createHotspotsOptionTab: function(){ | |
//optionTabHotspots | |
//hotspotsSwitch: '.optionsItem.optionsText[html=See what\'s hot and what\'s not.]' | |
var menu = this.elements.controls.options.menu, | |
tabs = __.xest(menu.optionTabsContainer), | |
pages = __.xest(menu.pages), | |
tab = s('span.menuTitle.menuTitleHotspots[data-tab=Hotspots][html=' + l('%HOTSPOTS%') + ']'), | |
page = s('.hotspotsSwitch.menuPage.menuPageHotspots > .optionsItem.optionsText[html=' + l('%HOTSPOTS_HOT_NOT%') + ']'); | |
tabs.appendChild(tab); | |
pages.appendChild(page); | |
this.createHotspotsSwitch(); | |
}, | |
// create and init hotspots buttons | |
createHotspotsSwitch: function() { | |
var self = this, | |
player = this.player, | |
options = this.elements.controls.options, | |
hotspotsSwitch = __.xest(options.menu.hotspotsSwitch); | |
this.onSwitch = s('.optionsItem.optionsItemOn[html=' + l('%ON%') + '] i.icon.icon-slim-checkmark'); | |
this.offSwitch = s('.optionsItem.optionsItemOff[html=' + l('%OFF%') + '] i.icon.icon-slim-checkmark'); | |
hotspotsSwitch.appendChild(this.onSwitch); | |
hotspotsSwitch.appendChild(this.offSwitch); | |
var toggleHotspots = function(state) { | |
if (state) { | |
player.setHotspotsState(true); | |
} else { | |
player.setHotspotsState(false); | |
} | |
self.toggleHotspotsGraphVisibility(); | |
self.hideOptionsMenu(); | |
}; | |
this.addClickEvent(this.onSwitch, function(e) { | |
e.preventDefault(); | |
e.stopPropagation(); | |
toggleHotspots(true); | |
}); | |
this.addClickEvent(this.offSwitch, function(e) { | |
e.preventDefault(); | |
e.stopPropagation(); | |
toggleHotspots(false); | |
}); | |
}, | |
initHotspotsElements: function() { | |
var player = this.player, | |
seekBarContainer = __.xest(this.elements.controls.seekBar.container); | |
this.hotspotsTemplate = __.xest( | |
'#mhp1138_skin'+ | |
' .mhp1138_svg_hotspots' | |
); | |
this.polygon = null; | |
this.hotspotsSettings = this.settings.hotspots; | |
if(!__.isUndefined(this.hotspotsTemplate)) { | |
var templateClone = (this.hotspotsTemplate.firstChild || this.hotspotsTemplate.content.firstChild).cloneNode(true); | |
templateClone.getElementsByTagName('clipPath')[0].setAttribute('id', this.container.getAttribute('id')+'_hotspotsClip'); | |
templateClone.getElementsByTagName('g')[0].setAttribute('clip-path', 'url(#'+this.container.getAttribute('id')+'_hotspotsClip)'); | |
seekBarContainer.appendChild(templateClone); | |
var hotspots = this.elements.hotspots; | |
this.polygon = __.xest(hotspots.polygon); | |
this.hotspotsContainer = __.xest(hotspots.container); | |
this.hotspotsProgress = __.xest(hotspots.progress); | |
this.hotspotsProgress.setAttribute('fill', this.hotspotsSettings.chartColor); | |
this.hotspotsProgress.setAttribute('transform', 'translate(-1000)'); | |
this.hotspotsContainer.style.height = this.hotspotsSettings.chartHeight; | |
} | |
}, | |
createHotspotsGraph: function(){ | |
var player = this.player, | |
embeds = this.settings.embeds, | |
points = '', | |
cntWidth = 1000, //viewBox area width | |
cntHeight = 100; //viewBox area height | |
if(this.hotspotsSettings.data.length) { | |
this.hotspotsSettings.data.splice(0, 2); | |
} else { | |
return; | |
} | |
var l=this.hotspotsSettings.data.length, //amount of points on graph | |
intervalWidth = cntWidth/(l-1), // counting interval width | |
intervalHeightDef = Math.max.apply(null, this.hotspotsSettings.data)/cntHeight; // counting 1% of maximum point | |
if (!__.isUndefined(this.hotspotsTemplate) && !embeds.enabled) { | |
// Building points for polygon | |
for(var i=0; i < l; i++){ | |
var item = parseInt(this.hotspotsSettings.data[i]), | |
height = Math.floor(item/intervalHeightDef); | |
points += (intervalWidth*i) + ',' + (cntHeight-height) + ' '; | |
} | |
//Lines to finish the polygon | |
points += intervalWidth*l + ',' + cntHeight + ' ' + '0,' + cntHeight; | |
this.polygon.setAttribute('points', points); | |
this.toggleHotspotsGraphVisibility(); | |
} | |
}, | |
toggleHotspotsGraphVisibility: function(){ | |
var player = this.player; | |
if (this.hotspotsContainer) { | |
if (player.hotspotsState) { | |
this.hotspotsContainer.style.display = 'block'; | |
if (this.onSwitch) { | |
__.addClass(this.onSwitch, 'mhp1138_active'); | |
__.removeClass(this.offSwitch, 'mhp1138_active'); | |
} | |
} else { | |
this.hotspotsContainer.style.display = 'none'; | |
if (this.offSwitch) { | |
__.addClass(this.offSwitch, 'mhp1138_active'); | |
__.removeClass(this.onSwitch, 'mhp1138_active'); | |
} | |
} | |
} | |
}, | |
setHotspotsState: function(state) { | |
if(state){ | |
__.addClass(this.onSwitch, 'mhp1138_active'); | |
} else { | |
__.addClass(this.offSwitch, 'mhp1138_active'); | |
} | |
}, | |
// -------------------- Hotspots -------------------- | |
//setting video attributes in ios to diable native ios controls | |
initIosControls: function() { | |
if(MHP1138.detector.isIos()){ | |
var playerContainer = this.player.playerContainerElement; | |
var video = playerContainer.getElementsByTagName("video")[0]; | |
if (video) { | |
video.removeAttribute("controls"); | |
video.setAttribute('playsinline',''); | |
} | |
} | |
}, | |
// EMPTY METHODS to support universal core | |
deleteOverlays: function() { | |
}, | |
createOverlays: function() { | |
}, | |
deleteActionTags: function() { | |
}, | |
createActionTags: function() { | |
}, | |
moveSeekBarHandle: function(delta) { | |
}, | |
disableOptions: function() { | |
}, | |
enableOptions: function() { | |
} | |
} | |
}; | |
(function(window, _) { | |
'use strict'; | |
// We have extended underscore to "double-underscore", but the module shouldnt know about it, | |
// using its basic methods such as .each | |
/** | |
* Adds fullscreen support to the player | |
* | |
* @param {MHP1138.HTML5Player} player | |
* @param {function} fireEvent Function to fire local player events (starts from 'onXXX...') | |
* @param {function} subscribeToEvent custom event handler from the player package | |
* @param {boolean} ios iOS flag from detector | |
*/ | |
var Fullscreen = function(player, fireEvent, subscribeToEvent, ios) { | |
var doc = window.document, | |
playerId = player.playerId; | |
// list of external player events to exit fullscreen (if entered) | |
var exitEvents = ['collapsePlayer', 'expandPlayer', 'onShare', 'onRedirect']; | |
// fullscreen events to listen | |
var fullscreenEvents = ['webkitfullscreenchange', 'mozfullscreenchange', 'MSFullscreenChange', 'fullscreenchange']; | |
var fullscreenState = false; | |
function checkAvailability() { | |
var element = doc.documentElement, | |
elementIos = player.playerElement;//IOS contains webkitSupportsFullscreen in video element | |
if (element.requestFullScreen || | |
element.mozRequestFullScreen || | |
element.webkitRequestFullScreen || | |
element.msRequestFullscreen || | |
elementIos.webkitEnterFullscreen | |
) { | |
return true; | |
} | |
return false; | |
} | |
function enterFullscreen() { | |
var element = player.playerContainerElement; | |
if (element.requestFullScreen) { | |
element.requestFullScreen(); | |
} else if (element.mozRequestFullScreen) { | |
element.mozRequestFullScreen(); | |
} else if (element.webkitRequestFullScreen) { | |
element.webkitRequestFullScreen(); | |
} else if (element.msRequestFullscreen) { | |
element.msRequestFullscreen(); | |
// special case for iOS | |
} else if (ios && !element.webkitRequestFullScreen) { | |
// assuming we would find a video tag inside player container | |
var video = player.playerElement; | |
// there is a different method name to enter fullscreen | |
if (video.webkitSupportsFullscreen) { | |
video.webkitEnterFullscreen(); | |
} | |
} | |
} | |
function exitFullscreen() { | |
if (doc.cancelFullScreen) { | |
doc.cancelFullScreen(); | |
} else if (doc.mozCancelFullScreen) { | |
doc.mozCancelFullScreen(); | |
} else if (doc.webkitCancelFullScreen) { | |
doc.webkitCancelFullScreen(); | |
} else if (doc.msExitFullscreen) { | |
doc.msExitFullscreen(); | |
} | |
} | |
function toggleFullscreen() { | |
if (fullscreenState) { | |
exitFullscreen(); | |
} else { | |
enterFullscreen(); | |
} | |
} | |
function listenChangeEvents() { | |
function fullscreenChanged() { | |
var element = doc.fullscreenElement || | |
doc.webkitFullscreenElement || | |
doc.mozFullScreenElement || | |
doc.msFullscreenElement || | |
null; | |
if (_.isNull(element)) { | |
if (fullscreenState) { | |
fullscreenState = false; | |
fireEvent('onFullscreen', { fullscreen: false }); | |
} | |
} else { // fullscreenElement is exists | |
if (element.id == playerId) { | |
fullscreenState = true; | |
fireEvent('onFullscreen', { fullscreen: true }); | |
} | |
} | |
} | |
_.each(fullscreenEvents, function(eventName) { | |
doc.addEventListener(eventName, fullscreenChanged); | |
}); | |
} | |
function listenPlayerEvents() { | |
_.each(exitEvents, function(eventName) { | |
subscribeToEvent(eventName, playerId, exitFullscreen); | |
}); | |
} | |
if (checkAvailability()) { | |
listenChangeEvents(); | |
listenPlayerEvents(); | |
return { | |
enabled: true, | |
enter: enterFullscreen, | |
exit: exitFullscreen, | |
toggle: toggleFullscreen | |
}; | |
} else { | |
return { | |
enabled: false | |
}; | |
} | |
}; | |
window.MHP1138 = window.MHP1138 || {}; | |
window.MHP1138.Fullscreen = Fullscreen; | |
})(window, __); | |
(function(window, _) { | |
'use strict'; | |
var L10n = function(locales, language) { | |
var defaultLanguage = 'en'; | |
var systemLanguage = (function() { | |
// works for IE / Safari / Chrome / Firefox | |
var language = window.navigator.userLanguage || window.navigator.language; | |
// trim it to prefix only (en-US, en-GB, etc) | |
return language.substr(0, 2); | |
})(); | |
if (!language || language === 'auto') { | |
language = systemLanguage; | |
} | |
return { | |
defaultLanguage: defaultLanguage, | |
systemLanguage: systemLanguage, | |
language: language, | |
localize: function(string, forceLanguage) { | |
var l = language; | |
if (forceLanguage) { | |
l = forceLanguage.substr(0,2); | |
} | |
var matches = string.match(/(%\S+%)/g); | |
_.each(matches, function(match) { | |
var replacement; | |
if (locales[l] && locales[l][match]) { | |
replacement = locales[l][match].replace(new RegExp('(\')', 'g'), '’'); | |
} | |
if (!replacement) { | |
//removeIf(production) | |
window.MHP1138.error('Missing ' + match + ' replacement for "' + l + '" locale'); | |
//endRemoveIf(production) | |
replacement = locales[defaultLanguage][match]; | |
} | |
if (replacement) { | |
string = string.replace(match, replacement); | |
} else { | |
//removeIf(production) | |
window.MHP1138.error('Missing ' + match + ' replacement for "' + defaultLanguage + '" locale'); | |
//endRemoveIf(production) | |
} | |
}); | |
return string; | |
} | |
}; | |
}; | |
window.MHP1138 = window.MHP1138 || {}; | |
window.MHP1138.L10n = L10n; | |
})(window, __); | |
(function(window, _) { | |
'use strict'; | |
/** | |
* Thumbnails preloader | |
* | |
* @param {MHP1138.HTML5Player} player | |
* @param {object} thumbs Video thumbnails settings (part of the global player settings from mainRoll section) | |
* @param {function} subscribeToEvent Custom event handler from the player package | |
*/ | |
var ThumbnailsLoader = function(player, thumbs, subscribeToEvent) { | |
var thumbnailsRegex = /{(\d+)}/, | |
sheets = [], | |
thumbnails = [], | |
//thumbnails from centro are always have width = 168px, just to be safe | |
centroThumbnailsWidth = 168, | |
samplingFrequency; | |
function init(thumbs) { | |
var sheetFormat = null, | |
pattern = thumbs.urlPattern, | |
columns = 1, | |
rows = 1, | |
count = 1, | |
url; | |
if (!pattern.length) { | |
return; | |
} | |
samplingFrequency = parseInt(thumbs.samplingFrequency, 10); | |
if (thumbs.cdnType == 'centro') { | |
if (!player.mainRoll.duration) { | |
//removeIf(production) | |
window.MHP1138.error('thumbnails: no mainRoll video duration available'); | |
//endRemoveIf(production) | |
} | |
var numberOfSlides = parseInt(player.mainRoll.duration / thumbs.samplingFrequency, 10); | |
if (numberOfSlides) { | |
columns = numberOfSlides + 1; // +1 last slide | |
rows = 1; | |
thumbs.thumbWidth = centroThumbnailsWidth; | |
} else { | |
return; | |
} | |
} else { | |
sheetFormat = thumbs.format.split('x'); | |
columns = parseInt(sheetFormat[0], 10); | |
rows = parseInt(sheetFormat[1], 10); | |
// TODO: add automatic calculation of thumbs sheet dimensions | |
if (sheetFormat.length != 2 || | |
_.isNaN(columns) || | |
_.isNaN(rows) | |
) { | |
//removeIf(production) | |
//the thumbnails format is not valid | |
window.MHP1138.error('The thumbnails format (' + thumbs.format + | |
') is not valid for player with ID "#' + player.playerId + '".'); | |
//endRemoveIf(production) | |
return; | |
} | |
var match = pattern.match(thumbnailsRegex); | |
if (match === null) { | |
//removeIf(production) | |
//the urlPatern is not valid | |
window.MHP1138.error('The thumbnails urlPattern is not valid for player with ID "#' + | |
player.playerId + '".'); | |
//endRemoveIf(production) | |
return; | |
} | |
count = parseInt(match[1], 10) + 1; | |
if (isNaN(count) || count === 0) { | |
return; | |
} | |
} | |
for (var i = 0; i < count; i++) { | |
if (thumbs.cdnType == 'centro') { | |
url = pattern; | |
} else { | |
url = pattern.replace(thumbnailsRegex, i); | |
} | |
sheets[i] = { | |
index: i, | |
url: url, | |
thumbWidth: thumbs.thumbWidth, | |
thumbHeight: thumbs.thumbHeight, | |
width: thumbs.thumbWidth * columns, | |
height: thumbs.thumbHeight * rows, | |
cached: false, | |
ready: false, // the state of sheet when its ready to display (but COULD be not fully loaded yet) | |
loaded: false, | |
error: false, | |
cdnType: thumbs.cdnType | |
}; | |
} | |
//register each thumbs position to an array.. this take ~0.076ms, so it's super fast. | |
var tbCount = 0; | |
for (var sheet = 0; sheet < count; sheet++) { | |
for (var row = 0; row < rows; row++) { | |
for (var col = 0; col < columns; col++) { | |
thumbnails[tbCount] = { | |
index: tbCount, | |
sheet: sheet, | |
row: row, | |
col: col, | |
cssLeft: -1 * col * thumbs.thumbWidth + 'px', | |
cssTop: -1 * row * thumbs.thumbHeight + 'px' | |
}; | |
tbCount++; | |
} | |
} | |
} | |
} | |
function preload(async) { | |
// getting index of the first not cached sheet | |
for (var i = 0; i < sheets.length; i++) { | |
if (!sheets[i].cached) { | |
if (async) { | |
// load them all | |
cacheSpritesheet(sheets[i]); | |
} else { | |
// use callback to load sheets one by one | |
cacheSpritesheet(sheets[i], preload); | |
break; | |
} | |
} | |
} | |
} | |
function cacheSpritesheet(sheet, callback) { | |
var img = document.createElement('img'); | |
img.onload = function() { | |
sheet.loaded = true; | |
sheet.ready = true; | |
// 404 image has different dimensions | |
if (sheet.cdnType != 'centro' && | |
(this.naturalWidth != sheet.width || | |
this.naturalHeight != sheet.height) | |
) { | |
sheet.error = true; | |
} | |
// img.src is always the absolute url, while the sheet.url could be relative (ex: "/videos/12342523/S3.jpg") | |
// updating it | |
sheet.url = img.src; | |
if (callback) { callback(); } | |
}; | |
img.onerror = function() { | |
sheet.error = true; | |
if (callback) { callback(); } | |
}; | |
img.src = sheet.url; | |
sheet.cached = true; | |
if (thumbs.progressive && callback) { | |
watchSheetData(img, sheet, callback); | |
} | |
} | |
/** | |
* watch for image dimensions availability BEFORE its full load | |
* could save some seconds on slow connections when using progressive jpegs | |
* | |
* @param {DOMElement} img | |
* @param {object} sheet | |
* @param {function} callback | |
*/ | |
function watchSheetData(img, sheet, callback) { | |
if (img.naturalWidth > 0 && | |
img.naturalHeight > 0 | |
) { | |
sheet.ready = true; | |
callback(); | |
} | |
if (!sheet.loaded && | |
!sheet.ready && | |
!sheet.error | |
) { | |
setTimeout(function() { | |
watchSheetData(img, sheet); | |
}, 100); | |
} | |
} | |
/* | |
* There are two ways to use this method. | |
* You can call it with seconds argument only and instantly get thumbnail info or false if it isnt loaded yet | |
* OR | |
* You can also specify callback function, and get thumbnail info when its spritesheet would be loaded | |
* (or error if not). | |
* | |
* @param {float} seconds Video timeline position | |
* @param {function} callback Callback function with 3 arguments: thumbnail, spritesheet, error | |
*/ | |
function get(seconds, callback) { | |
var index = Math.floor(seconds / samplingFrequency), | |
thumbnail = thumbnails[index], | |
sheet; | |
if (!thumbnail) { | |
// no thumbnail for this time, instant error callback | |
if (callback) { callback(false, false, { error: 'out of time' }); } | |
return false; | |
} else { | |
// checking whatever it is available or should be loaded first | |
sheet = sheets[thumbnail.sheet]; | |
if (sheet) { | |
if (sheet.error) { | |
if (callback) { callback(false, false, { error: 'error loading spritesheet' }); } | |
return false; | |
} else if (!sheet.cached) { | |
// preload spritesheet | |
cacheSpritesheet(sheet, function() { | |
//console.log('preloaded', sheet); | |
if (callback) { callback(thumbnail, sheet); } | |
}); | |
return false; | |
} else if (sheet.ready) { | |
// spritesheet is ready | |
if (callback) { callback(thumbnail, sheet); } | |
return { | |
thumbnail: thumbnail, | |
sheet: sheet | |
}; | |
} | |
} else { | |
// no sheet data provided for thumbnail | |
// unrealistic scenario if the generator did it right | |
return false; | |
} | |
} | |
return false; | |
} | |
init(thumbs); | |
if (thumbs.preload) { | |
subscribeToEvent('onVideoReady', player.playerId, function() { | |
preload(thumbs.async); | |
}); | |
} | |
return { | |
preload: preload, | |
sheets: sheets, | |
thumbnails: thumbnails, | |
get: get, | |
samplingFrequency: samplingFrequency, | |
progressive: thumbs.progressive, | |
}; | |
}; | |
window.MHP1138 = window.MHP1138 || {}; | |
window.MHP1138.ThumbnailsLoader = ThumbnailsLoader; | |
})(window, __); | |
function mhp1138_playerPlugin_HTML5Player() { | |
var l, | |
fireEvent, | |
subscribeToEvent = MHP1138.player.subscribeToEvent; | |
return { | |
settings: {}, | |
playerType: 'HTML5Player', | |
chromecast: {}, | |
skin: {}, | |
volume: 100, | |
muted: false, | |
viewedSeconds: 0, | |
viewingStart: 0, | |
viewedTimeout: null, | |
markup: { | |
video: '<video <%= attributes %>><%= source %></video>', | |
virtualVideo: '<canvas>This feature is not supported on your browser!</canvas><video crossorigin="anonymous" <%= attributes %>><%= source %></video>', | |
source: '<source src="<%= link %>" type="video/mp4" />' | |
}, | |
initPlayer: function(id, settings) { | |
var self = this; | |
// shortcut with local this | |
fireEvent = function(eventName, params) { | |
return __.fireEvent(self, eventName, params); | |
}; | |
settings = this.overrideInitSettings(settings); | |
settings = this.overrideEmbedSettings(settings); | |
settings = this.overrideTabletSettings(settings); | |
settings = this.overrideMobileSettings(settings); | |
settings = this.overrideSafariSettings(settings); | |
settings = this.overrideIOSSafariSettings(settings); | |
settings = this.supportDeprecatedSettings(settings); | |
settings = this.supportDefaultOverlayTextAd(settings); | |
this.settings = settings; | |
this.playerId = id; | |
if (MHP1138.L10n && MHP1138.Locales) { | |
var langsPack = MHP1138.Locales; | |
if (this.settings.extendedLocales) { | |
__.deepExtend(langsPack, this.settings.extendedLocales); | |
} | |
this.l10n = new MHP1138.L10n(langsPack, this.settings.locale); | |
// shortcut | |
l = this.l10n.localize; | |
} | |
this.loadSkin(); | |
this.createInstanceOfSkin(); | |
this.createPlayer(); | |
}, | |
loadSkin: function() { | |
if (!document.getElementById('mhp1138_skin')) { | |
var skinContainer = document.createElement('div'), | |
head = document.head, | |
body = document.body; | |
skinContainer.id = 'mhp1138_skin'; | |
skinContainer.style.display = 'none'; | |
//Skin styles | |
if (MHP1138.skinsMarkup['css']) { | |
var stylesElement = document.createElement('style'); | |
//Firefox don't support innerText.. | |
// stylesElement.innerText = stylesElement.textContent = MHP1138.skinsMarkup['css']; | |
stylesElement.innerHTML = MHP1138.skinsMarkup['css']; | |
head.appendChild(stylesElement); | |
} else { | |
//removeIf(production) | |
//if the skin compiled wrong way | |
MHP1138.error('You are missing skin styles'); | |
//endRemoveIf(production) | |
return; | |
} | |
//Skin template | |
if (MHP1138.skinsMarkup['html']) { | |
skinContainer.innerHTML = MHP1138.skinsMarkup['html']; | |
} else { | |
//removeIf(production) | |
//if the skin compiled wrong way | |
MHP1138.error('You are missing skin template'); | |
//endRemoveIf(production) | |
return; | |
} | |
// compile and store player markup for the first time in globally accessible variable | |
if (MHP1138.markup && !MHP1138.skinsMarkup['markup']) { | |
this.compileSkinMarkup(); | |
} | |
body.insertBefore(skinContainer, body.firstChild); | |
} | |
}, | |
compileSkinMarkup: function() { | |
var compiledMarkup = __.toMarkup(MHP1138.markup, 'mhp1138_'); | |
if (this.l10n) { | |
compiledMarkup = l(compiledMarkup); | |
}; | |
MHP1138.skinsMarkup['markup'] = compiledMarkup; | |
}, | |
createInstanceOfSkin: function() { | |
this.skin = window['mhp1138_skin'](); | |
this.skin.elements = __.addPrefixToSkinElements( | |
MHP1138.selectors, | |
'mhp1138', | |
this.playerId | |
); | |
if (__.isArray(MHP1138.themeCss)) { | |
var themeCss = __.addPrefixAndColorToSkinThemeCss( | |
MHP1138.themeCss, | |
'mhp1138', | |
this.playerId, | |
this.settings.features.themeColor | |
), | |
themeCssNode = document.createElement('style'), | |
head = document.head; | |
themeCssNode.innerHTML = themeCss.join('\n'); | |
head.appendChild(themeCssNode); | |
} | |
MHP1138.loadedMasterCSS = true; | |
}, | |
setOverlays: function(overlays) { | |
this.overlays = overlays; | |
this.skin.deleteOverlays(); | |
this.skin.createOverlays(); | |
}, | |
getSourceForMainRoll: function() { | |
var mainRoll = this.mainRoll; | |
// parse mediaDefinition and create quality arrays for internal use | |
if (mainRoll.mediaDefinition.length) { | |
// update sources in mediaDefinition object | |
this.mainRoll.mediaDefinition = this.filterMediaSources(mainRoll.mediaDefinition); | |
this.getStoredQuality(); | |
return this.videoSources[this.selectedResolution]; | |
// no mediaDefinitions but just one video url provided | |
} else if (__.isPath(mainRoll.videoUrl)) { | |
return mainRoll; | |
} else { | |
return ''; | |
} | |
}, | |
createPlayer: function() { | |
var self = this, | |
settings = this.settings, | |
mainRoll = settings.mainRoll; | |
this.playing = false; | |
this.videoEnded = false; | |
this.videoStarted = false; | |
this.fullscreen = false; | |
this.isPreRollActive = false; | |
this.currentTime = 0.0; | |
// if the web site want us to act like the video is unavailable | |
// for some reason. | |
if (mainRoll.videoUnavailable || | |
mainRoll.videoUnavailableMessage.length | |
) { | |
this.videoNotAvailable(); | |
return; | |
} | |
this.mainRoll = mainRoll; | |
var source = this.getSourceForMainRoll(), | |
sourceUrl = (source && source.videoUrl) ? source.videoUrl : ''; | |
this.initVastParser(); | |
this.initPreRoll(); | |
this.initPauseRoll(); | |
// init video player with preRoll source instead of the main one | |
if (this.preRoll.enabled && | |
__.isPath(this.preRoll.videoUrl) | |
) { | |
sourceUrl = this.preRoll.videoUrl; | |
} | |
// create main controls | |
this.initContainer(); | |
if (!sourceUrl) { | |
//removeIf(production) | |
//check to be sure there is at least one valid video source | |
MHP1138.error('You need to define at least one valid video source for the player with ID "#'+ this.playerId +'".'); | |
//endRemoveIf(production) | |
this.videoNotAvailable(); | |
return; | |
} | |
if (!this.preRoll.enabled) { | |
// Do not empty sourceUrl in Safari on iOS | |
if ((!this.isIosSafari && source.format == 'hls') || | |
source.format == 'dash' | |
) { | |
// create player markup without static video source | |
// will be replaced by run-time generated HLS source | |
sourceUrl = ''; | |
} else { | |
sourceUrl = this._appendUrlParams(sourceUrl, this.initSourceParams(source)); | |
} | |
} | |
// create player markup | |
this.createPlayerMarkup(sourceUrl); | |
if (!this.preRoll.enabled) { | |
// Do not run init for HLS player in Safari on iOS | |
if (!this.isIosSafari && source.format == 'hls') { | |
this.initHlsPlayer(source); | |
} else if (source.format == 'dash') { | |
this.initDashPlayer(source); | |
} | |
} | |
// initialize fullscreen prior to skin to enable/disable fullscreen buttton in UI | |
if (MHP1138.Fullscreen) { | |
this.fullscreen = new MHP1138.Fullscreen(this, fireEvent, subscribeToEvent, MHP1138.detector.isIos()); | |
// fullscreen module failed to initialize or no support | |
if (!this.fullscreen.enabled) { | |
this.settings.features.fullscreen = false; | |
} | |
} else { | |
this.settings.features.fullscreen = false; | |
} | |
if (MHP1138.ThumbnailsLoader) { | |
this.thumbnails = new MHP1138.ThumbnailsLoader(this, mainRoll.thumbs, subscribeToEvent); | |
} | |
this.initSkin(); | |
// get settings from localStorage | |
this.getStoredMotionRate(); | |
if (settings.hotspots.enabled) { | |
this.getStoredHotspotsState(); | |
} | |
this.getStoredVolume(); | |
// add event handlers to player <video> tag | |
this.bindPlayerEvents(); | |
// add keyboard and fullscreen events handling at document (sic!) level | |
if (MHP1138.Keyboard) { | |
this.keyboard = new MHP1138.Keyboard(this, this.skin, fireEvent); // player, skin, create event function | |
} | |
// init chromecast and vr plugins if specified by settings | |
if (MHP1138.Chromecast && !this.settings.isVr) { | |
this.chromecast = new MHP1138.Chromecast(this, fireEvent); // player, create event function | |
} else { | |
this.chromecast = {}; | |
} | |
this.initVrPlayer(); | |
// onReady event signals video tag existance and availability, | |
// NOT actual video source readiness, see 'onVideoReady' | |
fireEvent('onReady'); | |
// This is tablets way. They cant automatically play videos on page load, | |
// so we have to fake main player poster, actiontags, etc, | |
// but start playing preRoll video on the first 'play' click | |
if (this.preRoll.enabled && !this.autoplay) { | |
this.deferredPreRoll = true; | |
} | |
if (this.preRoll.enabled && | |
!this.deferredPreRoll | |
) { | |
this.showPreRoll(); | |
} else { | |
this.showMainRoll(); | |
} | |
// deferred seek for tablets and mobiles if set | |
if (!MHP1138.detector.isDesktop() && | |
settings.startOffset | |
) { | |
this.deferredStartSeek = true; | |
return; | |
} | |
// Seek to startOffset only if its main roll | |
if (!this.preRoll.enabled && parseInt(settings.startOffset) > 0) { | |
// seek and play | |
this.seek(parseInt(settings.startOffset), true); | |
} else if (this.autoplay) { | |
// DASH player fires error at this moment, source isnt ready yet | |
// We should wait for CAN_PLAY event from lib | |
if (!this.dashSource) { | |
// just play | |
this.play(); | |
} | |
} | |
}, | |
createPlayerMarkup: function(sourceUrl) { | |
var settings = this.settings, | |
videoTagWrapper = satisfy('.mhp1138_videoWrapper')[0], | |
videoTagTemplate = __.template(this.markup.video), | |
sourceTagTemplate = __.template(this.markup.source), | |
canvasTagTemplate = __.template(this.markup.virtualVideo), | |
attributesObj = { | |
style:'width:100%;height:100%', | |
preload: settings.videoPreload, | |
class: '',//'mhp1138_is-hidden', | |
}, | |
attributes = '', | |
attributeName, | |
sources = []; | |
if (settings.isVr) { | |
attributesObj.style += ';display:none'; | |
} | |
__.each(attributesObj, function(value, key) { | |
attributes += ' ' + key + '="' + value + '"'; | |
}); | |
var source = sourceTagTemplate({ | |
link: sourceUrl | |
}); | |
// Check for VR video | |
if (settings.isVr) { | |
videoTagWrapper.innerHTML = canvasTagTemplate({ | |
attributes: attributes, | |
source: source | |
}); | |
} else { | |
videoTagWrapper.innerHTML = videoTagTemplate({ | |
attributes: attributes, | |
source: source | |
}); | |
} | |
this.videoWrapper = this.playerContainerElement.appendChild(videoTagWrapper); | |
this.playerElement = this.playerContainerElement.getElementsByTagName('video')[0]; | |
this.playerPoster = __.xest('#'+this.playerId+' .mhp1138_videoPoster'); | |
}, | |
filterMediaSources: function(sources) { | |
var self = this, | |
adaptiveFlag, | |
removeProgressiveStreams; | |
this.videoResolutions = []; | |
this.videoSources = {}; | |
__.each(sources, function(el) { | |
if (el.format == 'dash' || el.format == 'hls') { | |
if (el.quality && | |
el.quality.length && | |
__.isPath(el.videoUrl) // do not create anything if url failed the test | |
) { | |
removeProgressiveStreams = true; | |
__.each(el.quality, function(q) { | |
sources.push({ | |
format: el.format, | |
quality: String(q), | |
videoUrl: el.videoUrl, | |
params: el.params || false | |
}); | |
}); | |
} | |
} | |
}); | |
// sorting media array by quality in reverse order | |
sources = __.sortBy(sources, function(el) { | |
// Adaptive AUTO | |
// always the first one in a list | |
if (el.format == 'dash' && (!el.quality || typeof el.quality == 'object')) { return 9999; } | |
if (el.format == 'hls' && (!el.quality || typeof el.quality == 'object')) { return 9998; } | |
// converting strings like '720p48' to negative floats -720.48 | |
return -parseFloat(String(el.quality).replace(/[_p]/ig, '.')) - (el.format == 'upsell'?10000:0); | |
}); | |
// checking for valid url or upsell labels | |
sources = __.filter(sources, function(el) { | |
if (el.format == 'hls') { | |
if (!window.Hls) return false; | |
// Since we do not use HLS library do not filter hls source in Safari on iOS | |
if (!self.isIosSafari && !Hls.isSupported()) return false; | |
} | |
if (el.format == 'dash') { | |
if (!window.dashjs) return false; | |
} | |
return __.isPath(el.videoUrl) || el.format == 'upsell'; | |
}); | |
// adaptive playlist + adaptive quality selectors is here, no need to keep MP4s | |
if (removeProgressiveStreams) { | |
sources = __.filter(sources, function(el) { | |
//console.log(el); | |
if (!el.format || el.format == 'mp4') { | |
return false; | |
} else { | |
return true; | |
} | |
}); | |
} | |
__.each(sources, function(el) { | |
var qualityName = el.quality; | |
// adaptive stream | |
if ((!el.quality || typeof el.quality == 'object') && | |
(el.format == 'dash' || el.format == 'hls') | |
) { | |
qualityName = el.format; | |
adaptiveFlag = el.format; | |
} | |
// do not overwrite upsell elements by "secret" qualities in adaptive playlist | |
if (!self.videoSources[qualityName]) { | |
self.videoResolutions.push(qualityName); | |
self.videoSources[qualityName] = el; | |
if (el.format != 'upsell' && el.defaultQuality) { | |
self.selectedResolution = qualityName; | |
self.selectedFormat = el.format; | |
} | |
} | |
}); | |
// return us the highest resolution from the sources list | |
// if a default one was not defined | |
if (!this.selectedResolution) { | |
// no defaultQuality key but choose adaptive stream as default any way | |
if (adaptiveFlag) { | |
this.selectedResolution = adaptiveFlag; | |
} else { | |
this.selectedResolution = (__.max(this.videoSources, function(el) { | |
return parseFloat(String(el.quality).replace(/[_p]/ig, '.') * (el.format == 'upsell'?-1:1)); | |
})).quality; | |
} | |
} | |
// set it back to original definitions array | |
for (var i = 0; i < sources.length;i++) { | |
if (sources[i].quality == this.selectedResolution) { | |
sources[i].defaultQuality = true; | |
} | |
} | |
return sources; | |
}, | |
initVrPlayer: function() { | |
if (!this.settings.isVr) return; | |
var projection, | |
stereoType, | |
vrVideo = this.playerContainerElement.getElementsByTagName('video')[0], | |
vrCanvas = this.playerContainerElement.getElementsByTagName('canvas')[0], | |
settings = this.settings; | |
__.addClass(this.playerContainerElement, 'vr'); | |
switch (settings.vrProps.projection) { | |
case 1: | |
projection = VrPlayer.PROJECTION_EQUIDISTANT_180; | |
break; | |
case 2: | |
projection = VrPlayer.PROJECTION_EQUIRECTANGULAR_360; | |
break; | |
case 3: | |
projection = VrPlayer.PROJECTION_EQUIRECTANGULAR_180; | |
break; | |
default: | |
throw "Invalid projection type"; | |
} | |
if (!settings.vrProps.stereoSrc) { | |
stereoType = VrPlayer.MONO | |
} else { | |
switch (settings.vrProps.stereoType) { | |
case 1: | |
stereoType = VrPlayer.STEREO_SIDE_BY_SIDE_LR; | |
break; | |
case 2: | |
stereoType = VrPlayer.STEREO_OVER_UNDER_LR; | |
break; | |
case 3: | |
stereoType = VrPlayer.STEREO_SIDE_BY_SIDE_RL; | |
break; | |
case 4: | |
stereoType = VrPlayer.STEREO_OVER_UNDER_RL; | |
break; | |
default: | |
throw "Invalid stereo type"; | |
} | |
} | |
try { | |
this.vrPlayer = new VrPlayer({ | |
canvas: vrCanvas, | |
video: vrVideo, | |
projection: projection, | |
stereoType: stereoType, | |
stereoView: false | |
}); | |
var self = this; | |
// restart it every fuckin event! | |
vrVideo.addEventListener('playing', function() { | |
self.vrPlayer.start(); | |
}); | |
vrVideo.addEventListener('seeked', function() { | |
self.vrPlayer.start(); | |
}); | |
// vrVideo.addEventListener('pause', function() { | |
// self.vrPlayer.stop(); | |
// }); | |
window.addEventListener('resize', this.vrPlayer.resize); | |
} catch (e) { | |
fireEvent('onVrError'); | |
} | |
}, | |
initVastParser: function() { | |
var self = this, | |
settings = this.settings, | |
vastCampaigns = settings.vast | |
settings.preRoll = settings.preRoll || []; | |
if (vastCampaigns && !__.isUndefined(MHP1138.vast)) { | |
if(!__.isArray(vastCampaigns)) { | |
vastCampaigns = [vastCampaigns]; | |
} | |
__.each(vastCampaigns, function(campaign) { | |
var parser = new MHP1138.vast(), | |
campaignHash = __.hashString(campaign.rollSettings.campaignName); | |
parser.init(self, campaign, 'pre'); | |
if (parser.status == 'parsed' && parser.rolls.length) { | |
// Saving rolls from vast into preRoll array | |
settings.preRoll = settings.preRoll.concat(parser.rolls); | |
if (parser.overlays.length) { | |
var randomBanner = parser.overlays[__.random(parser.overlays.length - 1)]; | |
self.mainRoll.overlays = [randomBanner]; | |
} | |
} else if (parser.status == 'error') { | |
return false; | |
} else if (parser.status == 'loading') { | |
// parser will manually update roll settings and re-run initAdsRoll | |
return false; | |
} | |
}); | |
} | |
}, | |
videoNotAvailable: function() { | |
this.noValidVideoSource = true; | |
this.initSkin(); | |
this.skin.videoNotAvailable(); | |
}, | |
overrideInitSettings: function(settings){ | |
// Disable hotspots controls and graph if data have not been sent | |
if(__.isEmpty(settings.hotspots.data)) { | |
settings.hotspots.enabled = false; | |
} | |
return settings; | |
}, | |
overrideEmbedSettings: function(settings) { | |
// override initial settings | |
if (settings.embeds.enabled) { | |
__.deepExtend(settings, { | |
hotspots: { | |
enabled: false | |
}, | |
features: { | |
ignorePreferences: true, | |
topControlBar: true, | |
shareBar: true, | |
// aliases | |
cinema: false, | |
playerSizeToggle: false, | |
// aliases | |
options: false, | |
optionsEnabled: false, | |
showHotspots: false, | |
chromecast: false | |
} | |
}); | |
} | |
return settings; | |
}, | |
overrideTabletSettings: function(settings) { | |
if (MHP1138.detector.isTablet()) { | |
__.deepExtend(settings, { | |
features: { | |
ignorePreferences: true, | |
// aliases | |
showAutoplayOption: false, | |
autoplayOption: false, | |
// aliases | |
cinema: false, | |
playerSizeToggle: false, | |
logo: false, // do we need to disable it? | |
tooltips: false, | |
volumeBar: false | |
}, | |
videoPreload: 'none', // 'metadata' not supported on tablets | |
autoplay: false | |
}); | |
} | |
return settings; | |
}, | |
overrideMobileSettings: function(settings) { | |
if (MHP1138.detector.isMobile()) { | |
__.deepExtend(settings, { | |
features: { | |
ignorePreferences: true | |
}, | |
videoPreload: 'none', // 'metadata' not supported on tablets | |
autoplay: false | |
}); | |
} | |
return settings; | |
}, | |
overrideSafariSettings: function(settings) { | |
//getting autoplay state, as safari requires preload metadata if auto play is on | |
this.getStoredAutoplayState(settings); | |
var browser = MHP1138.detector.getBrowser(), | |
isSafari = browser.name === 'safari'; | |
if (browser.type == 'desktop' && isSafari && this.autoplay) { | |
__.deepExtend(settings, { | |
//Changed from "metadata" to "none" because of Safari update hot fix 21.09.2017 | |
videoPreload: 'none' | |
}) | |
//Added because of Safari update hot fix 21.09.2017 | |
this.setAutoplay(false); | |
} | |
return settings; | |
}, | |
overrideIOSSafariSettings: function(settings){ | |
var browser = MHP1138.detector.getBrowser(); | |
//Detecting if Safari on iOS | |
if(MHP1138.detector.isIos() && (browser.name === 'safari' || browser.name === 'ios')){ | |
this.isIosSafari = true; | |
} | |
return settings; | |
}, | |
supportDefaultOverlayTextAd: function(settings) { | |
var textAd = settings.mainRoll.overlayTextAd; | |
if (textAd && textAd.displayText.length) { | |
__.extend(textAd, { | |
label: textAd.displayText, | |
time: textAd.showDelay, | |
duration: textAd.displayDuration, | |
bottom: '60px', | |
fontScale: '3%', | |
hCentered: true | |
}); | |
settings.mainRoll.overlays.push(textAd); | |
} | |
return settings; | |
}, | |
// support for deprecated medias array | |
supportDeprecatedSettings: function(settings) { | |
if (!__.isEmpty(settings.medias)) { | |
//removeIf(production) | |
MHP1138.warn('You are using deprecated "medias" structure, upgrade your config to "mainRoll"'); | |
//endRemoveIf(production) | |
} | |
return settings; | |
}, | |
// init quality state | |
getStoredQuality: function() { | |
if (this.settings.embeds.enabled) { | |
return; | |
} | |
var storedValue = store.get('player_quality'); | |
if (storedValue && | |
this.videoSources[storedValue.quality] && | |
this.videoSources[storedValue.quality].format !== 'upsell' | |
) { | |
this.selectedResolution = storedValue.quality; | |
} | |
}, | |
getStoredAutoplayState: function(settings) { | |
var storedState = store.get('player_autoplay'); | |
// override from player config | |
if (settings.autoplay) { | |
this.setAutoplay(true); | |
} | |
//embed mode hardcoded settings | |
if (settings.features.ignorePreferences) { | |
if (!settings.autoplay) { | |
this.setAutoplay(false); | |
} | |
} else if (storedState && !__.isUndefined(storedState.autoplay)) { | |
this.setAutoplay(storedState.autoplay); | |
} | |
}, | |
getStoredMotionRate: function() { | |
var settings = this.settings, | |
storedState = store.get('player_motionRate'); | |
if (storedState && !__.isUndefined(storedState.motionRate)) { | |
this.setMotionRate(storedState.motionRate); | |
} else { | |
this.setMotionRate(1); | |
} | |
}, | |
getStoredHotspotsState: function() { | |
var settings = this.settings, | |
storedState = store.get('player_hotspots'); | |
this.hotspotsState = settings.features.showHotspots; | |
if (storedState && !__.isUndefined(storedState.hotspotsState)) { //embed mode hardcoded settings | |
this.setHotspotsState(storedState.hotspotsState); | |
} | |
fireEvent('onHotspotsStateChange', { hotspotsState: this.hotspotsState }); | |
}, | |
getStoredVolume: function() { | |
var settings = this.settings, | |
storedVolume = store.get('player_volume'); | |
if (!storedVolume || settings.features.ignorePreferences) { | |
var startVolume = 100, | |
startMute = false; | |
} else if (storedVolume && !__.isUndefined(storedVolume.volume)) { | |
var startVolume = storedVolume.volume, | |
startMute = storedVolume.isMuted; | |
} | |
//Set the video volume based on the start volume | |
this.setVolume(startVolume); | |
this.setMute(startMute); | |
}, | |
initContainer: function() { | |
var container = document.getElementById(this.playerId); | |
//removeIf(production) | |
//check to be sure that a container was created for the player | |
if (!container) { | |
MHP1138.error('You need to create a container element for the player with ID "#'+ this.playerId +'".'); | |
return; | |
} | |
//endRemoveIf(production) | |
MHP1138.detector.generateClassList(container); | |
__.addClass(container, 'container'); | |
// hide controls bar on player init, only centered play button shown and only on desktop | |
if ( MHP1138.detector.isDesktop() ) { | |
__.addClass(container, 'hideControls'); | |
} | |
//add embedded class to the container | |
if (this.settings.embeds.enabled) { | |
__.addClass(container, 'embedded'); | |
} | |
//WARNING, ANY REFERENCE OR EVENTS BINDED ON THE PLAYER ELEMENTS BEFORE THIS LINE WILL BE DELETED!!!!!! | |
//Where copying the skin markup to the current player | |
var playerMarkup = MHP1138.skinsMarkup['markup']; | |
container.innerHTML = playerMarkup; | |
this.playerContainerElement = container; | |
}, | |
initSkin: function() { | |
this.skin.init(this, function() { | |
//the callback | |
}); | |
}, | |
_appendUrlParams: function(url, params) { | |
if (url.indexOf('?') == -1) { | |
url = url + '?' + params.substring(1); | |
} else { | |
url += params; | |
} | |
return url; | |
}, | |
initSourceParams: function(source){ | |
var urlParams = ''; | |
if (source.params) { | |
if (typeof source.params == 'string') { | |
urlParams = '&' + source.params | |
} else { | |
__.each(source.params, function(value, key) { | |
urlParams += '&' + key + '=' + value; | |
}) | |
} | |
} | |
return urlParams; | |
}, | |
initHlsPlayer: function(source) { | |
var self = this, | |
path = source.videoUrl, | |
urlParams = ''; | |
if (!window.Hls || !Hls.isSupported()) { | |
return; | |
} | |
// load NEW source to existing hls player | |
if (this.hlsPlayer) { | |
this.hlsPlayer.loadSource(path); | |
return; | |
} | |
urlParams = this.initSourceParams(source); | |
this.hlsPlayer = new Hls(__.deepExtend({}, this.settings.hlsSettings, { | |
fetchSetup: function(context, initParams) { | |
// Always send cookies, even for cross-origin calls. | |
//initParams.credentials = 'include'; | |
return new Request(self._appendUrlParams(context.url, urlParams), initParams); | |
}, | |
xhrSetup: function(xhr, url) { | |
//xhr.withCredentials = true; // do send cookies | |
// hackery: overriding xhr.open request made before xhrSetup callback | |
xhr.open('GET', self._appendUrlParams(url, urlParams), true); | |
} | |
})); | |
this.hlsPlayer.attachMedia(this.playerElement); | |
this.hlsPlayer.loadSource(path); | |
// cache the HLS source value for later use | |
this.hlsSource = source; | |
this.bindHlsPlayerEvents(this.hlsPlayer); | |
// set flag to change quality to manual value on CAN_PLAY event | |
if (typeof source.quality == 'string') { | |
this.hlsQuality = source.quality; | |
} | |
// check for updates of the player container to re-set quality limit | |
// window.addEventListener('resize', function() { | |
// // hls video is playing AND was set to Auto quality | |
// if (this.hlsSource && !this.hlsQuality) { | |
// this.limitHlsQualityByPortal(); | |
// } | |
// }); | |
}, | |
bindHlsPlayerEvents: function(hls) { | |
var self = this, | |
skin = this.skin, | |
settings = this.settings; | |
// hls.on(Hls.Events.MEDIA_ATTACHED, function () { | |
// console.log("HLS: parser attached to the video tag"); | |
// }); | |
hls.on(Hls.Events.MANIFEST_PARSED, function() { | |
// deferred manual quality selection | |
if (self.hlsQuality) { | |
self.setHlsQuality(self.hlsQuality); | |
} else { | |
//self.limitHlsQualityByPortal(); | |
} | |
}); | |
hls.on(Hls.Events.FRAG_CHANGED,function(data1, data2) { | |
var chunkDetails = { | |
'hlsChunkId' : data2.frag.sn, | |
'hlsChunkSize' : data2.frag.loaded, | |
'hlsChunkQuality' : data2.frag.level, | |
'hlsChunkBandwidth' : self.hlsPlayer.streamController.fragLastKbps | |
} | |
fireEvent('fragmentChanged', {chunkDetails:chunkDetails}); | |
//levels : 0-240, 1-380, 2-480, 3-720, 4-1080 | |
}); | |
hls.on(Hls.Events.ERROR, function (event, data) { | |
if (data.fatal) { | |
switch (data.type) { | |
case Hls.ErrorTypes.NETWORK_ERROR: | |
// try to recover network error | |
console.log("HLS: fatal network error encountered, try to recover"); | |
// hls.startLoad(); | |
skin.videoNotAvailable(l(settings.htmlSettings.videoErrorMessage)); | |
break; | |
case Hls.ErrorTypes.MEDIA_ERROR: | |
skin.videoNotAvailable(l(settings.htmlSettings.videoErrorMessage)); | |
console.log("HLS: fatal media error encountered, try to recover"); | |
//hls.recoverMediaError(); | |
break; | |
default: | |
// cannot recover | |
self.destroyHlsPlayer(); | |
} | |
} | |
}); | |
}, | |
setHlsQuality: function(quality) { | |
if (!this.hlsSource) return; | |
var hls = this.hlsPlayer, | |
list = hls.levels; | |
__.each(list, function(el, index) { | |
if (parseInt(quality) == el.height || parseInt(quality) == parseInt(el.name)) { | |
hls.nextLevel = index; | |
// hls.loadLevel = index; | |
// hls.currentLevel = index; | |
self.hlsQuality = quality; | |
hls.autoLevelCapping = -1; // disable quality cap | |
} | |
}); | |
}, | |
setHlsAutoQuality: function() { | |
if (!this.hlsSource) return; | |
var hls = this.hlsPlayer; | |
hls.nextLevel = -1; | |
//hls.loadLevel = -1; | |
//hls.currentLevel = -1; | |
this.hlsQuality = false; | |
//this.limitHlsQualityByPortal(); | |
}, | |
limitHlsQualityByPortal: function() { | |
if (!this.hlsPlayer) return; | |
var hls = this.hlsPlayer, | |
list = hls.levels, | |
maxIndex = -1, | |
playerHeight = this.playerContainerElement.clientHeight; | |
__.each(list, function(el, index) { | |
var qHeight = Math.max(el.height, parseInt(el.name)); | |
// 120px is the margin delta to have a chance to set quality cap one step further than player height | |
// '480p' for H360px player and so on | |
if (index > maxIndex && qHeight <= playerHeight + 120) { | |
maxIndex = index; | |
} | |
}); | |
hls.autoLevelCapping = maxIndex; | |
}, | |
destroyHlsPlayer: function() { | |
this.hlsPlayer.destroy(); | |
this.hlsPlayer = false; | |
this.hlsSource = false; | |
}, | |
initDashPlayer: function(source) { | |
if (!window.dashjs) return false; | |
var self = this, | |
path = source.videoUrl, | |
urlParams = ''; | |
if (this.dashPlayer) { | |
// restart existing player | |
this.dashPlayer.pause(); | |
this.dashPlayer.attachSource(path); | |
return; | |
} | |
urlParams = this.initSourceParams(source); | |
this.dashPlayer = dashjs.MediaPlayer().create(); | |
this.dashPlayer.initialize(this.playerElement, null, false); | |
this.dashPlayer.extend('RequestModifier', function() { | |
return { | |
modifyRequestURL: function(url) { | |
return self._appendUrlParams(url, urlParams); | |
} | |
}; | |
}, | |
true | |
); | |
this.applyDashSettings(this.dashPlayer); | |
this.dashPlayer.attachSource(path); | |
this.dashSource = source; | |
this.bindDashPlayerEvents(this.dashPlayer); | |
// set flag to change quality to manual value on CAN_PLAY event | |
if (typeof source.quality == 'string') { | |
this.dashQuality = source.quality; | |
} | |
}, | |
applyDashSettings: function(dash) { | |
var debug = dash.getDebug(); | |
debug.setLogToBrowserConsole(false); | |
dash.setFastSwitchEnabled(true); // REPLACE loaded chunks instead of adding new to the end of buffered part | |
// // initial value, do not buffer anything | |
// dash.setStableBufferTime(1); // default is 12sec | |
// dash.setBufferTimeAtTopQuality(120); // default is 30sec | |
// dash.setBufferTimeAtTopQualityLongForm(120); // default is 60sec | |
// dash.enableLastBitrateCaching(true, 7 * 24 * 60 * 60 * 100) // 7 days | |
// dash.enableLastMediaSettingsCaching(true, 7 * 24 * 60 * 60 * 100) // 7 days | |
// limit the representation used based on the size of the playback area | |
//dash.setLimitBitrateByPortal(true); | |
// count retina pixels too | |
//dash.setUsePixelRatioInLimitBitrateByPortal(true); | |
}, | |
bindDashPlayerEvents: function(dash) { | |
var self = this, | |
skin = this.skin, | |
settings = this.settings, | |
timer; | |
function resizeDashPortal() { | |
if (dash.getLimitBitrateByPortal()) { | |
clearTimeout(timer); | |
timer = setTimeout(function() { | |
dash.updatePortalSize(); | |
}, 1000); | |
} | |
} | |
// update portal size if window / player dimensions changed | |
subscribeToEvent('collapsePlayer', resizeDashPortal); | |
subscribeToEvent('expandPlayer', resizeDashPortal); | |
window.addEventListener('resize', resizeDashPortal); | |
// dash.on(dashjs.MediaPlayer.events.MANIFEST_LOADED, function (e) { | |
// console.log('DASH: MANIFEST_LOADED', e); | |
// }); | |
var firstTimeReady = true; | |
dash.on(dashjs.MediaPlayer.events.CAN_PLAY, function (e) { | |
// console.log('DASH: CAN_PLAY', e); | |
// CAN_PLAY fires every time player prebuffers stream after lag | |
// We need only the very first action | |
if (firstTimeReady) { | |
// deferred manual quality selection | |
if (self.dashQuality) { | |
self.setDashQuality(self.dashQuality); | |
} | |
if (self.autoplay) { | |
self.playerElement.play(); | |
} | |
firstTimeReady = false; | |
} | |
}); | |
dash.on(dashjs.MediaPlayer.events.ERROR, function (e) { | |
console.log('DASH: fatal media error encountered', e); | |
skin.videoNotAvailable(l(settings.htmlSettings.videoErrorMessage)); | |
}); | |
// dash.on(dashjs.MediaPlayer.events.QUALITY_CHANGE_REQUESTED, function (e) { | |
// if (e.mediaType == 'video') { | |
// console.log('DASH: QUALITY_CHANGE_REQUESTED', e); | |
// } | |
// }); | |
// dash.on(dashjs.MediaPlayer.events.QUALITY_CHANGE_RENDERED, function (e) { | |
// console.log('DASH: QUALITY_CHANGE_RENDERED', e); | |
// }); | |
// dash.on(dashjs.MediaPlayer.events.PERIOD_SWITCH_COMPLETED, function (e) { | |
// console.log('DASH: PERIOD_SWITCH_COMPLETED'); | |
// }); | |
// dash.on(dashjs.MediaPlayer.events.STREAM_INITIALIZED, function (e) { | |
// console.log('DASH: STREAM_INITIALIZED'); | |
// }); | |
var firstTimePlaying = true; | |
dash.on(dashjs.MediaPlayer.events.PLAYBACK_PLAYING, function(e) { | |
//console.log('DASH: PLAYBACK_PLAYING'); | |
if (firstTimePlaying) { | |
// allow up to 6sec to buffer | |
//dash.setStableBufferTime(6); | |
firstTimePlaying = false; | |
} | |
}); | |
// dash.on(dashjs.MediaPlayer.events.PLAYBACK_PAUSED, function(e) { | |
// console.log('DASH: PLAYBACK_PAUSED'); | |
// }); | |
// dash.on(dashjs.MediaPlayer.events.PLAYBACK_SEEKING, function(e) { | |
// console.log('DASH: PLAYBACK_SEEKING'); | |
// }); | |
// dash.on(dashjs.MediaPlayer.events.PLAYBACK_SEEKED, function(e) { | |
// console.log('DASH: PLAYBACK_SEEKED'); | |
// }); | |
// dash.on(dashjs.MediaPlayer.events.PLAYBACK_ENDED, function(e) { | |
// console.log('DASH: PLAYBACK_ENDED'); | |
// }); | |
dash.on(dashjs.MediaPlayer.events.FRAGMENT_LOADING_COMPLETED, function(e, data) { | |
if(e.request.mediaType === 'video') { | |
var metrics = self.dashPlayer.getMetricsFor('video'), | |
dashMetrics = self.dashPlayer.getDashMetrics(), | |
representationId = dashMetrics.getCurrentRepresentationSwitch(metrics).to, | |
streamInfo = self.dashPlayer.getActiveStream().getStreamInfo(), | |
periodId = streamInfo.index, | |
bandwidth = dashMetrics.getBandwidthForRepresentation(representationId, periodId); | |
var chunkDetails = { | |
'hlsChunkId' : e.request.index, | |
'hlsChunkSize' : e.request.bytesLoaded, | |
'hlsChunkQuality' : e.request.quality == 0 ? e.request.quality : (e.request.quality+1), | |
'hlsChunkBandwidth' : (bandwidth*0.125).toFixed(2) | |
} | |
fireEvent('fragmentChanged', {chunkDetails:chunkDetails}); | |
} | |
}); | |
}, | |
setDashQuality: function(quality) { | |
if (!this.dashSource) return; | |
var self = this, | |
dash = this.dashPlayer, | |
list = dash.getBitrateInfoListFor('video'); | |
//console.log('list:', list, 'buffered: ', dash.getBufferLength()/*, dash.setBufferToKeep(0)*/); | |
//dash.setBufferToKeep(0.5); // 0.5sec // doesnt seems to be working | |
__.each(list, function(el) { | |
if (parseInt(quality) == el.height) { | |
//dash.setLimitBitrateByPortal(false); | |
dash.setAutoSwitchQualityFor('video', false); | |
dash.setQualityFor('video', el.qualityIndex); | |
self.dashQuality = quality; | |
} | |
}); | |
}, | |
setDashAutoQuality: function() { | |
if (!this.dashSource) return; | |
var dash = this.dashPlayer; | |
// return to default value | |
//dash.setLimitBitrateByPortal(true); | |
dash.setAutoSwitchQualityFor('video', true); | |
this.dashQuality = false; | |
}, | |
destroyDashPlayer: function() { | |
// no need to actually destroy DASH player | |
// in a way we do so for HLS | |
// But we have to reset DASH player (2.4.1) this way | |
// Setting wrong/empty source brings "dash media error" to console. | |
// This hack allows regular .mp4 playback ONLY after that | |
// in any other case, DASH lib blocks it | |
this.dashPlayer.pause(); | |
this.dashPlayer.attachSource('#'); | |
this.dashSource = false; | |
}, | |
initPreRoll: function() { | |
var roll = this.initAdsRoll('pre'); | |
this.preRoll = roll; | |
}, | |
showPreRoll: function() { | |
this.isPreRollActive = true; | |
this.showAdsRoll(this.preRoll); | |
}, | |
initPauseRoll: function() { | |
var roll = this.initAdsRoll('pause'); | |
this.pauseRoll = roll; | |
}, | |
showPauseRoll: function() { | |
this.isPauseRollActive = true; | |
this.showAdsRoll(this.pauseRoll); | |
}, | |
skipPauseRoll: function() { | |
this.isPauseRollActive = false; | |
this.hideStaticRoll(); | |
this.enableOptions(); | |
// if (!this.pauseRoll.repeat) { | |
// this.pauseRoll.enabled = false; | |
// } | |
}, | |
showMainRoll: function() { | |
var mainRoll = this.mainRoll, | |
settings = this.settings; | |
// no reason to set poster if it will be replaced by ad in a moment | |
// no reason to set poster if the seek bar will be moved | |
if (!parseInt(settings.startOffset) && !this.autoplay || | |
settings.startOffset && !MHP1138.detector.isDesktop() || | |
this.preRoll.enabled && !this.autoplay | |
) { | |
this.setPoster(mainRoll.poster); | |
} | |
// Set the video duration if it's given as a parameter, | |
// so it's not shown as empty before the metadata are loaded. | |
if (mainRoll.duration > 0) { | |
this.updateDuration(mainRoll.duration); | |
this.setActionTags(mainRoll.actionTags); | |
this.setOverlays(mainRoll.overlays); | |
} | |
}, | |
initAdsRoll: function(prefix) { | |
var self = this, | |
timestamp = new Date().getTime(), | |
settings = this.settings, | |
roll = settings[prefix+'Roll'], | |
defaultRollObject = this.settings.defaultRollObject, | |
campaigns = [], | |
campaignCandidates = [], | |
candidates = [], | |
cookie = store.get('player_'+prefix+'roll') || { | |
views: 0, | |
time: {} | |
}; | |
if (__.isEmpty(roll)){ | |
return false; | |
} | |
//TFE-718 fix for users who has old localStorage data structure | |
if(!__.isObject(cookie.time)){ | |
cookie.time = {}; | |
} | |
// Increase counter of views | |
cookie.views += 1; | |
store.set('player_' + prefix + 'roll', cookie); | |
if(!__.isArray(roll)) { | |
roll = [roll]; | |
} | |
this.campaignCandidates = roll; | |
__.each(roll, function(candidate, index) { | |
candidate.onNth +=1; | |
//removeIf(production) | |
if (typeof candidate.repeat !== 'undefined'){ | |
//Parameter will be removed in version 2.5.0 | |
MHP1138.warn('You are using deleted "repeat" parameter in roll section, please upgrade your config.'); | |
} | |
//endRemoveIf(production) | |
// apply default settings to each roll candidate | |
candidate = __.deepExtend({}, defaultRollObject, candidate); | |
// resetTime is the number of seconds (default is 24Hrs) to reset the display of ads roll | |
var resetTime = candidate.forgetUserAfter * 1000; | |
// create empty array for campaign candidates | |
if(__.isUndefined(campaignCandidates[candidate.campaign])){ | |
campaignCandidates[candidate.campaign] = []; | |
} | |
// first time, cookie doesn't exist yet | |
if(__.isUndefined(cookie.time[candidate.campaign])){ | |
cookie.time[candidate.campaign] = 0; | |
} | |
// check if forgetUserAfter time for this campaign didn't pass yet | |
if ((timestamp - cookie.time[candidate.campaign] > resetTime)) { | |
campaignCandidates[candidate.campaign].push(candidate); | |
} | |
}); | |
campaigns = __.keys(campaignCandidates); | |
__.each(campaigns, function(campaign, index) { | |
// looking for roll candidates as array | |
var cn = self.filterRollCandidates(campaignCandidates[campaign], cookie.views); | |
if(cn.length){ | |
cn = cn[__.random(cn.length - 1)] | |
candidates.push(cn); | |
} | |
}); | |
// if all candidates failed the test | |
if (!candidates.length) return false; | |
// or choose random one from array | |
// roll set to object! no more arrays at this point | |
roll = candidates[__.random(candidates.length - 1)]; | |
if(!this.settings.isVr) { | |
roll.enabled = true; | |
} | |
if (!this.checkRollPath(roll)) return false; | |
if (!__.isUndefined(roll.mediaDefinition)){ | |
if (roll.mediaDefinition.length) { | |
roll.videoUrl = roll.mediaDefinition[0].videoUrl; | |
} | |
} | |
// legacy properties for 4play | |
if (__.isPath(roll.imageUrl)) { | |
roll.type = 'static'; | |
roll.static = true; | |
roll.variant = 'image'; | |
delete roll.trackUrl; // disable tracking for static rolls | |
} else if (__.isPath(roll.videoUrl)) { | |
roll.type = 'video'; | |
roll.video = true; | |
} | |
roll.timing = prefix + 'roll'; | |
// special treatment for pauseRolls | |
// | |
// no 'playing' functionality for static images while on pause | |
// but show them on every pause event | |
if (prefix == 'pause') { | |
if (__.isPath(roll.imageUrl)) { | |
roll.skipDelay = 0; | |
roll.enabled = true; | |
// block video ads on pause | |
// if accidentally set in settings | |
} else if (__.isPath(roll.videoUrl)) { | |
roll.enabled = false; | |
} | |
} else { | |
// staticRolls on pre or post should be disabled | |
if (__.isPath(roll.imageUrl)) { | |
roll.enabled = false; | |
} | |
} | |
if (roll.enabled) { | |
if (roll.skippable) { | |
if (!roll.skipMessage) { | |
roll.skipMessage = l(settings.htmlSettings.skipMessage) | |
} | |
if (!roll.skipDelayMessage) { | |
roll.skipDelayMessage = l(settings.htmlSettings.skipDelayMessage); | |
} | |
} | |
var defaultTrackUrl = settings.htmlSettings.adsTrackUrl; | |
if (!roll.trackUrl) { | |
roll.trackUrl = [defaultTrackUrl]; | |
} else if(__.isArray(roll.trackUrl)){ | |
roll.trackUrl.push(defaultTrackUrl); | |
} else if(__.isString(roll.trackUrl)) { | |
// do not fire track callback twice if urls are the same | |
if (roll.trackUrl != defaultTrackUrl) { | |
roll.trackUrl = [roll.trackUrl, defaultTrackUrl]; | |
} else { | |
roll.trackUrl = [defaultTrackUrl]; | |
} | |
} | |
// update stored timestamp to current time of displayed ad | |
// views counter stays the same | |
cookie.time[roll.campaign] = timestamp; | |
store.set('player_' + prefix + 'roll', cookie); | |
} | |
return roll; | |
}, | |
showAdsRoll: function(roll) { | |
var self = this; | |
// video source | |
if (__.isPath(roll.videoUrl)) { | |
self.showAdsRollUI(roll); | |
self.firePreRollEvent = true; | |
// callback would never happen if there is no videoPreload = 'metadata' | |
this.setSource(roll, function() { | |
if (self.isPreRollActive) { | |
fireEvent('showPreRoll'); | |
} | |
}); | |
// static image | |
} else if (__.isPath(roll.imageUrl)) { | |
this.playStaticRoll(roll); | |
} | |
}, | |
// TODO: move it to skin | |
showAdsRollUI: function(roll) { | |
this.setOverlays([]); | |
this.showRollAdsMessage(); | |
if (roll.skippable) { | |
// right after switching from mainRoll vid and currentTime has prev value | |
this.currentTime = 0; | |
this.initRollSkipButton(roll); | |
this.showRollSkipButton(); | |
} | |
}, | |
// TODO: move it to skin | |
hideAdsRollUI: function() { | |
var skin = this.skin; | |
this.hideRollAdsMessage(); | |
this.hideRollSkipButton(); | |
this.enableOptions(); | |
skin.seekBarRemoveAnimation(); | |
skin.updateSeekBarPosition(0); | |
setTimeout(function() { | |
skin.seekBarAddAnimation(); | |
}, 100); | |
}, | |
filterRollCandidates: function(roll, rollViewCount) { | |
var candidates = []; | |
__.each(roll, function(candidate) { | |
// support legacy naming | |
if (__.isUndefined(candidate.onNth) && | |
__.isNumber(candidate.on_nth) | |
) { | |
candidate.onNth = candidate.on_nth; | |
} | |
//we filter the invalid onNth with modulus | |
if (rollViewCount % candidate.onNth) return false; | |
candidates.push(candidate); | |
}); | |
return candidates; | |
}, | |
checkRollPath: function(roll) { | |
if (!__.isPath(roll.videoUrl) && | |
!__.isPath(roll.imageUrl) | |
) { | |
return false; | |
} else { | |
return true; | |
} | |
}, | |
initRollSkipButton: function(roll) { | |
if (!this.rollSkipButton) { | |
this.createRollSkipButton(); | |
} | |
this.updateRollSkipButton(roll); | |
}, | |
createRollSkipButton: function() { | |
var self = this; | |
this.rollSkipButton = __.xest('#' + this.playerId + ' .mhp1138_preRollSkipButton div'); | |
if (!this.rollSkipButton) return; | |
// rollSkipButton is a label inside actual button | |
var eventType = MHP1138.detector.isDesktop() ? 'click' : 'touchstart'; | |
this.rollSkipButton.parentNode.addEventListener(eventType, function () { | |
if (self.rollTimeLeft <= 0) { | |
var roll = self.adsRoll(); | |
if (roll) { | |
self.adsRollTracking(roll, 'skip'); | |
} | |
self.deferredPreRoll = false; | |
self.setSource( | |
self.getCurrentQualitySource(), | |
self.changeVideoSourceCallback.bind(self) | |
); | |
} | |
}); | |
}, | |
updateRollSkipButton: function(roll) { | |
if (roll.skippable) { | |
this.rollTimeLeft = Math.floor(roll.skipDelay - Math.floor(this.currentTime)); | |
if (!this.rollSkipButton) return; | |
if (this.rollTimeLeft > 0) { | |
this.rollSkipButton.innerHTML = roll.skipDelayMessage.replace('%', this.rollTimeLeft).replace('(s)', (this.rollTimeLeft>1?'s':'')); | |
} else { | |
this.rollSkipButton.innerHTML = roll.skipMessage; | |
} | |
} | |
}, | |
showRollSkipButton: function() { | |
if (this.rollSkipButton) { | |
this.rollSkipButton.parentNode.style.display = 'block'; | |
} | |
}, | |
hideRollSkipButton: function() { | |
if (this.rollSkipButton) { | |
this.rollSkipButton.parentNode.style.display = 'none'; | |
} | |
}, | |
showRollAdsMessage: function() { | |
__.addClass(this.playerContainerElement, 'preRollRunning'); | |
}, | |
hideRollAdsMessage: function() { | |
__.removeClass(this.playerContainerElement, 'preRollRunning'); | |
}, | |
getCurrentQualitySource: function() { | |
return this.videoSources[this.selectedResolution]; | |
}, | |
bindPlayerEvents: function() { | |
var self = this, | |
settings = this.settings; | |
//TOTAL DURATION | |
this.playerElement.ondurationchange = function(e) { | |
// skip duration update on preroll metadata load, | |
// to create effect of main video will be played on button click | |
if (self.deferredPreRoll) { | |
self.adDuration = this.duration; | |
return; | |
} | |
// 'this' is referring to player video tag | |
if (self.duration != this.duration) { | |
self.updateDuration(this.duration); | |
if (!self.adsRoll()) { | |
var mainRoll = settings.mainRoll; | |
self.setActionTags(mainRoll.actionTags); | |
self.setOverlays(mainRoll.overlays); | |
} | |
} | |
}; | |
//CURRENT TIME | |
this.playerElement.ontimeupdate = function() { | |
var time; | |
if (self.chromecast.active) { | |
time = self.chromecast.media.getEstimatedTime(); | |
} else { | |
time = this.currentTime; | |
} | |
fireEvent('onBuffer', { buffered: this.buffered }); | |
if (!self.updatingSource && !self.seeking) { | |
self.updateCurrentTime(time); | |
} | |
var roll = self.adsRoll(); | |
if (roll) { | |
self.updateRollSkipButton(roll); | |
} | |
}; | |
//BUFFERING PROGRESSION | |
this.playerElement.onprogress = function(e) { | |
fireEvent('onBuffer', { buffered: this.buffered }); | |
}; | |
//STOP TO BUFFER | |
this.playerElement.onwaiting = function(){ | |
fireEvent('onWaiting'); | |
self.playing = false; | |
}; | |
this.playerElement.onpause = function() { | |
if (!self.seeking) { | |
fireEvent('onPause'); | |
} | |
self.playing = false; | |
} | |
this.playerElement.onplaying = function() { | |
self.videoEnded = false; | |
if (!self.videoStarted) { | |
self.videoStarted = true; | |
self.showVideoTag(); | |
} | |
if (self.deferredPreRoll) { | |
self.updateDuration(self.adDuration); | |
} | |
if (!self.initialSeek && !self.seeking && !self.seekToEnd) { | |
fireEvent('onPlay', { playAfterSeek: self.playAfterSeek }); | |
fireEvent('hideRoll'); | |
} | |
self.updatingSource = false; | |
self.playing = true; | |
}; | |
this.playerElement.onseeked = function() { | |
// 'this' is referring to self.playerElement, no need to use player object | |
if (this.paused) { | |
// player was paused before source change, | |
// need to fire pause event for newly loaded source | |
if (self.updatingSource || self.initialSeek || self.seeking) { | |
self.playing = false; | |
if (!self.seekToEnd) { | |
fireEvent('onPause'); | |
} | |
} | |
self.updatingSource = false; | |
} | |
self.seeking = false; | |
if (self.deferredSeek) { | |
self.seek(self.deferredSeek.offset, self.deferredSeek.playAfter); | |
self.deferredSeek = false; | |
} else if (self.deferredPause && !this.paused) { | |
self.playing = true; | |
self.deferredPause = false; | |
self.pause(); | |
// playerElement wouldnt fire onpause event because the player pauses vid before every seek call | |
// need to fire it manually | |
fireEvent('onPause'); | |
} else if (self.playAfterSeek) { | |
self.play(); | |
fireEvent('onPlay', { playAfterSeek: self.playAfterSeek }); | |
} | |
if (self.initialSeek) { | |
self.initialSeek = false; | |
//IOS fires onseeked after play when seeked initially before playback | |
if (!this.videoStarted && | |
MHP1138.detector.isIos() | |
) { | |
self.play(); | |
fireEvent('onPlay', { playAfterSeek: self.playAfterSeek }); | |
} | |
self.showVideoTag(); | |
} | |
}; | |
this.playerElement.oncanplay = function() { | |
if (!self.videoStarted) { | |
self.videoReady(this.src) | |
} | |
}; | |
//ON END | |
this.playerElement.onended = function() { | |
var roll = self.adsRoll(); | |
if (self.isPreRollActive) { | |
self.deferredPreRoll = false; | |
self.setSource( | |
self.getCurrentQualitySource(), | |
self.changeVideoSourceCallback.bind(self) | |
); | |
self.adsRollTracking(roll, 'finish'); | |
return; | |
} | |
self.videoEnded = true; | |
self.playing = false; | |
//Stop the counter because user reached the end of the video and havent seen 60 secs | |
self.stopViewedCounter(); | |
self.fireEndEvent(); | |
fireEvent('showPostRoll'); | |
self.seekToEnd = false; | |
}; | |
if (settings.videoPreload == 'none' ) { | |
this.videoReady(this.playerElement.src); | |
} | |
this.playerCreated = true; | |
}, | |
skinNotReady: function() { | |
//removeIf(production) | |
MHP1138.warn('Wait for "onSkinReady" event'); | |
//endRemoveIf(production) | |
}, | |
playerNotReady: function() { | |
//removeIf(production) | |
MHP1138.warn('Wait for "onReady" event'); | |
//endRemoveIf(production) | |
}, | |
fireVolumeChangeEvent: function() { | |
if (!this.settings.features.ignorePreferences) { | |
this.saveVolumeToCookie(this.volume, this.muted); | |
} | |
fireEvent('onVolumeChange', { | |
volume : this.volume, | |
muted : this.muted | |
}); | |
}, | |
saveVolumeToCookie: function(newVolume, isMuted) { | |
store.set('player_volume', { | |
volume : newVolume, | |
isMuted : isMuted | |
}); | |
}, | |
saveQualityToCookie: function(newQuality) { | |
store.set('player_quality', { quality: newQuality }); | |
}, | |
saveAutoplay: function(autoplay) { | |
this.setAutoplay(autoplay); | |
store.set('player_autoplay', { autoplay: autoplay }); | |
}, | |
saveSlowMotionRate: function(motionRate) { | |
store.set('player_motionRate', { motionRate: motionRate }); | |
}, | |
saveHotspotsState: function(hotspotsState) { | |
store.set('player_hotspots', { hotspotsState: hotspotsState }); | |
}, | |
replaceTrackUrlMasks: function(roll, action, url) { | |
var appid = roll.appId, | |
site = encodeURIComponent(roll.clickUrl), | |
siteName = encodeURIComponent(roll.siteName ? roll.siteName : 'undefined'), | |
campaign = roll.campaignName, | |
platform = MHP1138.detector.isDesktop() ? 'PC' : 'Mobile'; | |
var link = url.replace('%APPID%', appid) | |
.replace('%ACTION%', action) | |
.replace('%SITE%', site) | |
.replace('%CAMPAIGN%', campaign) | |
.replace('%PLAYER%', this.playerType) | |
.replace('%PLATFORM%', platform); | |
if (siteName.length > 0) { | |
link = link.replace('%SITENAME%', siteName); | |
} | |
return link; | |
}, | |
// TODO: implement google masking standard | |
replaceVASTTrackUrlMasks: function(roll, action, url) { | |
var link = url; | |
return link; | |
}, | |
adsRollTracking: function (roll, action) { | |
var url = roll.trackUrl; | |
if (roll.vastParser) { | |
if (action == 'play' && | |
roll.impressionUrl | |
) { | |
url = roll.impressionUrl; | |
} else if (action == 'click' && | |
roll.clickTrackUrl | |
) { | |
url = roll.clickTrackUrl; | |
} | |
} else { | |
url = roll.trackUrl; | |
} | |
for (var i = 0, len = url.length; i < len; i++) { | |
var link = ''; | |
if (__.isPath(url[i])) { | |
link = this.replaceTrackUrlMasks(roll, action, url[i]); | |
if (roll.vastParser) { | |
link = this.replaceVASTTrackUrlMasks(roll, action, link); | |
} else { | |
// DEPRECATED | |
// Do not call remote track urls except for the 'play' events | |
// ('first impression' in VAST terminology) | |
// but do so for our own tracker (etahub) | |
// | |
// VAST urls however should be called for ANY event | |
if (action != 'play' && | |
link.indexOf('etahub.com') == -1 | |
) { | |
continue; | |
} | |
} | |
__.ajaxLoader(link); | |
} | |
} | |
}, | |
setQuality: function(resolution, callback) { | |
var sources = this.videoSources, | |
source = sources[resolution], | |
src = source.videoUrl || '', | |
format = source.format; | |
this.selectedResolution = resolution; | |
this.selectedFormat = format; | |
fireEvent('onQualityChange', { | |
src: src, | |
resolution: resolution, | |
format: format | |
}); | |
fireEvent('hideRoll'); | |
// stop all activity and event handlers while changing video! | |
if (this.vrPlayer) { | |
this.vrPlayer.stop(); | |
} | |
if (this.seeking) { | |
this.qualityChanged = true; | |
} | |
if (format == 'dash') { | |
if (resolution == 'dash') { // Auto | |
this.setDashAutoQuality(); | |
} else { | |
this.setDashQuality(resolution); | |
} | |
} else if (format == 'hls') { | |
if (resolution == 'hls') { // Auto | |
this.setHlsAutoQuality(); | |
} else { // integer value | |
this.setHlsQuality(resolution); | |
} | |
} else { | |
this.setSource(source); | |
} | |
this.saveQualityToCookie(resolution); | |
if (format == 'dash' || format == 'hls') { | |
if (this.videoStarted) { | |
if (this.playing) { | |
fireEvent('onPlay'); | |
} else { | |
fireEvent('onPause'); | |
} | |
} else { | |
fireEvent('onVideoReady') | |
} | |
} | |
if (__.isFunction(callback)) { | |
callback(); | |
} | |
}, | |
setSource: function(source, callback) { | |
var self = this, | |
path = source.videoUrl, | |
fileExtention = __.extractFileExtention(path), | |
previousTime = this.playerElement.currentTime, | |
wasPlaying = this.playing; | |
this.updatingSource = true; | |
var loadedCallback = function(e) { | |
// special case: stream change was started in videoEnded state, we need to restore it | |
if (self.videoEnded) { | |
fireEvent('onEnd'); | |
fireEvent('showPostRoll'); | |
} else { | |
self.videoReady(path); | |
var roll = self.adsRoll(); | |
// seek to the same position after changing source (if its not 0) | |
if (!roll && previousTime && self.updatingSource) { | |
self.seek(previousTime, wasPlaying); | |
} | |
} | |
if (__.isFunction(callback)) { | |
callback(); | |
} | |
}; | |
if (this.isPreRollActive && this.firePreRollEvent){ | |
this.firePreRollEvent = false; | |
if (__.isFunction(callback)) { | |
callback(); | |
} | |
} | |
if (!this.videoStarted) { | |
this.videoReady(path); | |
} else { | |
this.playerElement.oncanplay = loadedCallback | |
} | |
// init custom media stream players on quality change | |
if (source.format != 'hls' && this.hlsPlayer) { | |
this.destroyHlsPlayer(); | |
} | |
if (source.format != 'dash' && this.dashPlayer && this.dashSource) { | |
this.destroyDashPlayer(); | |
} | |
if (source.format == 'hls') { | |
this.initHlsPlayer(source); | |
return; | |
} | |
if (source.format == 'dash') { | |
this.initDashPlayer(source); | |
return; | |
} | |
// update preload value to "auto" | |
// no need to use .play() or .load() | |
// mobiles only | |
this.playerElement.src = path; | |
if (this.isPreRollActive || this.videoStarted) { | |
this.playerElement.preload = 'auto'; | |
//ios unable preload and requires play() | |
if (MHP1138.detector.isIos()) { | |
this.playerElement.load(); | |
} | |
} | |
//playback rate need to be reset if source is changed | |
//for ios need to set playback after load() else it'll be set to default value(1) | |
if (!__.isUndefined(this.slowMotion) && !this.isPreRollActive) { | |
this.playerElement.playbackRate = this.slowMotion; | |
} | |
if (this.seeking && this.qualityChanged){ | |
this.seeking = false; | |
this.qualityChanged = false; | |
if (!this.initialSeek) { | |
wasPlaying = true; | |
this.playerElement.play(); | |
} | |
} | |
}, | |
changeVideoSourceCallback: function() { | |
// caching value to start main video playback immediatelly after preRoll | |
var preRollState = this.isPreRollActive; | |
this.hideAdsRollUI(); | |
// active flags should be reset BEFORE main video playback | |
this.isPreRollActive = false; | |
this.preRoll.enabled = false; | |
// preroll was playing before | |
if (preRollState) { | |
if (this.settings.mainRoll.duration) { | |
this.updateDuration(this.settings.mainRoll.duration); | |
} | |
this.setActionTags(this.mainRoll.actionTags); | |
this.playing = false; | |
if(!__.isUndefined(this.slowMotion)) { | |
this.playerElement.playbackRate = this.slowMotion; | |
} | |
if (parseInt(this.settings.startOffset) > 0) { | |
// seek and play | |
this.seek(parseInt(this.settings.startOffset), true); | |
} else { | |
// just play | |
this.play(); | |
} | |
} | |
}, | |
setAutoplay: function(state) { | |
this.autoplay = state; | |
fireEvent('onAutoplayChange', { autoplay: state }); | |
}, | |
setMotionRate: function(rate) { | |
this.slowMotion = rate; | |
if(!__.isUndefined(rate)) { | |
this.playerElement.playbackRate = rate; | |
} | |
this.saveSlowMotionRate(rate); | |
fireEvent('onSlowMotionChange', { motionRate: rate }); | |
}, | |
setHotspotsState: function(state) { | |
this.hotspotsState = state; | |
// apply but do not store new values in embedded mode | |
if (!this.settings.embeds.enabled) { | |
this.saveHotspotsState(state); | |
} | |
fireEvent('onHotspotsStateChange', { hotspotsState: state }); | |
}, | |
togglePlayPause: function() { | |
if (!this.playing) { | |
this.play(); | |
} else { | |
this.pause(); | |
} | |
}, | |
toggleCinemaMode: function() { | |
fireEvent((this.cinemaMode?'collapsePlayer':'expandPlayer')); | |
this.cinemaMode = !this.cinemaMode; | |
}, | |
toggleChromecast: function() { | |
if (!this.chromecast.active) { | |
if (this.playing) { | |
this.pause(); | |
} | |
this.chromecast.requestSession(); | |
} else { | |
this.playerElement.load(); | |
this.showVideoTag(); | |
this.chromecast.stopSession(); | |
} | |
}, | |
//CURRENT TIME | |
updateCurrentTime: function(currentTime) { | |
// doublecheck | |
// IE sometimes fires really weird numbers! | |
if (__.isNaN(currentTime)) currentTime = 0; | |
if (currentTime < 0) currentTime = 0; | |
if (currentTime > this.duration) currentTime = this.duration; | |
this.currentTime = currentTime; | |
fireEvent('onTimeChange', { time: currentTime }); | |
var timeLeft = Math.floor(this.duration) - Math.floor(currentTime); | |
//onPlaylistCountdown | |
if (timeLeft < 4) { | |
if ((!this.onPlaylistCountdownLastTimeFired && timeLeft) || | |
timeLeft == (this.onPlaylistCountdownLastTimeFired - 1) | |
) { | |
this.onPlaylistCountdownLastTimeFired = timeLeft; | |
fireEvent('onPlaylistCountdown', { count: timeLeft }); | |
} | |
} else if (this.onPlaylistCountdownLastTimeFired > 0) { | |
this.onPlaylistCountdownLastTimeFired = 0; | |
} | |
}, | |
//TOTAL DURATION | |
updateDuration: function(duration) { | |
// doublecheck | |
// IE sometimes fires really weird numbers! | |
if (__.isNaN(duration)) duration = 0; | |
this.duration = parseFloat(duration); | |
fireEvent('onDurationChange', { duration: duration }); | |
}, | |
fireEndEvent: function() { | |
fireEvent('onEnd'); | |
}, | |
fireUpsellEvent: function() { | |
fireEvent('onQualityUpsell'); | |
}, | |
fireShareEvent: function() { | |
fireEvent('onShare'); | |
}, | |
addUTM: function(url, medium, campaign){ | |
url += (( url.indexOf('?') < 0 ) ? '?' : '&') +'utm_source='+ this.settings.referrerUrl +'&utm_medium='+ medium +'&utm_campaign='+ campaign; | |
return url; | |
}, | |
addCurrentTimeToUrl: function(url) { | |
url = url.replace(/[?&]t=\d+/, ''); // delete previous timestamp if exists | |
url += (( url.indexOf('?') < 0 ) ? '?' : '&') +'t='+ Math.floor(this.currentTime || 0); | |
return url; | |
}, | |
// just a quick macro | |
openRedirectWindow: function(url, targetSelf) { | |
fireEvent('onRedirect'); | |
var target = targetSelf ? '_self' : '_blank'; | |
window.open(url, target); | |
}, | |
//API | |
play: function() { | |
if (!this.playerCreated) { this.playerNotReady(); return false; } | |
if (this.deferredPreRoll && (this.playerElement.readyState == 0)) { | |
this.showPreRoll(); | |
} | |
var roll = this.adsRoll(); | |
if (roll) { | |
if (this.isPauseRollActive) { | |
// pauseRoll skipped by pressing player's play button | |
// hide static pause roll and restore normal player state | |
if (!roll.paused) { | |
this.adsRollTracking(roll, 'skip'); | |
roll.paused = true; | |
} | |
this.skipPauseRoll(); | |
} else { | |
// pre or post roll started | |
// do not send play event twice if advertising was paused | |
if (!roll.played) { | |
this.adsRollTracking(roll, 'play'); | |
this.disableOptions(); | |
this.showRollSkipButton(); | |
roll.played = true; | |
} | |
} | |
} | |
if (this.chromecast.active) { | |
this.chromecast.play(); | |
} else { | |
if (!this.videoStarted && this.deferredStartSeek) { | |
this.seek(this.settings.startOffset, true); | |
this.playerElement.play(); | |
} else { | |
this.playerElement.play(); | |
} | |
} | |
this.playing = true; | |
if (roll === false) { | |
this.startViewedCounter(); | |
} | |
}, | |
pause: function() { | |
var settings = this.settings; | |
if (!this.playerCreated) { this.playerNotReady(); return false; } | |
if (this.playing) { | |
if (this.chromecast.active) { | |
this.chromecast.pause(); | |
} else { | |
this.playerElement.pause(); | |
} | |
if (!this.updatingSource) { | |
// do nothing on pre/post rolls pausing | |
if (this.isPreRollActive) { | |
return; | |
} | |
if (this.pauseRoll.enabled) { | |
this.disableOptions(); | |
this.showPauseRoll(); | |
} else if (!settings.embeds.enabled) { | |
fireEvent('showPauseRoll'); | |
} | |
} | |
} else { | |
// deferred pause | |
this.deferredPause = true; | |
this.playAfterSeek = false; | |
this.deferredSeek = false; | |
} | |
this.stopViewedCounter(this.currentTime); | |
}, | |
seek: function(offset, playAfter) { | |
offset = parseFloat(offset); | |
if (__.isNaN(offset)) return false; | |
if (!this.playerCreated) { | |
this.playerNotReady(); | |
return false; | |
} | |
// you shall not pass the counter! | |
if (this.adsRoll() && !this.isPauseRollActive) { // (except static pause rolls) | |
return false; | |
} | |
// chromecast fires onSeek event by itself | |
// no deferredSeek support for remote device, just make it simple | |
if (this.chromecast.active) { | |
this.chromecast.seek(offset, playAfter); | |
return; | |
} | |
if (this.seeking) { | |
this.deferredSeek = { | |
offset: offset, | |
playAfter: playAfter | |
}; | |
return false; | |
} | |
// could be used only once, reset the flag if manual seek was done | |
this.deferredStartSeek = false; | |
var self = this, | |
previousTime = this.playerElement.currentTime; | |
// IE fix for seekbar X-coords incorrect rounding | |
if (offset > this.duration) { | |
offset = this.duration; | |
} | |
// special case of seeking to the end of video | |
// do seek to at least 1 frame before the actual video end, | |
// to reach it (and trigger 'onended' event) in playing state | |
if (offset == this.duration) { | |
offset -= 0.05; // 1sec / 24fps = 0.041666 | |
} | |
// initial player state, no video loaded or played yet | |
// do deferred seek right AFTER canplay event | |
// DO NOT fire onSeek event to skin | |
if (this.playerElement.readyState == 0) { | |
// statically named function to use removeEventListener later | |
function playOnReady(e) { | |
this.removeEventListener('canplay', playOnReady); | |
// aditional flag for first-time seek without immediate play | |
// to prevent normal event firing | |
self.initialSeek = true; | |
//fireEvent('onVideoReady'); | |
/* MAGIC */ | |
// put on pause to get 'seeked' event in IE | |
// (they wouldnt fire it if player is playing something at this moment) | |
if(MHP1138.detector.isIe()){ | |
this.pause(); | |
} | |
// set currentTime from startOffset property | |
this.currentTime = offset; | |
self.seeking = true; | |
self.playAfterSeek = playAfter; | |
// "seek to the end" has its special treatment (and callbacks chain) | |
// because when you just load video and do like vid.currentTime = vid.duration | |
// IEs dont fire "onended" event. Videos should be finished by actual playing to get the event, | |
// so each seek of this type looks like | |
// vid.currentTime = vid.duration - 0.05sec; | |
// vid.play(); | |
if (this.duration - offset < 0.06) { | |
self.seekToEnd = true; | |
} | |
} | |
// play() will be fired at the end of this method | |
// and the real seek will be done right after the vid will start ('canplay' event) | |
this.playerElement.addEventListener('canplay', playOnReady); | |
//IE bug TFE-460. Playback starts after switching the quality | |
var browser = MHP1138.detector.getBrowser(); | |
if (!this.dashSource && // DASH player fires error at this moment, source isnt ready yet | |
typeof browser.name !== 'undefined' && | |
browser.name != 'ie' && | |
playAfter | |
) { | |
// manually play the video to get canplay event and process seek! | |
this.playerElement.play(); | |
} | |
setTimeout(function() { | |
if (playAfter) { | |
self.showVideoTag(); | |
} | |
}, 200); // time to show/animate seekPreview before hiding poster | |
return; | |
} | |
// HACKERY | |
// IE doesnt fire 'onplaying' event after 'seeked' if seek happend in play state | |
// need to manually put player on pause | |
// (WARN: do not use this.pause() as it does much more than just pausing the player) | |
this.playerElement.pause(); | |
this.playing = false; | |
this.playerElement.currentTime = offset; | |
this.seeking = true; | |
this.playAfterSeek = playAfter; | |
this.stopViewedCounter(previousTime); | |
fireEvent('onSeek', { | |
from: previousTime, | |
to: offset | |
}); | |
fireEvent('hideRoll'); | |
}, | |
pauseTimeWhenSeekPegHold : function(val) { | |
this.seeking = val; | |
}, | |
videoReady: function(path) { | |
if (path != this.sourceUrl) { | |
fireEvent('onVideoReady'); | |
} | |
this.sourceUrl = path; | |
}, | |
showVideoTag: function() { | |
// TODO: remove direct control | |
this.playerElement.style.visibility = 'visible'; | |
this.playerPoster.style.display = 'none'; | |
}, | |
playStaticRoll: function(roll) { | |
// create image container before first use | |
if (!this.staticRollContainer) { | |
this.createStaticRollContainer(); | |
} | |
if (!roll.played) { | |
this.adsRollTracking(roll, 'play'); | |
this.staticRollContainer.style.backgroundImage = 'url(' + roll.imageUrl + ')'; | |
roll.played = true; | |
} | |
this.showStaticRoll(); | |
}, | |
createStaticRollContainer: function() { | |
// WARN: could create bug in multi-player environment | |
this.staticRollContainer = satisfy('.mhp1138_staticRoll.mhp1138_hidden')[0]; | |
this.videoWrapper.appendChild(this.staticRollContainer); | |
}, | |
showStaticRoll: function() { | |
__.removeClass(this.staticRollContainer, 'hidden'); | |
}, | |
hideStaticRoll: function() { | |
__.addClass(this.staticRollContainer, 'hidden'); | |
}, | |
isVideoStarted: function(){ | |
return this.videoStarted; | |
}, | |
isPlaying: function() { | |
return !this.playerElement.paused; | |
}, | |
adsRoll: function() { | |
if (this.isPreRollActive) { | |
return this.preRoll; | |
} else if (this.isPauseRollActive) { | |
return this.pauseRoll; | |
} else { | |
return false; | |
} | |
}, | |
getVolume: function(){ | |
return this.volume; | |
}, | |
setVolume: function(volumeLevel){ | |
if (!__.isNaN(volumeLevel)) { | |
if (volumeLevel > 100) volumeLevel = 100; | |
if (volumeLevel < 0) volumeLevel = 0; | |
this.volume = volumeLevel; | |
this.playerElement.volume = volumeLevel / 100; | |
this.fireVolumeChangeEvent(); | |
} | |
}, | |
setMute: function(state) { | |
if (__.isBoolean(state) && state != this.muted) { | |
this.playerElement.muted = state; | |
this.muted = state; | |
this.fireVolumeChangeEvent(); | |
} | |
}, | |
getCurrentTime: function() { | |
return Math.round(this.playerElement.currentTime); // do we really need it rounded to seconds? | |
}, | |
setPoster: function(url) { | |
this.posterUrl = url; | |
// transparent gif image | |
//var videoPosterImage = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'; | |
if (__.isPath(url)) { | |
this.playerPoster.setAttribute('style', "background-image: url('" + url + "')"); | |
//this.playerElement.setAttribute('poster', videoPosterImage); | |
} else { | |
//this.playerElement.setAttribute('poster', ''); | |
this.showVideoTag(); | |
} | |
}, | |
setActionTags: function(actionTags) { | |
this.actionTags = actionTags; | |
// TODO: remove direct calls but switch to firing internal event to skin | |
this.skin.deleteActionTags(); | |
this.skin.createActionTags(); | |
}, | |
enableOptions: function() { | |
this.skin.enableOptions(); | |
}, | |
disableOptions: function() { | |
this.skin.disableOptions(); | |
}, | |
startViewedCounter: function(){ | |
var self = this, | |
link = this.settings.viewedRequestURL || '', | |
timeout = this.settings.viewedRequestTimeout; | |
this.viewedTimeout = this.viewedTimeout || null; | |
if(!link) return; | |
this.viewingStart = this.playerElement.currentTime; | |
if(this.viewedSeconds < timeout){ | |
this.viewedTimeout = setTimeout(function(){ | |
self.viewedSeconds = timeout; | |
//poke the server after "this.settings.viewedRequestTimeout" sec of viewing | |
__.ajaxLoader(link); | |
}, timeout*1000-this.viewedSeconds*1000); | |
} | |
}, | |
stopViewedCounter: function(currentTime){ | |
if(this.viewedTimeout){ | |
currentTime = currentTime || this.playerElement.currentTime; | |
this.viewingStart = this.viewingStart || 0; | |
this.viewedSeconds += Math.floor(currentTime) - Math.floor(this.viewingStart); | |
clearTimeout(this.viewedTimeout); | |
} | |
}, | |
//remove the player | |
destroy: function(callback) { | |
// Reset video tag event handlers to interrupt lazy networking and so on | |
// Browsers could spend up to several seconds on actual videoElement destroy | |
// Sometimes we are getting events from the World of the Dead | |
this.playerElement.ondurationchange = function() {}; | |
this.playerElement.ontimeupdate = function() {}; | |
this.playerElement.onprogress = function() {}; | |
this.playerElement.onwaiting = function() {}; | |
this.playerElement.onpause = function() {}; | |
this.playerElement.onplaying = function() {}; | |
this.playerElement.onseeked = function() {}; | |
this.playerElement.oncanplay = function() {}; | |
this.playerElement.onended = function() {}; | |
this.playerContainerElement.parentNode.removeChild(this.playerContainerElement); | |
callback(); | |
} | |
}; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment