Advertisement
Guest User

Untitled

a guest
Jan 10th, 2016
259
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 462.50 KB | None | 0 0
  1. ! function(a, b) {
  2. function d() {
  3. return b.browser.mobile
  4. }
  5.  
  6. function e() {
  7. return b.browser.mobile
  8. }
  9. var f = {};
  10. f.chat = {}, f.player = {}, f.room = {}, f.profile = {}, f.playlist = {}, f.global = {}, f.help = {}, f.helpers = {}, f.playlist.containerElCreateApp = !1, f.bindedDocument = !1, f.users = {}, f.user = {};
  11. var g = {
  12. config: {}
  13. };
  14. a.DUBTRACK_API_URL || (a.DUBTRACK_API_URL = "https://api.dubtrack.fm"), a.Dubtrack = {
  15. init: function() {
  16. if (!Dubtrack.initialized) {
  17. Dubtrack.initialized = !0;
  18. var a = Dubtrack.helpers.cookie.get("dubtrack-hide-images");
  19. a && "hide" == a && (Dubtrack.HideImages = !0), soundManager.waitForWindowLoad = !0, Dubtrack.helpers.loadDependencies(function() {
  20. Dubtrack.app = new DubtrackRoute, Backbone.history.start({
  21. pushState: !0
  22. })
  23. })
  24. }
  25. },
  26. player_initialized: !1,
  27. initialized: !1,
  28. chat: {},
  29. player: {},
  30. room: {},
  31. roomList: {},
  32. layout: {},
  33. users: {},
  34. user: {},
  35. session: {},
  36. views: {},
  37. Model: {},
  38. Collection: {},
  39. View: {},
  40. HideImages: !1,
  41. $: {
  42. body: b("body"),
  43. mainSectionEl: b("section#main-section")
  44. },
  45. config: {
  46. apiUrl: a.DUBTRACK_API_URL,
  47. urls: {
  48. mediaBaseUrl: "https://dubtrack-fm.s3.amazonaws.com",
  49. commentsDubs: "/comments/:id/dubs",
  50. commentsFlag: "/comments/:id/flag",
  51. room: "/room",
  52. roomSearch: "/room/term/:term",
  53. roomImage: "/room/:id/image",
  54. roomUsers: "/room/{id}/users",
  55. roomBanUsers: "/room/:id/users/ban",
  56. roomMuteUsers: "/room/:id/users/mute",
  57. roomStaffUsers: "/room/:id/users/staff",
  58. roomBeacon: "/room/beacon/:id/:userid",
  59. roomQueue: "/room/{id}/playlist",
  60. roomQueueDetails: "/room/:id/playlist/details",
  61. roomHistory: "/room/:id/playlist/history",
  62. roomLockQueue: "/room/:id/lockQueue",
  63. userQueuePause: "/room/:id/queue/pause",
  64. dubs: "/dubs",
  65. user: "/user",
  66. updateUsername: "/user/updateUsername",
  67. queryUsernameAvailability: "/user/query/availabilty",
  68. session: "/auth/session",
  69. playlist: "/playlist",
  70. playlistUpdate: "/playlist/:id",
  71. playlistOrder: "/playlist/:id/order",
  72. playlistSong: "/playlist/:id/songs",
  73. getSoundCloudPlaylists: "/playlist/soundcloud",
  74. importYoutubePlaylist: "/playlist/import/youtube",
  75. importSoundcloudPlaylist: "/playlist/import/soundcloud",
  76. song: "/song",
  77. songComments: "/song/:id/comments",
  78. chat: "/chat/:id",
  79. deleteChat: "/chat/:id/:chatid",
  80. roomPlaylist: "/room/:id/playlist",
  81. roomQueuePlaylist: "/room/:id/queueplaylist/:playlistid",
  82. roomPlaylistActive: "/room/:id/playlist/active",
  83. dubsPlaylistActive: "/room/:id/playlist/:playlistid/dubs",
  84. kickUser: "/chat/kick/:roomid/user/:id",
  85. banUser: "/chat/ban/:roomid/user/:id",
  86. muteUser: "/chat/mute/:roomid/user/:id",
  87. setModUser: "/chat/52d1ce33c38a06510c000001/:roomid/user/:id",
  88. setDJUser: "/chat/5615feb8e596154fc2000002/:roomid/user/:id",
  89. setManagerUser: "/chat/5615fd84e596150061000003/:roomid/user/:id",
  90. setVIPUser: "/chat/5615fe1ee596154fc2000001/:roomid/user/:id",
  91. setOwnerUser: "/chat/5615fa9ae596154a5c000000/:roomid/user/:id",
  92. setRoomDJUser: "/chat/564435423f6ba174d2000001/:roomid/user/:id",
  93. skipSong: "/chat/skip/:id/:songid",
  94. userQueue: "/user/session/room/:id/queue",
  95. userQueueOrder: "/user/session/room/:id/queue/order",
  96. roomUserQueueOrder: "/room/:id/queue/order",
  97. userFollow: "/user/:id/follows",
  98. userFollowing: "/user/:id/following",
  99. userImage: "/user/:id/image",
  100. search: "/search",
  101. messages: "/message",
  102. messages_items: "/message/:id",
  103. messages_news: "/message/new",
  104. messages_read: "/message/:id/read"
  105. },
  106. keys: {
  107. pubunub: "sub-c-2b40f72a-6b59-11e3-ab46-02ee2ddab7fe",
  108. soundcloud: "a7d642eb62cd95e8619987508f634859"
  109. },
  110. player: {
  111. youtube: {
  112. youtubeVars: {
  113. controls: 0,
  114. rel: 0,
  115. showinfo: 0,
  116. autoplay: 1,
  117. output: "embed",
  118. wmode: "transparent",
  119. playsinline: 1,
  120. iv_load_policy: 3,
  121. html5: 1,
  122. is_html5_mobile_device: 1,
  123. disablekb: 1,
  124. frameborder: 0
  125. },
  126. playerParams: {
  127. controls: 0,
  128. rel: 0,
  129. showinfo: 0,
  130. autoplay: 0,
  131. modestbranding: 1,
  132. output: "embed",
  133. wmode: "transparent",
  134. playsinline: 1,
  135. iv_load_policy: 3,
  136. html5: 1,
  137. is_html5_mobile_device: 1,
  138. disablekb: 1,
  139. frameborder: 0
  140. }
  141. },
  142. playerWidth: "100%",
  143. playerHeight: "100%",
  144. playerEmbedWidth: "100%",
  145. playerEmbedHeight: 360
  146. },
  147. loadingEls: '<div class="spinner"><div class="bounce1"></div><div class="bounce2"></div><div class="bounce3"></div></div>',
  148. urlPLayerPlaylist: "/room/playlist/get/idroom/",
  149. urlRoomInfo: "/api/rooms/load_room_info/idroom/",
  150. chatEndPointUrl: "/room/chat/send/idroom/",
  151. playerVoteUrl: "/room/main/vote/idroom/",
  152. browserPlaylistDeatilsUrl: "/api/playlist/getPlaylist/id/",
  153. roomJoin: "/room/main/join/idroom/",
  154. roomJoinInco: "/api/rooms/joinIncognito/idroom/",
  155. roomLeave: "/room/main/removeUser",
  156. roomListUrl: "/api/rooms/get_rooms/iduser/0",
  157. browserSearchUrl: "/api/youtube/",
  158. dubsUrl: "/api/dubs/api",
  159. dubsGetSong: "/api/dubs/viewapi/url_sh/",
  160. searchDubsUrl: "/api/dubs/apiSearch",
  161. userProfileUrl: "/api/users/get_user_info",
  162. saveDubComment: "/api/dubs/save_comment/",
  163. reportSpamComment: "/api/dubs/spam_comment/",
  164. deleteComment: "/api/dubs/delete_comment/id/",
  165. getAvatarsRoom: "/api/rooms/loadUsers/idroom/",
  166. getRolesRoom: "/api/rooms/get_room_roles/idroom/",
  167. getAvatarUrl: "/api/users/get/details/1/id/",
  168. getWallPost: "/api/users/get_wall_post/id/",
  169. dubWallPost: "/api/dubs/dub_wall_comment/",
  170. saveWall: "/user/save_wall/",
  171. deleteWall: "/user/delete",
  172. getPlaylistPublic: "/api/playlist/getListPublic",
  173. getFollowing: "/api/users/follows/",
  174. fetchNotification: "/api/users/notification_feed/page/",
  175. addQueue: "/room/playlist/add/idroom/",
  176. saveUserId: "/api/users/updatedt",
  177. checkusername: "/api/users/check_usernamedt",
  178. roomUpdate: "/room/main/update",
  179. roomCreate: "/room/main/create",
  180. followUrl: "/api/users/follow/",
  181. unfollowUrl: "/api/users/unfollow/",
  182. getWallPostsUrl: "/api/users/get_wall_posts/id/",
  183. addToPlaylist: "/api/playlist/addMedia",
  184. removeFromPlaylist: "/api/playlist/deleteMedia",
  185. changePlaylistType: "/api/playlist/change_playlist_type",
  186. queuePlaylist: "/room/playlist/addPlaylist",
  187. removeFromQueue: "/room/playlist/deleteMedia/",
  188. addPlaylist: "/api/playlist/add",
  189. removePlaylist: "/api/playlist/delete",
  190. getQueueUrl: "/room/playlist/getListUser/",
  191. mytracksUrl: "/dubtrack/music/get",
  192. updateMytracksUrl: "/dubtrack/music/update",
  193. deleteMytracksUrl: "/dubtrack/music/delete",
  194. getMusicTracks: "/dubtrack/music/getMusic/userid/",
  195. roomHistory: "/room/playlist/getHistory/",
  196. getQueuePlace: "/room/playlist/shownext/",
  197. notificationsCountUrl: "/api/users/get_notification_feed_count",
  198. getFriendsRoomUrl: "/api/rooms/getRoomFriends/idroom/",
  199. getModsRoomUrl: "/api/rooms/getRoomMods/idroom/",
  200. getFriendsGlobalUrl: "/api/users/get_friends",
  201. getChatHistory: "/api/rooms/get_history/idroom/",
  202. sendMessageUrl: "/user/sendmessage",
  203. getMessagesUrl: "",
  204. globalBaseUrl: "http://dubtrack.fm/",
  205. mainRoomContainer: b("#main_room"),
  206. playerMainContainer: b("#main_player"),
  207. playerContainer: b("#main_player").find("div.player_container"),
  208. playerConrols: b("#room_info"),
  209. gaId: "UA-31613628-1",
  210. chatContainer: b("div#chat"),
  211. roomListContainer: "roomListContainer",
  212. dubsListContainer: "dubsListContainer",
  213. mainSectionEl: b("section#main-section"),
  214. avatarContEl: b("div#avatarCont")
  215. },
  216. els: {
  217. mainLoading: null,
  218. init: function() {
  219. this.mainLoading = b("#main-loading").show(), this.mainLoadingText = this.mainLoading.find(".loading-text"), this.mainLoadingText.html(dubtrack_lang.global.loading)
  220. },
  221. displayloading: function(a) {
  222. a || (a = dubtrack_lang.global.loading), this.mainLoadingText.html(a), this.mainLoading.show()
  223. },
  224. hideMainLoading: function() {
  225. this.mainLoading.hide()
  226. },
  227. controls: function(a, c) {
  228. c.loadingEl = b("<div/>", {
  229. "class": "loading"
  230. }).html("Loading...").appendTo(a), c.bufferingEl = b("<div/>", {
  231. "class": "buffering"
  232. }).html("Buffering...").css({
  233. display: "none"
  234. }).appendTo(a), c.replayEl = b("<div/>", {
  235. "class": "replay"
  236. }).html("replay").appendTo(a), c.errorEl = b("<div/>", {
  237. "class": "error"
  238. }).html("An unexpected error occurred, please try again later").appendTo(a), c.errorEl.hide(), c.controlsContainer = b("<div/>", {
  239. "class": "controlContainer"
  240. }).appendTo(a), c.buttonsEl = b("<div/>", {
  241. "class": "buttons"
  242. }).appendTo(c.controlsContainer), c.playEl = b("<a/>", {
  243. "class": "play noaction",
  244. href: "#"
  245. }).html('<span class="icon-play"></span>').appendTo(c.buttonsEl), c.pauseEl = b("<a/>", {
  246. "class": "pause noaction",
  247. href: "#"
  248. }).hide().html('<span class="icon-pause"></span>').appendTo(c.buttonsEl), c.progressOuterEl = b("<div/>", {
  249. "class": "progressContainer"
  250. }).appendTo(c.controlsContainer), c.progressEl = b("<div/>", {
  251. "class": "progress"
  252. }).appendTo(c.progressOuterEl), c.loadedEl = b("<div/>", {
  253. "class": "loaded"
  254. }).appendTo(c.progressOuterEl), c.volumeContainer = b('<div class="volume-container"><span class="tooltip"></span><div class="volume-control"></div><span class="volume"></span></div>').prependTo(c.controlsContainer)
  255. }
  256. },
  257. helpers: {
  258. getParameterByName: function(a) {
  259. a = a.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
  260. var b = new RegExp("[\\?&]" + a + "=([^&#]*)"),
  261. c = b.exec(location.search);
  262. return null === c ? "" : decodeURIComponent(c[1].replace(/\+/g, " "))
  263. },
  264. isDubtrackAdmin: function(a) {
  265. return "52c821781e2b1fd945000001" == a || "52c8ef6037e22b0200000005" == a || "52d24bff4cf9670200000515" == a || "52c8efcf37e22b0200000008" == a || "551d295433cd73030089d184" == a || "53f7c199892b010200a98809" == a || "560892bf8e9cb60300550aa2" == a || "52c8254ca7b7260200000001" == a ? !0 : !1
  266. },
  267. cookie: {
  268. set: function(a, b, c, d) {
  269. var e = "";
  270. if (c && d !== !0) {
  271. var f = new Date;
  272. f.setTime(f.getTime() + 24 * c * 60 * 60 * 1e3), e = "; expires=" + f.toGMTString()
  273. }
  274. document.cookie = a + "=" + encodeURIComponent(b) + e + "; path=/"
  275. },
  276. get: function(a) {
  277. for (var b = a + "=", c = document.cookie.split(";"), d = 0; d < c.length; d++) {
  278. for (var e = c[d];
  279. " " == e.charAt(0);) e = e.substring(1, e.length);
  280. if (0 === e.indexOf(b)) return decodeURIComponent(e.substring(b.length, e.length))
  281. }
  282. return null
  283. },
  284. "delete": function(a) {
  285. Dubtrack.helpers.cookie.set(a, "", -1, !1)
  286. }
  287. },
  288. parse: function(a, b) {
  289. return a.data
  290. },
  291. image: {
  292. imageError: function(a, b) {
  293. return a.onerror = "", b ? a.src = Dubtrack.config.urls.mediaBaseUrl + b : a.src = Dubtrack.config.urls.mediaBaseUrl + "/assets/images/media/pic_notfound.jpg", !0
  294. },
  295. getImage: function(a, b, c, d) {
  296. var e = "Dubtrack.helpers.displayUser('" + a + "', this);",
  297. f = Dubtrack.config.apiUrl + Dubtrack.config.urls.userImage.replace(":id", a);
  298. c && (f += "/large");
  299. var g;
  300. return d || (e = b && null !== b ? "Dubtrack.app.navigate('/" + b + "', {trigger: true});" : ""), g = '<img src="' + f + '" alt="' + b + '" onclick="' + e + '" class="cursor-pointer" onerror="Dubtrack.helpers.image.imageError(this);" />'
  301. },
  302. getProfileImg: function(a, b, c, d) {
  303. var e = "",
  304. f = "Dubtrack.helpers.displayUser('" + a + "', this);";
  305. "facebook" == c ? (d ? "large" === d && (d = "large") : d = "square", e = "https://graph.facebook.com/" + a + "/picture?type=" + d) : "google" == c ? (d = d ? "?sz=200" : "", e = "https://plus.google.com/s2/photos/profile/" + a + d) : "soundcloud" == c ? e = "http://media.dubtrack.fm/media/soundCloud.png" : (d ? ("large" == d && (d = "original"), "square" == d && (d = "normal")) : d = "bigger", e = "https://api.twitter.com/1/users/profile_image?id=" + a + "&size=" + d);
  306. var g = '<img src="' + e + '" alt="' + b + '" onclick="' + f + '" class="cursor-pointer" onerror="Dubtrack.helpers.image.imageError(this);" />';
  307. return g
  308. }
  309. },
  310. displayUser: function(a, c) {
  311. Dubtrack.views.user_popover || (Dubtrack.views.user_popover = new f.global.userPopover, Dubtrack.views.user_popover.$el.appendTo("body")), Dubtrack.views.user_popover.displayUser(a);
  312. var d = b(c).offset(),
  313. e = d.left - 200,
  314. g = d.top;
  315. 0 > e && (e = 0), 0 > g && (g = 0), Dubtrack.views.user_popover.$el.css({
  316. left: e,
  317. top: g
  318. }).show(), Dubtrack.views.user_popover.offset_top = d.top, b(window).height() < d.top + Dubtrack.views.user_popover.$el.height() && (g = d.top - Dubtrack.views.user_popover.$el.height(), 0 > g && (g = 0), Dubtrack.views.user_popover.$el.css({
  319. top: g
  320. }))
  321. },
  322. flashLogin: function() {
  323. b("#header_login").stop(!0).fadeIn(300).fadeOut(300).fadeIn(300).fadeOut(300).fadeIn(300)
  324. },
  325. navigateHistoryTags: function(a) {
  326. var c = a.find("a.navigate");
  327. c.unbind("click"), c.bind("click", function() {
  328. return $href = b(this).attr("href"), $href && Dubtrack.app.navigate($href, {
  329. trigger: !0
  330. }), !1
  331. })
  332. },
  333. playlist: {
  334. addQueue: function(a, b, c) {
  335. if (Dubtrack.room) {
  336. var d = Dubtrack.config.apiUrl + Dubtrack.config.urls.roomQueue.replace("{id}", Dubtrack.room.model.id);
  337. Dubtrack.helpers.sendRequest(d, {
  338. songId: a,
  339. songType: b
  340. }, "post", c)
  341. } else c && c.call(this, null)
  342. },
  343. removeQueue: function(a, b) {
  344. if (Dubtrack.room) {
  345. var c = Dubtrack.config.apiUrl + Dubtrack.config.urls.roomQueue.replace("{id}", Dubtrack.room.model.id) + "/" + a;
  346. Dubtrack.helpers.sendRequest(c, {}, "delete", b)
  347. } else b && b.call(this, null)
  348. }
  349. },
  350. genPlaylistContainer: function(a, c, d, e, g) {
  351. Dubtrack.createPlaylist && Dubtrack.createPlaylist.close(), Dubtrack.app.loadUserPlaylists(function() {
  352. Dubtrack.createPlaylist = new Dubtrack.View.containerElCreate({
  353. model: Dubtrack.user.playlist
  354. }).render(a, c, d, e), g && Dubtrack.createPlaylist.$el.addClass(g), f.bindedDocument || (b(window).on("click", function(a) {
  355. $parents = b(a.target).parents(".playlist-options"), 0 === $parents.length && Dubtrack.createPlaylist && Dubtrack.createPlaylist.close()
  356. }), f.bindedDocument = !0)
  357. })
  358. },
  359. sendRequest: function(a, c, d, e, f) {
  360. f || (f = this);
  361. try {
  362. b.ajax({
  363. url: a,
  364. data: c,
  365. type: d,
  366. xhrFields: {
  367. withCredentials: !0
  368. },
  369. success: function(a) {
  370. try {
  371. e && e.call(f, null, a)
  372. } catch (b) {}
  373. },
  374. error: function(a, c, d) {
  375. var g = d;
  376. try {
  377. g = b.parseJSON(a.responseText)
  378. } catch (h) {}
  379. e && e.call(f, g, null)
  380. }
  381. }, "json")
  382. } catch (g) {
  383. e.call(f, g, null)
  384. }
  385. },
  386. displayDubs: function(a, c, d) {
  387. d || (d = "");
  388. var e = dubtrack.app.roomAvatarList.collection.get(a);
  389. if (e) {
  390. var f = e.get("dubs");
  391. dubs = parseInt(f) + c, e.set({
  392. dubs: dubs
  393. });
  394. var g = b("<div/>", {
  395. "class": "dubDisplay"
  396. }).html("<b>" + d + " +" + c + " dub</b><span>" + dubs + "</span>").appendTo(e.viewEl.$el);
  397. setTimeout(function() {
  398. g.remove()
  399. }, 1500)
  400. }
  401. return !1
  402. },
  403. loadDependenciesEl: function(a) {
  404. Dubtrack.layout = new Dubtrack.View.LayoutView, Dubtrack.playerController = new Dubtrack.View.PlayerController, a && a.call()
  405. },
  406. loadDependencies: function(a) {
  407. Dubtrack.user = {}, Dubtrack.user.loggedIn = !1, Dubtrack.els.init(), Dubtrack.session = new Dubtrack.Model.User, Dubtrack.loggedIn = !1, Dubtrack.session.urlRoot = Dubtrack.config.apiUrl + Dubtrack.config.urls.session, Dubtrack.session.parse = Dubtrack.helpers.parse, Dubtrack.session.fetch({
  408. success: function(b, c) {
  409. Dubtrack.loggedIn = !0, Dubtrack.helpers.loadDependenciesEl(a), Dubtrack.cache.users.add(c.data)
  410. },
  411. error: function() {
  412. Dubtrack.helpers.loadDependenciesEl(a)
  413. }
  414. })
  415. },
  416. displayError: function(a, c, d, e) {
  417. b("#warning").remove();
  418. var f = b("<div/>", {
  419. id: "warning"
  420. }).html("<h3>" + a + "</h3><p>" + c + "</p>").appendTo("body");
  421. d ? b("<button onclick='location.reload();return false;'>" + dubtrack_lang.global.refresh + "</button>").appendTo(f) : (e || (e = '$("#warning").remove();return false;'), b("<button onclick=" + e + ">Ok</button>").appendTo(f))
  422. },
  423. text: {
  424. shortenLink: function(a, b) {
  425. return a.length > b && (a = a.substring(0, b) + "..."), a
  426. },
  427. shortenMessage: function(a, b) {
  428. return a.substring(0, b)
  429. },
  430. convertHtmltoTags: function(a, b) {
  431. var c = /^(http|https)(.*)\.(png|jpg|jpeg|gif)$/;
  432. return a = a.replace(/(\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%()[\]?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|])/gim, function(a) {
  433. if (!Dubtrack.HideImages && a.match(c)) {
  434. return a = '<a href="' + a + '" class="autolink" target="_blank"><img src="https://dbu1ls7999okz.cloudfront.net/chat?url=' + a + '" /></a>'
  435. }
  436. return a = '<a href="' + a + '" class="autolink" target="_blank">' + Dubtrack.helpers.text.shortenLink(a, 60) + "</a>"
  437. })
  438. },
  439. shrinkImg: function(a) {
  440. var c = b(a);
  441. 20 === c.width() ? c.animate({
  442. width: "100%",
  443. height: "100%"
  444. }, 500) : c.animate({
  445. width: "20px",
  446. height: "20px"
  447. }, 500)
  448. },
  449. convertAttoLink: function(a) {
  450. return a.replace(/(@[A-Za-z0-9_.]+)/g, '<span class="username-handle">$&</span>')
  451. }
  452. }
  453. },
  454. app: null,
  455. dubtrackPlayer: null
  456. },
  457. function(a) {
  458. b.browser = {}, b.browser.mobile = /(ipad|android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))
  459. }(navigator.userAgent || navigator.vendor || window.opera), b.fn.serializeObject = function() {
  460. var a = {},
  461. c = this.serializeArray();
  462. return b.each(c, function() {
  463. void 0 !== a[this.name] ? (a[this.name].push || (a[this.name] = [a[this.name]]), a[this.name].push(this.value || "")) : a[this.name] = this.value || ""
  464. }), a
  465. }, b.fn.hasValue = function() {
  466. var a = this.val();
  467. return !(_.isNull(a) || _.isUndefined(a) || _.isString(a) && "" === h(a))
  468. }, b.fn.randomize = function(a) {
  469. var c = a ? b(this).find(a) : b(this).children(),
  470. d = c.parent();
  471. return d.each(function() {
  472. b(this).children(a).sort(function() {
  473. return Math.round(Math.random()) - .5
  474. }).detach().appendTo(this)
  475. }), this
  476. };
  477. var h = String.prototype.trim ? function(a) {
  478. return null === a ? "" : String.prototype.trim.call(a)
  479. } : function(a) {
  480. var b = /^\s+/,
  481. c = /\s+$/;
  482. return null === a ? "" : a.toString().replace(b, "").replace(c, "")
  483. };
  484. jQuery.expr[":"].regex = function(a, b, c) {
  485. var d = c[3].split(","),
  486. e = /^(data|css):/,
  487. f = {
  488. method: d[0].match(e) ? d[0].split(":")[0] : "attr",
  489. property: d.shift().replace(e, "")
  490. },
  491. g = "ig",
  492. h = new RegExp(d.join("").replace(/^\s+|\s+$/g, ""), g);
  493. return h.test(jQuery(a)[f.method](f.property))
  494. },
  495. function(a, b, c) {
  496. "use strict";
  497. a.fn.backstretch = function(d, f) {
  498. return (d === c || 0 === d.length) && a.error("No images were supplied for Backstretch"), 0 === a(b).scrollTop() && b.scrollTo(0, 0), this.each(function() {
  499. var b = a(this),
  500. c = b.data("backstretch");
  501. if (c) {
  502. if ("string" == typeof d && "function" == typeof c[d]) return void c[d](f);
  503. f = a.extend(c.options, f), c.destroy(!0)
  504. }
  505. c = new e(this, d, f), b.data("backstretch", c)
  506. })
  507. }, a.backstretch = function(b, c) {
  508. return a("body").backstretch(b, c).data("backstretch")
  509. }, a.expr[":"].backstretch = function(b) {
  510. return a(b).data("backstretch") !== c
  511. }, a.fn.backstretch.defaults = {
  512. centeredX: !0,
  513. centeredY: !0,
  514. duration: 5e3,
  515. fade: 0
  516. };
  517. var d = {
  518. wrap: {
  519. left: 0,
  520. top: 0,
  521. overflow: "hidden",
  522. margin: 0,
  523. padding: 0,
  524. height: "100%",
  525. width: "100%",
  526. zIndex: -999999
  527. },
  528. img: {
  529. position: "absolute",
  530. display: "none",
  531. margin: 0,
  532. padding: 0,
  533. border: "none",
  534. width: "auto",
  535. height: "auto",
  536. maxHeight: "none",
  537. maxWidth: "none",
  538. zIndex: -999999
  539. }
  540. },
  541. e = function(c, e, g) {
  542. this.options = a.extend({}, a.fn.backstretch.defaults, g || {}), this.images = a.isArray(e) ? e : [e], a.each(this.images, function() {
  543. a("<img />")[0].src = this
  544. }), this.isBody = c === document.body, this.$container = a(c), this.$root = this.isBody ? a(f ? b : document) : this.$container;
  545. var h = this.$container.children(".backstretch").first();
  546. if (this.$wrap = h.length ? h : a('<div class="backstretch"></div>').css(d.wrap).appendTo(this.$container), !this.isBody) {
  547. var i = this.$container.css("position"),
  548. j = this.$container.css("zIndex");
  549. this.$container.css({
  550. position: "static" === i ? "relative" : i,
  551. zIndex: "auto" === j ? 0 : j,
  552. background: "none"
  553. }), this.$wrap.css({
  554. zIndex: -999998
  555. })
  556. }
  557. this.$wrap.css({
  558. position: this.isBody && f ? "fixed" : "absolute"
  559. }), this.index = 0, this.show(this.index), a(b).on("resize.backstretch", a.proxy(this.resize, this)).on("orientationchange.backstretch", a.proxy(function() {
  560. this.isBody && 0 === b.pageYOffset && (b.scrollTo(0, 1), this.resize())
  561. }, this))
  562. };
  563. e.prototype = {
  564. resize: function() {
  565. try {
  566. var a, c = {
  567. left: 0,
  568. top: 0
  569. },
  570. d = this.isBody ? this.$root.width() : this.$root.innerWidth(),
  571. e = d,
  572. f = this.isBody ? b.innerHeight ? b.innerHeight : this.$root.height() : this.$root.innerHeight(),
  573. g = e / this.$img.data("ratio");
  574. g >= f ? (a = (g - f) / 2, this.options.centeredY && (c.top = "-" + a + "px")) : (g = f, e = g * this.$img.data("ratio"), a = (e - d) / 2, this.options.centeredX && (c.left = "-" + a + "px")), this.$wrap.css({
  575. width: d,
  576. height: f
  577. }).find("img:not(.deleteable)").css({
  578. width: e,
  579. height: g
  580. }).css(c)
  581. } catch (h) {}
  582. return this
  583. },
  584. show: function(b) {
  585. if (!(Math.abs(b) > this.images.length - 1)) {
  586. var c = this,
  587. e = c.$wrap.find("img").addClass("deleteable"),
  588. f = {
  589. relatedTarget: c.$container[0]
  590. };
  591. return c.$container.trigger(a.Event("backstretch.before", f), [c, b]), this.index = b, clearInterval(c.interval), c.$img = a("<img />").css(d.img).bind("load", function(d) {
  592. var g = this.width || a(d.target).width(),
  593. h = this.height || a(d.target).height();
  594. a(this).data("ratio", g / h), a(this).fadeIn(c.options.speed || c.options.fade, function() {
  595. e.remove(), c.paused || c.cycle(), a(["after", "show"]).each(function() {
  596. c.$container.trigger(a.Event("backstretch." + this, f), [c, b])
  597. })
  598. }), c.resize()
  599. }).appendTo(c.$wrap), c.$img.attr("src", c.images[b]), c
  600. }
  601. },
  602. next: function() {
  603. return this.show(this.index < this.images.length - 1 ? this.index + 1 : 0)
  604. },
  605. prev: function() {
  606. return this.show(0 === this.index ? this.images.length - 1 : this.index - 1)
  607. },
  608. pause: function() {
  609. return this.paused = !0, this
  610. },
  611. resume: function() {
  612. return this.paused = !1, this.next(), this
  613. },
  614. cycle: function() {
  615. return this.images.length > 1 && (clearInterval(this.interval), this.interval = setInterval(a.proxy(function() {
  616. this.paused || this.next()
  617. }, this), this.options.duration)), this
  618. },
  619. destroy: function(c) {
  620. a(b).off("resize.backstretch orientationchange.backstretch"), clearInterval(this.interval), c || this.$wrap.remove(), this.$container.removeData("backstretch")
  621. }
  622. };
  623. var f = function() {
  624. var a = navigator.userAgent,
  625. c = navigator.platform,
  626. d = a.match(/AppleWebKit\/([0-9]+)/),
  627. e = !!d && d[1],
  628. f = a.match(/Fennec\/([0-9]+)/),
  629. g = !!f && f[1],
  630. h = a.match(/Opera Mobi\/([0-9]+)/),
  631. i = !!h && h[1],
  632. j = a.match(/MSIE ([0-9]+)/),
  633. k = !!j && j[1];
  634. return !((c.indexOf("iPhone") > -1 || c.indexOf("iPad") > -1 || c.indexOf("iPod") > -1) && e && 534 > e || b.operamini && "[object OperaMini]" === {}.toString.call(b.operamini) || h && 7458 > i || a.indexOf("Android") > -1 && e && 533 > e || g && 6 > g || "palmGetResource" in b && e && 534 > e || a.indexOf("MeeGo") > -1 && a.indexOf("NokiaBrowser/8.5.0") > -1 || k && 6 >= k)
  635. }()
  636. }(jQuery, window),
  637. function(a) {
  638. "use strict";
  639. "function" == typeof define && define.amd ? define(["jquery", "jquery.ui.widget"], a) : a(window.jQuery)
  640. }(function(a) {
  641. "use strict";
  642. a.support.fileInput = !(new RegExp("(Android (1\\.[0156]|2\\.[01]))|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)|(w(eb)?OSBrowser)|(webOS)|(Kindle/(1\\.0|2\\.[05]|3\\.0))").test(window.navigator.userAgent) || a('<input type="file">').prop("disabled")), a.support.xhrFileUpload = !(!window.ProgressEvent || !window.FileReader), a.support.xhrFormDataFileUpload = !!window.FormData, a.support.blobSlice = window.Blob && (Blob.prototype.slice || Blob.prototype.webkitSlice || Blob.prototype.mozSlice), a.widget("blueimp.fileupload", {
  643. options: {
  644. dropZone: a(document),
  645. pasteZone: a(document),
  646. fileInput: void 0,
  647. replaceFileInput: !0,
  648. paramName: void 0,
  649. singleFileUploads: !0,
  650. limitMultiFileUploads: void 0,
  651. limitMultiFileUploadSize: void 0,
  652. limitMultiFileUploadSizeOverhead: 512,
  653. sequentialUploads: !1,
  654. limitConcurrentUploads: void 0,
  655. forceIframeTransport: !1,
  656. redirect: void 0,
  657. redirectParamName: void 0,
  658. postMessage: void 0,
  659. multipart: !0,
  660. maxChunkSize: void 0,
  661. uploadedBytes: void 0,
  662. recalculateProgress: !0,
  663. progressInterval: 100,
  664. bitrateInterval: 500,
  665. autoUpload: !0,
  666. messages: {
  667. uploadedBytes: "Uploaded bytes exceed file size"
  668. },
  669. i18n: function(b, c) {
  670. return b = this.messages[b] || b.toString(), c && a.each(c, function(a, c) {
  671. b = b.replace("{" + a + "}", c)
  672. }), b
  673. },
  674. formData: function(a) {
  675. return a.serializeArray()
  676. },
  677. add: function(b, c) {
  678. return b.isDefaultPrevented() ? !1 : void((c.autoUpload || c.autoUpload !== !1 && a(this).fileupload("option", "autoUpload")) && c.process().done(function() {
  679. c.submit()
  680. }))
  681. },
  682. processData: !1,
  683. contentType: !1,
  684. cache: !1
  685. },
  686. _specialOptions: ["fileInput", "dropZone", "pasteZone", "multipart", "forceIframeTransport"],
  687. _blobSlice: a.support.blobSlice && function() {
  688. var a = this.slice || this.webkitSlice || this.mozSlice;
  689. return a.apply(this, arguments)
  690. },
  691. _BitrateTimer: function() {
  692. this.timestamp = Date.now ? Date.now() : (new Date).getTime(), this.loaded = 0, this.bitrate = 0, this.getBitrate = function(a, b, c) {
  693. var d = a - this.timestamp;
  694. return (!this.bitrate || !c || d > c) && (this.bitrate = (b - this.loaded) * (1e3 / d) * 8, this.loaded = b, this.timestamp = a), this.bitrate
  695. }
  696. },
  697. _isXHRUpload: function(b) {
  698. return !b.forceIframeTransport && (!b.multipart && a.support.xhrFileUpload || a.support.xhrFormDataFileUpload)
  699. },
  700. _getFormData: function(b) {
  701. var c;
  702. return "function" === a.type(b.formData) ? b.formData(b.form) : a.isArray(b.formData) ? b.formData : "object" === a.type(b.formData) ? (c = [], a.each(b.formData, function(a, b) {
  703. c.push({
  704. name: a,
  705. value: b
  706. })
  707. }), c) : []
  708. },
  709. _getTotal: function(b) {
  710. var c = 0;
  711. return a.each(b, function(a, b) {
  712. c += b.size || 1
  713. }), c
  714. },
  715. _initProgressObject: function(b) {
  716. var c = {
  717. loaded: 0,
  718. total: 0,
  719. bitrate: 0
  720. };
  721. b._progress ? a.extend(b._progress, c) : b._progress = c
  722. },
  723. _initResponseObject: function(a) {
  724. var b;
  725. if (a._response)
  726. for (b in a._response) a._response.hasOwnProperty(b) && delete a._response[b];
  727. else a._response = {}
  728. },
  729. _onProgress: function(b, c) {
  730. if (b.lengthComputable) {
  731. var d, e = Date.now ? Date.now() : (new Date).getTime();
  732. if (c._time && c.progressInterval && e - c._time < c.progressInterval && b.loaded !== b.total) return;
  733. c._time = e, d = Math.floor(b.loaded / b.total * (c.chunkSize || c._progress.total)) + (c.uploadedBytes || 0), this._progress.loaded += d - c._progress.loaded, this._progress.bitrate = this._bitrateTimer.getBitrate(e, this._progress.loaded, c.bitrateInterval), c._progress.loaded = c.loaded = d, c._progress.bitrate = c.bitrate = c._bitrateTimer.getBitrate(e, d, c.bitrateInterval), this._trigger("progress", a.Event("progress", {
  734. delegatedEvent: b
  735. }), c), this._trigger("progressall", a.Event("progressall", {
  736. delegatedEvent: b
  737. }), this._progress)
  738. }
  739. },
  740. _initProgressListener: function(b) {
  741. var c = this,
  742. d = b.xhr ? b.xhr() : a.ajaxSettings.xhr();
  743. d.upload && (a(d.upload).bind("progress", function(a) {
  744. var d = a.originalEvent;
  745. a.lengthComputable = d.lengthComputable, a.loaded = d.loaded, a.total = d.total, c._onProgress(a, b)
  746. }), b.xhr = function() {
  747. return d
  748. })
  749. },
  750. _isInstanceOf: function(a, b) {
  751. return Object.prototype.toString.call(b) === "[object " + a + "]"
  752. },
  753. _initXHRData: function(b) {
  754. var c, d = this,
  755. e = b.files[0],
  756. f = b.multipart || !a.support.xhrFileUpload,
  757. g = "array" === a.type(b.paramName) ? b.paramName[0] : b.paramName;
  758. b.headers = a.extend({}, b.headers), b.contentRange && (b.headers["Content-Range"] = b.contentRange), f && !b.blob && this._isInstanceOf("File", e) || (b.headers["Content-Disposition"] = 'attachment; filename="' + encodeURI(e.name) + '"'), f ? a.support.xhrFormDataFileUpload && (b.postMessage ? (c = this._getFormData(b), b.blob ? c.push({
  759. name: g,
  760. value: b.blob
  761. }) : a.each(b.files, function(d, e) {
  762. c.push({
  763. name: "array" === a.type(b.paramName) && b.paramName[d] || g,
  764. value: e
  765. })
  766. })) : (d._isInstanceOf("FormData", b.formData) ? c = b.formData : (c = new FormData, a.each(this._getFormData(b), function(a, b) {
  767. c.append(b.name, b.value)
  768. })), b.blob ? c.append(g, b.blob, e.name) : a.each(b.files, function(e, f) {
  769. (d._isInstanceOf("File", f) || d._isInstanceOf("Blob", f)) && c.append("array" === a.type(b.paramName) && b.paramName[e] || g, f, f.uploadName || f.name)
  770. })), b.data = c) : (b.contentType = e.type || "application/octet-stream", b.data = b.blob || e), b.blob = null
  771. },
  772. _initIframeSettings: function(b) {
  773. var c = a("<a></a>").prop("href", b.url).prop("host");
  774. b.dataType = "iframe " + (b.dataType || ""), b.formData = this._getFormData(b), b.redirect && c && c !== location.host && b.formData.push({
  775. name: b.redirectParamName || "redirect",
  776. value: b.redirect
  777. })
  778. },
  779. _initDataSettings: function(a) {
  780. this._isXHRUpload(a) ? (this._chunkedUpload(a, !0) || (a.data || this._initXHRData(a), this._initProgressListener(a)), a.postMessage && (a.dataType = "postmessage " + (a.dataType || ""))) : this._initIframeSettings(a)
  781. },
  782. _getParamName: function(b) {
  783. var c = a(b.fileInput),
  784. d = b.paramName;
  785. return d ? a.isArray(d) || (d = [d]) : (d = [], c.each(function() {
  786. for (var b = a(this), c = b.prop("name") || "files[]", e = (b.prop("files") || [1]).length; e;) d.push(c), e -= 1
  787. }), d.length || (d = [c.prop("name") || "files[]"])), d
  788. },
  789. _initFormSettings: function(b) {
  790. b.form && b.form.length || (b.form = a(b.fileInput.prop("form")), b.form.length || (b.form = a(this.options.fileInput.prop("form")))), b.paramName = this._getParamName(b), b.url || (b.url = b.form.prop("action") || location.href), b.type = (b.type || "string" === a.type(b.form.prop("method")) && b.form.prop("method") || "").toUpperCase(), "POST" !== b.type && "PUT" !== b.type && "PATCH" !== b.type && (b.type = "POST"), b.formAcceptCharset || (b.formAcceptCharset = b.form.attr("accept-charset"))
  791. },
  792. _getAJAXSettings: function(b) {
  793. var c = a.extend({}, this.options, b);
  794. return this._initFormSettings(c), this._initDataSettings(c), c
  795. },
  796. _getDeferredState: function(a) {
  797. return a.state ? a.state() : a.isResolved() ? "resolved" : a.isRejected() ? "rejected" : "pending"
  798. },
  799. _enhancePromise: function(a) {
  800. return a.success = a.done, a.error = a.fail, a.complete = a.always, a
  801. },
  802. _getXHRPromise: function(b, c, d) {
  803. var e = a.Deferred(),
  804. f = e.promise();
  805. return c = c || this.options.context || f, b === !0 ? e.resolveWith(c, d) : b === !1 && e.rejectWith(c, d), f.abort = e.promise, this._enhancePromise(f)
  806. },
  807. _addConvenienceMethods: function(b, c) {
  808. var d = this,
  809. e = function(b) {
  810. return a.Deferred().resolveWith(d, b).promise()
  811. };
  812. c.process = function(b, f) {
  813. return (b || f) && (c._processQueue = this._processQueue = (this._processQueue || e([this])).pipe(function() {
  814. return c.errorThrown ? a.Deferred().rejectWith(d, [c]).promise() : e(arguments)
  815. }).pipe(b, f)), this._processQueue || e([this])
  816. }, c.submit = function() {
  817. return "pending" !== this.state() && (c.jqXHR = this.jqXHR = d._trigger("submit", a.Event("submit", {
  818. delegatedEvent: b
  819. }), this) !== !1 && d._onSend(b, this)), this.jqXHR || d._getXHRPromise()
  820. }, c.abort = function() {
  821. return this.jqXHR ? this.jqXHR.abort() : (this.errorThrown = "abort", d._trigger("fail", null, this), d._getXHRPromise(!1))
  822. }, c.state = function() {
  823. return this.jqXHR ? d._getDeferredState(this.jqXHR) : this._processQueue ? d._getDeferredState(this._processQueue) : void 0
  824. }, c.processing = function() {
  825. return !this.jqXHR && this._processQueue && "pending" === d._getDeferredState(this._processQueue)
  826. }, c.progress = function() {
  827. return this._progress
  828. }, c.response = function() {
  829. return this._response
  830. }
  831. },
  832. _getUploadedBytes: function(a) {
  833. var b = a.getResponseHeader("Range"),
  834. c = b && b.split("-"),
  835. d = c && c.length > 1 && parseInt(c[1], 10);
  836. return d && d + 1
  837. },
  838. _chunkedUpload: function(b, c) {
  839. b.uploadedBytes = b.uploadedBytes || 0;
  840. var d, e, f = this,
  841. g = b.files[0],
  842. h = g.size,
  843. i = b.uploadedBytes,
  844. j = b.maxChunkSize || h,
  845. k = this._blobSlice,
  846. l = a.Deferred(),
  847. m = l.promise();
  848. return this._isXHRUpload(b) && k && (i || h > j) && !b.data ? c ? !0 : i >= h ? (g.error = b.i18n("uploadedBytes"), this._getXHRPromise(!1, b.context, [null, "error", g.error])) : (e = function() {
  849. var c = a.extend({}, b),
  850. m = c._progress.loaded;
  851. c.blob = k.call(g, i, i + j, g.type), c.chunkSize = c.blob.size, c.contentRange = "bytes " + i + "-" + (i + c.chunkSize - 1) + "/" + h, f._initXHRData(c), f._initProgressListener(c), d = (f._trigger("chunksend", null, c) !== !1 && a.ajax(c) || f._getXHRPromise(!1, c.context)).done(function(d, g, j) {
  852. i = f._getUploadedBytes(j) || i + c.chunkSize, m + c.chunkSize - c._progress.loaded && f._onProgress(a.Event("progress", {
  853. lengthComputable: !0,
  854. loaded: i - c.uploadedBytes,
  855. total: i - c.uploadedBytes
  856. }), c), b.uploadedBytes = c.uploadedBytes = i, c.result = d, c.textStatus = g, c.jqXHR = j, f._trigger("chunkdone", null, c), f._trigger("chunkalways", null, c), h > i ? e() : l.resolveWith(c.context, [d, g, j])
  857. }).fail(function(a, b, d) {
  858. c.jqXHR = a, c.textStatus = b, c.errorThrown = d, f._trigger("chunkfail", null, c), f._trigger("chunkalways", null, c), l.rejectWith(c.context, [a, b, d])
  859. })
  860. }, this._enhancePromise(m), m.abort = function() {
  861. return d.abort()
  862. }, e(), m) : !1
  863. },
  864. _beforeSend: function(a, b) {
  865. 0 === this._active && (this._trigger("start"), this._bitrateTimer = new this._BitrateTimer, this._progress.loaded = this._progress.total = 0, this._progress.bitrate = 0), this._initResponseObject(b), this._initProgressObject(b), b._progress.loaded = b.loaded = b.uploadedBytes || 0, b._progress.total = b.total = this._getTotal(b.files) || 1, b._progress.bitrate = b.bitrate = 0, this._active += 1, this._progress.loaded += b.loaded, this._progress.total += b.total
  866. },
  867. _onDone: function(b, c, d, e) {
  868. var f = e._progress.total,
  869. g = e._response;
  870. e._progress.loaded < f && this._onProgress(a.Event("progress", {
  871. lengthComputable: !0,
  872. loaded: f,
  873. total: f
  874. }), e), g.result = e.result = b, g.textStatus = e.textStatus = c, g.jqXHR = e.jqXHR = d, this._trigger("done", null, e)
  875. },
  876. _onFail: function(a, b, c, d) {
  877. var e = d._response;
  878. d.recalculateProgress && (this._progress.loaded -= d._progress.loaded, this._progress.total -= d._progress.total), e.jqXHR = d.jqXHR = a, e.textStatus = d.textStatus = b, e.errorThrown = d.errorThrown = c, this._trigger("fail", null, d)
  879. },
  880. _onAlways: function(a, b, c, d) {
  881. this._trigger("always", null, d)
  882. },
  883. _onSend: function(b, c) {
  884. c.submit || this._addConvenienceMethods(b, c);
  885. var d, e, f, g, h = this,
  886. i = h._getAJAXSettings(c),
  887. j = function() {
  888. return h._sending += 1, i._bitrateTimer = new h._BitrateTimer,
  889. d = d || ((e || h._trigger("send", a.Event("send", {
  890. delegatedEvent: b
  891. }), i) === !1) && h._getXHRPromise(!1, i.context, e) || h._chunkedUpload(i) || a.ajax(i)).done(function(a, b, c) {
  892. h._onDone(a, b, c, i)
  893. }).fail(function(a, b, c) {
  894. h._onFail(a, b, c, i)
  895. }).always(function(a, b, c) {
  896. if (h._onAlways(a, b, c, i), h._sending -= 1, h._active -= 1, i.limitConcurrentUploads && i.limitConcurrentUploads > h._sending)
  897. for (var d = h._slots.shift(); d;) {
  898. if ("pending" === h._getDeferredState(d)) {
  899. d.resolve();
  900. break
  901. }
  902. d = h._slots.shift()
  903. }
  904. 0 === h._active && h._trigger("stop")
  905. })
  906. };
  907. return this._beforeSend(b, i), this.options.sequentialUploads || this.options.limitConcurrentUploads && this.options.limitConcurrentUploads <= this._sending ? (this.options.limitConcurrentUploads > 1 ? (f = a.Deferred(), this._slots.push(f), g = f.pipe(j)) : (this._sequence = this._sequence.pipe(j, j), g = this._sequence), g.abort = function() {
  908. return e = [void 0, "abort", "abort"], d ? d.abort() : (f && f.rejectWith(i.context, e), j())
  909. }, this._enhancePromise(g)) : j()
  910. },
  911. _onAdd: function(b, c) {
  912. var d, e, f, g, h = this,
  913. i = !0,
  914. j = a.extend({}, this.options, c),
  915. k = c.files,
  916. l = k.length,
  917. m = j.limitMultiFileUploads,
  918. n = j.limitMultiFileUploadSize,
  919. o = j.limitMultiFileUploadSizeOverhead,
  920. p = 0,
  921. q = this._getParamName(j),
  922. r = 0;
  923. if (!n || l && void 0 !== k[0].size || (n = void 0), (j.singleFileUploads || m || n) && this._isXHRUpload(j))
  924. if (j.singleFileUploads || n || !m)
  925. if (!j.singleFileUploads && n)
  926. for (f = [], d = [], g = 0; l > g; g += 1) p += k[g].size + o, (g + 1 === l || p + k[g + 1].size + o > n || m && g + 1 - r >= m) && (f.push(k.slice(r, g + 1)), e = q.slice(r, g + 1), e.length || (e = q), d.push(e), r = g + 1, p = 0);
  927. else d = q;
  928. else
  929. for (f = [], d = [], g = 0; l > g; g += m) f.push(k.slice(g, g + m)), e = q.slice(g, g + m), e.length || (e = q), d.push(e);
  930. else f = [k], d = [q];
  931. return c.originalFiles = k, a.each(f || k, function(e, g) {
  932. var j = a.extend({}, c);
  933. return j.files = f ? g : [g], j.paramName = d[e], h._initResponseObject(j), h._initProgressObject(j), h._addConvenienceMethods(b, j), i = h._trigger("add", a.Event("add", {
  934. delegatedEvent: b
  935. }), j)
  936. }), i
  937. },
  938. _replaceFileInput: function(b) {
  939. var c = b.clone(!0);
  940. a("<form></form>").append(c)[0].reset(), b.after(c).detach(), a.cleanData(b.unbind("remove")), this.options.fileInput = this.options.fileInput.map(function(a, d) {
  941. return d === b[0] ? c[0] : d
  942. }), b[0] === this.element[0] && (this.element = c)
  943. },
  944. _handleFileTreeEntry: function(b, c) {
  945. var d, e = this,
  946. f = a.Deferred(),
  947. g = function(a) {
  948. a && !a.entry && (a.entry = b), f.resolve([a])
  949. };
  950. return c = c || "", b.isFile ? b._file ? (b._file.relativePath = c, f.resolve(b._file)) : b.file(function(a) {
  951. a.relativePath = c, f.resolve(a)
  952. }, g) : b.isDirectory ? (d = b.createReader(), d.readEntries(function(a) {
  953. e._handleFileTreeEntries(a, c + b.name + "/").done(function(a) {
  954. f.resolve(a)
  955. }).fail(g)
  956. }, g)) : f.resolve([]), f.promise()
  957. },
  958. _handleFileTreeEntries: function(b, c) {
  959. var d = this;
  960. return a.when.apply(a, a.map(b, function(a) {
  961. return d._handleFileTreeEntry(a, c)
  962. })).pipe(function() {
  963. return Array.prototype.concat.apply([], arguments)
  964. })
  965. },
  966. _getDroppedFiles: function(b) {
  967. b = b || {};
  968. var c = b.items;
  969. return c && c.length && (c[0].webkitGetAsEntry || c[0].getAsEntry) ? this._handleFileTreeEntries(a.map(c, function(a) {
  970. var b;
  971. return a.webkitGetAsEntry ? (b = a.webkitGetAsEntry(), b && (b._file = a.getAsFile()), b) : a.getAsEntry()
  972. })) : a.Deferred().resolve(a.makeArray(b.files)).promise()
  973. },
  974. _getSingleFileInputFiles: function(b) {
  975. b = a(b);
  976. var c, d, e = b.prop("webkitEntries") || b.prop("entries");
  977. if (e && e.length) return this._handleFileTreeEntries(e);
  978. if (c = a.makeArray(b.prop("files")), c.length) void 0 === c[0].name && c[0].fileName && a.each(c, function(a, b) {
  979. b.name = b.fileName, b.size = b.fileSize
  980. });
  981. else {
  982. if (d = b.prop("value"), !d) return a.Deferred().resolve([]).promise();
  983. c = [{
  984. name: d.replace(/^.*\\/, "")
  985. }]
  986. }
  987. return a.Deferred().resolve(c).promise()
  988. },
  989. _getFileInputFiles: function(b) {
  990. return b instanceof a && 1 !== b.length ? a.when.apply(a, a.map(b, this._getSingleFileInputFiles)).pipe(function() {
  991. return Array.prototype.concat.apply([], arguments)
  992. }) : this._getSingleFileInputFiles(b)
  993. },
  994. _onChange: function(b) {
  995. var c = this,
  996. d = {
  997. fileInput: a(b.target),
  998. form: a(b.target.form)
  999. };
  1000. this._getFileInputFiles(d.fileInput).always(function(e) {
  1001. d.files = e, c.options.replaceFileInput && c._replaceFileInput(d.fileInput), c._trigger("change", a.Event("change", {
  1002. delegatedEvent: b
  1003. }), d) !== !1 && c._onAdd(b, d)
  1004. })
  1005. },
  1006. _onPaste: function(b) {
  1007. var c = b.originalEvent && b.originalEvent.clipboardData && b.originalEvent.clipboardData.items,
  1008. d = {
  1009. files: []
  1010. };
  1011. c && c.length && (a.each(c, function(a, b) {
  1012. var c = b.getAsFile && b.getAsFile();
  1013. c && d.files.push(c)
  1014. }), this._trigger("paste", a.Event("paste", {
  1015. delegatedEvent: b
  1016. }), d) !== !1 && this._onAdd(b, d))
  1017. },
  1018. _onDrop: function(b) {
  1019. b.dataTransfer = b.originalEvent && b.originalEvent.dataTransfer;
  1020. var c = this,
  1021. d = b.dataTransfer,
  1022. e = {};
  1023. d && d.files && d.files.length && (b.preventDefault(), this._getDroppedFiles(d).always(function(d) {
  1024. e.files = d, c._trigger("drop", a.Event("drop", {
  1025. delegatedEvent: b
  1026. }), e) !== !1 && c._onAdd(b, e)
  1027. }))
  1028. },
  1029. _onDragOver: function(b) {
  1030. b.dataTransfer = b.originalEvent && b.originalEvent.dataTransfer;
  1031. var c = b.dataTransfer;
  1032. c && -1 !== a.inArray("Files", c.types) && this._trigger("dragover", a.Event("dragover", {
  1033. delegatedEvent: b
  1034. })) !== !1 && (b.preventDefault(), c.dropEffect = "copy")
  1035. },
  1036. _initEventHandlers: function() {
  1037. this._isXHRUpload(this.options) && (this._on(this.options.dropZone, {
  1038. dragover: this._onDragOver,
  1039. drop: this._onDrop
  1040. }), this._on(this.options.pasteZone, {
  1041. paste: this._onPaste
  1042. })), a.support.fileInput && this._on(this.options.fileInput, {
  1043. change: this._onChange
  1044. })
  1045. },
  1046. _destroyEventHandlers: function() {
  1047. this._off(this.options.dropZone, "dragover drop"), this._off(this.options.pasteZone, "paste"), this._off(this.options.fileInput, "change")
  1048. },
  1049. _setOption: function(b, c) {
  1050. var d = -1 !== a.inArray(b, this._specialOptions);
  1051. d && this._destroyEventHandlers(), this._super(b, c), d && (this._initSpecialOptions(), this._initEventHandlers())
  1052. },
  1053. _initSpecialOptions: function() {
  1054. var b = this.options;
  1055. void 0 === b.fileInput ? b.fileInput = this.element.is('input[type="file"]') ? this.element : this.element.find('input[type="file"]') : b.fileInput instanceof a || (b.fileInput = a(b.fileInput)), b.dropZone instanceof a || (b.dropZone = a(b.dropZone)), b.pasteZone instanceof a || (b.pasteZone = a(b.pasteZone))
  1056. },
  1057. _getRegExp: function(a) {
  1058. var b = a.split("/"),
  1059. c = b.pop();
  1060. return b.shift(), new RegExp(b.join("/"), c)
  1061. },
  1062. _isRegExpOption: function(b, c) {
  1063. return "url" !== b && "string" === a.type(c) && /^\/.*\/[igm]{0,3}$/.test(c)
  1064. },
  1065. _initDataAttributes: function() {
  1066. var b = this,
  1067. c = this.options,
  1068. d = a(this.element[0].cloneNode(!1));
  1069. a.each(d.data(), function(a, e) {
  1070. var f = "data-" + a.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
  1071. d.attr(f) && (b._isRegExpOption(a, e) && (e = b._getRegExp(e)), c[a] = e)
  1072. })
  1073. },
  1074. _create: function() {
  1075. this._initDataAttributes(), this._initSpecialOptions(), this._slots = [], this._sequence = this._getXHRPromise(!0), this._sending = this._active = 0, this._initProgressObject(this), this._initEventHandlers()
  1076. },
  1077. active: function() {
  1078. return this._active
  1079. },
  1080. progress: function() {
  1081. return this._progress
  1082. },
  1083. add: function(b) {
  1084. var c = this;
  1085. b && !this.options.disabled && (b.fileInput && !b.files ? this._getFileInputFiles(b.fileInput).always(function(a) {
  1086. b.files = a, c._onAdd(null, b)
  1087. }) : (b.files = a.makeArray(b.files), this._onAdd(null, b)))
  1088. },
  1089. send: function(b) {
  1090. if (b && !this.options.disabled) {
  1091. if (b.fileInput && !b.files) {
  1092. var c, d, e = this,
  1093. f = a.Deferred(),
  1094. g = f.promise();
  1095. return g.abort = function() {
  1096. return d = !0, c ? c.abort() : (f.reject(null, "abort", "abort"), g)
  1097. }, this._getFileInputFiles(b.fileInput).always(function(a) {
  1098. if (!d) {
  1099. if (!a.length) return void f.reject();
  1100. b.files = a, c = e._onSend(null, b).then(function(a, b, c) {
  1101. f.resolve(a, b, c)
  1102. }, function(a, b, c) {
  1103. f.reject(a, b, c)
  1104. })
  1105. }
  1106. }), this._enhancePromise(g)
  1107. }
  1108. if (b.files = a.makeArray(b.files), b.files.length) return this._onSend(null, b)
  1109. }
  1110. return this._getXHRPromise(!1, b && b.context)
  1111. }
  1112. })
  1113. }),
  1114. function(a) {
  1115. "use strict";
  1116. "function" == typeof define && define.amd ? define(["jquery"], a) : a(window.jQuery)
  1117. }(function(a) {
  1118. "use strict";
  1119. var b = 0;
  1120. a.ajaxTransport("iframe", function(c) {
  1121. if (c.async) {
  1122. var d, e, f, g = c.initialIframeSrc || "javascript:false;";
  1123. return {
  1124. send: function(h, i) {
  1125. d = a('<form style="display:none;"></form>'), d.attr("accept-charset", c.formAcceptCharset), f = /\?/.test(c.url) ? "&" : "?", "DELETE" === c.type ? (c.url = c.url + f + "_method=DELETE", c.type = "POST") : "PUT" === c.type ? (c.url = c.url + f + "_method=PUT", c.type = "POST") : "PATCH" === c.type && (c.url = c.url + f + "_method=PATCH", c.type = "POST"), b += 1, e = a('<iframe src="' + g + '" name="iframe-transport-' + b + '"></iframe>').bind("load", function() {
  1126. var b, f = a.isArray(c.paramName) ? c.paramName : [c.paramName];
  1127. e.unbind("load").bind("load", function() {
  1128. var b;
  1129. try {
  1130. if (b = e.contents(), !b.length || !b[0].firstChild) throw new Error
  1131. } catch (c) {
  1132. b = void 0
  1133. }
  1134. i(200, "success", {
  1135. iframe: b
  1136. }), a('<iframe src="' + g + '"></iframe>').appendTo(d), window.setTimeout(function() {
  1137. d.remove()
  1138. }, 0)
  1139. }), d.prop("target", e.prop("name")).prop("action", c.url).prop("method", c.type), c.formData && a.each(c.formData, function(b, c) {
  1140. a('<input type="hidden"/>').prop("name", c.name).val(c.value).appendTo(d)
  1141. }), c.fileInput && c.fileInput.length && "POST" === c.type && (b = c.fileInput.clone(), c.fileInput.after(function(a) {
  1142. return b[a]
  1143. }), c.paramName && c.fileInput.each(function(b) {
  1144. a(this).prop("name", f[b] || c.paramName)
  1145. }), d.append(c.fileInput).prop("enctype", "multipart/form-data").prop("encoding", "multipart/form-data"), c.fileInput.removeAttr("form")), d.submit(), b && b.length && c.fileInput.each(function(c, d) {
  1146. var e = a(b[c]);
  1147. a(d).prop("name", e.prop("name")).attr("form", e.attr("form")), e.replaceWith(d)
  1148. })
  1149. }), d.append(e).appendTo(document.body)
  1150. },
  1151. abort: function() {
  1152. e && e.unbind("load").prop("src", g), d && d.remove()
  1153. }
  1154. }
  1155. }
  1156. }), a.ajaxSetup({
  1157. converters: {
  1158. "iframe text": function(b) {
  1159. return b && a(b[0].body).text()
  1160. },
  1161. "iframe json": function(b) {
  1162. return b && a.parseJSON(a(b[0].body).text())
  1163. },
  1164. "iframe html": function(b) {
  1165. return b && a(b[0].body).html()
  1166. },
  1167. "iframe xml": function(b) {
  1168. var c = b && b[0];
  1169. return c && a.isXMLDoc(c) ? c : a.parseXML(c.XMLDocument && c.XMLDocument.xml || a(c.body).html())
  1170. },
  1171. "iframe script": function(b) {
  1172. return b && a.globalEval(a(b[0].body).text())
  1173. }
  1174. }
  1175. })
  1176. }), ! function(a) {
  1177. a.fn.multiselectable = function(b) {
  1178. function c(c) {
  1179. var d = a(this),
  1180. e = d.parent(),
  1181. f = d.index(),
  1182. g = e.find(".multiselectable-previous");
  1183. g = g.length ? g : a(e.find("." + b.selectedClass)[0]).addClass("multiselectable-previous");
  1184. var h = g.index();
  1185. if ((c.ctrlKey || c.metaKey) && (d.hasClass(b.selectedClass) ? (d.removeClass(b.selectedClass).removeClass("multiselectable-previous"), d.not(".child").length && d.nextUntil(":not(.child)").removeClass(b.selectedClass)) : (e.find(".multiselectable-previous").removeClass("multiselectable-previous"), d.addClass(b.selectedClass).addClass("multiselectable-previous"), d.not(".child").length && d.nextUntil(":not(.child)").addClass(b.selectedClass))), c.shiftKey) {
  1186. var i = e.find(".multiselectable-shift");
  1187. i.removeClass(b.selectedClass).removeClass("multiselectable-shift");
  1188. var j;
  1189. f > h ? j = d.prevUntil(".multiselectable-previous").add(g).add(d) : h > f && (j = d.nextUntil(".multiselectable-previous").add(g).add(d)), j.addClass(b.selectedClass).addClass("multiselectable-shift")
  1190. } else e.find(".multiselectable-shift").removeClass("multiselectable-shift");
  1191. c.ctrlKey || c.metaKey || c.shiftKey || (e.find(".multiselectable-previous").removeClass("multiselectable-previous"), d.hasClass(b.selectedClass) || (e.find("." + b.selectedClass).removeClass(b.selectedClass), d.addClass(b.selectedClass).addClass("multiselectable-previous"), d.not(".child").length && d.nextUntil(":not(.child)").addClass(b.selectedClass))), b.mousedown(c, d)
  1192. }
  1193.  
  1194. function d(c) {
  1195. if (!a(this).is(".ui-draggable-dragging")) {
  1196. var d = a(this),
  1197. e = d.parent();
  1198. c.ctrlKey || c.metaKey || c.shiftKey || (e.find(".multiselectable-previous").removeClass("multiselectable-previous"), e.find("." + b.selectedClass).removeClass(b.selectedClass), d.addClass(b.selectedClass).addClass("multiselectable-previous"), d.not(".child").length && d.nextUntil(":not(.child)").addClass(b.selectedClass)), b.click(c, d)
  1199. }
  1200. }
  1201. return b || (b = {}), b = a.extend({}, a.fn.multiselectable.defaults, b), this.each(function() {
  1202. var e = a(this);
  1203. e.data("multiselectable") || e.data("multiselectable", !0).delegate(b.items, "mousedown", c).delegate(b.items, "click", d).disableSelection()
  1204. })
  1205. }, a.fn.multiselectable.defaults = {
  1206. click: function(a, b) {},
  1207. mousedown: function(a, b) {},
  1208. selectedClass: "selected",
  1209. items: "li"
  1210. }, a.fn.multisortable = function(b) {
  1211. function c(b, c) {
  1212. if (c.find("." + d.selectedClass).length > 0) {
  1213. var e = b.data("i"),
  1214. f = c.find("." + d.selectedClass).filter(function() {
  1215. return a(this).data("i") < e
  1216. }).css({
  1217. position: "",
  1218. width: "",
  1219. left: "",
  1220. top: "",
  1221. zIndex: ""
  1222. });
  1223. b.before(f);
  1224. var g = c.find("." + d.selectedClass).filter(function() {
  1225. return a(this).data("i") > e
  1226. }).css({
  1227. position: "",
  1228. width: "",
  1229. left: "",
  1230. top: "",
  1231. zIndex: ""
  1232. });
  1233. b.after(g), setTimeout(function() {
  1234. g.add(f).addClass(d.selectedClass)
  1235. }, 0)
  1236. }
  1237. }
  1238. b || (b = {});
  1239. var d = a.extend({}, a.fn.multisortable.defaults, b);
  1240. return this.each(function() {
  1241. var e = a(this);
  1242. e.multiselectable({
  1243. selectedClass: d.selectedClass,
  1244. click: d.click,
  1245. items: d.items,
  1246. mousedown: d.mousedown
  1247. }), b.cancel = d.items + ":not(." + d.selectedClass + ")", b.placeholder = d.placeholder, b.start = function(b, c) {
  1248. if (c.item.hasClass(d.selectedClass)) {
  1249. var e = c.item.parent();
  1250. e.find("." + d.selectedClass).each(function(b) {
  1251. a(this).data("i", b)
  1252. });
  1253. var f = e.find("." + d.selectedClass).length * c.item.outerHeight();
  1254. c.placeholder.height(f)
  1255. }
  1256. d.start(b, c)
  1257. }, b.stop = function(a, b) {
  1258. c(b.item, b.item.parent()), d.stop(a, b)
  1259. }, b.sort = function(b, c) {
  1260. var e = c.item.parent(),
  1261. f = c.item.data("i"),
  1262. g = parseInt(c.item.css("top").replace("px", "")),
  1263. h = parseInt(c.item.css("left").replace("px", ""));
  1264. a.fn.reverse = Array.prototype._reverse || Array.prototype.reverse;
  1265. var i = 0;
  1266. a("." + d.selectedClass, e).filter(function() {
  1267. return a(this).data("i") < f
  1268. }).reverse().each(function() {
  1269. i += a(this).outerHeight(), a(this).css({
  1270. left: h,
  1271. top: g - i,
  1272. position: "absolute",
  1273. zIndex: 1e3,
  1274. width: c.item.width()
  1275. })
  1276. }), i = c.item.outerHeight(), a("." + d.selectedClass, e).filter(function() {
  1277. return a(this).data("i") > f
  1278. }).each(function() {
  1279. var b = a(this);
  1280. b.css({
  1281. left: h,
  1282. top: g + i,
  1283. position: "absolute",
  1284. zIndex: 1e3,
  1285. width: c.item.width()
  1286. }), i += b.outerHeight()
  1287. }), d.sort(b, c)
  1288. }, b.receive = function(a, b) {
  1289. c(b.item, b.sender), d.receive(a, b)
  1290. }, e.sortable(b).disableSelection()
  1291. })
  1292. }, a.fn.multisortable.defaults = {
  1293. start: function(a, b) {},
  1294. stop: function(a, b) {},
  1295. sort: function(a, b) {},
  1296. receive: function(a, b) {},
  1297. click: function(a, b) {},
  1298. mousedown: function(a, b) {},
  1299. selectedClass: "selected",
  1300. placeholder: "placeholder",
  1301. items: "li"
  1302. }
  1303. }(jQuery),
  1304. function(a) {
  1305. "function" == typeof define && define.amd ? define(["jquery"], a) : a(jQuery)
  1306. }(function(a) {
  1307. function b() {
  1308. var b = c(this),
  1309. g = f.settings;
  1310. return isNaN(b.datetime) || (0 == g.cutoff || e(b.datetime) < g.cutoff) && a(this).text(d(b.datetime)), this
  1311. }
  1312.  
  1313. function c(b) {
  1314. if (b = a(b), !b.data("timeago")) {
  1315. b.data("timeago", {
  1316. datetime: f.datetime(b)
  1317. });
  1318. var c = a.trim(b.text());
  1319. f.settings.localeTitle ? b.attr("title", b.data("timeago").datetime.toLocaleString()) : !(c.length > 0) || f.isTime(b) && b.attr("title") || b.attr("title", c)
  1320. }
  1321. return b.data("timeago")
  1322. }
  1323.  
  1324. function d(a) {
  1325. return f.inWords(e(a))
  1326. }
  1327.  
  1328. function e(a) {
  1329. return (new Date).getTime() - a.getTime()
  1330. }
  1331. a.timeago = function(b) {
  1332. return d(b instanceof Date ? b : "string" == typeof b ? a.timeago.parse(b) : "number" == typeof b ? new Date(b) : a.timeago.datetime(b))
  1333. };
  1334. var f = a.timeago;
  1335. a.extend(a.timeago, {
  1336. settings: {
  1337. refreshMillis: 6e4,
  1338. allowFuture: !1,
  1339. localeTitle: !1,
  1340. cutoff: 0,
  1341. strings: {
  1342. prefixAgo: null,
  1343. prefixFromNow: null,
  1344. suffixAgo: "ago",
  1345. suffixFromNow: "from now",
  1346. seconds: "less than a minute",
  1347. minute: "about a minute",
  1348. minutes: "%d minutes",
  1349. hour: "about an hour",
  1350. hours: "about %d hours",
  1351. day: "a day",
  1352. days: "%d days",
  1353. month: "about a month",
  1354. months: "%d months",
  1355. year: "about a year",
  1356. years: "%d years",
  1357. wordSeparator: " ",
  1358. numbers: []
  1359. }
  1360. },
  1361. inWords: function(b) {
  1362. function c(c, e) {
  1363. var f = a.isFunction(c) ? c(e, b) : c,
  1364. g = d.numbers && d.numbers[e] || e;
  1365. return f.replace(/%d/i, g)
  1366. }
  1367. var d = this.settings.strings,
  1368. e = d.prefixAgo,
  1369. f = d.suffixAgo;
  1370. this.settings.allowFuture && 0 > b && (e = d.prefixFromNow, f = d.suffixFromNow);
  1371. var g = Math.abs(b) / 1e3,
  1372. h = g / 60,
  1373. i = h / 60,
  1374. j = i / 24,
  1375. k = j / 365,
  1376. l = 45 > g && c(d.seconds, Math.round(g)) || 90 > g && c(d.minute, 1) || 45 > h && c(d.minutes, Math.round(h)) || 90 > h && c(d.hour, 1) || 24 > i && c(d.hours, Math.round(i)) || 42 > i && c(d.day, 1) || 30 > j && c(d.days, Math.round(j)) || 45 > j && c(d.month, 1) || 365 > j && c(d.months, Math.round(j / 30)) || 1.5 > k && c(d.year, 1) || c(d.years, Math.round(k)),
  1377. m = d.wordSeparator || "";
  1378. return void 0 === d.wordSeparator && (m = " "), a.trim([e, l, f].join(m))
  1379. },
  1380. parse: function(b) {
  1381. var c = a.trim(b);
  1382. return c = c.replace(/\.\d+/, ""), c = c.replace(/-/, "/").replace(/-/, "/"), c = c.replace(/T/, " ").replace(/Z/, " UTC"), c = c.replace(/([\+\-]\d\d)\:?(\d\d)/, " $1$2"), c = c.replace(/([\+\-]\d\d)$/, " $100"), new Date(c)
  1383. },
  1384. datetime: function(b) {
  1385. var c = f.isTime(b) ? a(b).attr("datetime") : a(b).attr("title");
  1386. return f.parse(c)
  1387. },
  1388. isTime: function(b) {
  1389. return "time" === a(b).get(0).tagName.toLowerCase()
  1390. }
  1391. });
  1392. var g = {
  1393. init: function() {
  1394. var c = a.proxy(b, this);
  1395. c();
  1396. var d = f.settings;
  1397. d.refreshMillis > 0 && (this._timeagoInterval = setInterval(c, d.refreshMillis))
  1398. },
  1399. update: function(c) {
  1400. var d = f.parse(c);
  1401. a(this).data("timeago", {
  1402. datetime: d
  1403. }), f.settings.localeTitle && a(this).attr("title", d.toLocaleString()), b.apply(this)
  1404. },
  1405. updateFromDOM: function() {
  1406. a(this).data("timeago", {
  1407. datetime: f.parse(f.isTime(this) ? a(this).attr("datetime") : a(this).attr("title"))
  1408. }), b.apply(this)
  1409. },
  1410. dispose: function() {
  1411. this._timeagoInterval && (window.clearInterval(this._timeagoInterval), this._timeagoInterval = null)
  1412. }
  1413. };
  1414. a.fn.timeago = function(a, b) {
  1415. var c = a ? g[a] : g.init;
  1416. if (!c) throw new Error("Unknown function name '" + a + "' for timeago");
  1417. return this.each(function() {
  1418. c.call(this, b)
  1419. }), this
  1420. }, document.createElement("abbr"), document.createElement("time")
  1421. }),
  1422. function(a) {
  1423. "function" == typeof define && define.amd ? define(["jquery"], a) : a(jQuery)
  1424. }(function(a, b) {
  1425. var c = 0,
  1426. d = Array.prototype.slice,
  1427. e = a.cleanData;
  1428. a.cleanData = function(b) {
  1429. for (var c, d = 0; null != (c = b[d]); d++) try {
  1430. a(c).triggerHandler("remove")
  1431. } catch (f) {}
  1432. e(b)
  1433. }, a.widget = function(b, c, d) {
  1434. var e, f, g, h, i = {},
  1435. j = b.split(".")[0];
  1436. b = b.split(".")[1], e = j + "-" + b, d || (d = c, c = a.Widget), a.expr[":"][e.toLowerCase()] = function(b) {
  1437. return !!a.data(b, e)
  1438. }, a[j] = a[j] || {}, f = a[j][b], g = a[j][b] = function(a, b) {
  1439. return this._createWidget ? void(arguments.length && this._createWidget(a, b)) : new g(a, b)
  1440. }, a.extend(g, f, {
  1441. version: d.version,
  1442. _proto: a.extend({}, d),
  1443. _childConstructors: []
  1444. }), h = new c, h.options = a.widget.extend({}, h.options), a.each(d, function(b, d) {
  1445. return a.isFunction(d) ? void(i[b] = function() {
  1446. var a = function() {
  1447. return c.prototype[b].apply(this, arguments)
  1448. },
  1449. e = function(a) {
  1450. return c.prototype[b].apply(this, a)
  1451. };
  1452. return function() {
  1453. var b, c = this._super,
  1454. f = this._superApply;
  1455. return this._super = a, this._superApply = e, b = d.apply(this, arguments), this._super = c, this._superApply = f, b
  1456. }
  1457. }()) : void(i[b] = d)
  1458. }), g.prototype = a.widget.extend(h, {
  1459. widgetEventPrefix: f ? h.widgetEventPrefix : b
  1460. }, i, {
  1461. constructor: g,
  1462. namespace: j,
  1463. widgetName: b,
  1464. widgetFullName: e
  1465. }), f ? (a.each(f._childConstructors, function(b, c) {
  1466. var d = c.prototype;
  1467. a.widget(d.namespace + "." + d.widgetName, g, c._proto)
  1468. }), delete f._childConstructors) : c._childConstructors.push(g), a.widget.bridge(b, g)
  1469. }, a.widget.extend = function(c) {
  1470. for (var e, f, g = d.call(arguments, 1), h = 0, i = g.length; i > h; h++)
  1471. for (e in g[h]) f = g[h][e], g[h].hasOwnProperty(e) && f !== b && (a.isPlainObject(f) ? c[e] = a.isPlainObject(c[e]) ? a.widget.extend({}, c[e], f) : a.widget.extend({}, f) : c[e] = f);
  1472. return c
  1473. }, a.widget.bridge = function(c, e) {
  1474. var f = e.prototype.widgetFullName || c;
  1475. a.fn[c] = function(g) {
  1476. var h = "string" == typeof g,
  1477. i = d.call(arguments, 1),
  1478. j = this;
  1479. return g = !h && i.length ? a.widget.extend.apply(null, [g].concat(i)) : g, h ? this.each(function() {
  1480. var d, e = a.data(this, f);
  1481. return e ? a.isFunction(e[g]) && "_" !== g.charAt(0) ? (d = e[g].apply(e, i), d !== e && d !== b ? (j = d && d.jquery ? j.pushStack(d.get()) : d, !1) : void 0) : a.error("no such method '" + g + "' for " + c + " widget instance") : a.error("cannot call methods on " + c + " prior to initialization; attempted to call method '" + g + "'")
  1482. }) : this.each(function() {
  1483. var b = a.data(this, f);
  1484. b ? b.option(g || {})._init() : a.data(this, f, new e(g, this))
  1485. }), j
  1486. }
  1487. }, a.Widget = function() {}, a.Widget._childConstructors = [], a.Widget.prototype = {
  1488. widgetName: "widget",
  1489. widgetEventPrefix: "",
  1490. defaultElement: "<div>",
  1491. options: {
  1492. disabled: !1,
  1493. create: null
  1494. },
  1495. _createWidget: function(b, d) {
  1496. d = a(d || this.defaultElement || this)[0], this.element = a(d), this.uuid = c++, this.eventNamespace = "." + this.widgetName + this.uuid, this.options = a.widget.extend({}, this.options, this._getCreateOptions(), b), this.bindings = a(), this.hoverable = a(), this.focusable = a(), d !== this && (a.data(d, this.widgetFullName, this), this._on(!0, this.element, {
  1497. remove: function(a) {
  1498. a.target === d && this.destroy()
  1499. }
  1500. }), this.document = a(d.style ? d.ownerDocument : d.document || d), this.window = a(this.document[0].defaultView || this.document[0].parentWindow)), this._create(), this._trigger("create", null, this._getCreateEventData()), this._init()
  1501. },
  1502. _getCreateOptions: a.noop,
  1503. _getCreateEventData: a.noop,
  1504. _create: a.noop,
  1505. _init: a.noop,
  1506. destroy: function() {
  1507. this._destroy(), this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(a.camelCase(this.widgetFullName)), this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName + "-disabled ui-state-disabled"), this.bindings.unbind(this.eventNamespace), this.hoverable.removeClass("ui-state-hover"), this.focusable.removeClass("ui-state-focus")
  1508. },
  1509. _destroy: a.noop,
  1510. widget: function() {
  1511. return this.element
  1512. },
  1513. option: function(c, d) {
  1514. var e, f, g, h = c;
  1515. if (0 === arguments.length) return a.widget.extend({}, this.options);
  1516. if ("string" == typeof c)
  1517. if (h = {}, e = c.split("."), c = e.shift(), e.length) {
  1518. for (f = h[c] = a.widget.extend({}, this.options[c]), g = 0; g < e.length - 1; g++) f[e[g]] = f[e[g]] || {}, f = f[e[g]];
  1519. if (c = e.pop(), d === b) return f[c] === b ? null : f[c];
  1520. f[c] = d
  1521. } else {
  1522. if (d === b) return this.options[c] === b ? null : this.options[c];
  1523. h[c] = d
  1524. }
  1525. return this._setOptions(h), this
  1526. },
  1527. _setOptions: function(a) {
  1528. var b;
  1529. for (b in a) this._setOption(b, a[b]);
  1530. return this
  1531. },
  1532. _setOption: function(a, b) {
  1533. return this.options[a] = b, "disabled" === a && (this.widget().toggleClass(this.widgetFullName + "-disabled ui-state-disabled", !!b).attr("aria-disabled", b), this.hoverable.removeClass("ui-state-hover"), this.focusable.removeClass("ui-state-focus")), this
  1534. },
  1535. enable: function() {
  1536. return this._setOption("disabled", !1)
  1537. },
  1538. disable: function() {
  1539. return this._setOption("disabled", !0)
  1540. },
  1541. _on: function(b, c, d) {
  1542. var e, f = this;
  1543. "boolean" != typeof b && (d = c, c = b, b = !1), d ? (c = e = a(c), this.bindings = this.bindings.add(c)) : (d = c, c = this.element, e = this.widget()), a.each(d, function(d, g) {
  1544. function h() {
  1545. return b || f.options.disabled !== !0 && !a(this).hasClass("ui-state-disabled") ? ("string" == typeof g ? f[g] : g).apply(f, arguments) : void 0
  1546. }
  1547. "string" != typeof g && (h.guid = g.guid = g.guid || h.guid || a.guid++);
  1548. var i = d.match(/^(\w+)\s*(.*)$/),
  1549. j = i[1] + f.eventNamespace,
  1550. k = i[2];
  1551. k ? e.delegate(k, j, h) : c.bind(j, h)
  1552. })
  1553. },
  1554. _off: function(a, b) {
  1555. b = (b || "").split(" ").join(this.eventNamespace + " ") + this.eventNamespace, a.unbind(b).undelegate(b)
  1556. },
  1557. _delay: function(a, b) {
  1558. function c() {
  1559. return ("string" == typeof a ? d[a] : a).apply(d, arguments)
  1560. }
  1561. var d = this;
  1562. return setTimeout(c, b || 0)
  1563. },
  1564. _hoverable: function(b) {
  1565. this.hoverable = this.hoverable.add(b), this._on(b, {
  1566. mouseenter: function(b) {
  1567. a(b.currentTarget).addClass("ui-state-hover")
  1568. },
  1569. mouseleave: function(b) {
  1570. a(b.currentTarget).removeClass("ui-state-hover")
  1571. }
  1572. })
  1573. },
  1574. _focusable: function(b) {
  1575. this.focusable = this.focusable.add(b), this._on(b, {
  1576. focusin: function(b) {
  1577. a(b.currentTarget).addClass("ui-state-focus")
  1578. },
  1579. focusout: function(b) {
  1580. a(b.currentTarget).removeClass("ui-state-focus")
  1581. }
  1582. })
  1583. },
  1584. _trigger: function(b, c, d) {
  1585. var e, f, g = this.options[b];
  1586. if (d = d || {}, c = a.Event(c), c.type = (b === this.widgetEventPrefix ? b : this.widgetEventPrefix + b).toLowerCase(), c.target = this.element[0], f = c.originalEvent)
  1587. for (e in f) e in c || (c[e] = f[e]);
  1588. return this.element.trigger(c, d), !(a.isFunction(g) && g.apply(this.element[0], [c].concat(d)) === !1 || c.isDefaultPrevented())
  1589. }
  1590. }, a.each({
  1591. show: "fadeIn",
  1592. hide: "fadeOut"
  1593. }, function(b, c) {
  1594. a.Widget.prototype["_" + b] = function(d, e, f) {
  1595. "string" == typeof e && (e = {
  1596. effect: e
  1597. });
  1598. var g, h = e ? e === !0 || "number" == typeof e ? c : e.effect || c : b;
  1599. e = e || {}, "number" == typeof e && (e = {
  1600. duration: e
  1601. }), g = !a.isEmptyObject(e), e.complete = f, e.delay && d.delay(e.delay), g && a.effects && a.effects.effect[h] ? d[b](e) : h !== b && d[h] ? d[h](e.duration, e.easing, f) : d.queue(function(c) {
  1602. a(this)[b](), f && f.call(d[0]), c()
  1603. })
  1604. }
  1605. })
  1606. }),
  1607. function(a) {
  1608. "function" == typeof define && define.amd ? define(["jquery"], a) : a(jQuery)
  1609. }(function(a) {
  1610. var b = {
  1611. wheelSpeed: 10,
  1612. wheelPropagation: !1,
  1613. minScrollbarLength: null,
  1614. useBothWheelAxes: !1,
  1615. useKeyboard: !0,
  1616. suppressScrollX: !1,
  1617. suppressScrollY: !1,
  1618. scrollXMarginOffset: 0,
  1619. scrollYMarginOffset: 0,
  1620. onscrollCallback: !1
  1621. };
  1622. a.fn.perfectScrollbar = function(c, d) {
  1623. return this.each(function() {
  1624. var e = a.extend(!0, {}, b),
  1625. f = a(this);
  1626. if ("object" == typeof c ? a.extend(!0, e, c) : d = c, "update" === d) return f.data("perfect-scrollbar-update") && f.data("perfect-scrollbar-update")(), f;
  1627. if ("destroy" === d) return f.data("perfect-scrollbar-destroy") && f.data("perfect-scrollbar-destroy")(), f;
  1628. if (f.data("perfect-scrollbar")) return f.data("perfect-scrollbar");
  1629. f.addClass("ps-container");
  1630. var g, h, i, j, k, l, m, n, o, p, q = a("<div class='ps-scrollbar-x-rail'></div>").appendTo(f),
  1631. r = a("<div class='ps-scrollbar-y-rail'></div>").appendTo(f),
  1632. s = a("<div class='ps-scrollbar-x'></div>").appendTo(q),
  1633. t = a("<div class='ps-scrollbar-y'></div>").appendTo(r),
  1634. u = parseInt(q.css("bottom"), 10),
  1635. v = parseInt(r.css("right"), 10),
  1636. w = function(a, b) {
  1637. var c = a + b,
  1638. d = j - o;
  1639. p = 0 > c ? 0 : c > d ? d : c;
  1640. var e = parseInt(p * (l - j) / (j - o), 10);
  1641. f.scrollTop(e), q.css({
  1642. bottom: u - e
  1643. })
  1644. },
  1645. x = function(a, b) {
  1646. var c = a + b,
  1647. d = i - m;
  1648. n = 0 > c ? 0 : c > d ? d : c;
  1649. var e = parseInt(n * (k - i) / (i - m), 10);
  1650. f.scrollLeft(e), r.css({
  1651. right: v - e
  1652. })
  1653. },
  1654. y = function(a) {
  1655. return e.minScrollbarLength && (a = Math.max(a, e.minScrollbarLength)), a
  1656. },
  1657. z = function() {
  1658. q.css({
  1659. left: f.scrollLeft(),
  1660. bottom: u - f.scrollTop(),
  1661. width: i,
  1662. display: e.suppressScrollX ? "none" : "inherit"
  1663. }), r.css({
  1664. top: f.scrollTop(),
  1665. right: v - f.scrollLeft(),
  1666. height: j,
  1667. display: e.suppressScrollY ? "none" : "inherit"
  1668. }), s.css({
  1669. left: n,
  1670. width: m
  1671. }), t.css({
  1672. top: p,
  1673. height: o
  1674. })
  1675. },
  1676. A = function() {
  1677. i = f.width(), j = f.height(), k = f.prop("scrollWidth"), l = f.prop("scrollHeight"), !e.suppressScrollX && i + e.scrollXMarginOffset < k ? (g = !0, m = y(parseInt(i * i / k, 10)), n = parseInt(f.scrollLeft() * (i - m) / (k - i), 10)) : (g = !1, m = 0, n = 0, f.scrollLeft(0)), !e.suppressScrollY && j + e.scrollYMarginOffset < l ? (h = !0, o = y(parseInt(j * j / l, 10)), p = parseInt(f.scrollTop() * (j - o) / (l - j), 10)) : (h = !1, o = 0, p = 0, f.scrollTop(0)), p >= j - o && (p = j - o), n >= i - m && (n = i - m), z(), e.onscrollCallback && e.onscrollCallback.call(this, f.scrollTop(), l - j)
  1678. },
  1679. B = function() {
  1680. var b, c;
  1681. s.bind("mousedown.perfect-scrollbar", function(a) {
  1682. c = a.pageX, b = s.position().left, q.addClass("in-scrolling"), a.stopPropagation(), a.preventDefault()
  1683. }), a(document).bind("mousemove.perfect-scrollbar", function(a) {
  1684. q.hasClass("in-scrolling") && (x(b, a.pageX - c), a.stopPropagation(), a.preventDefault())
  1685. }), a(document).bind("mouseup.perfect-scrollbar", function(a) {
  1686. q.hasClass("in-scrolling") && q.removeClass("in-scrolling")
  1687. }), b = c = null
  1688. },
  1689. C = function() {
  1690. var b, c;
  1691. t.bind("mousedown.perfect-scrollbar", function(a) {
  1692. c = a.pageY, b = t.position().top, r.addClass("in-scrolling"), a.stopPropagation(), a.preventDefault()
  1693. }), a(document).bind("mousemove.perfect-scrollbar", function(a) {
  1694. r.hasClass("in-scrolling") && (w(b, a.pageY - c), a.stopPropagation(), a.preventDefault())
  1695. }), a(document).bind("mouseup.perfect-scrollbar", function(a) {
  1696. r.hasClass("in-scrolling") && r.removeClass("in-scrolling")
  1697. }), b = c = null
  1698. },
  1699. D = function(a, b) {
  1700. var c = f.scrollTop();
  1701. if (0 === a) {
  1702. if (!h) return !1;
  1703. if (0 === c && b > 0 || c >= l - j && 0 > b) return !e.wheelPropagation
  1704. }
  1705. var d = f.scrollLeft();
  1706. if (0 === b) {
  1707. if (!g) return !1;
  1708. if (0 === d && 0 > a || d >= k - i && a > 0) return !e.wheelPropagation
  1709. }
  1710. return !0
  1711. },
  1712. E = function() {
  1713. var a = !1;
  1714. f.bind("mousewheel.perfect-scrollbar", function(b, c, d, i) {
  1715. e.useBothWheelAxes ? h && !g ? i ? f.scrollTop(f.scrollTop() - i * e.wheelSpeed) : f.scrollTop(f.scrollTop() + d * e.wheelSpeed) : g && !h && (d ? f.scrollLeft(f.scrollLeft() + d * e.wheelSpeed) : f.scrollLeft(f.scrollLeft() - i * e.wheelSpeed)) : (f.scrollTop(f.scrollTop() - i * e.wheelSpeed), f.scrollLeft(f.scrollLeft() + d * e.wheelSpeed)), A(), a = D(d, i), a && b.preventDefault()
  1716. }), f.bind("MozMousePixelScroll.perfect-scrollbar", function(b) {
  1717. a && b.preventDefault()
  1718. })
  1719. },
  1720. F = function() {
  1721. var b = !1;
  1722. f.bind("mouseenter.perfect-scrollbar", function(a) {
  1723. b = !0
  1724. }), f.bind("mouseleave.perfect-scrollbar", function(a) {
  1725. b = !1
  1726. });
  1727. var c = !1;
  1728. a(document).bind("keydown.perfect-scrollbar", function(a) {
  1729. if (b) {
  1730. var d = 0,
  1731. g = 0;
  1732. switch (a.which) {
  1733. case 37:
  1734. d = -3;
  1735. break;
  1736. case 38:
  1737. g = 3;
  1738. break;
  1739. case 39:
  1740. d = 3;
  1741. break;
  1742. case 40:
  1743. g = -3;
  1744. break;
  1745. default:
  1746. return
  1747. }
  1748. f.scrollTop(f.scrollTop() - g * e.wheelSpeed), f.scrollLeft(f.scrollLeft() + d * e.wheelSpeed), c = D(d, g), c && a.preventDefault()
  1749. }
  1750. })
  1751. },
  1752. G = function() {
  1753. var a = function(a) {
  1754. a.stopPropagation()
  1755. };
  1756. t.bind("click.perfect-scrollbar", a), r.bind("click.perfect-scrollbar", function(a) {
  1757. var b = parseInt(o / 2, 10),
  1758. c = a.pageY - r.offset().top - b,
  1759. d = j - o,
  1760. e = c / d;
  1761. 0 > e ? e = 0 : e > 1 && (e = 1), f.scrollTop((l - j) * e)
  1762. }), s.bind("click.perfect-scrollbar", a), q.bind("click.perfect-scrollbar", function(a) {
  1763. var b = parseInt(m / 2, 10),
  1764. c = a.pageX - q.offset().left - b,
  1765. d = i - m,
  1766. e = c / d;
  1767. 0 > e ? e = 0 : e > 1 && (e = 1), f.scrollLeft((k - i) * e)
  1768. })
  1769. },
  1770. H = function() {
  1771. var b = function(a, b) {
  1772. f.scrollTop(f.scrollTop() - b), f.scrollLeft(f.scrollLeft() - a), A()
  1773. },
  1774. c = {},
  1775. d = 0,
  1776. e = {},
  1777. g = null,
  1778. h = !1;
  1779. a(window).bind("touchstart.perfect-scrollbar", function(a) {
  1780. h = !0
  1781. }), a(window).bind("touchend.perfect-scrollbar", function(a) {
  1782. h = !1
  1783. }), f.bind("touchstart.perfect-scrollbar", function(a) {
  1784. var b = a.originalEvent.targetTouches[0];
  1785. c.pageX = b.pageX, c.pageY = b.pageY, d = (new Date).getTime(), null !== g && clearInterval(g), a.stopPropagation()
  1786. }), f.bind("touchmove.perfect-scrollbar", function(a) {
  1787. if (!h && 1 === a.originalEvent.targetTouches.length) {
  1788. var f = a.originalEvent.targetTouches[0],
  1789. g = {};
  1790. g.pageX = f.pageX, g.pageY = f.pageY;
  1791. var i = g.pageX - c.pageX,
  1792. j = g.pageY - c.pageY;
  1793. b(i, j), c = g;
  1794. var k = (new Date).getTime();
  1795. e.x = i / (k - d), e.y = j / (k - d), d = k, a.preventDefault()
  1796. }
  1797. }), f.bind("touchend.perfect-scrollbar", function(a) {
  1798. clearInterval(g), g = setInterval(function() {
  1799. return Math.abs(e.x) < .01 && Math.abs(e.y) < .01 ? void clearInterval(g) : (b(30 * e.x, 30 * e.y), e.x *= .8, void(e.y *= .8))
  1800. }, 10)
  1801. })
  1802. },
  1803. I = function() {
  1804. f.bind("scroll.perfect-scrollbar", function(a) {
  1805. A()
  1806. })
  1807. },
  1808. J = function() {
  1809. f.unbind(".perfect-scrollbar"), a(window).unbind(".perfect-scrollbar"), a(document).unbind(".perfect-scrollbar"), f.data("perfect-scrollbar", null), f.data("perfect-scrollbar-update", null), f.data("perfect-scrollbar-destroy", null), s.remove(), t.remove(), q.remove(), r.remove(), s = t = i = j = k = l = m = n = u = o = p = v = null
  1810. },
  1811. K = function(b) {
  1812. f.addClass("ie").addClass("ie" + b);
  1813. var c = function() {
  1814. var b = function() {
  1815. a(this).addClass("hover")
  1816. },
  1817. c = function() {
  1818. a(this).removeClass("hover")
  1819. };
  1820. f.bind("mouseenter.perfect-scrollbar", b).bind("mouseleave.perfect-scrollbar", c), q.bind("mouseenter.perfect-scrollbar", b).bind("mouseleave.perfect-scrollbar", c), r.bind("mouseenter.perfect-scrollbar", b).bind("mouseleave.perfect-scrollbar", c), s.bind("mouseenter.perfect-scrollbar", b).bind("mouseleave.perfect-scrollbar", c), t.bind("mouseenter.perfect-scrollbar", b).bind("mouseleave.perfect-scrollbar", c)
  1821. },
  1822. d = function() {
  1823. z = function() {
  1824. s.css({
  1825. left: n + f.scrollLeft(),
  1826. bottom: u,
  1827. width: m
  1828. }), t.css({
  1829. top: p + f.scrollTop(),
  1830. right: v,
  1831. height: o
  1832. }), s.hide().show(), t.hide().show()
  1833. }
  1834. };
  1835. 6 === b && (c(), d())
  1836. },
  1837. L = "ontouchstart" in window || window.DocumentTouch && document instanceof window.DocumentTouch,
  1838. M = function() {
  1839. var a = navigator.userAgent.toLowerCase().match(/(msie) ([\w.]+)/);
  1840. a && "msie" === a[1] && K(parseInt(a[2], 10)), A(), I(), B(), C(), G(), L && H(), f.mousewheel && E(), e.useKeyboard && F(), f.data("perfect-scrollbar", f), f.data("perfect-scrollbar-update", A), f.data("perfect-scrollbar-destroy", J)
  1841. };
  1842. return M(), f
  1843. })
  1844. }
  1845. }), Dubtrack.Events = {}, _.extend(Dubtrack.Events, Backbone.Events), Dubtrack.realtime = {
  1846. channel: null,
  1847. dtPubNub: null,
  1848. init: function() {
  1849. var a = null;
  1850. return a = Dubtrack.loggedIn ? Dubtrack.session.get("_id") : PUBNUB.uuid(), Dubtrack.realtime.dtPubNub = PUBNUB.init({
  1851. backfill: !1,
  1852. publish_key: "",
  1853. subscribe_key: Dubtrack.config.keys.pubunub,
  1854. ssl: !0,
  1855. uuid: a
  1856. }), this
  1857. },
  1858. destroy: function() {
  1859. null !== Dubtrack.realtime.channel && (Dubtrack.realtime.dtPubNub.unsubscribe({
  1860. channel: Dubtrack.realtime.channel
  1861. }), Dubtrack.realtime.channel = null, Dubtrack.realtime.dtPubNub = null)
  1862. },
  1863. channelPresence: function(a) {
  1864. null !== Dubtrack.realtime.channel && (null === Dubtrack.realtime.dtPubNub && Dubtrack.realtime.init(), Dubtrack.realtime.dtPubNub.here_now({
  1865. channel: Dubtrack.realtime.channel,
  1866. callback: a
  1867. }))
  1868. },
  1869. subscribe: function(a, b, c) {
  1870. if (null === Dubtrack.realtime.dtPubNub ? Dubtrack.realtime.init() : Dubtrack.realtime.destroy(), void 0 === a || null === a || "" === a) throw new Error("Cannot connect to empty channel");
  1871. Dubtrack.realtime.channel = a, Dubtrack.loggedIn && (a = Dubtrack.realtime.channel + ",dubtrackuser-" + Dubtrack.session.get("_id")), Dubtrack.realtime.dtPubNub.subscribe({
  1872. channel: a,
  1873. callback: function(a) {
  1874. Dubtrack.realtime.callback(a)
  1875. },
  1876. presence: function(a) {
  1877. a.type = "pubnub-" + (a.type ? a.type : "presence"), Dubtrack.realtime.callback(a)
  1878. },
  1879. disconnect: function() {},
  1880. reconnect: function() {},
  1881. connect: function() {
  1882. b && b()
  1883. },
  1884. error: function(a) {}
  1885. })
  1886. },
  1887. callback: function(a) {
  1888. a.type && Dubtrack.Events.trigger("realtime:" + a.type, a)
  1889. }
  1890. }, Dubtrack.els.templates = {
  1891. messages: {
  1892. message: '<div class="image-container"><%= image_str %></div><div class="message-content"><h3><%- name %></h3><p><%- latest_message_str %></p></div><div class="message-time"><%- latest_message %></div>',
  1893. messageItem: '<figure class="media"><%= Dubtrack.helpers.image.getImage(_user._id, _user.username) %></figure><div class="message-content"><h3><%- _user.username %>: </h3><p><%= message %></p></div><div class="message-time"><%- created %></div>'
  1894. },
  1895. comments: {
  1896. commentsContainer: '<% if(Dubtrack.loggedIn) { %><section class="post-comment-container"><figure><%= Dubtrack.helpers.image.getImage(Dubtrack.session.id, Dubtrack.session.username) %></figure><div class="comments-textarea-container"><textarea placeholder="Leave a message..."></textarea><button>Post a comment</button></div></section><% } %><div class="comments-list"></div><button class="comments-display-all">Display all comments</button>',
  1897. commentsItem: '<figure><%= Dubtrack.helpers.image.getImage(user._id, user.username) %></figure><div class="content"><header><a href="#" class="username"><%- user.username %></a><i class="icon-dot"></i><time class="timeago" datetime="<%- date.toISOString() %>"><%- date.toLocaleString() %></time></header><div class="comment-content"><p><%- comment %></p></div><div class="comment-dub"><span class="comment-dubs-total"><%- updubs - downdubs %></span><span class="icon-arrow-up"></span><span>|</span><span class="icon-arrow-down"></span><% if(Dubtrack.session && Dubtrack.session.id == userid) { %><a href="#" class="delete">delete</a><% } %></div></div><a href="#" class="icon-flag"></a>'
  1898. },
  1899. search: {
  1900. searchRoom: ' <img src="' + Dubtrack.config.apiUrl + '/room/<%- _id %>/image/thumbnail-small" alt="" /><span><%- name %></span><span class="count"><%- activeUsers %> users</span>',
  1901. searchUser: " <%= Dubtrack.helpers.image.getImage(_id, username) %><span><%= username %></span>"
  1902. },
  1903. profile: {
  1904. popover: '<div class="usercontent"></div><div class="global-actions"><a href="#" class="send-pm-message" title="Send private message"><span class="icon-chat"></span></a><a href="#" class="chat-mention" title="Mention in chat">@</a></div><div class="actions"><a href="#" class="kick">Kick</a><a href="#" class="ban">Ban for <input type="text" value="" maxlength="3" /> minutes</a><a href="#" class="mute">Mute</a><a href="#" class="unmute">Unmute</a><a href="#" class="setowner setrole" data-roleref="setOwnerUser">Set co-owner</a><a href="#" class="unsetowner unsetrole" data-roleref="setOwnerUser">Unset co-owner</a><a href="#" class="setmanager setrole" data-roleref="setManagerUser">Set manager</a><a href="#" class="unsetmanager unsetrole" data-roleref="setManagerUser">Unset manager</a><a href="#" class="setmod setrole" data-roleref="setModUser">Set mod</a><a href="#" class="unsetmod unsetrole" data-roleref="setModUser">Unset mod</a><a href="#" class="setvip setrole" data-roleref="setVIPUser">Set VIP</a><a href="#" class="unsetvip unsetrole" data-roleref="setVIPUser">Unset VIP</a><a href="#" class="setresdj setrole" data-roleref="setDJUser">Set Resident DJ</a><a href="#" class="unsetresdj unsetrole" data-roleref="setDJUser">Unset Resident DJ</a><a href="#" class="setdj setrole" data-roleref="setRoomDJUser">Set DJ</a><a href="#" class="unsetdj unsetrole" data-roleref="setRoomDJUser">Unset DJ</a></div>',
  1905. popover_user: '<figure><img src="' + Dubtrack.config.apiUrl + '/user/<%- _id %>/image" alt="" /></figure><header><h3><%- username %></h3><span class="dubs"></span></header>',
  1906. profileSidebar: '<div id="profileSidebar"><div id="followersEl"><div class="followingContainer"><div class="followers-counter">Followers<span class="total-followers"></span></div><ul class="avatarList clearfix avatarFollower"></ul></div></div></div>',
  1907. profileView: '<div class="profileWrapper"><div class="profileView"><div class="rewindProfile"><a href="#"><span class="icon-close"></span></a></div><div class="header"><div class="pictureContainer"><% if(Dubtrack.session && Dubtrack.session.id === _id) { %><a class="updatePictureGif" href="#"><span class="icon-camera"></span></a><% } %><%= imgProfile %></div><div class="descriptionProfile"></div></div><div class="infoProfile"><h2><span class="usernameContainer"><%- username %></span><% if(Dubtrack.session && Dubtrack.session.id === _id) { %><input type="text" name="dt_username" value="<%- username %>" maxlength="30" /><div class="check_username_info"></div><span class="edit-btn editUsername">edit</span><span class="edit-btn saveUsername">save</span><span class="edit-btn cancelUsername">cancel</span><% } %></h2><% if(Dubtrack.session && Dubtrack.session.id !== _id) { %><button class="follow follow-btn message"><i class="icon-user"></i> ' + dubtrack_lang.profile.follow + '</button><button class="unfollow follow-btn message">' + dubtrack_lang.profile.unfollow + "</button><% } %></div></div></div>"
  1908. },
  1909. help: {
  1910. chat: '<div class="modal help" id="maindthelp"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button><h3>' + dubtrack_lang.help.chat_commands + '</h3></div><div class="modal-body chat-mod-help clearfix"><p class="clearfix"><b>/skip</b><span>' + dubtrack_lang.help.skip + '</span></p><p class="clearfix"><b>/kick @username</b><span>' + dubtrack_lang.help.kick + "</span><b>/kick @username||#</b><span>" + dubtrack_lang.help.kick_time + "</span><b>/ban @username</b><span>" + dubtrack_lang.help.ban + '</span></p><p class="clearfix"><b>/setmod @username</b><span>' + dubtrack_lang.help.set_mod + "</span><b>/removemod @username</b><span>" + dubtrack_lang.help.remove_mod + '</span></p><p class="clearfix"><b>/setdjcount #</b><span>' + dubtrack_lang.help.set_dj_count + "</span><b>/setdj @username</b><span>" + dubtrack_lang.help.set_dj + "</span><b>/removedj @username</b><span>" + dubtrack_lang.help.remove_dj + '</span></p></div><div class="modal-footer"><a href="#" class="btn btn-close">' + dubtrack_lang.help.close + "</a></div>"
  1911. },
  1912. rooms: {
  1913. roomModalView: '<div class="room-info-display-container"><h2><%- name %><span>hosted by <i><%- _user.username %></i></span></h2><div class="description"><%= description %></div></div>',
  1914. roomFormUpdate: ' <form class="form-horizontal"><span class="closebtn icon-close"></span><div class="modal-header mainForm"><h3>' + dubtrack_lang.roomForm.formLabel + '</h3></div><div class="mid"><div class="control-group"><label class="control-label display-block">' + dubtrack_lang.roomForm.roomNameLabel + '</label><div class="controls"><input class="input" name="name" id="roomName" placeholder="' + dubtrack_lang.roomForm.roomNameLabel + '" type="text" value="<%- name %>" maxlength="100"></div></div><div class="control-group" id="background-room-update"><label class="control-label display-block">Room background</label><div class="controls"><input id="fileupload" type="file" name="room_bg"><div id="progress"><div class="bar" style="width: 0%;"></div></div></div></div><div class="larger control-group"><label class="control-label display-block">' + dubtrack_lang.roomForm.roomDescLabel + '</label><div class="controls textarea"><textarea class="textarea" id="roomDescription" name="description" placeholder="' + dubtrack_lang.roomForm.roomDesc + '" maxlength="2000"><%- description %></textarea></div></div><div class="larger control-group"><label class="control-label display-block">Welcome message (you can use {username} and {roomname} as variables :])</label><div class="controls textarea"><textarea class="textarea mid-textarea" id="welcomeMessage" name="welcomeMessage" placeholder="Welcome message" maxlength="300"><%- welcomeMessage %></textarea></div></div><div class="larger control-group"><label class="control-label display-block">Metadata description (this will be shown on social media sites and google search engines)</label><div class="controls textarea"><textarea class="textarea mid-textarea" id="metaDescription" name="metaDescription" placeholder="Metadata description" maxlength="255"><%- metaDescription %></textarea></div></div><div class="control-group"><label class="control-label display-block">Lock queue</label><div class="controls textarea"><select name="lockQueue" id="lockQueueSelect"><option value="1"<% if(lockQueue){%> selected<%}%>>Yes</option><option value="0"<% if(!lockQueue){%> selected<%}%>>No</option></select></div><label class="control-label display-block">Room Type</label><div class="controls textarea"><select name="roomType" id="roomTypeSelect"><option value="room"<% if(roomType && roomType == "room"){%> selected<%}%>>Dubtrack</option><option value="iframe"<% if(roomType && roomType == "iframe"){%> selected<%}%>>Iframe Embed</option></select></div></div><div class="control-group" id="iframeEmbedField"><label class="control-label">Iframe embed url (src value in your embed code)</label><div class="controls textarea"><textarea class="textarea" name="roomEmbed" id="roomEmbedInput" placeholder="Iframe embed url (src value in your embed code)"><%- roomEmbed %></textarea></div><div id="iframe-embed-preview"></div></div></div><div class="modal-footer mainForm"><button class="btn cancel">' + dubtrack_lang.profile.cancel + '</button><button class="btn btn-primary" data-loading-text="' + dubtrack_lang.global.loading + '">' + dubtrack_lang.roomForm.save + "</button></div></form>",
  1915. roomListItem: '<figure class="roomImage"><% if(currentSong && currentSong.songid){ %><img src="' + Dubtrack.config.apiUrl + '/song/<%- currentSong.songid %>/image/large" alt="" /><% } else { %><img src="' + Dubtrack.config.apiUrl + '/room/<%- _id %>/image/thumbnail" alt="" /><% } %><a class="join" href="/join/<%- roomUrl %>"><span>' + dubtrack_lang.room.tune_in + '</span></a></figure><div class="user-count"><% if(activeUsers) { %><span class="icon-people"></span><%- activeUsers %><% } %></div><header><div class="description"><span class="name"><%- name %></span></div><div class="user-info"><div class="room-user">' + dubtrack_lang.room.hosted_by + '<a href="/<%- userid %>" class="navigate"></a></div></div></header><span class="current-song"><% if(currentSong && currentSong.name){ %><%- currentSong.name %><% } else { %>Go ahead, play a song!<% } %></span>',
  1916. avatarsContainer: '<div class="loadingAva">' + dubtrack_lang.global.loading + '</div><div class="avatar_tools"><div class="input-room-users-search"><input type="text" name="room-users-search" placeholder="Filter room users"></div></div><div class="tabsContainer"><div class="tabItem" id="main-user-list-room"><ul class="avatar-list" id="avatar-list"></ul></div></div>',
  1917. avatarsContainerItem: '<p class="username"></p><p class="dubs"><span><%- dubs %> </span> dubs</p>',
  1918. roomBanListItem: '<%- _user.username %><span class="actions">unban</span>',
  1919. roomMuteListItem: '<%- _user.username %><span class="actions">unmute</span>',
  1920. roomStaffListItem: '<%- _user.username %> - <%- roleid.label %><% if (Dubtrack.room.model.get("userid") != _user._id) { %><span class="actions">remove role</span><% } %>'
  1921. },
  1922. chat: {
  1923. chatContainer: '<div class="chat_tools"><span class="display-chat icon-chat active"></span><span class="display-room-users icon-people"><i class="room-user-counter"></i><i class="room-guest-counter"></i></span><span class="display-chat-settings icon-chatsettings"></span></div><div class="chat-options"><span class="chat-option-header">Chat display</span><div class="chat-option-buttons chat-option-buttons-display"><span class="hideImagesToggle">Hide Images</span><span class="clearChatToggle">Clear chat</span></div><span class="chat-option-header">Sound notifications</span><div class="chat-option-buttons chat-option-buttons-sound"><span class="setOnChatNotifications"><i class="icon-volume-high"></i> On</span><span class="setMentionChatNotifications"><i class="icon-volume-high"></i> @Mention</span><span class="setOffChatNotifications"><i class="icon-volume-mute"></i> Off</span></div></div><div class="chat-container"><div class="chatLoading">' + dubtrack_lang.chat.loadingHistory + '</div><div class="hidden" id="sound-notification"></div><div class="chat-messages"><ul class="chat-main"></ul></div><div class="pusher-chat-widget-input"><div id="new-messages-counter"><span class="messages-display"></span> <i class="icon-arrow-down2"></i></div><% if(Dubtrack.loggedIn) { %><input id="chat-txt-message" name="message" type="text" placeholder= "' + dubtrack_lang.chat.type_message + '" autocomplete="off" maxlength="255"><span class="icon-camera"></span><button class= "pusher-chat-widget-send-btn"><span class="icon-arrow-right2"></span></button><% } else { %><div class="chatLogin">' + dubtrack_lang.chat.login_message + "</div><% } %></div></div>",
  1924. chatMessage: '<div class="stream-item-content"><div class="chatDelete"><span class="icon-close"></span></div><div class="image_row"><%= Dubtrack.helpers.image.getImage(user._id, user.username, false, true) %></div><div class="activity-row"><div class="text"><p><a href="#" class="username"><%- user.username %></a> <%= message %></p></div><div class="meta-info"><span class="username"><%- user.username %> </span><i class="icon-dot"></i><span class="timeinfo"></span></div></div></div>'
  1925. },
  1926. playlist: {
  1927. previewContainer: '<div class="close"><span class="icon-close"></span></div><div class="playerDubContainer"></div><div class="comments-container"></div>',
  1928. playlistContainer: '<div class="create-playlist-header">Add to playlist <span class="icon-close"></span></div><div class="create-playlist-input"><input type="text" placeholder="' + dubtrack_lang.playlist.create + '" class="playlist-input" id="playlist-input" maxlength="50" /><span class="icon-add"></span></div><ul class="playlist-list-action"></ul>',
  1929. playlistBrowser: '<%- name %> <span class="playlist-items-count"><%- totalItems %></span>',
  1930. playlistSearchBrowser: '<div class="description"><span><i class="icon-search"></i> <%- name %></span></div>',
  1931. playlistHistoryBrowser: '<div class="description"><input type="text" class="playlist_filter" placeholder="Filter history" value=""></div>',
  1932. playlistInfo: '<div class="description"><input type="text" class="editplaylist_name" placeholder="Playlist name" value="<%- name %>" value="" /><span class="icon-save save-playlistname"></span><input type="text" class="playlist_filter" placeholder="' + dubtrack_lang.playlist.filter + '" value="" /></div><div class="right"><a href="#" class="icon-shuffle shuffle-playlist tt-wrapper"></a><a href="#" class="icon-editplaylist edit-playlist-name tt-wrapper"></a><a href="#" class="icon-trash delete-playlist tt-wrapper"></a><a href="#" class="playlist_type tt-wrapper"></a><a href="#" class="text-button queue-playlist">Queue all</a></div>',
  1933. roomQueueInfo: '<div class="description"><input type="text" class="playlist_filter" placeholder="Filter queue" value="" /></div><div class="right"><a href="#" class="icon-lock room-queue-lock tt-wrapper"></a><a href="#" class="icon-unlocked room-queue-unlock tt-wrapper"></a></div>',
  1934. myQueueInfo: '<div class="description"><input type="text" class="playlist_filter" placeholder="Filter queue" value="" /></div><div class="right"><a href="#" class="icon-shuffle shuffle-playlist tt-wrapper"></a><a href="#" class="text-button clear-queue clear-queue-browser-bth">Clear</a><a href="#" class="text-button pause-queue pause-queue-browser-bth">Pause</a></div>',
  1935. playlistSearchItem: ' <span class="display-error"></span><span class="display-success"></span><span class="timeDisplay"><%- minute %>:<%- second %></span><figure><% if(images.thumbnail) {%><img src="<%- images.thumbnail %>" alt="" /><% } else {%><img src="' + Dubtrack.config.urls.mediaBaseUrl + '/assets/images/media/pic_notfound.jpg" alt="" /><% } %></figure><div class="description"><h2><%- name %></h2><p><span class="preview">' + dubtrack_lang.playlist.preview + '</span></p></div><div class="actions"><a href="#" class="img_bg add_to_queue"><span class="icon-play"></span></a><a class="img_bg add_to_playlist" href="#"><span class="icon-heart"></span></a><a href="#" class="set_song_to_top_queue"><span class="icon-angle-double-up"></span></a><a href="#" class="img_bg remove_icon"><span class="icon-trash"></span></a></div>',
  1936. playlistHistoryItem: '<span class="display-error"></span><span class="timeDisplay"><%- minute %>:<%- second %></span><figure><% if(images.thumbnail) {%><img src="<%- images.thumbnail %>" alt="" /><% } else {%><img src="' + Dubtrack.config.urls.mediaBaseUrl + '/assets/images/media/pic_notfound.jpg" alt="" /><% } %></figure><div class="description"><h2><%- name %></h2><p><span class="preview">' + dubtrack_lang.playlist.preview + '</span><% if (_user) { %><span class="playedby">Played by <b><%- _user.username %></b></span><span class="dubs-display">updubs <b><%- updubs %></b> | downdubs <b><%- downdubs %></b> | grabs <b><%- grabs %></b></span><span class="timeinfo"></span><% if(skipped) { %><span class="skipped">skipped</span><% } %><% } %></p></div><div class="actions"><a href="#" class="img_bg add_to_queue"><span class="icon-play"></span></a><a class="img_bg add_to_playlist" href="#"><span class="icon-heart"></span></a></div>',
  1937. playlistRoomQueueItem: '<span class="display-error"></span><span class="timeDisplay"><%- minute %>:<%- second %></span><figure><% if(images.thumbnail) {%><img src="<%- images.thumbnail %>" alt="" /><% } else {%><img src="' + Dubtrack.config.urls.mediaBaseUrl + '/assets/images/media/pic_notfound.jpg" alt="" /><% } %></figure><div class="description"><h2><%- name %></h2><p><span class="preview">' + dubtrack_lang.playlist.preview + '</span><span class="playedby">Queued by <b><%- _user.username %></b></span></p></div><div class="actions"><a href="#" class="set_song_to_top_queue"><span class="icon-angle-double-up"></span></a><a href="#" class="text-button remove_dj_all">Remove DJ</a><a class="img_bg add_to_playlist" href="#"><span class="icon-heart"></span></a><a href="#" class="img_bg remove_dj"><span class="icon-trash"></span></a></div>'
  1938. },
  1939. layout: {
  1940. header: '<div id="header_login"><a href="/login" id="login-link">LOGIN</a> | <a href="/signup" id="signup-link">SIGN UP</a></div><% if(Dubtrack.loggedIn) {%><div class="header-right-navigation"><div class="user-info"><span><%- username %></span><figure class="user-image"><%= Dubtrack.helpers.image.getImage(_id, username) %></figure></div><div class="user-messages"><span class="message-counter"></span><span class="icon-message"></span></div></div><% } %>',
  1941. soundCloudImportItem: '<%- title %><i class="total-items"><%- total_tracks %></i>',
  1942. browser: '<div class="browser-content"><div id="import-playlist-container"><span class="close-import-playlist icon-close"></span><h3>Import playlists</h3><div class="playlist-type-select playlist-tab-import-active"><span class="icon-youtube import-youtube"></span><span class="icon-soundcloud import-soundcloud"></span></div><div class="import-playlist-youtube"><div class="loading-import">Importing playlist....</div><div class="err-message"></div><input class="youtube-username" placeholder="Youtube playlist ID" /><select class="playlist-select" name="playlist-id"></select><span class="import-playlist icon-inbox">Import</span></div><div class="import-playlist-soundcloud"><div class="loading-import">Importing playlist....</div><div class="err-message"></div><input class="soundcloud-username" placeholder="Soundcloud username" /><div class="playlist-container"><ul></ul></div><select class="playlist-select" name="playlist-id"></select><span class="import-playlist icon-inbox">Import</span></div></div><div class="browser-content-header"><span class="close-browser icon-downvote"></span><div class="form"><input type="text" class="placeholder" name="youtube-search" id="youtube-search" value="" placeholder="' + dubtrack_lang.global.search + '" /><a href="#" class="search-btn"><span class="icon-arrow-right2"></span></a><div class="music-type-select"><span class="current-music-type-selection"><i class="icon-youtube"></i></span><span class="icon-arrow-dropdown"></span><div class="music-type-dropdown"><span class="icon-youtube youtube-btn"></span><span class="icon-soundcloud" id="soundcloud-btn"></span></div></div></div><a href="#" class="close"><span class="icon-remove-circle"></span></a></div><div class="browser-content-main"><div class="sidebar"><div class="display-sidebar"><span class="icon-playlist"></span></div><div class="import-playlist"><span class="icon-inbox"></span> Import playlists</div><div class="create-playlist"><div class="create-playlist-display"><span class="icon-createplaylist"></span> Create playlist</div><div class="create-playlist-form"><input type="text" placeholder="' + dubtrack_lang.playlist.create + '" maxlength="100" /><span class="icon-createplaylist"></span></div></div><div id="queue-next"></div><span class="title">Your playlists</span><div id="playlists-scroll"><ul class="playlist-style"><li class="current_queue"><span class="icon-play"></span>' + dubtrack_lang.playlist.your_queue + '<span class="playlist-items-count"></span></li><li class="current_room_queue"><span class="icon-playlist"></span> ' + dubtrack_lang.playlist.room_queue + '<span class="playlist-items-count"></span></li><li class="room_history"><span class="icon-history"></span>Room history</li></ul><div><ul class="playlist-style playlist-list"></ul></div></div></div><div class="nano"><div class="content-videos"><div class="result-videos"><div class="loading">' + dubtrack_lang.global.loading + '</div><div id="results_video_api"><ul></ul></div></div></div></div></div></div>',
  1943. playerController: '<div class="right"><ul><% if(Dubtrack.loggedIn) {%><li class="display-browser remove-if-banned"><a class="display-browser"><span class="icon-playlist"></span><span class="queue-position"></span><span class="queue-position-split">/</span><span class="queue-total"></span></a></li><li class="add-to-playlist remove-if-banned remove-if-iframe"><a class="add-to-playlist-button"><span class="icon-heart"></span><span class="grab-counter">0</span></a></li><% } %><li class="remove-if-banned remove-if-iframe"><a class="dubup"><span class="icon-arrow-up"></span><span class="dub-counter">0</span></a></li><li class="remove-if-banned remove-if-iframe"><a class="dubdown"><span class="icon-arrow-down"></span><span class="dub-counter">0</span></a></li></ul></div><div class="left"><div class="custom-embed-info">Custom embed channel</div><ul><% if(Dubtrack.loggedIn) {%><li class="playlist remove-if-banned"><a href="/browser" class="navigate"><span class="icon-list"></span></a></li><% } %><li class="imgEl"></li><li class="infoContainer"><div class="infoContainerInner"><div class="progressBg"></div><span class="currentDJSong"></span><span class="currentSong">' + dubtrack_lang.player.joinRoom + '</span><div class="currentTime"><span class="min"></span>:<span class="sec"></span></div></div></li></ul></div>'
  1944. }
  1945. }, Backbone.Collection.prototype.parse = Dubtrack.helpers.parse, Backbone.Model.prototype.idAttribute = "_id", Backbone.Model.prototype.initialize = function() {
  1946. b.ajaxPrefilter(function(a, b, c) {
  1947. a.crossDomain = {
  1948. crossDomain: !0
  1949. }, a.xhrFields = {
  1950. withCredentials: !0
  1951. }
  1952. })
  1953. }, Backbone.View.prototype.close = function() {
  1954. return this.beforeClose && this.beforeClose(), this.remove(), this.unbind(), !1
  1955. }, Dubtrack.Model.chat = Backbone.Model.extend({
  1956. urlRoot: Dubtrack.config.apiUrl + Dubtrack.config.urls.chat,
  1957. defaults: {
  1958. message: null,
  1959. type: null,
  1960. chatid: null
  1961. },
  1962. parse: function(a, b) {
  1963. return a.data
  1964. }
  1965. }), Dubtrack.Model.Comments = Backbone.Model.extend({
  1966. defaults: {
  1967. spamFlag: Number,
  1968. comment: String,
  1969. deleted: Boolean,
  1970. dubs: Number,
  1971. created: Number,
  1972. model: String,
  1973. fkid: String,
  1974. userid: String
  1975. }
  1976. }), Dubtrack.Model.Dubs = Backbone.Model.extend({
  1977. urlRoot: Dubtrack.config.apiUrl + Dubtrack.config.urls.dubs
  1978. }), Dubtrack.Model.Message = Backbone.Model.extend({
  1979. defaults: {
  1980. created: "",
  1981. name: "",
  1982. latest_message: "",
  1983. latest_message_str: "",
  1984. updateItemRead: [],
  1985. usersid: []
  1986. }
  1987. }), Dubtrack.Model.MessageItem = Backbone.Model.extend({
  1988. defaults: {
  1989. created: "",
  1990. message: "",
  1991. userid: "",
  1992. messageid: "",
  1993. _message: {},
  1994. _user: {}
  1995. }
  1996. }), Dubtrack.Model.Playlist = Backbone.Model.extend({
  1997. urlRoot: Dubtrack.config.apiUrl + Dubtrack.config.urls.playlist,
  1998. defaults: {
  1999. name: null,
  2000. status: null,
  2001. isPublic: !1,
  2002. totalItems: 0,
  2003. created: null,
  2004. userid: null
  2005. }
  2006. }), Dubtrack.Model.SoundCloudPlaylist = Backbone.Model.extend({
  2007. defaults: {
  2008. description: null,
  2009. genre: null,
  2010. user_id: null,
  2011. total_tracks: 0,
  2012. title: null,
  2013. permalink: null
  2014. }
  2015. }), Dubtrack.Model.Room = Backbone.Model.extend({
  2016. urlRoot: Dubtrack.config.apiUrl + Dubtrack.config.urls.room,
  2017. defaults: {
  2018. name: null,
  2019. roomDisplay: "public",
  2020. description: null,
  2021. roomUrl: null,
  2022. status: null,
  2023. roomType: null,
  2024. lockQueue: !1,
  2025. isPublic: null,
  2026. lang: null,
  2027. musicType: null,
  2028. metaDescription: null,
  2029. welcomeMessage: null,
  2030. password: null,
  2031. activeUsers: 0,
  2032. allowedDjs: null,
  2033. currentSong: null,
  2034. realTimeChannel: null,
  2035. maxLengthSong: null,
  2036. displayQueue: null,
  2037. background: null,
  2038. roomEmbed: null,
  2039. created: null,
  2040. updated: null,
  2041. userid: null
  2042. }
  2043. }), Dubtrack.Model.UserQueue = Backbone.Model.extend({
  2044. defaults: {
  2045. songLength: 0,
  2046. isActive: !1,
  2047. isPlayed: !1,
  2048. skipped: !1,
  2049. created: 0,
  2050. played: 0,
  2051. updubs: 0,
  2052. downdubs: 0,
  2053. grabs: 0,
  2054. order: 0,
  2055. songid: null,
  2056. roomid: null,
  2057. userid: null
  2058. }
  2059. }), Dubtrack.Model.ActiveQueue = Backbone.Model.extend({
  2060. defaults: {
  2061. song: null,
  2062. songInfo: null,
  2063. user: null,
  2064. startTime: null
  2065. }
  2066. }), Dubtrack.Model.RoomActiveQueue = Backbone.Model.extend({
  2067. defaults: {
  2068. active: null,
  2069. dubs: null,
  2070. ip: null,
  2071. playedCount: null,
  2072. roomid: null,
  2073. skippedCount: null,
  2074. songsInQueue: null,
  2075. updated: null,
  2076. userid: null
  2077. }
  2078. }), Dubtrack.Model.Search = Backbone.Model.extend({
  2079. urlRoot: Dubtrack.config.apiUrl + Dubtrack.config.urls.search,
  2080. parse: Dubtrack.helpers.parse,
  2081. defaults: {
  2082. activeUsers: 0
  2083. }
  2084. }), Dubtrack.Model.Song = Backbone.Model.extend({
  2085. urlRoot: Dubtrack.config.apiUrl + Dubtrack.config.urls.song,
  2086. defaults: {
  2087. name: null,
  2088. description: null,
  2089. images: {},
  2090. genre: null,
  2091. type: null,
  2092. fkid: null,
  2093. streamUrl: null,
  2094. fileUrl: null,
  2095. songArtist: null,
  2096. songLength: 0,
  2097. songBitrate: 0,
  2098. songBpm: 0,
  2099. songMeta: null,
  2100. created: 0,
  2101. updub: 0,
  2102. downdub: 0,
  2103. userid: null
  2104. }
  2105. }), Dubtrack.Model.User = Backbone.Model.extend({
  2106. urlRoot: Dubtrack.config.apiUrl + Dubtrack.config.urls.user,
  2107. defaults: {
  2108. username: null,
  2109. status: 0,
  2110. roleid: null,
  2111. dubs: 0,
  2112. created: 0,
  2113. lastLogin: 0,
  2114. userInfo: {}
  2115. }
  2116. }), Dubtrack.Model.RoomUser = Backbone.Model.extend({
  2117. defaults: {
  2118. updated: Number,
  2119. skippedCount: Number,
  2120. playedCount: Number,
  2121. songsInQueue: Number,
  2122. active: Boolean,
  2123. dubs: Number,
  2124. user: null,
  2125. roomid: String,
  2126. userid: String
  2127. },
  2128. comparator: function(a) {
  2129. return -parseInt(a.get("dubs"), 10)
  2130. }
  2131. }), Dubtrack.Model.UserFollowing = Backbone.Model.extend({
  2132. defaults: {
  2133. userid: String,
  2134. following: String,
  2135. created: Number
  2136. }
  2137. }), Dubtrack.Collection.chat = Backbone.Collection.extend({
  2138. model: Dubtrack.Model.chat
  2139. }), Dubtrack.Collection.Comments = Backbone.Collection.extend({
  2140. model: Dubtrack.Model.Comments
  2141. }), Dubtrack.Collection.Dubs = Backbone.Collection.extend({
  2142. url: Dubtrack.config.apiUrl + Dubtrack.config.urls.dubs,
  2143. model: Dubtrack.Model.Dubs
  2144. }), Dubtrack.Collection.Message = Backbone.Collection.extend({
  2145. url: Dubtrack.config.apiUrl + Dubtrack.config.urls.messages,
  2146. model: Dubtrack.Model.Message
  2147. }), Dubtrack.Collection.MessageItem = Backbone.Collection.extend({
  2148. url: Dubtrack.config.apiUrl + Dubtrack.config.urls.messages_items,
  2149. model: Dubtrack.Model.MessageItem
  2150. }), Dubtrack.Collection.Playlist = Backbone.Collection.extend({
  2151. url: Dubtrack.config.apiUrl + Dubtrack.config.urls.playlist,
  2152. model: Dubtrack.Model.Playlist
  2153. }), Dubtrack.Collection.Room = Backbone.Collection.extend({
  2154. url: Dubtrack.config.apiUrl + Dubtrack.config.urls.room,
  2155. model: Dubtrack.Model.Room
  2156. }), Dubtrack.Collection.RoomUser = Backbone.Collection.extend({
  2157. model: Dubtrack.Model.RoomUser
  2158. }), Dubtrack.Collection.UserQueue = Backbone.Collection.extend({
  2159. model: Dubtrack.Model.UserQueue
  2160. }), Dubtrack.Collection.RoomActiveQueue = Backbone.Collection.extend({
  2161. model: Dubtrack.Model.RoomActiveQueue
  2162. }), Dubtrack.Collection.Song = Backbone.Collection.extend({
  2163. url: Dubtrack.config.apiUrl + Dubtrack.config.urls.song,
  2164. model: Dubtrack.Model.Song
  2165. }), Dubtrack.Collection.User = Backbone.Collection.extend({
  2166. model: Dubtrack.Model.User,
  2167. comparator: function(a) {
  2168. return -1 * a.get("dubs")
  2169. }
  2170. }), Dubtrack.Collection.UserFollowing = Backbone.Collection.extend({
  2171. model: Dubtrack.Model.UserFollowing
  2172. }), f.global.friendClickAction = !1, f.global.friendsView = Backbone.View.extend({
  2173. tagName: "div",
  2174. events: {
  2175. "click .close": "closeAction"
  2176. },
  2177. initialize: function() {
  2178. b(this.el).attr({
  2179. "class": "ajax_container no-padding",
  2180. id: "ajax_tmp_loader"
  2181. })
  2182. },
  2183. render: function() {
  2184. b(this.el).html(tpl.get("friendCont")), this.friendsUlEl = b(this.el).find("#friends_list");
  2185. var a = this;
  2186. return f.global.friendClickAction || (f.global.friendClickAction = !0, b("body").bind("click", function(c) {
  2187. $parents = b(c.target).parents("#friends_list"), 0 === $parents.length && b(a.el).hide()
  2188. })), this
  2189. },
  2190. closeAction: function() {
  2191. return b(this.el).hide(), !1
  2192. },
  2193. fetchData: function(a, c) {
  2194. b(this.el).show().css({
  2195. top: a,
  2196. right: c
  2197. }), this.friendsUlEl.html(dubtrack_lang.global.loading);
  2198. var d = this;
  2199. this.model.fetch({
  2200. success: function(a, b) {
  2201. d.friendsUlEl.html(""), d.resetEl(b.data.friends_online, b.data.friends_offline)
  2202. }
  2203. })
  2204. },
  2205. resetEl: function(a, c) {
  2206. this.friendsUlEl.append(b("<li/>", {
  2207. "class": "cyan"
  2208. }).html(dubtrack_lang.global.online + "(" + a.length + ")")), _.each(a, function(a) {
  2209. this.appendEl(a, "friendsItem")
  2210. }, this), this.friendsUlEl.append(b("<li/>", {
  2211. "class": "cyan"
  2212. }).html(dubtrack_lang.global.offline + "(" + c.length + ")")), _.each(c, function(a) {
  2213. this.appendEl(a, "friendsOffline")
  2214. }, this)
  2215. },
  2216. appendEl: function(a, c) {
  2217. var a = b(new f.global.friendsViewItem({
  2218. model: new f.global.friendsModel(a)
  2219. }).render(c).el).appendTo(this.friendsUlEl)
  2220. }
  2221. }), f.global.friendsViewItem = Backbone.View.extend({
  2222. tagName: "li",
  2223. events: {
  2224. click: "clickAction"
  2225. },
  2226. render: function(a) {
  2227. var c = g.helpers.getProfileImg(this.model.get("oauth_uid"), this.model.get("username"), this.model.get("oauth_provider"));
  2228. return this.model.set({
  2229. img: c
  2230. }), b(_.template(tpl.get(a), this.model.toJSON())).appendTo(b(this.el)), this
  2231. },
  2232. clickAction: function() {
  2233. g.app.navigate("/" + this.model.get("username"), {
  2234. trigger: !0
  2235. }), this.close()
  2236. }
  2237. }), Dubtrack.View.LayoutView = Backbone.View.extend({
  2238. el: b("body"),
  2239. events: {
  2240. "click #header-global .header-right-navigation .user-info": "navigateUser",
  2241. "click #header-global a.navigate": "navigate",
  2242. "click #header-global li.logout": "logout",
  2243. "click #header-global .header-left-navigation h1": "setActiveMenu",
  2244. "mouseenter #header-global .header-left-navigation h1": "setActiveMenu",
  2245. "click #header-global #header_login #login-link": "displayLogin",
  2246. "click #header-global #header_login #signup-link": "displaySignup",
  2247. "click #header-global .user-messages": "setActiveMenuRight",
  2248. "click #mobile-room-menu .chat-button": "diplayChatLayout",
  2249. "click #mobile-room-menu .player-button": "diplayPlayerLayout"
  2250. },
  2251. displayLogin: function(a) {
  2252. a.preventDefault(), Dubtrack.app.navigate("/login", {
  2253. trigger: !0
  2254. })
  2255. },
  2256. displaySignup: function(a) {
  2257. a.preventDefault(), Dubtrack.app.navigate("/signup", {
  2258. trigger: !0
  2259. })
  2260. },
  2261. diplayPlayerLayout: function() {
  2262. return this.$el.removeClass("diplay-chat"), !1
  2263. },
  2264. diplayChatLayout: function() {
  2265. return this.$el.addClass("diplay-chat"), !1
  2266. },
  2267. initialize: function() {
  2268. this.$("#header-global").append(_.template(Dubtrack.els.templates.layout.header, Dubtrack.session.toJSON())), this.searchView = new Dubtrack.View.SearchView({
  2269. el: this.$("li.global-search-header")
  2270. }), Dubtrack.loggedIn ? (this.$("#mobile-login").hide(), Dubtrack.Events.bind("realtime:user-update-" + Dubtrack.session.id, this.updateImage, this)) : (this.$("#header_login").show(), b("body").addClass("not-logged-in")), this.menu_right = new Dubtrack.View.MainRightMenuView, this.menu_left = new Dubtrack.View.MainLeftMenuView, b("body").bind("click", function(a) {
  2271. 0 === b(a.target).parents("#main-menu-left").length && b("html").removeClass("menu-left-in"), 0 === b(a.target).parents("#main-menu-right").length && (b("html").removeClass("menu-right-in"), Dubtrack.layout.menu_right.message_view.$el.removeClass("view-message-details"))
  2272. }.bind(this)), emojify.setConfig({
  2273. img_dir: Dubtrack.config.urls.mediaBaseUrl + "/assets/emoji/images/emoji"
  2274. }), this.main_login_window = new Dubtrack.View.LoginMainWindowView, this.getNewMessages()
  2275. },
  2276. setActiveMenu: function() {
  2277. return b("html").addClass("menu-left-in"), !1
  2278. },
  2279. setActiveMenuRight: function() {
  2280. return b("html").toggleClass("menu-right-in"), b("html").hasClass("menu-right-in") ? this.menu_right.loadMessages() : Dubtrack.layout.menu_right.message_view.$el.removeClass("view-message-details"), !1
  2281. },
  2282. getNewMessages: function() {
  2283. var a = Dubtrack.config.apiUrl + Dubtrack.config.urls.messages_news,
  2284. b = this;
  2285. this.timeout_newmessages && clearTimeout(b.timeout_newmessages), Dubtrack.helpers.sendRequest(a, {}, "get", function(a, c) {
  2286. if (c && c.data) {
  2287. var d = parseInt(c.data, 10);
  2288. d > 0 ? b.$(".user-messages .message-counter").html(d).show() : b.$(".user-messages .message-counter").hide()
  2289. } else b.$(".user-messages .message-counter").hide();
  2290. b.timeout_newmessages = setTimeout(function() {
  2291. b.getNewMessages()
  2292. }, 3e4)
  2293. })
  2294. },
  2295. updateImage: function(a) {
  2296. a && a.img && a.img.url && this.$("figure.user-image img").attr("src", a.img.url)
  2297. },
  2298. logout: function() {
  2299. window.location = "/login/logout"
  2300. },
  2301. render: function() {},
  2302. navigate: function(a) {
  2303. return this.$(".menu-expand").removeClass("active"), $href = b(a.target).attr("href"), $href && Dubtrack.app.navigate($href, {
  2304. trigger: !0
  2305. }), !1
  2306. },
  2307. navigateUser: function() {
  2308. return Dubtrack.app.navigate("/" + Dubtrack.session.get("username"), {
  2309. trigger: !0
  2310. }), !1
  2311. }
  2312. }), Dubtrack.View.SearchView = Backbone.View.extend({
  2313. events: {
  2314. "keyup input#global-search": "renderSearchResults"
  2315. },
  2316. initialize: function() {
  2317. this.model = new Dubtrack.Model.Search, this.model.bind("change", this.render, this), this.model.bind("reset", this.render, this), this.search_results = this.$(".search-results"), this.search_results_rooms = this.$(".search-results-rooms"), this.search_results_users = this.$(".search-results-users");
  2318. var a = this;
  2319. b(window).on("click", function(c) {
  2320. var d = b(c.target).parents(".global-search-header");
  2321. 0 === d.length && (a.search_results.hide(), a.$("input#global-search").val(""))
  2322. })
  2323. },
  2324. render: function() {
  2325. this.search_results_rooms.empty(), this.search_results_users.empty();
  2326. var a = this.model.get("rooms"),
  2327. b = this.model.get("users"),
  2328. c = this;
  2329. a && a.length > 0 ? _.each(a, function(a) {
  2330. c.appendRoomItem(a)
  2331. }) : this.search_results_rooms.append('<div class="result-item"><span class="count">No results found</span></div>'), b && b.length > 0 ? _.each(b, function(a) {
  2332. c.appendUserItem(a)
  2333. }) : this.search_results_users.append('<div class="result-item"><span class="count">No results found</span></div>')
  2334. },
  2335. appendRoomItem: function(a) {
  2336. this.search_results_rooms.append((new Dubtrack.View.SearchRoomItem).render(a).$el)
  2337. },
  2338. appendUserItem: function(a) {
  2339. this.search_results_users.append((new Dubtrack.View.SearchUserItem).render(a).$el)
  2340. },
  2341. renderSearchResults: function() {
  2342. var a = b.trim(this.$("input#global-search").val());
  2343. if ("" === a || null === a) return void this.search_results.hide();
  2344. this.search_results.show();
  2345. this.model.fetch({
  2346. data: {
  2347. query: a
  2348. }
  2349. })
  2350. }
  2351. }), Dubtrack.View.SearchRoomItem = Backbone.View.extend({
  2352. attributes: {
  2353. "class": "result-item"
  2354. },
  2355. events: {
  2356. click: "clickAction"
  2357. },
  2358. initialize: function() {},
  2359. render: function(a) {
  2360. return this.room = a, a.activeUsers || (a.activeUsers = 0), this.$el.html(_.template(Dubtrack.els.templates.search.searchRoom, a)), this
  2361. },
  2362. clickAction: function() {
  2363. return window.location = "/join/" + this.room.roomUrl, Dubtrack.layout.searchView.$("input#global-search").val(""), Dubtrack.layout.searchView.search_results.hide(), !1
  2364. }
  2365. }), Dubtrack.View.SearchUserItem = Backbone.View.extend({
  2366. attributes: {
  2367. "class": "result-item"
  2368. },
  2369. events: {
  2370. click: "clickAction"
  2371. },
  2372. initialize: function() {},
  2373. render: function(a) {
  2374. return this.user = a, this.$el.html(_.template(Dubtrack.els.templates.search.searchUser, a)), this
  2375. },
  2376. clickAction: function() {
  2377. return Dubtrack.app.navigate("/" + this.user.username, {
  2378. trigger: !0
  2379. }), Dubtrack.layout.searchView.$("input#global-search").val(""), Dubtrack.layout.searchView.search_results.hide(), !1
  2380. }
  2381. }), Dubtrack.View.MainRightMenuView = Backbone.View.extend({
  2382. el: b("#main-menu-right"),
  2383. events: {
  2384. "click a.close-menu": "closeMenu"
  2385. },
  2386. initialize: function() {
  2387. this.message_view = new Dubtrack.View.Message.Main
  2388. },
  2389. loadMessages: function() {
  2390. this.message_view.loadMessages()
  2391. },
  2392. closeMenu: function() {
  2393. return b("html").removeClass("menu-right-in"), !1
  2394. }
  2395. }), Dubtrack.View.MainLeftMenuView = Backbone.View.extend({
  2396. el: b("#main-menu-left"),
  2397. events: {
  2398. "click a.navigate": "navigate",
  2399. "click a.close-menu": "closeMenu",
  2400. mouseleave: "closeMenu"
  2401. },
  2402. initialize: function() {
  2403. Dubtrack.loggedIn && this.$("a.logout-link").css("display", "block")
  2404. },
  2405. closeMenu: function() {
  2406. return b("html").removeClass("menu-left-in"), !1
  2407. },
  2408. navigate: function(a) {
  2409. var c = b(a.target).attr("href");
  2410. return c && (b("html").removeClass("menu-left-in"), Dubtrack.app.navigate(c, {
  2411. trigger: !0
  2412. })), !1
  2413. }
  2414. }), Dubtrack.View.LoginMainWindowView = Backbone.View.extend({
  2415. el: b("#login-model-window"),
  2416. events: {
  2417. "click .close-login-window": "hideWindow"
  2418. },
  2419. initialize: function() {
  2420. return Dubtrack.loggedIn ? void this.$el.remove() : (this.signup_window = new Dubtrack.View.LoginWindowView({
  2421. el: this.$("#login-create-window")
  2422. }), this.forgot_window = new Dubtrack.View.LoginWindowView({
  2423. el: this.$("#login-forgot-window")
  2424. }), this.login_window = new Dubtrack.View.LoginWindowView({
  2425. el: this.$("#login-window")
  2426. }), this.change_window = new Dubtrack.View.LoginWindowView({
  2427. el: this.$("#login-chage-password-window")
  2428. }), this.login_password_window = new Dubtrack.View.LoginWindowView({
  2429. el: this.$("#login-passwordupdate-window")
  2430. }), this.signup_window.formSuccess = function() {
  2431. this.sucess_el.text("Thanks for signing up! We sent you a verification email"), this.sucess_el.show()
  2432. }, this.forgot_window.formSuccess = function() {
  2433. this.sucess_el.text("We sent you an email, please follow the link to change your password"), this.sucess_el.show()
  2434. }, this.change_window.formSuccess = function() {
  2435. this.displayWindow("login_password_window")
  2436. }.bind(this), this.login_window.formSuccess = function() {
  2437. this.sucess_el.text("Login successful"), this.sucess_el.show(), Dubtrack.room && Dubtrack.room.model ? location.href = "/join/" + Dubtrack.room.model.get("roomUrl") : location.href = "/"
  2438. }, void(this.login_password_window.formSuccess = function() {
  2439. this.sucess_el.text("Login successful"), this.sucess_el.show(), Dubtrack.room && Dubtrack.room.model ? location.href = "/join/" + Dubtrack.room.model.get("roomUrl") : location.href = "/"
  2440. }))
  2441. },
  2442. hideWindow: function() {
  2443. this.$el.hide(), Dubtrack.room && Dubtrack.room.model ? Dubtrack.app.navigate("/join/" + Dubtrack.room.model.get("roomUrl"), {
  2444. trigger: !0
  2445. }) : Dubtrack.app.navigate("/lobby", {
  2446. trigger: !0
  2447. })
  2448. },
  2449. displayWindow: function(a) {
  2450. return this[a] && this[a].$el ? (this.$el.show(), Dubtrack.els.mainLoading.hide(), this.$(".login-model-container").removeClass("show-form"), this.$(".login-model-container form").show(), this.$(".login-model-container form .err-message").hide(), this.$(".login-model-container .success-message").hide(), this[a].$el.addClass("show-form"), void("signup_window" !== a || this.captcah_loaded || (this.captcah_loaded = !0, b.getScript("https://www.google.com/recaptcha/api.js?onload=onRecaptchaloadCallback&render=explicit")))) : !1
  2451. }
  2452. }), Dubtrack.View.LoginWindowView = Backbone.View.extend({
  2453. events: {
  2454. "click .account-actions a": "triggerAction",
  2455. "submit form": "submitForm"
  2456. },
  2457. initialize: function() {
  2458. this.form_el = this.$("form"), this.password_el = this.$("form input[name=password]"), this.password2_el = this.$("form input[name=password2]"), this.token_el = this.$("form input[name=token]"), this.submit_el = this.$("form input[type=submit]"), this.form_target = this.form_el.length ? this.form_el.attr("action") : null, this.error_el = this.$("form .err-message"), this.sucess_el = this.$(".success-message"), this.token = null
  2459. },
  2460. triggerAction: function(a) {
  2461. a.preventDefault();
  2462. var c = b(a.target);
  2463. if (c.is("a") || c.parents("a"), c) {
  2464. var d = c.attr("href");
  2465. d && Dubtrack.app.navigate(d, {
  2466. trigger: !0
  2467. })
  2468. }
  2469. },
  2470. submitForm: function(a) {
  2471. if (a.preventDefault(), this.error_el.hide(), this.sucess_el.hide(), this.form_target) {
  2472. if (this.password2_el.length && this.password_el.length && this.password2_el.val() !== this.password_el.val()) return this.error_el.show(), void this.error_el.html("Passwords don't match");
  2473. this.submit_el.attr("disabled", !0);
  2474. var c = this.submit_el.val();
  2475. this.submit_el.val("loading..."), this.token && this.token_el.length && this.token_el.val(this.token);
  2476. var d = this.form_el.serialize();
  2477. b.post(Dubtrack.config.apiUrl + this.form_target, d).fail(function(a) {
  2478. try {
  2479. var b = JSON.parse(a.responseText);
  2480. b.data && b.data.details && b.data.details.message ? this.error_el.text(b.data.details.message) : this.error_el.text("error on form submission")
  2481. } catch (c) {
  2482. this.error_el.text("error on form submission")
  2483. }
  2484. this.error_el.show();
  2485. try {
  2486. grecaptcha.reset()
  2487. } catch (c) {}
  2488. }.bind(this)).done(function() {
  2489. this.form_el.hide(), this.formSuccess()
  2490. }.bind(this)).always(function() {
  2491. this.submit_el.val(c), this.submit_el.attr("disabled", !1)
  2492. }.bind(this))
  2493. }
  2494. },
  2495. formSuccess: function() {}
  2496. }), Dubtrack.View.PlayerController = Backbone.View.extend({
  2497. el: b("#player-controller"),
  2498. volume: 100,
  2499. events: {
  2500. "click .dubup": "voteUpAction",
  2501. "click .dubdown": "voteDownAction",
  2502. "click .add-to-playlist": "addToPlaylist",
  2503. "click .display-browser": "displayBrowser"
  2504. },
  2505. initialize: function() {
  2506. this.$el.html(_.template(Dubtrack.els.templates.layout.playerController)), this.volumeSliderEl = b("#volume-div"), this.fetchQueueInfoThrottled = _.debounce(this.fetchQueueInfo.bind(this), 1e3), Dubtrack.Events.bind("realtime:room_playlist-dub", this.realTimeDub, this), Dubtrack.Events.bind("realtime:room_playlist-queue-update-grabs", this.realTimeGrab, this), Dubtrack.Events.bind("realtime:room_playlist-update", this.realTimeUpdate, this), Dubtrack.Events.bind("realtime:room_playlist-queue-reorder", this.fetchQueueInfoThrottled, this), Dubtrack.Events.bind("realtime:room_playlist-queue-update-dub", this.fetchQueueInfoThrottled, this), Dubtrack.Events.bind("realtime:room_playlist-queue-remove-user", this.fetchQueueInfoThrottled, this), Dubtrack.Events.bind("realtime:user-leave", this.fetchQueueInfoThrottled, this), this.volumeControl()
  2507. },
  2508. update: function() {
  2509. return this.addToPlaylistButton = this.$(".add-to-playlist-button"), this.voteUp = b(".dubup"), this.voteUpCounter = b(".dubup .dub-counter"), this.grabCounter = b(".add-to-playlist-button .grab-counter"), this.voteDown = b(".dubdown"), this.voteDownCounter = b(".dubdown .dub-counter"), this.queuePosition = this.$(".queue-position"), this.queuePositionSplit = this.$(".queue-position-split"), this.queueTotal = this.$(".queue-total"), this.inQueue = !1, this.updateVote(), this.fetchQueueInfo(), !1
  2510. },
  2511. realTimeUpdate: function(a) {
  2512. Dubtrack.helpers.cookie["delete"]("dub-" + Dubtrack.room.model.get("_id")), Dubtrack.helpers.cookie["delete"]("grab-" + Dubtrack.room.model.get("_id")), this.fetchQueueInfoThrottled.call()
  2513. },
  2514. addToPlaylist: function(a) {
  2515. if (Dubtrack.loggedIn) {
  2516. var c = Dubtrack.room.player.activeSong.get("song");
  2517. if (!Dubtrack.room || null === c) return !1;
  2518. var d = {
  2519. right: 200,
  2520. bottom: 43
  2521. };
  2522. return Dubtrack.helpers.genPlaylistContainer(b("body"), d, c.songid, !1, "playerBottomFixed"), b("html, body").scrollTop(0), !1
  2523. }
  2524. },
  2525. displayBrowser: function() {
  2526. Dubtrack.app.navigate("/browser/queue", {
  2527. trigger: !0
  2528. })
  2529. },
  2530. fetchQueueInfo: function() {
  2531. Dubtrack.room.player.activeQueueCollection.fetch({
  2532. reset: !0,
  2533. success: function() {
  2534. var a = 0,
  2535. b = !1;
  2536. this.queueTotal.html() != Dubtrack.room.player.activeQueueCollection.length && this.queueTotal.html(Dubtrack.room.player.activeQueueCollection.length), Dubtrack.app.browserView && Dubtrack.app.browserView.$("#playlists-scroll .current_room_queue .playlist-items-count").text(Dubtrack.room.player.activeQueueCollection.length), _.each(Dubtrack.room.player.activeQueueCollection.models, function(c) {
  2537. a++, Dubtrack.session.id == c.get("userid") && (this.inQueue = !0, b = !0, this.queuePositionSplit.show(), this.queuePosition.html(a), Dubtrack.app.browserView && Dubtrack.app.browserView.$("#playlists-scroll .current_queue .playlist-items-count").text(c.get("songsInQueue")))
  2538. }, this), b || (this.inQueue = !1, Dubtrack.app.browserView && Dubtrack.app.browserView.$("#playlists-scroll .current_queue .playlist-items-count").text(0), this.queuePosition.empty(), this.queuePositionSplit.hide())
  2539. }.bind(this)
  2540. })
  2541. },
  2542. voteUpAction: function() {
  2543. return this.vote("updub"), !1
  2544. },
  2545. voteDownAction: function() {
  2546. return this.vote("downdub"), !1
  2547. },
  2548. realTimeDub: function(a) {
  2549. var b = Dubtrack.room.player.activeSong.get("song");
  2550. Dubtrack.room && null !== b && a.playlist._id === b._id && (this.voteUpCounter.text(a.playlist.updubs), this.voteDownCounter.text(a.playlist.downdubs), this.grabCounter.text(a.playlist.grabs), Dubtrack.room.player.activeSong.set({
  2551. song: a.playlist
  2552. }))
  2553. },
  2554. realTimeGrab: function(a) {
  2555. a && a.playlist && a.playlist.grabs && (this.grabCounter.text(a.playlist.grabs), Dubtrack.session && Dubtrack.session.id == a.user._id && (this.addToPlaylistButton.addClass("grabbed"), Dubtrack.helpers.cookie.set("grab-" + Dubtrack.room.model.get("_id"), "grab", 30)))
  2556. },
  2557. shareFacebook: function() {
  2558. var a = Dubtrack.room.player.activeSong.get("songInfo"),
  2559. b = encodeURIComponent(Dubtrack.config.globalBaseUrl + "join/" + Dubtrack.room.model.get("roomUrl")),
  2560. c = "";
  2561. c = Dubtrack.room && null !== a ? encodeURIComponent(_.template(dubtrack_lang.room.facebookShare, {
  2562. song: a.name
  2563. })) : "Join my dubtrack.fm room";
  2564. var d = "https://www.facebook.com/sharer.php?u=" + b + "&t=" + c,
  2565. e = dubtrack_lang.room.shareTitle,
  2566. f = "width=600,height=500,scrollbars=yes";
  2567. return window.open(d, e, f), !1
  2568. },
  2569. shareTwitter: function() {
  2570. var a = Dubtrack.room.player.activeSong.get("songInfo"),
  2571. b = encodeURIComponent(Dubtrack.config.globalBaseUrl + "join/" + Dubtrack.room.model.get("roomUrl")),
  2572. c = "";
  2573. c = Dubtrack.room && null !== a ? encodeURIComponent(_.template(dubtrack_lang.room.twitterShare, {
  2574. song: a.name
  2575. })) : "Join my dubtrack.fm room";
  2576. var d = "https://twitter.com/share?url=" + b + "&text=" + c,
  2577. e = dubtrack_lang.room.shareTitle,
  2578. f = "width=600,height=500,scrollbars=yes";
  2579. return window.open(d, e, f), !1
  2580. },
  2581. vote: function(a) {
  2582. if (Dubtrack.loggedIn) {
  2583. var c = Dubtrack.room.player.activeSong.get("song");
  2584. if (Dubtrack.room && null !== c) {
  2585. var d = Dubtrack.config.urls.dubsPlaylistActive.replace(":id", Dubtrack.room.model.get("_id")).replace(":playlistid", c._id),
  2586. e = Dubtrack.helpers.cookie.get("dub-" + Dubtrack.room.model.get("_id")),
  2587. f = Dubtrack.helpers.cookie.get("dub-song"),
  2588. g = c.updubs - c.downdubs;
  2589. if (c.songid !== f && (e = null), !e || e !== a)
  2590. if (Dubtrack.helpers.sendRequest(Dubtrack.config.apiUrl + d, {
  2591. type: a
  2592. }, "post"), b(".voted").removeClass("voted"), Dubtrack.helpers.cookie.set("dub-" + Dubtrack.room.model.get("_id"), a, 30), Dubtrack.helpers.cookie.set("dub-song", c.songid, 30), "updub" === a) {
  2593. var h = parseInt(this.voteUpCounter.text(), 10),
  2594. i = parseInt(this.voteDownCounter.text(), 10);
  2595. e && (this.voteDownCounter.text(i - 1), g += 1), this.voteUpCounter.text(h + 1), g += 1
  2596. } else {
  2597. var h = parseInt(this.voteUpCounter.text(), 10),
  2598. i = parseInt(this.voteDownCounter.text(), 10);
  2599. e && (this.voteUpCounter.text(h - 1), g -= 1), this.voteDownCounter.text(i + 1), g -= 1
  2600. }
  2601. "updub" == a ? this.voteUp.addClass("voted") : this.voteDown.addClass("voted")
  2602. }
  2603. }
  2604. },
  2605. updateVote: function() {
  2606. b(".voted").removeClass("voted"), this.addToPlaylistButton.removeClass("grabbed"), this.grabCounter.text(0), this.voteUpCounter.text(0), this.voteDownCounter.text(0);
  2607. var a = Dubtrack.room.player.activeSong.get("song");
  2608. if (null !== a) {
  2609. var c = a.updubs - a.downdubs,
  2610. d = Dubtrack.helpers.cookie.get("dub-" + Dubtrack.room.model.get("_id")),
  2611. e = Dubtrack.helpers.cookie.get("grab-" + Dubtrack.room.model.get("_id")),
  2612. f = Dubtrack.helpers.cookie.get("dub-song");
  2613. a.songid !== f && (d = null), isNaN(c) && (c = 0), d && ("updub" === d ? this.voteUp.addClass("voted") : this.voteDown.addClass("voted")), e && this.addToPlaylistButton.addClass("grabbed"), this.voteUpCounter.text(a.updubs), this.voteDownCounter.text(a.downdubs), a.grabs && this.grabCounter.text(a.grabs)
  2614. }
  2615. },
  2616. volumeControl: function() {
  2617. var a = this,
  2618. b = Dubtrack.helpers.cookie.get("dubtrack-room-volume");
  2619. b || (b = 100), this.volumeSliderEl.slider({
  2620. value: b,
  2621. orientation: "horizontal",
  2622. range: "min",
  2623. animate: !1,
  2624. slide: function(b, c) {
  2625. a.setVolume(c.value, !1)
  2626. },
  2627. change: function(b, c) {
  2628. a.setVolume(c.value, !0)
  2629. }
  2630. }), this.setVolume(b)
  2631. },
  2632. setVolume: function(a) {
  2633. Dubtrack.helpers.cookie.set("dubtrack-room-volume", a, 30), this.volume = a, Dubtrack.room.player && Dubtrack.room.player.setVolume(a)
  2634. }
  2635. }), f.global.userPopover = Backbone.View.extend({
  2636. tagName: "div",
  2637. id: "user_popover",
  2638. events: {
  2639. "click a.kick": "kickuser",
  2640. "click a.ban": "banuser",
  2641. "keydown a.ban input": "banuserKeydown",
  2642. "click a.mute": "muteuser",
  2643. "click a.unmute": "unmuteuser",
  2644. "click .usercontent": "navigateUser",
  2645. "click a.unsetrole": "unsetRole",
  2646. "click a.setrole": "setRole",
  2647. "click a.chat-mention": "mentionUserInChat",
  2648. "click a.send-pm-message": "sendPersonalMessage"
  2649. },
  2650. initialize: function() {
  2651. this.offset_top = 0, this.$el.html(Dubtrack.els.templates.profile.popover)
  2652. },
  2653. displayUser: function(a) {
  2654. Dubtrack.cache.users.get(a, this.renderUser, this), this.userActive = !1, Dubtrack.session && Dubtrack.room && Dubtrack.room.users ? Dubtrack.session.get("_id") == a ? (this.$(".global-actions").hide(), this.$(".actions").hide()) : (this.$(".global-actions").show(), this.$(".actions a").hide(), (Dubtrack.helpers.isDubtrackAdmin(Dubtrack.session.id) || Dubtrack.room.users.getIfHasRole(Dubtrack.session.id) || Dubtrack.room.model.get("userid") == Dubtrack.session.id) && (this.$(".actions").show(), this.$(".actions a.send-pm-message").show(), Dubtrack.helpers.isDubtrackAdmin(Dubtrack.session.id) || Dubtrack.room.users.getIfOwner(Dubtrack.session.id) || Dubtrack.room.users.getIfMod(Dubtrack.session.id) || Dubtrack.room.users.getIfVIP(Dubtrack.session.id) || Dubtrack.room.users.getIfResidentDJ(Dubtrack.session.id) || Dubtrack.room.users.getIfManager(Dubtrack.session.id), Dubtrack.helpers.isDubtrackAdmin(Dubtrack.session.id) || Dubtrack.room.users.getIfOwner(Dubtrack.session.id) || Dubtrack.room.users.getIfMod(Dubtrack.session.id) || Dubtrack.room.users.getIfVIP(Dubtrack.session.id) || Dubtrack.room.users.getIfManager(Dubtrack.session.id), (Dubtrack.helpers.isDubtrackAdmin(Dubtrack.session.id) || Dubtrack.room.users.getIfOwner(Dubtrack.session.id) || Dubtrack.room.users.getIfMod(Dubtrack.session.id) || Dubtrack.room.users.getIfManager(Dubtrack.session.id)) && (Dubtrack.room.users.getIfmuted(a) ? (this.$(".actions a.mute").hide(), this.$(".actions a.unmute").show()) : (this.$(".actions a.mute").show(), this.$(".actions a.unmute").hide()), this.$(".actions a.kick").show(), this.$(".actions a.ban").show()), (Dubtrack.helpers.isDubtrackAdmin(Dubtrack.session.id) || Dubtrack.room.users.getIfOwner(Dubtrack.session.id) || Dubtrack.room.users.getIfManager(Dubtrack.session.id)) && (Dubtrack.room.users.getIfMod(a) ? (this.$(".actions a.setmod").hide(), this.$(".actions a.unsetmod").show()) : (this.$(".actions a.unsetmod").hide(), this.$(".actions a.setmod").show()), Dubtrack.room.users.getIfVIP(a) ? (this.$(".actions a.setvip").hide(), this.$(".actions a.unsetvip").show()) : (this.$(".actions a.setvip").show(), this.$(".actions a.unsetvip").hide()), Dubtrack.room.users.getIfResidentDJ(a) ? (this.$(".actions a.setresdj").hide(), this.$(".actions a.unsetresdj").show()) : (this.$(".actions a.setresdj").show(), this.$(".actions a.unsetresdj").hide()), Dubtrack.room.users.getIfDJ(a) ? (this.$(".actions a.setdj").hide(), this.$(".actions a.unsetdj").show()) : (this.$(".actions a.setdj").show(), this.$(".actions a.unsetdj").hide())), (Dubtrack.helpers.isDubtrackAdmin(Dubtrack.session.id) || Dubtrack.room.users.getIfOwner(Dubtrack.session.id)) && (Dubtrack.room.users.getIfManager(a) ? (this.$(".actions a.setmanager").hide(), this.$(".actions a.unsetmanager").show()) : (this.$(".actions a.setmanager").show(), this.$(".actions a.unsetmanager").hide())), Dubtrack.room.model.get("userid") == Dubtrack.session.id && (Dubtrack.room.users.getIfOwner(a) ? (this.$(".actions a.setowner").hide(), this.$(".actions a.unsetowner").show()) : (this.$(".actions a.setowner").show(), this.$(".actions a.unsetowner").hide())))) : (this.$(".actions").hide(), this.$(".global-actions").hide()), (Dubtrack.helpers.isDubtrackAdmin(a) || Dubtrack.room.model.get("userid") == a) && this.$(".actions").hide(), (Dubtrack.helpers.isDubtrackAdmin(a) || Dubtrack.room.users.getIfHasRole(a)) && (this.$(".actions a.mute").hide(), this.$(".actions a.kick").hide(), this.$(".actions a.ban").hide());
  2655. var c = this;
  2656. b("body").bind("click.userPopover", function(a) {
  2657. c.userActive && a && a.target && 0 === b(a.target).parents("a.ban").length && (c.userActive = !1, Dubtrack.views.user_popover.$el.hide(), b("body").unbind("click.userPopover"))
  2658. }), this.timeout && clearTimeout(this.timeout), this.timeout = setTimeout(function() {
  2659. c.userActive = !0
  2660. }, 500)
  2661. },
  2662. renderUser: function(a, b) {
  2663. this.user = b, this.$(".usercontent").html(_.template(Dubtrack.els.templates.profile.popover_user, b.toJSON())), Dubtrack.session && Dubtrack.room && Dubtrack.room.users && this.$(".usercontent .dubs").html(Dubtrack.room.users.getDubs(b.id) + " dubs")
  2664. },
  2665. sendPersonalMessage: function() {
  2666. b("html").addClass("menu-right-in");
  2667. var a = [];
  2668. return a.push(this.user.get("_id")), Dubtrack.layout.menu_right.message_view.createMessageIds(a), Dubtrack.views.user_popover.$el.hide(), !1
  2669. },
  2670. mentionUserInChat: function() {
  2671. var a = Dubtrack.room.chat._messageInputEl.val();
  2672. return a.length > 0 ? Dubtrack.room.chat._messageInputEl.val(Dubtrack.room.chat._messageInputEl.val() + "@" + this.user.get("username") + " ") : Dubtrack.room.chat._messageInputEl.val("@" + this.user.get("username") + " "), Dubtrack.room.chat._messageInputEl.focus(), Dubtrack.views.user_popover.$el.hide(), Dubtrack.room.$el.removeClass("display-users-rooms"), !1
  2673. },
  2674. kickuser: function() {
  2675. return this.userActive = !1, this.$el.hide(), Dubtrack.room.chat.kickUser(this.user.get("username")), !1
  2676. },
  2677. banuser: function(a) {
  2678. if (a && a.target && !b(a.target).is("input")) {
  2679. var c = this.$("a.ban input").val();
  2680. c.length > 0 ? Dubtrack.room.chat.banUser(this.user.get("username"), parseInt(c, 10)) : Dubtrack.room.chat.banUser(this.user.get("username"), 0), Dubtrack.views.user_popover.$el.hide()
  2681. }
  2682. return !1
  2683. },
  2684. banuserKeydown: function(a) {
  2685. if (c = a.which ? a.which : a.keyCode, 13 == c) {
  2686. var b = this.$("a.ban input").val();
  2687. return b.length > 0 ? Dubtrack.room.chat.banUser(this.user.get("username"), parseInt(b, 10)) : Dubtrack.room.chat.banUser(this.user.get("username"), 0), Dubtrack.views.user_popover.$el.hide(), !1
  2688. }
  2689. },
  2690. muteuser: function() {
  2691. return this.userActive = !1, this.$el.hide(), Dubtrack.room.chat.muteUser(this.user.get("username")), !1
  2692. },
  2693. unmuteuser: function() {
  2694. return this.userActive = !1, this.$el.hide(), Dubtrack.room.chat.unmuteUser(this.user.get("username")), !1
  2695. },
  2696. setRole: function(a) {
  2697. if (a && a.target) {
  2698. var c = b(a.target).attr("data-roleref");
  2699. return c && (this.userActive = !1, this.$el.hide(), Dubtrack.room.chat.setRole(this.user.get("username"), c)), !1
  2700. }
  2701. },
  2702. unsetRole: function(a) {
  2703. if (a && a.target) {
  2704. var c = b(a.target).attr("data-roleref");
  2705. return c && (this.userActive = !1, this.$el.hide(), Dubtrack.room.chat.unsetRole(this.user.get("username"), c)), !1
  2706. }
  2707. },
  2708. navigateUser: function() {
  2709. return this.userActive = !1, this.$el.hide(), Dubtrack.app.navigate("/" + this.user.get("username"), {
  2710. trigger: !0
  2711. }), !1
  2712. }
  2713. }), f.playlist.browserDocBind = !1, f.playlist.previewEl = !1, Dubtrack.View.Browser = Backbone.View.extend({
  2714. el: b("#browser"),
  2715. events: {
  2716. "click .close-browser": "hideBrowser",
  2717. "click .sidebar .display-sidebar": "toggleSidebar",
  2718. "click .sidebar .import-playlist": "displayImportView",
  2719. "keydown input#youtube-search": "searchKeyUp",
  2720. "click .music-type-select .music-type-dropdown .youtube-btn": "setYoutube",
  2721. "click .music-type-select .music-type-dropdown .icon-soundcloud": "setSoundcloud",
  2722. "click #searchBtnMain": "search",
  2723. "click a.search-btn": "search",
  2724. "click li.current_queue": "displayQueue",
  2725. "click li.room_history": "displayHistory",
  2726. "click li.current_room_queue": "displayRoomQueue",
  2727. "click li.my_tracks": "displayMyTracks",
  2728. "click .create-playlist .create-playlist-display": "createPlaylistDisplay",
  2729. "click .create-playlist .create-playlist-form span": "createPlaylist",
  2730. "keydown .create-playlist .create-playlist-form input": "createPlaylistInput"
  2731. },
  2732. initialize: function() {
  2733. this.searchCollection = new Dubtrack.Collection.Song, this.searchCollection.parse = function(a, b) {
  2734. return a.data.nextPageToken && (this.nextPageToken = a.data.nextPageToken), a.data.items
  2735. }, this.historyCollection = new Dubtrack.Collection.UserQueue, this.userQueueCollection = new Dubtrack.Collection.UserQueue, this.userPlaylistCollection = new Dubtrack.Collection.UserQueue, this.browser_view_state = null, this.canCloseBrowser = !1, b(window).bind("click.browser", function(a) {
  2736. $parents = b(a.target).parents("#browser"), $parents_preview = b(a.target).parents(".playerPreview"), 0 === $parents.length && 0 === $parents_preview.length && this.canCloseBrowser && this.hideBrowser()
  2737. }.bind(this)), this.render()
  2738. },
  2739. render: function() {
  2740. this.$el.html(Dubtrack.els.templates.layout.browser).show().addClass("animate"), this.importPlaylistView = new Dubtrack.View.ImportPlaylistBrowser({
  2741. el: this.$("#import-playlist-container")
  2742. }), this.importPlaylistView.setBrowser(this), this.playlistListContainer = this.$("ul.playlist-list"), this.loadingEl = this.$("div.loading"), this.playlistContainer = this.$("div#results_video_api"), this.inputSearch = this.$("input#youtube-search"), _.each(this.model.models, function(a) {
  2743. this.appendEl(a)
  2744. }, this), this.model.bind("add", this.appendEl, this), this.setYoutube();
  2745. return f.playlist.browserDocBind || (f.playlist.browserDocBind = !0), b("#browser .content-videos, #playlists-scroll").perfectScrollbar({
  2746. wheelSpeed: 20,
  2747. suppressScrollX: !0,
  2748. wheelPropagation: !1,
  2749. onscrollCallback: function(a, b) {
  2750. 100 > b - a && this.scrollPlaylistItemsActionBottom()
  2751. }.bind(this)
  2752. }), Dubtrack.playerController && Dubtrack.playerController.fetchQueueInfo(), this
  2753. },
  2754. scrollPlaylistItemsActionBottom: function() {},
  2755. displayImportView: function() {
  2756. return this.importPlaylistView.openView(), !1
  2757. },
  2758. toggleSidebar: function() {
  2759. return this.$el.toggleClass("display-browser-sidebar"), !1
  2760. },
  2761. createPlaylistDisplay: function() {
  2762. return this.$el.addClass("display-create-form"), this.$(".create-playlist .create-playlist-form input").focus(), !1
  2763. },
  2764. createPlaylistInput: function(a) {
  2765. c = a.which ? a.which : a.keyCode, 13 === c && this.createPlaylist()
  2766. },
  2767. createPlaylist: function() {
  2768. var a = b.trim(this.$(".create-playlist input").val());
  2769. if ("" !== a && null !== a) {
  2770. var c = new Dubtrack.Model.Playlist({
  2771. name: a
  2772. });
  2773. c.parse = Dubtrack.helpers.parse;
  2774. var d = this;
  2775. c.save({}, {
  2776. success: function() {
  2777. d.model.add(c), Dubtrack.app.navigate("/browser/user/" + c.id, {
  2778. trigger: !0
  2779. })
  2780. }
  2781. }), this.$(".create-playlist input").val("")
  2782. }
  2783. },
  2784. setDubtrack: function() {
  2785. return this.$find(".br-btn").removeClass("active"), this.$("a#dubtrack-btn").addClass("active"), !1
  2786. },
  2787. setYoutube: function() {
  2788. return this.$(".music-type-select .current-music-type-selection i").attr("class", "").addClass("icon-youtube"), this.searchType = "youtube", !1
  2789. },
  2790. setSoundcloud: function() {
  2791. return this.$(".music-type-select .current-music-type-selection i").attr("class", "").addClass("icon-soundcloud"), this.searchType = "soundcloud", !1
  2792. },
  2793. searchKeyUp: function(a) {
  2794. c = a.which ? a.which : a.keyCode, 13 == c && this.search()
  2795. },
  2796. search: function() {
  2797. return Dubtrack.app.navigate("/browser/search", {
  2798. trigger: !1
  2799. }), this.displayDetails("search", this.inputSearch.val()), !1
  2800. },
  2801. displayQueue: function() {
  2802. return Dubtrack.app.navigate("/browser/queue/", {
  2803. trigger: !0
  2804. }), !1
  2805. },
  2806. displayHistory: function() {
  2807. return Dubtrack.app.navigate("/browser/history/", {
  2808. trigger: !0
  2809. }), !1
  2810. },
  2811. displayRoomQueue: function() {
  2812. return Dubtrack.app.navigate("/browser/room-queue/", {
  2813. trigger: !0
  2814. }), !1
  2815. },
  2816. displayMyTracks: function() {
  2817. return dubtrackapp.navigate("/browser/tracks/", {
  2818. trigger: !0
  2819. }), !1
  2820. },
  2821. sortableUpdate: function(a, c) {
  2822. var d = [];
  2823. this.playlistDetailContainer.children("li").each(function(a, c) {
  2824. d.push(b(c).attr("data-id"))
  2825. }), Dubtrack.helpers.sendRequest(this.url_items_order, {
  2826. "order[]": d
  2827. }, "post", function(a) {}.bind(this))
  2828. },
  2829. displayDetails: function(a, c) {
  2830. this.loadingEl.show(), this.canCloseBrowserTimeout = setTimeout(function() {
  2831. this.canCloseBrowser = !0
  2832. }.bind(this), 500), this.browserInfoEl && this.browserInfoEl.close();
  2833. var d = this;
  2834. switch (this.playlistDetailContainer = b("<ul/>", {
  2835. "class": "browserPlaylistItems"
  2836. }), this.scrollPlaylistItemsActionBottom = function() {}, this.moreItemsToLoadTimeout && clearTimeout(this.moreItemsToLoadTimeout), this.browserItemsList && this.browserItemsList.close(), this.playlistContainer.find(".timeago").timeago("dispose"), this.playlistContainer.html(this.playlistDetailContainer), this.$(".content-videos").scrollTop(0), this.$(".content-videos").perfectScrollbar("update"), this.$("#playlists-scroll .selected").removeClass("selected"), this.$el.removeClass("display-create-form"), this.$el.removeClass("display-browser-sidebar"), this.browser_view_state = a, a) {
  2837. case "user":
  2838. $c = this.model.get(c), $c ? this.browserInfoEl = new Dubtrack.View.BrowserPlaylistInfo({
  2839. model: $c
  2840. }).setBrowser(d).render("playlistInfo", this.userPlaylistCollection) : (this.browserInfoEl = (new Dubtrack.View.BrowserPlaylistInfo).setBrowser(d).render("playlistInfo", this.userPlaylistCollection), this.browserInfoEl.setName(dubtrack_lang.global.loading)), this.$("#playlists-scroll .playlist-" + c).addClass("selected");
  2841. var e = Dubtrack.config.apiUrl + Dubtrack.config.urls.playlistSong.replace(":id", c),
  2842. f = Dubtrack.config.apiUrl + Dubtrack.config.urls.playlistOrder.replace(":id", c);
  2843. this.url_items_order = f, this.userPlaylistCollection.reset(), this.userPlaylistCollection.url = e, this.browserInfoEl.$el.prependTo(this.playlistContainer), this.browserItemsList = new Dubtrack.View.BrowserUserPlaylistList({
  2844. model: this.userPlaylistCollection,
  2845. el: this.playlistDetailContainer
  2846. }), this.browserItemsList.setBrowser(this), this.browserItemsList.url_queue_order = f, this.browserItemsList.url_queue_order_data = "data-id", this.browserItemsList.setSortable(), this.browserItemsList.fetchItems(function() {
  2847. this.scrollPlaylistItemsActionBottom = function() {
  2848. this.browserItemsList.fetchItems()
  2849. }.bind(this)
  2850. }.bind(this));
  2851. break;
  2852. case "search":
  2853. "" !== c || null !== c ? (this.browserInfoEl = (new Dubtrack.View.BrowserSearchInfo).render(c), this.browserInfoEl.$el.prependTo(this.playlistContainer), this.currentPage = 1, this.moreItemsToLoad = !1, this.scrollPlaylistItemsActionBottom = function() {
  2854. this.moreItemsToLoad && this.searchCollection.nextPageToken && (this.moreItemsToLoad = !1, this.loadingEl.show(), Dubtrack.helpers.sendRequest(Dubtrack.config.apiUrl + Dubtrack.config.urls.song, {
  2855. name: c,
  2856. type: this.searchType,
  2857. details: 1,
  2858. nextPageToken: this.searchCollection.nextPageToken
  2859. }, "get", function(a, c) {
  2860. this.loadingEl.hide(), c && c.data && c.data.items && c.data.items.length > 1 && c.data.nextPageToken && c.data.nextPageToken != this.searchCollection.nextPageToken && (this.searchCollection.nextPageToken = c.data.nextPageToken, _.each(c.data.items, function(a) {
  2861. var b = new Dubtrack.Model.Song(a),
  2862. c = new Dubtrack.View.BrowserPlaylistItem({
  2863. model: b
  2864. }).render("playlistSearchItem").$el.appendTo(this.playlistDetailContainer);
  2865. b.set({
  2866. browserView: c,
  2867. filterName: b.get("name")
  2868. }), this.searchCollection.add(b)
  2869. }.bind(this)), b("#browser .content-videos").perfectScrollbar("update"), this.moreItemsToLoadTimeout = setTimeout(function() {
  2870. this.moreItemsToLoad = !0
  2871. }.bind(this), 1e3))
  2872. }.bind(this)))
  2873. }.bind(this), this.nextPageToken = null, this.searchCollection.reset(), this.searchCollection.url = Dubtrack.config.apiUrl + Dubtrack.config.urls.song, this.searchCollection.fetch({
  2874. data: {
  2875. name: c,
  2876. type: this.searchType,
  2877. details: 1,
  2878. nextPageToken: ""
  2879. },
  2880. success: function() {
  2881. _.each(d.searchCollection.models, function(a) {
  2882. var b = new Dubtrack.View.BrowserPlaylistItem({
  2883. model: a
  2884. }).render("playlistSearchItem").$el.appendTo(d.playlistDetailContainer);
  2885. a.set({
  2886. browserView: b,
  2887. filterName: a.get("name")
  2888. })
  2889. }), d.searchCollection.models.length >= 15 && (d.moreItemsToLoad = !0), b("#browser .content-videos").perfectScrollbar("update"), d.loadingEl.hide()
  2890. },
  2891. error: function() {
  2892. d.loadingEl.hide()
  2893. }
  2894. })) : this.loadingEl.hide();
  2895. break;
  2896. case "history":
  2897. this.browserInfoEl = (new Dubtrack.View.BrowserHistoryInfo).render(this.historyCollection), this.browserInfoEl.$el.prependTo(this.playlistContainer), this.$("#playlists-scroll .room_history").addClass("selected");
  2898. var g = Dubtrack.config.apiUrl + Dubtrack.config.urls.roomHistory.replace(":id", Dubtrack.room.model.get("_id"));
  2899. this.historyCollection.url = g, this.historyCollection.reset(), this.browserItemsList = new Dubtrack.View.BrowserHistoryPlaylistList({
  2900. model: this.historyCollection,
  2901. el: this.playlistDetailContainer
  2902. }), this.browserItemsList.setBrowser(this), this.browserItemsList.fetchItems(function() {
  2903. this.browserItemsList.prependItems = !0
  2904. }.bind(this));
  2905. break;
  2906. case "queue":
  2907. if (this.browserInfoEl = (new Dubtrack.View.MyQueueInfo).setBrowser(d).render(this.userQueueCollection), this.browserInfoEl.$el.prependTo(this.playlistContainer), this.$("#playlists-scroll .current_queue").addClass("selected"), Dubtrack.room && Dubtrack.room.model.get("lockQueue") && !(Dubtrack.helpers.isDubtrackAdmin(Dubtrack.session.id) || Dubtrack.room.users && Dubtrack.room.users.getIfHasRole(Dubtrack.session.id))) d.loadingEl.hide(), b("<li/>").addClass("queue-locked-info").text("Queue is locked, but you can still enjoy the tunes in this room :]").appendTo(d.playlistDetailContainer);
  2908. else {
  2909. var h = Dubtrack.config.apiUrl + Dubtrack.config.urls.userQueue.replace(":id", Dubtrack.room.model.get("_id")),
  2910. i = Dubtrack.config.apiUrl + Dubtrack.config.urls.userQueueOrder.replace(":id", Dubtrack.room.model.get("_id"));
  2911. this.userQueueCollection.url = h, this.url_items_order = i, this.userQueueCollection.reset(), this.browserItemsList = new Dubtrack.View.BrowserUserQueuePlaylistList({
  2912. model: this.userQueueCollection,
  2913. el: this.playlistDetailContainer
  2914. }), this.browserItemsList.setBrowser(this), this.browserItemsList.url_queue_order = i, this.browserItemsList.url_queue_order_data = "data-id", this.browserItemsList.setSortable(), this.browserItemsList.fetchItems()
  2915. }
  2916. break;
  2917. case "room_queue":
  2918. this.$("#playlists-scroll .current_room_queue").addClass("selected");
  2919. var h = Dubtrack.config.apiUrl + Dubtrack.config.urls.roomQueueDetails.replace(":id", Dubtrack.room.model.get("_id")),
  2920. i = Dubtrack.config.apiUrl + Dubtrack.config.urls.roomUserQueueOrder.replace(":id", Dubtrack.room.model.get("_id"));
  2921. this.url_items_order = i, this.userQueueCollection.url = h, this.userQueueCollection.reset(), this.browserItemsList = new Dubtrack.View.BrowserRoomQueuePlaylistList({
  2922. model: this.userQueueCollection,
  2923. el: this.playlistDetailContainer
  2924. }), this.browserItemsList.setBrowser(this), this.browserItemsList.fetchItems(function() {
  2925. Dubtrack.session && Dubtrack.room && Dubtrack.room.users && (Dubtrack.helpers.isDubtrackAdmin(Dubtrack.session.id) || Dubtrack.room.users.getIfRoleHasPermission(Dubtrack.session.id, "queue-order")) ? (this.browserInfoEl = (new Dubtrack.View.RoomQueueInfo).setBrowser(this).render(this.userQueueCollection),
  2926. this.browserInfoEl.$el.prependTo(this.playlistContainer), this.playlistDetailContainer.addClass("display-mod-controls"), this.browserItemsList.url_queue_order = i, this.browserItemsList.url_queue_order_data = "data-userid", this.browserItemsList.setSortable()) : this.playlistDetailContainer.removeClass("display-mod-controls")
  2927. }.bind(this));
  2928. break;
  2929. default:
  2930. this.loadingEl.hide()
  2931. }
  2932. },
  2933. hideBrowser: function() {
  2934. return this.browser_view_state = null, this.canCloseBrowserTimeout && clearTimeout(this.canCloseBrowserTimeout), this.canCloseBrowser = !1, b(".dubtrack_overlay").hide(), this.$el.show().removeClass("animate"), Dubtrack.room && Dubtrack.room.model ? Dubtrack.app.navigate("/join/" + Dubtrack.room.model.get("roomUrl"), {
  2935. trigger: !0
  2936. }) : Dubtrack.app.navigate("/", {
  2937. trigger: !0
  2938. }), !1
  2939. },
  2940. displayBrowser: function() {
  2941. this.browser_view_state = null, this.$el.addClass("animate"), this.$("#youtube-search").val("").focus(), b(".dubtrack_overlay").show()
  2942. },
  2943. beforeClose: function() {
  2944. this.browserItemsList && this.browserItemsList.close(), this.browser_view_state = null;
  2945. try {
  2946. this.playlistDetailContainer.multisortable("destroy")
  2947. } catch (a) {}
  2948. Dubtrack.app.navigate("/", {
  2949. trigger: !0
  2950. })
  2951. },
  2952. appendEl: function(a) {
  2953. new Dubtrack.View.playlistItem({
  2954. model: a
  2955. }).render().$el.prependTo(this.playlistListContainer)
  2956. }
  2957. }), Dubtrack.View.BrowserInfo = Backbone.View.extend({
  2958. tagName: "div",
  2959. events: {
  2960. "keyup input.editplaylist_name": "updatePlaylistNameKeyup",
  2961. "keyup input.playlist_filter": "filterPlaylist",
  2962. "click .save-playlistname": "updatePlaylistName",
  2963. "click a.shuffle-playlist": "shufflePlaylist",
  2964. "click a.delete-playlist": "removePlaylist",
  2965. "click a.queue-playlist": "queuePlaylist",
  2966. "click .edit-playlist-name": "togglePlaylistEdit",
  2967. "click a.navigate": "navigate"
  2968. },
  2969. initialize: function() {
  2970. this.$el.addClass("playlist_info")
  2971. },
  2972. render: function(a, c) {
  2973. return this.model && this.$el.html(_.template(Dubtrack.els.templates.playlist[a], this.model.toJSON())), this.collection = c, this.aplaylist_typeEl = b(this.el).find("a.playlist_type"), this.model && this.renderPlaylistType(this.model.get("playlist_type")), this
  2974. },
  2975. navigate: function(a) {
  2976. var c = b(a.target);
  2977. return $href = c.attr("href"), $href && g.app.navigate($href, {
  2978. trigger: !0
  2979. }), !1
  2980. },
  2981. queuePlaylist: function() {
  2982. this.$("a.queue-playlist").text("loading....");
  2983. var a = Dubtrack.config.apiUrl + Dubtrack.config.urls.roomQueuePlaylist.replace(":playlistid", this.model.get("_id")).replace(":id", Dubtrack.room.model.get("_id"));
  2984. return Dubtrack.helpers.sendRequest(a, {}, "post", function(a) {
  2985. this.$("a.queue-playlist").text("Queue all")
  2986. }.bind(this)), !1
  2987. },
  2988. renderPlaylistType: function(a) {
  2989. "public" == a ? (this.aplaylist_typeEl.removeClass("playlist_type_private").html(dubtrack_lang.global.publicStr), this.aplaylist_typeEl.append("<span>your playlist is viewable by everyone</span>")) : (this.aplaylist_typeEl.addClass("playlist_type_private").html(dubtrack_lang.global.privateStr), this.aplaylist_typeEl.append("<span>your playlist is only viewable by you</span>"))
  2990. },
  2991. filterPlaylist: function(a) {
  2992. var b = a.target.value;
  2993. "" === b || " " === b ? _.each(this.collection.models, function(a) {
  2994. var b = a.get("browserView");
  2995. b.show()
  2996. }, this) : (b = b.toLowerCase(), _.each(this.collection.models, function(a) {
  2997. var c = a.get("browserView");
  2998. $name = a.get("filterName").toLowerCase(), -1 === $name.indexOf(b) ? c.hide() : c.show()
  2999. }, this))
  3000. },
  3001. togglePlaylistEdit: function() {
  3002. return this.$el.toggleClass("displayEdit"), this.$el.hasClass("displayEdit") && this.$("input.editplaylist_name").focus(), !1
  3003. },
  3004. updatePlaylistNameKeyup: function(a) {
  3005. c = a.which ? a.which : a.keyCode, 13 == c && this.updatePlaylistName()
  3006. },
  3007. updatePlaylistName: function() {
  3008. var a = this.$("input.editplaylist_name").val();
  3009. if (a && a.length > 0) {
  3010. this.$el.removeClass("displayEdit");
  3011. var b = Dubtrack.config.apiUrl + Dubtrack.config.urls.playlistUpdate.replace(":id", this.model.get("_id"));
  3012. Dubtrack.helpers.sendRequest(b, {
  3013. name: a
  3014. }, "put", function(a) {}.bind(this));
  3015. var c = Dubtrack.app.browserView.model.findWhere({
  3016. _id: this.model.get("_id")
  3017. });
  3018. c && c.set({
  3019. name: a
  3020. })
  3021. }
  3022. },
  3023. setBrowser: function(a) {
  3024. return this.parent_browser = a, this
  3025. },
  3026. shufflePlaylist: function(a) {
  3027. a && a.preventDefault(), this.parent_browser && (this.parent_browser.playlistDetailContainer.randomize("li.playlist-item"), this.parent_browser.sortableUpdate())
  3028. },
  3029. removePlaylist: function() {
  3030. var a = confirm(dubtrack_lang.playlist.removePlaylistConfirm);
  3031. return a && (this.model.destroy(), this.close()), this.parent_browser.playlistContainer.empty(), Dubtrack.app.navigate("/browser/queue/", {
  3032. trigger: !1
  3033. }), !1
  3034. },
  3035. setName: function(a) {
  3036. this.aplaylist_typeEl.html(a)
  3037. },
  3038. changePlaylistType: function() {
  3039. if (this.model) {
  3040. var a = this;
  3041. $type = this.model.get("type"), this.aplaylist_typeEl.html(dubtrack_lang.global.loading), b.ajax({
  3042. url: g.config.changePlaylistType,
  3043. data: {
  3044. idplaylist: this.model.get("id"),
  3045. type: $type
  3046. },
  3047. type: "POST",
  3048. success: function(b) {
  3049. "public" == $type ? (a.model.set({
  3050. type: "private"
  3051. }), a.renderPlaylistType("private")) : (a.model.set({
  3052. type: "public"
  3053. }), a.renderPlaylistType("public"))
  3054. },
  3055. error: function() {}
  3056. }, "json")
  3057. }
  3058. return !1
  3059. }
  3060. }), Dubtrack.View.BrowserPlaylistInfo = Dubtrack.View.BrowserInfo.extend({
  3061. filterPlaylist: function(a) {
  3062. if (this.parent_browser) {
  3063. var b = a.target.value;
  3064. this.parent_browser.browserItemsList.currentPage = 1, this.parent_browser.browserItemsList.moreItemsToLoad = !0, this.parent_browser.browserItemsList.model.reset(), "" != b || b.length > 0 ? (this.parent_browser.browserItemsList.searchString = b, this.parent_browser.browserItemsList.removeOnFetch = !0) : (this.parent_browser.browserItemsList.searchString = "", this.parent_browser.browserItemsList.removeOnFetch = !1), this.parent_browser.browserItemsList.fetchItemsTimeout()
  3065. }
  3066. }
  3067. }), Dubtrack.View.RoomQueueInfo = Backbone.View.extend({
  3068. tagName: "div",
  3069. events: {
  3070. "click .room-queue-lock": "lockRoom",
  3071. "click .room-queue-unlock": "lockRoom",
  3072. "keyup input.playlist_filter": "filterPlaylist"
  3073. },
  3074. initialize: function() {
  3075. this.$el.addClass("queue_info"), Dubtrack.Events.bind("realtime:room-lock-queue", this.lockRoomRT, this)
  3076. },
  3077. setBrowser: function(a) {
  3078. return this.parent_browser = a, this
  3079. },
  3080. filterPlaylist: function(a) {
  3081. var b = a.target.value;
  3082. "" === b || " " === b ? _.each(this.collection.models, function(a) {
  3083. var b = a.get("browserView");
  3084. b.show()
  3085. }, this) : (b = b.toLowerCase(), _.each(this.collection.models, function(a) {
  3086. var c = a.get("browserView");
  3087. $name = a.get("filterName").toLowerCase(), -1 === $name.indexOf(b) ? c.hide() : c.show()
  3088. }, this))
  3089. },
  3090. render: function(a) {
  3091. this.$el.html(_.template(Dubtrack.els.templates.playlist.roomQueueInfo));
  3092. var b = Dubtrack.room && Dubtrack.room.model.get("lockQueue") ? !0 : !1;
  3093. return b ? (this.$(".room-queue-lock").show(), this.$(".room-queue-unlock").hide()) : (this.$(".room-queue-lock").hide(), this.$(".room-queue-unlock").show()), this.collection = a, this
  3094. },
  3095. lockRoomRT: function(a) {
  3096. a && a.room && (a.room.lockQueue ? (this.$(".room-queue-lock").show(), this.$(".room-queue-unlock").hide()) : (this.$(".room-queue-lock").hide(), this.$(".room-queue-unlock").show()))
  3097. },
  3098. lockRoom: function() {
  3099. if (Dubtrack.helpers.isDubtrackAdmin(Dubtrack.session.id) || Dubtrack.room.users && Dubtrack.room.users.getIfHasRole(Dubtrack.session.id)) {
  3100. if (this.loading_lock_queue) return !1;
  3101. var a = Dubtrack.config.apiUrl + Dubtrack.config.urls.roomLockQueue.replace(":id", Dubtrack.room.model.get("_id")),
  3102. b = Dubtrack.room && Dubtrack.room.model.get("lockQueue") ? 0 : 1;
  3103. return this.loading_lock_queue = !0, Dubtrack.helpers.sendRequest(a, {
  3104. lockQueue: b
  3105. }, "put", function(a) {
  3106. this.loading_lock_queue = !1
  3107. }.bind(this)), !1
  3108. }
  3109. }
  3110. }), Dubtrack.View.MyQueueInfo = Backbone.View.extend({
  3111. tagName: "div",
  3112. events: {
  3113. "click .clear-queue": "clearMyQueue",
  3114. "click .pause-queue": "pauseMyQueue",
  3115. "click a.shuffle-playlist": "shufflePlaylist",
  3116. "keyup input.playlist_filter": "filterPlaylist"
  3117. },
  3118. filterPlaylist: function(a) {
  3119. var b = a.target.value;
  3120. "" === b || " " === b ? _.each(this.collection.models, function(a) {
  3121. var b = a.get("browserView");
  3122. b.show()
  3123. }, this) : (b = b.toLowerCase(), _.each(this.collection.models, function(a) {
  3124. var c = a.get("browserView");
  3125. $name = a.get("filterName").toLowerCase(), -1 === $name.indexOf(b) ? c.hide() : c.show()
  3126. }, this))
  3127. },
  3128. initialize: function() {
  3129. this.$el.addClass("queue_info"), Dubtrack.Events.bind("realtime:user-pause-queue", this.pauseMyQueueRT, this)
  3130. },
  3131. setBrowser: function(a) {
  3132. return this.parent_browser = a, this
  3133. },
  3134. shufflePlaylist: function() {
  3135. return this.parent_browser && (this.parent_browser.playlistDetailContainer.randomize("li.queue-item"), this.parent_browser.sortableUpdate()), !1
  3136. },
  3137. render: function(a) {
  3138. return this.$el.html(_.template(Dubtrack.els.templates.playlist.myQueueInfo)), Dubtrack.session && Dubtrack.room && Dubtrack.room.users && this.pauseMyQueueRT({
  3139. user_queue: {
  3140. queuePaused: Dubtrack.room.users.getIfQueueIsActive(Dubtrack.session.id)
  3141. }
  3142. }), this.collection = a, this
  3143. },
  3144. pauseMyQueueRT: function(a) {
  3145. a && a.user_queue && (a.user_queue.queuePaused ? this.$(".pause-queue").text("Resume") : this.$(".pause-queue").text("Pause"))
  3146. },
  3147. clearMyQueue: function(a) {
  3148. return a && a.preventDefault(), confirm("Are you sure you want to clear your queue?") && Dubtrack.room && Dubtrack.room.model && (this.$(".clear-queue").text("loading...."), b.ajax({
  3149. url: Dubtrack.config.apiUrl + "/room/" + Dubtrack.room.model.get("_id") + "/playlist",
  3150. type: "delete"
  3151. }).always(function() {
  3152. this.$(".clear-queue").text("clear"), this.$(".clear-queue-browser-bth").text("Clear"), this.parent_browser.displayDetails("queue")
  3153. }.bind(this))), !1
  3154. },
  3155. pauseMyQueue: function(a) {
  3156. if (this.loading_pause_queue) return !1;
  3157. this.$(".pause-queue").text("loading...."), this.loading_pause_queue = !0;
  3158. var b = Dubtrack.config.apiUrl + Dubtrack.config.urls.userQueuePause.replace(":id", Dubtrack.room.model.get("_id")),
  3159. c = Dubtrack.session && Dubtrack.room && Dubtrack.room.users && Dubtrack.room.users.getIfQueueIsActive(Dubtrack.session.id) ? 0 : 1;
  3160. return Dubtrack.helpers.sendRequest(b, {
  3161. queuePaused: c
  3162. }, "put", function(a) {
  3163. a && this.$(".pause-queue").text("Coundn't update your queue settings"), this.loading_pause_queue = !1
  3164. }.bind(this)), !1
  3165. }
  3166. }), Dubtrack.View.BrowserSearchInfo = Backbone.View.extend({
  3167. tagName: "div",
  3168. events: {},
  3169. initialize: function() {
  3170. this.$el.addClass("queue_info")
  3171. },
  3172. setBrowser: function(a) {
  3173. return this.parent_browser = a, this
  3174. },
  3175. render: function(a) {
  3176. return this.$el.html(_.template(Dubtrack.els.templates.playlist.playlistSearchBrowser, {
  3177. name: a
  3178. })), this
  3179. }
  3180. }), Dubtrack.View.BrowserHistoryInfo = Dubtrack.View.BrowserInfo.extend({
  3181. tagName: "div",
  3182. initialize: function() {
  3183. this.$el.addClass("queue_info")
  3184. },
  3185. setBrowser: function(a) {
  3186. return this.parent_browser = a, this
  3187. },
  3188. render: function(a) {
  3189. return this.$el.html(_.template(Dubtrack.els.templates.playlist.playlistHistoryBrowser)), this.collection = a, this
  3190. }
  3191. }), Dubtrack.View.playlistItem = Backbone.View.extend({
  3192. tagName: "li",
  3193. attributes: {
  3194. "class": "playlist_icon"
  3195. },
  3196. events: {
  3197. click: "viewDetails",
  3198. "click .add_to_queue": "queuePlaylist",
  3199. "click .delete": "removePlaylist"
  3200. },
  3201. initialize: function() {
  3202. this.model.bind("change", this.render, this), this.model.bind("destroy", this.close, this)
  3203. },
  3204. queuePlaylist: function() {
  3205. return Dubtrack.app.navigate("/browser/user/" + this.model.get("_id"), {
  3206. trigger: !1
  3207. }), Dubtrack.app.browserView.displayDetails("queueSong", this.model.get("_id")), !1
  3208. },
  3209. setBrowser: function() {
  3210. return this
  3211. },
  3212. removePlaylist: function() {
  3213. var a = confirm(dubtrack_lang.playlist.removePlaylistConfirm);
  3214. return a && (this.model.destroy(), this.close()), !1
  3215. },
  3216. render: function() {
  3217. return this.$el.html(_.template(Dubtrack.els.templates.playlist.playlistBrowser, this.model.toJSON())), this.$el.addClass("playlist-" + this.model.id), this
  3218. },
  3219. viewDetails: function(a) {
  3220. return Dubtrack.app.navigate("/browser/user/" + this.model.get("_id"), {
  3221. trigger: !0
  3222. }), !1
  3223. }
  3224. }), Dubtrack.View.BrowserPlaylistItem = Backbone.View.extend({
  3225. tagName: "li",
  3226. attributes: {
  3227. "class": "search-item"
  3228. },
  3229. events: {
  3230. click: "closePlaylistCont",
  3231. "click .add_to_queue": "addToQueue",
  3232. "click .remove_icon": "removePlaylist",
  3233. "click .add_to_playlist": "addPlaylistContainer",
  3234. "click .add_to_playlistQueue": "addPlaylistQueueContainer",
  3235. "click .remove_queue": "removeFromQueue",
  3236. "click .remove_track": "removeTrack",
  3237. "click .remove_dj": "removeDJFromQueue",
  3238. "click .remove_dj_all": "removeDJAllFromQueue",
  3239. "click .preview": "preview",
  3240. "click a.editBtn": "focusInput",
  3241. "blur input.track_name_input": "updateTrackName",
  3242. "click .set_song_to_top_queue": "moveToTop"
  3243. },
  3244. initialize: function() {},
  3245. moveToTop: function(a) {
  3246. a && a.preventDefault(), this.parent_browser && (this.$el.prependTo(this.$el.parents(".browserPlaylistItems")), this.parent_browser.sortableUpdate())
  3247. },
  3248. setBrowser: function(a) {
  3249. return this.parent_browser = a, this
  3250. },
  3251. closePlaylistCont: function(a) {
  3252. $parents = b(a.target).parents(".playlist-options"), 0 === $parents.length && f.playlist.containerElCreateApp && f.playlist.containerElCreateApp.close()
  3253. },
  3254. setTime: function() {
  3255. var a = Math.floor(parseFloat(this.model.get("songLength")) / 6e4),
  3256. b = Math.floor(parseFloat(this.model.get("songLength")) / 1e3 - 60 * a);
  3257. b.length < 2 && (b = "0" + b), a = "0".substring(a >= 10) + a, b = "0".substring(b >= 10) + b, this.model.set({
  3258. minute: a,
  3259. second: b
  3260. })
  3261. },
  3262. render: function(a) {
  3263. return this.setTime(), this.$el.html(_.template(Dubtrack.els.templates.playlist[a], this.model.toJSON())), this
  3264. },
  3265. focusInput: function() {
  3266. return b(this.el).find("input.track_name_input").focus(), !1
  3267. },
  3268. updateTrackName: function(a) {
  3269. $songName = b(a.target).val(), $songName && " " !== $songName && 0 !== $songName && b.ajax({
  3270. url: g.config.updateMytracksUrl,
  3271. data: {
  3272. id: this.model.get("id"),
  3273. title: $songName
  3274. },
  3275. type: "POST",
  3276. success: function(a) {},
  3277. error: function() {}
  3278. }, "json")
  3279. },
  3280. removePlaylist: function() {
  3281. return !1
  3282. },
  3283. preview: function() {
  3284. return f.playlist.previewEl && f.playlist.previewEl.close(), f.playlist.previewEl = new Dubtrack.View.PreivewEl({
  3285. model: this.model
  3286. }), f.playlist.previewEl.$el.appendTo(b("body")), f.playlist.previewEl.render(), b("html,body").stop(!0).animate({
  3287. scrollTop: 0
  3288. }), !1
  3289. },
  3290. removeFromQueue: function() {
  3291. return b.ajax({
  3292. url: g.config.removeFromQueue,
  3293. data: {
  3294. id: this.model.get("id")
  3295. },
  3296. type: "POST",
  3297. success: function(a) {},
  3298. error: function() {}
  3299. }, "json"), this.close(), !1
  3300. },
  3301. removeDJFromQueue: function() {
  3302. return !1
  3303. },
  3304. removeDJAllFromQueue: function() {
  3305. return !1
  3306. },
  3307. removeTrack: function() {
  3308. var a = confirm(dubtrack_lang.playlist.confirmRemoveTrack);
  3309. return a && (b.ajax({
  3310. url: g.config.deleteMytracksUrl,
  3311. data: {
  3312. id: this.model.get("id")
  3313. },
  3314. type: "POST",
  3315. success: function(a) {},
  3316. error: function() {}
  3317. }, "json"), this.close()), !1
  3318. },
  3319. addPlaylistContainer: function(a) {
  3320. var b = {
  3321. right: 0,
  3322. top: 10
  3323. };
  3324. return Dubtrack.helpers.genPlaylistContainer(this.$el, b, this.model.get("fkid"), this.model.get("type")), !1
  3325. },
  3326. addToQueue: function() {
  3327. var a = this.model.get("type"),
  3328. b = this.model.get("fkid"),
  3329. c = this;
  3330. return this.$(".add_to_queue").addClass("loading-action"), Dubtrack.helpers.playlist.addQueue(b, a, function(a, b) {
  3331. if (a) try {
  3332. a && a.data && a.data.err && a.data.err.details && a.data.err.details && a.data.err.details.message ? c.$(".display-error").show().html(a.data.err.details.message) : c.$(".display-error").show().html("Song already in queue or played in the last hour")
  3333. } catch (d) {
  3334. c.$(".display-error").show().html("Song already in queue or played in the last hour")
  3335. } else c.$(".display-success").show().html("Song added to queue");
  3336. c.$(".add_to_queue").hide()
  3337. }), !1
  3338. }
  3339. }), Dubtrack.View.BrowserPlaylisHistorytItem = Dubtrack.View.BrowserPlaylistItem.extend({
  3340. attributes: {
  3341. "class": "history-item"
  3342. },
  3343. fetchSong: function(a) {
  3344. this.queue = a;
  3345. var b = this.queue.get("_song");
  3346. return b && "object" == typeof b ? (b = Dubtrack.cache.songs.add(b), this.render(null, b)) : Dubtrack.cache.songs.get(this.queue.get("songid"), this.render, this), this
  3347. },
  3348. render: function(a, c) {
  3349. return this.model = c, this.queue.set("song", c.toJSON()), this.queue.set({
  3350. filterName: c.get("name")
  3351. }), this.setTime(), this.$el.html(_.template(Dubtrack.els.templates.playlist.playlistSearchItem, this.model.toJSON())).show(), b("#browser .content-videos").perfectScrollbar("update"), this
  3352. }
  3353. }), Dubtrack.View.BrowserPlaylisHistorytItemWithDescription = Dubtrack.View.BrowserPlaylistItem.extend({
  3354. attributes: {
  3355. "class": "history-item"
  3356. },
  3357. fetchSong: function(a) {
  3358. this.queue = a;
  3359. var b = this.queue.get("_song");
  3360. return b && "object" == typeof b ? (b = Dubtrack.cache.songs.add(b), this.render(null, b)) : Dubtrack.cache.songs.get(this.queue.get("songid"), this.render, this), this
  3361. },
  3362. render: function(a, c) {
  3363. this.model = c, this.queue.set("song", c.toJSON()), this.queue.set({
  3364. filterName: c.get("name")
  3365. }), this.setTime();
  3366. var d = this.model.toJSON();
  3367. d._user = this.queue.get("_user"), d.updubs = this.queue.get("updubs"), d.downdubs = this.queue.get("downdubs"), d.grabs = this.queue.get("grabs"), d.skipped = this.queue.get("skipped"), this.$el.html(_.template(Dubtrack.els.templates.playlist.playlistHistoryItem, d)).show();
  3368. var e = new Date(this.queue.get("played") + this.queue.get("songLength"));
  3369. return this.$(".timeinfo").html('<time class="timeago" datetime="' + e.toISOString() + '">' + e.toLocaleString() + "</time>"), this.$(".timeago").timeago(), b("#browser .content-videos").perfectScrollbar("update"), this
  3370. }
  3371. }), Dubtrack.View.BrowserPlaylisUserPlaylisttItem = Dubtrack.View.BrowserPlaylisHistorytItem.extend({
  3372. attributes: {
  3373. "class": "playlist-item"
  3374. },
  3375. render: function(a, b) {
  3376. return Dubtrack.View.BrowserPlaylisHistorytItem.prototype.render.call(this, a, b), this.$el.attr("data-id", this.queue.get("_id")), this
  3377. },
  3378. removePlaylist: function() {
  3379. var a = Dubtrack.config.apiUrl + Dubtrack.config.urls.playlistSong.replace(":id", this.model.get("playlistid"));
  3380. return this.queue.baseUrl = a, this.queue.destroy({
  3381. success: function(a, b) {
  3382. if (b && b.data) {
  3383. var c = Dubtrack.app.browserView.model.findWhere({
  3384. _id: b.data._id
  3385. });
  3386. c && c.set(b.data)
  3387. }
  3388. }
  3389. }), this.close(), !1
  3390. }
  3391. }), Dubtrack.View.BrowserQueuePlaylisttItem = Dubtrack.View.BrowserPlaylisHistorytItem.extend({
  3392. attributes: {
  3393. "class": "queue-item"
  3394. },
  3395. render: function(a, b) {
  3396. return Dubtrack.View.BrowserPlaylisHistorytItem.prototype.render.call(this, a, b), this.$el.attr("data-id", this.queue.get("_id")), this
  3397. },
  3398. removePlaylist: function() {
  3399. return Dubtrack.helpers.playlist.removeQueue(this.queue.get("_id")), this.close(), !1
  3400. }
  3401. }), Dubtrack.View.BrowserRoomQueuePlaylisttItem = Dubtrack.View.BrowserPlaylisHistorytItem.extend({
  3402. attributes: {
  3403. "class": "queue-item room-queue-item"
  3404. },
  3405. removeDJFromQueue: function() {
  3406. return this.$(".remove_dj").addClass("loading-action"), b.ajax({
  3407. url: Dubtrack.config.apiUrl + "/room/" + Dubtrack.room.model.get("_id") + "/queue/user/" + this.queue.get("userid"),
  3408. type: "delete"
  3409. }).success(function(a) {
  3410. try {
  3411. a && a.data && a.data.userNextSong && a.data.userNextSong._song ? this.render(null, new Dubtrack.Model.Song(a.data.userNextSong._song)) : this.$el.remove()
  3412. } catch (b) {
  3413. this.$el.remove()
  3414. }
  3415. }.bind(this)).error(function() {
  3416. this.$(".display-error").show().html("You don't have permissions to do this")
  3417. }.bind(this)).always(function() {
  3418. this.$(".remove_dj").removeClass("loading-action")
  3419. }.bind(this)), !1
  3420. },
  3421. removeDJAllFromQueue: function() {
  3422. return this.$(".remove_dj_all").addClass("loading-action"), b.ajax({
  3423. url: Dubtrack.config.apiUrl + "/room/" + Dubtrack.room.model.get("_id") + "/queue/user/" + this.queue.get("userid") + "/all",
  3424. type: "delete"
  3425. }).success(function(a) {
  3426. this.$el.remove()
  3427. }.bind(this)).error(function() {
  3428. this.$(".display-error").show().html("You don't have permissions to do this")
  3429. }.bind(this)).always(function() {
  3430. this.$(".remove_dj_all").removeClass("loading-action")
  3431. }.bind(this)), !1
  3432. },
  3433. render: function(a, c) {
  3434. this.model = c, this.queue.set("song", c.toJSON()), this.$el.attr("data-userid", this.queue.get("userid")), this.$el.attr("data-id", this.queue.get("userid")), this.queue.set({
  3435. filterName: c.get("name")
  3436. }), this.setTime();
  3437. var d = this.model.toJSON();
  3438. return d._user = this.queue.get("_user"), this.$el.html(_.template(Dubtrack.els.templates.playlist.playlistRoomQueueItem, d)).show(), b("#browser .content-videos").perfectScrollbar("update"), this
  3439. }
  3440. }), Dubtrack.View.containerElCreate = Backbone.View.extend({
  3441. tagName: "div",
  3442. events: {
  3443. "click .create-playlist-header .icon-close": "closeWindow",
  3444. "click a": "addPLaylist",
  3445. "click .create-playlist-input span": "createPlaylist",
  3446. "keydown .create-playlist-input input": "createPlaylistInput"
  3447. },
  3448. attributes: {
  3449. id: "addToPlaylistFloatContainer"
  3450. },
  3451. initialize: function() {
  3452. b(this.el).attr("class", "playlist-options")
  3453. },
  3454. render: function(a, c, d, e) {
  3455. return this.$el.html(_.template(Dubtrack.els.templates.playlist.playlistContainer, {})).appendTo("body"), this.songid = d, this.type = e, _.each(this.model.models, function(a) {
  3456. this.appendEl(a)
  3457. }, this), b("#addToPlaylistFloatContainer .playlist-list-action").perfectScrollbar({
  3458. wheelSpeed: 20,
  3459. suppressScrollX: !0,
  3460. wheelPropagation: !1
  3461. }), this.model.bind("add", this.appendEl, this), this
  3462. },
  3463. appendEl: function(a) {
  3464. new Dubtrack.View.containerElCreateItem({
  3465. model: a
  3466. }).render(this).$el.prependTo(this.$("ul.playlist-list-action"))
  3467. },
  3468. createPlaylistInput: function(a) {
  3469. c = a.which ? a.which : a.keyCode, 13 === c && this.createPlaylist()
  3470. },
  3471. createPlaylist: function() {
  3472. var a = b.trim(this.$(".create-playlist-input input").val());
  3473. if ("" !== a && null !== a) {
  3474. var c = new Dubtrack.Model.Playlist({
  3475. name: a
  3476. });
  3477. c.parse = Dubtrack.helpers.parse;
  3478. c.save({}, {
  3479. success: function() {
  3480. Dubtrack.user.playlist.add(c), Dubtrack.app.browserView.appendEl(c)
  3481. }
  3482. }), this.$(".create-playlist-input input").val("")
  3483. }
  3484. },
  3485. closeWindow: function() {
  3486. return this.close(), !1
  3487. }
  3488. }), Dubtrack.View.containerElCreateItem = Backbone.View.extend({
  3489. tagName: "li",
  3490. events: {
  3491. click: "addToPlaylist"
  3492. },
  3493. initialize: function() {},
  3494. render: function(a) {
  3495. return this.$el.html(this.model.get("name")), this.parentView = a, this
  3496. },
  3497. addToPlaylist: function() {
  3498. this.$el.parents("li").find("a.add_to_playlist").addClass("active");
  3499. var a = Dubtrack.config.apiUrl + Dubtrack.config.urls.playlistSong.replace(":id", this.model.get("_id"));
  3500. return this.parentView.type ? Dubtrack.helpers.sendRequest(a, {
  3501. fkid: this.parentView.songid,
  3502. type: this.parentView.type
  3503. }, "post", function(a, b) {
  3504. if (!a && b && b.data) {
  3505. var c = Dubtrack.app.browserView.model.findWhere({
  3506. _id: this.model.get("_id")
  3507. });
  3508. c && (c.set(b.data), this.model.set(b.data))
  3509. }
  3510. }.bind(this)) : Dubtrack.helpers.sendRequest(a, {
  3511. songid: this.parentView.songid
  3512. }, "post", function(a, b) {
  3513. if (!a && b && b.data) {
  3514. var c = Dubtrack.app.browserView.model.findWhere({
  3515. _id: this.model.get("_id")
  3516. });
  3517. c && (c.set(b.data), this.model.set(b.data))
  3518. }
  3519. }.bind(this)), this.parentView.close(), !1
  3520. }
  3521. }), Dubtrack.View.PreivewEl = Backbone.View.extend({
  3522. tagName: "div",
  3523. className: "playerPreview",
  3524. events: {
  3525. "click .close": "closeAction"
  3526. },
  3527. initialize: function() {
  3528. this.$el.html(Dubtrack.els.templates.playlist.previewContainer)
  3529. },
  3530. render: function() {
  3531. return this.player_container = this.$(".playerDubContainer"), b(document).on("click", function(a) {
  3532. f.playlist.previewEl && ($parents = b(a.target).parents(".playerPreview"), 0 === $parents.length && f.playlist.previewEl.close())
  3533. }), this.buildPlayer(), this.loadComments(), this
  3534. },
  3535. buildPlayer: function() {
  3536. switch (this.id = this.model.get("fkid"), this.model.get("type")) {
  3537. case "youtube":
  3538. this.buildYT();
  3539. break;
  3540. case "soundcloud":
  3541. case "dubtrack":
  3542. this.buildSoundCloud()
  3543. }
  3544. },
  3545. closeAction: function() {
  3546. this.close()
  3547. },
  3548. buildYT: function() {
  3549. this.player = new i, this.player_container.append(this.player.render(this.id, this.id + "_video").$el), this.player.buildPlayer(!0)
  3550. },
  3551. buildSoundCloud: function() {
  3552. this.player = new scDubsPlayerView, this.player_container.append(this.player.render(this.model.get("streamUrl"), this.id + "_audio", this.model.get("type"), !0).$el)
  3553. },
  3554. loadComments: function() {},
  3555. beforeClose: function() {
  3556. this.player && this.player.close()
  3557. }
  3558. }), Dubtrack.View.BrowserPlaylistList = Backbone.View.extend({
  3559. initialize: function() {
  3560. this.prependItems = !1, this.moreItemsToLoad = !0, this.checkItemsOrder = !0, this.removeOnFetch = !0, this.currentPage = 1, this.loadingMoreItems = !1, this.paginationDisabled = !0, this.model.bind("add", this.addItem, this), this.model.bind("remove", this.removeItem, this), this.model.bind("change", this.updateItem, this), this.model.bind("reset", this.resetItems, this), this.setSortable()
  3561. },
  3562. setSortable: function() {
  3563. this.url_queue_order && this.url_queue_order_data && this.$el.multisortable({
  3564. axis: "y",
  3565. cursor: "move",
  3566. placeholder: "ui-state-highlight",
  3567. update: function(a, c) {
  3568. order = [], this.$("li").each(function(a, c) {
  3569. order.push(b(c).attr(this.url_queue_order_data))
  3570. }.bind(this)), Dubtrack.helpers.sendRequest(this.url_queue_order, {
  3571. "order[]": order
  3572. }, "post")
  3573. }.bind(this)
  3574. })
  3575. },
  3576. setBrowser: function(a) {
  3577. return this.browser = a, this
  3578. },
  3579. resetItems: function(a) {
  3580. this.$("li").remove()
  3581. },
  3582. addItem: function(a) {},
  3583. updateItem: function(a) {},
  3584. removeItem: function(a) {
  3585. var b = a.get("browserView");
  3586. b && b.remove()
  3587. },
  3588. fetchItemsTimeout: function(a) {
  3589. this.fetchItemsTimeoutID && clearTimeout(this.fetchItemsTimeoutID), this.fetchItemsTimeoutID = setTimeout(function() {
  3590. this.fetchItems()
  3591. }.bind(this), 500)
  3592. },
  3593. getFetchData: function() {
  3594. return {}
  3595. },
  3596. fetchItems: function(a) {
  3597. !this.moreItemsToLoad && !this.paginationDisabled || this.loadingMoreItems || (this.moreItemsToLoad = !1, this.loadingMoreItems = !0, this.browser.loadingEl.show(), this.model.fetch({
  3598. data: this.getFetchData(),
  3599. remove: this.removeOnFetch,
  3600. success: function(b, c) {
  3601. if (this.loadingMoreItems = !1, this.moreItemsToLoadTimeout = setTimeout(function() {
  3602. c && c.data && c.data.length >= 20 && (this.moreItemsToLoad = !0, this.currentPage++)
  3603. }.bind(this), 500), this.browser.loadingEl.hide(), c && c.data && this.checkItemsOrder && _.each(c.data, function(a, b) {
  3604. var c = this.model.findWhere({
  3605. _id: a._id
  3606. });
  3607. if (c) {
  3608. var d = c.get("browserView");
  3609. c.get("_id");
  3610. d && b != d.index() && d.insertBefore(this.$("li:eq(" + b + ")"))
  3611. }
  3612. }.bind(this)), a) try {
  3613. a.call()
  3614. } catch (d) {}
  3615. }.bind(this),
  3616. error: function() {
  3617. this.browser.loadingEl.hide(), this.loadingMoreItems = !1
  3618. }.bind(this)
  3619. }))
  3620. },
  3621. beforeClose: function() {
  3622. try {
  3623. Dubtrack.Events.unbind(null, null, this), this.url_queue_order && this.$el.multisortable("destroy")
  3624. } catch (a) {}
  3625. }
  3626. }), Dubtrack.View.BrowserRoomQueuePlaylistList = Dubtrack.View.BrowserPlaylistList.extend({
  3627. initialize: function() {
  3628. Dubtrack.View.BrowserPlaylistList.prototype.initialize.call(this), Dubtrack.Events.bind("realtime:room_playlist-update", this.fetchItemsTimeout, this), Dubtrack.Events.bind("realtime:room_playlist-queue-update", this.fetchItemsTimeout, this), Dubtrack.Events.bind("realtime:room_playlist-queue-reorder", this.fetchItemsTimeout, this)
  3629. },
  3630. addItem: function(a) {
  3631. var b = (new Dubtrack.View.BrowserRoomQueuePlaylisttItem).fetchSong(a).setBrowser(this.browser).$el.appendTo(this.$el);
  3632. a.set({
  3633. browserView: b
  3634. })
  3635. }
  3636. }), Dubtrack.View.BrowserHistoryPlaylistList = Dubtrack.View.BrowserPlaylistList.extend({
  3637. initialize: function() {
  3638. Dubtrack.View.BrowserPlaylistList.prototype.initialize.call(this), Dubtrack.Events.bind("realtime:room_playlist-update", this.fetchItemsTimeout, this)
  3639. },
  3640. addItem: function(a) {
  3641. var b = "appendTo";
  3642. this.prependItems && (b = "prependTo");
  3643. var c = (new Dubtrack.View.BrowserPlaylisHistorytItemWithDescription).fetchSong(a).setBrowser(this.browser).$el[b](this.$el);
  3644. a.set({
  3645. browserView: c
  3646. })
  3647. }
  3648. }), Dubtrack.View.BrowserUserQueuePlaylistList = Dubtrack.View.BrowserPlaylistList.extend({
  3649. initialize: function() {
  3650. Dubtrack.View.BrowserPlaylistList.prototype.initialize.call(this), Dubtrack.Events.bind("realtime:room_playlist-update", this.fetchItemsTimeout, this), Dubtrack.Events.bind("realtime:room_playlist-queue-update", this.fetchItemsTimeout, this)
  3651. },
  3652. addItem: function(a) {
  3653. var b = (new Dubtrack.View.BrowserQueuePlaylisttItem).fetchSong(a).setBrowser(this.browser).$el.appendTo(this.$el);
  3654. a.set({
  3655. browserView: b
  3656. })
  3657. }
  3658. }), Dubtrack.View.BrowserUserPlaylistList = Dubtrack.View.BrowserPlaylistList.extend({
  3659. initialize: function() {
  3660. Dubtrack.View.BrowserPlaylistList.prototype.initialize.call(this), this.checkItemsOrder = !1, this.removeOnFetch = !1, this.paginationDisabled = !1, this.searchString = ""
  3661. },
  3662. addItem: function(a) {
  3663. var b = (new Dubtrack.View.BrowserPlaylisUserPlaylisttItem).fetchSong(a).setBrowser(this.browser).$el.appendTo(this.$el);
  3664. a.set({
  3665. browserView: b
  3666. })
  3667. },
  3668. getFetchData: function() {
  3669. return {
  3670. name: this.searchString,
  3671. page: this.currentPage
  3672. }
  3673. }
  3674. }), Dubtrack.View.ImportPlaylistBrowser = Backbone.View.extend({
  3675. events: {
  3676. "click .playlist-type-select .import-youtube": "displayYoutubeImport",
  3677. "click .import-playlist-youtube .import-playlist": "importYoutubePlaylist",
  3678. "keyup .import-playlist-youtube input": "importYoutubePlaylistKeyUp",
  3679. "click .playlist-type-select .import-soundcloud": "displaySoundCloudImport",
  3680. "click .import-playlist-soundcloud .import-playlist": "importSoundcloudUserPlaylist",
  3681. "keyup .import-playlist-soundcloud input": "importSoundcloudUserPlaylistKeyUp",
  3682. "click .close-import-playlist": "closeView"
  3683. },
  3684. initialize: function() {
  3685. return this.soundCloudPlaylistList = this.$(".import-playlist-soundcloud ul"), this.$(".playlist-container").perfectScrollbar({
  3686. wheelSpeed: 20,
  3687. suppressScrollX: !0,
  3688. wheelPropagation: !1
  3689. }), this
  3690. },
  3691. setBrowser: function(a) {
  3692. this.browser = a
  3693. },
  3694. displayYoutubeImport: function() {
  3695. return this.$(".playlist-tab-import-active").removeClass("playlist-tab-import-active"), this.$(".import-playlist-youtube").addClass("playlist-tab-import-active"), this.$(".import-playlist-youtube input").focus(), this.$(".err-message").hide(), !1
  3696. },
  3697. displaySoundCloudImport: function() {
  3698. return this.$(".playlist-tab-import-active").removeClass("playlist-tab-import-active"), this.$(".import-playlist-soundcloud").addClass("playlist-tab-import-active"), this.$(".import-playlist-soundcloud input").focus(), this.$(".err-message").hide(), this.soundCloudPlaylistList.empty(), !1
  3699. },
  3700. importSoundcloudUserPlaylistKeyUp: function(a) {
  3701. c = a.which ? a.which : a.keyCode, this.soundCloudPlaylistSelect = null, 13 == c && this.importSoundcloudUserPlaylist()
  3702. },
  3703. importSoundcloudUserPlaylist: function() {
  3704. if (this.$(".import-playlist-soundcloud").addClass("importing"), this.soundCloudPlaylistSelect) {
  3705. var a = Dubtrack.config.apiUrl + Dubtrack.config.urls.importSoundcloudPlaylist;
  3706. Dubtrack.helpers.sendRequest(a, {
  3707. id: this.$(".import-playlist-soundcloud select").val(),
  3708. playlistid: this.soundCloudPlaylistSelect.get("id")
  3709. }, "post", function(a, b) {
  3710. a || b.data && b.data && b.data._id && (this.browser.model.add(b.data), Dubtrack.app.navigate("/browser/user/" + b.data._id, {
  3711. trigger: !0
  3712. })), this.setSelect(), this.soundCloudPlaylistList.find("li.selected").removeClass("selected"), this.soundCloudPlaylistSelect = null, this.$(".import-playlist-soundcloud").removeClass("importing")
  3713. }.bind(this))
  3714. } else {
  3715. var b = this.$(".import-playlist-soundcloud input").val();
  3716. if (this.$(".err-message").hide(), this.soundCloudPlaylistList.empty(), this.$(".playlist-container").perfectScrollbar("update"), this.soundCloudPlaylistSelect = null, b && b.length > 0) {
  3717. var a = Dubtrack.config.apiUrl + Dubtrack.config.urls.getSoundCloudPlaylists;
  3718. Dubtrack.helpers.sendRequest(a, {
  3719. username: b
  3720. }, "get", function(a, b) {
  3721. a || b.data && _.each(b.data, function(a) {
  3722. new Dubtrack.View.ImportPlaylistBrowserSoundCloudItem({
  3723. model: new Dubtrack.Model.SoundCloudPlaylist(a)
  3724. }).setParent(this).$el.appendTo(this.soundCloudPlaylistList)
  3725. }.bind(this)), this.$(".import-playlist-soundcloud").removeClass("importing"), this.$(".playlist-container").perfectScrollbar("update")
  3726. }.bind(this))
  3727. }
  3728. }
  3729. },
  3730. importYoutubePlaylistKeyUp: function(a) {
  3731. c = a.which ? a.which : a.keyCode, 13 == c && this.importYoutubePlaylist()
  3732. },
  3733. importYoutubePlaylist: function() {
  3734. var a = this.$(".import-playlist-youtube input").val();
  3735. if (this.$(".err-message").hide(), a && a.length > 0) {
  3736. this.$(".import-playlist-youtube").addClass("importing");
  3737. var b = Dubtrack.config.apiUrl + Dubtrack.config.urls.importYoutubePlaylist;
  3738. Dubtrack.helpers.sendRequest(b, {
  3739. id: this.$(".import-playlist-youtube select").val(),
  3740. yt_playlistid: a
  3741. }, "post", function(a, b) {
  3742. a ? this.$(".import-playlist-youtube .err-message").show().text(a.data && a.data.err && a.data.err.message ? a.data && a.data.err && a.data.err.message : "playlist not found") : (this.$(".import-playlist-youtube input").val(""), b.data && b.data._id && (this.browser.model.add(b.data), Dubtrack.app.navigate("/browser/user/" + b.data._id, {
  3743. trigger: !0
  3744. })), this.closeView()), this.$(".import-playlist-youtube").removeClass("importing")
  3745. }.bind(this))
  3746. }
  3747. return !1
  3748. },
  3749. setSelectedPlaylist: function(a) {
  3750. this.soundCloudPlaylistList.find("li.selected").removeClass("selected"), this.soundCloudPlaylistSelect = a
  3751. },
  3752. openView: function() {
  3753. return this.$el.show(), this.$(".playlist-tab-import-active").removeClass("playlist-tab-import-active"), this.$(".playlist-type-select").addClass("playlist-tab-import-active"), this.$(".err-message").hide(), this.soundCloudPlaylistList.empty(), this.$(".playlist-container").perfectScrollbar("update"), this.soundCloudPlaylistSelect = null, this.setSelect(), !1
  3754. },
  3755. setSelect: function() {
  3756. this.$("select.playlist-select").empty(), this.$("select.playlist-select").append('<option value="" selected>New playlist</option>'), _.each(this.browser.model.models, function(a) {
  3757. this.$("select.playlist-select").append('<option value="' + a.id + '">' + a.get("name") + "</option>")
  3758. }.bind(this))
  3759. },
  3760. closeView: function() {
  3761. return this.$el.hide(), !1
  3762. }
  3763. }), Dubtrack.View.ImportPlaylistBrowserSoundCloudItem = Backbone.View.extend({
  3764. tagName: "li",
  3765. events: {
  3766. click: "clickEvent"
  3767. },
  3768. setParent: function(a) {
  3769. return this.parent = a, this
  3770. },
  3771. initialize: function() {
  3772. return this.$el.html(_.template(Dubtrack.els.templates.layout.soundCloudImportItem, this.model.toJSON())), this.$el.attr("data-id", this.model.id), this
  3773. },
  3774. clickEvent: function() {
  3775. return this.parent.setSelectedPlaylist(this.model), this.$el.addClass("selected"), !1
  3776. }
  3777. }), Dubtrack.AvatarUsersRegistered = new Backbone.Collection, Dubtrack.View.chat = Backbone.View.extend({
  3778. renderSound: !0,
  3779. el: b("#chat"),
  3780. chatSoundFilter: "off",
  3781. _type_message: null,
  3782. events: {
  3783. "keydown input#chat-txt-message": "keyPressAction",
  3784. "click button.pusher-chat-widget-send-btn": "sendMessage",
  3785. "click a.chatSound": "setSound",
  3786. "click .setOnChatNotifications": "setSoundOn",
  3787. "click .setOffChatNotifications": "setSoundOff",
  3788. "click .setMentionChatNotifications": "setSoundMention",
  3789. "click .disableVideo-el": "disableVideo",
  3790. "click a.chat-commands": "displayChatHelp",
  3791. "click #new-messages-counter": "clickChatCounter",
  3792. "click .display-room-users": "displayRoomUsers",
  3793. "click .display-chat": "displayChat",
  3794. "click .display-chat-settings": "displayChatOptions",
  3795. "click .pusher-chat-widget-input .icon-camera": "openGifCreator",
  3796. "click .clearChatToggle": "clearChat",
  3797. "click .hideImagesToggle": "hideImageToggleClick"
  3798. },
  3799. initialize: function() {
  3800. this.chatEndPointUrl = Dubtrack.config.apiUrl + Dubtrack.config.urls.chat.replace(":id", Dubtrack.room.model.id), this.scrollToBottom = !0, this.model = new Dubtrack.Collection.chat, this.model.url = this.chatEndPointUrl, this.model.bind("add", this.appendItem, this), this.disableVideoElBtn = this.$(".disableVideo-el"), this.lastItemChatUser = !1, this.lastItemEl = !1, this.user_muted = !1, this.chatMessageWarningCounter = 0, this.lastSentChatMessage = 0, this.render(), Dubtrack.helpers.sendRequest(this.chatEndPointUrl, {}, "get", function(a, b) {
  3801. this.bindRealtimeEvents(), this.model.add(new Dubtrack.Model.chat({
  3802. time: Date.now(),
  3803. type: "room-welcome-message"
  3804. })), !a && b && b.data && (_.each(b.data, function(a) {
  3805. if ("chat-message" == a.type) {
  3806. var b = new Dubtrack.Model.chat(a);
  3807. this.model.add(b)
  3808. } else "delete-chat-message" == a.type ? this.deleteChatItem(a) : "delete-chat-message-global" == a.type ? this.deleteUserChat(a) : "user-ban" == a.type && this.removeBanUserChat(a)
  3809. }.bind(this)), this.setSoundMention())
  3810. }.bind(this), this), Dubtrack.HideImages && this.hideImageToggle()
  3811. },
  3812. bindRealtimeEvents: function() {
  3813. Dubtrack.Events.bind("realtime:chat-message", this.receiveMessage, this), Dubtrack.Events.bind("realtime:chat-skip", this.receiveMessage, this), Dubtrack.Events.bind("realtime:user-kick", this.receiveMessage, this), Dubtrack.Events.bind("realtime:user-ban", this.receiveMessage, this), Dubtrack.Events.bind("realtime:user-unban", this.receiveMessage, this), Dubtrack.Events.bind("realtime:user-setrole", this.receiveMessage, this), Dubtrack.Events.bind("realtime:user-unsetrole", this.receiveMessage, this), Dubtrack.Events.bind("realtime:user-mute", this.muteUserRealtime, this), Dubtrack.Events.bind("realtime:user-unmute", this.unmuteUserRealtime, this), Dubtrack.Events.bind("realtime:room_playlist-queue-remove-user-song", this.receiveMessage, this), Dubtrack.Events.bind("realtime:room_playlist-queue-remove-user", this.receiveMessage, this), Dubtrack.Events.bind("realtime:room_playlist-queue-reorder", this.receiveMessage, this), Dubtrack.Events.bind("realtime:room-lock-queue", this.receiveMessage, this), Dubtrack.Events.bind("realtime:delete-chat-message", this.deleteChatItem, this), Dubtrack.Events.bind("realtime:delete-chat-message-global", this.deleteUserChat, this), Dubtrack.Events.bind("realtime:user-update-" + Dubtrack.session.id, this.updateImage, this)
  3814. },
  3815. hideImageToggleClick: function() {
  3816. return Dubtrack.HideImages = !Dubtrack.HideImages, Dubtrack.helpers.cookie.set("dubtrack-hide-images", Dubtrack.HideImages ? "hide" : "show", 30), this.hideImageToggle(), this.displayChat(), !1
  3817. },
  3818. hideImageToggle: function() {
  3819. Dubtrack.HideImages ? (this.$(".hideImagesToggle").html("Show Images"), this.$el.addClass("hide-images-in-text")) : (this.$(".hideImagesToggle").html("Hide Images"), this.$el.removeClass("hide-images-in-text")), this.$(".chat-messages").scrollTop(0), this.$(".chat-messages").perfectScrollbar("update");
  3820. var a = this.$(".chat-messages")[0].scrollHeight;
  3821. this.$(".chat-messages").scrollTop(a), this.$(".chat-messages").perfectScrollbar("update")
  3822. },
  3823. clearChat: function() {
  3824. return this.model.reset({}), Dubtrack.room.chat._messagesEl.find("li").remove(), this.clear_chat_timeout && clearTimeout(this.clear_chat_timeout), this.clear_chat_timeout = setTimeout(function() {
  3825. (new Dubtrack.View.chatLoadingItem).$el.text("Chat has been cleared!").appendTo(Dubtrack.room.chat._messagesEl)
  3826. }, 300), this.$(".chat-messages").scrollTop(0), this.$(".chat-messages").perfectScrollbar("update"), this.displayChat(), !1
  3827. },
  3828. disableVideo: function() {
  3829. var a;
  3830. this.isdisableVideo ? (this.isdisableVideo = !1, Dubtrack.room.player.reloadVideo(), b(".chat-option-buttons-video span").css("color", "#878c8e"), this.disableVideoElBtn.removeClass("active"), a = "off") : (this.isdisableVideo = !0, Dubtrack.room.player.YTplayerDelegate && Dubtrack.room.player.YTplayerDelegate.close(), Dubtrack.room.player.SCplayerDelegate && Dubtrack.room.player.SCplayerDelegate.close(), Dubtrack.room.player.YTplayerDelegate = null, Dubtrack.room.player.SCplayerDelegate = null, b(".playerElement").remove(), b(".chat-option-buttons-video span").css("color", "white"), this.disableVideoElBtn.addClass("active"), a = "on")
  3831. },
  3832. muteUserRealtime: function(a) {
  3833. Dubtrack.session && Dubtrack.session.id == a.mutedUser._id && (this.user_muted = !0)
  3834. },
  3835. unmuteUserRealtime: function(a) {
  3836. Dubtrack.session && Dubtrack.session.id == a.mutedUser._id && (this.user_muted = !1)
  3837. },
  3838. openGifCreator: function() {
  3839. return window.open("/imgur/index.html#&client_id=94daca23890c704?action=chat&roomid=" + Dubtrack.room.model.id, "Dubtrack FM - GIF creator", "height=590,width=340,resizable=no,location=no,scrollbars=no"), !1
  3840. },
  3841. displayRoomUsers: function() {
  3842. return Dubtrack.room && Dubtrack.room.$el && (Dubtrack.room.$el.removeClass("display-chat-settings").addClass("display-users-rooms"), Dubtrack.room && Dubtrack.room.users && (Dubtrack.room.users.resetEl(), Dubtrack.room.users.displayActiveUsers())), !1
  3843. },
  3844. displayChat: function() {
  3845. return Dubtrack.room && Dubtrack.room.$el && Dubtrack.room.$el.removeClass("display-users-rooms display-chat-settings"), !1
  3846. },
  3847. displayChatOptions: function() {
  3848. return Dubtrack.room && Dubtrack.room.$el && Dubtrack.room.$el.removeClass("display-users-rooms").addClass("display-chat-settings"), !1
  3849. },
  3850. updateImage: function(a) {
  3851. this.refreshImage = (new Date).getTime(), b.each(this.$("ul.chat-main li:regex(class, .*user-" + a.user._id.toLowerCase() + ".*)"), function() {
  3852. b(this).find(".image_row img").attr("src", a.img)
  3853. })
  3854. },
  3855. render: function() {
  3856. var a = this;
  3857. return this.$el.html(_.template(Dubtrack.els.templates.chat.chatContainer, {})), this._messageInputEl = this.$("input#chat-txt-message"), this._messagesEl = this.$("ul.chat-main"), this.chatSoundHtmlEl = this.$("a.chatSound"), this.renderSound = !1, this.chatCmdEl = this.$(".chat-commands"), this.loadingHistory = this.$(".chatLoading"), this.globalNotificationsEl = this.$("ul.globalNotifications"), this.renderSound = !0, this.isScrolling = !1, this.newMessageCounter = 0, this.createSound(), this.$(".chat-messages").perfectScrollbar({
  3858. wheelSpeed: 50,
  3859. suppressScrollX: !0,
  3860. wheelPropagation: !1,
  3861. onscrollCallback: function(b, c) {
  3862. a.onChatScroll(b, c)
  3863. }
  3864. }), this
  3865. },
  3866. clickChatCounter: function() {
  3867. return this.scrollToBottom = !0, this.scollBottomChat(), !1
  3868. },
  3869. onChatScroll: function(a, b) {
  3870. b - 200 > a ? this.scrollToBottom = !1 : (this.scrollToBottom = !0, this.$("#new-messages-counter").hide(), this.newMessageCounter = 0)
  3871. },
  3872. receiveMessage: function(a) {
  3873. var c = a.user && "_id" in a.user ? a.user._id : !1;
  3874. if ("user-ban" === a.type && this.removeBanUserChat(a), !Dubtrack.session || !c || "chat-message" !== a.type || a.user._id !== Dubtrack.session.get("_id")) {
  3875. var d = new Dubtrack.Model.chat(a);
  3876. if (this.model.add(d), Dubtrack.session) {
  3877. var e = "@" + Dubtrack.session.get("username");
  3878. a && a.message && a.message.toLowerCase().indexOf(e) > -1 && b(".username-handle:contains(" + e + ")").css("color", "rgba(255,0,255,0.80)")
  3879. }
  3880. }
  3881. },
  3882. userJoin: function(a) {
  3883. var b = a.user && "_id" in a.user ? a.user._id : !1;
  3884. if (!Dubtrack.session || !b || a.user._id !== Dubtrack.session.get("_id")) {
  3885. var c = Dubtrack.AvatarUsersRegistered.findWhere({
  3886. _id: a.user._id
  3887. });
  3888. if (!c) {
  3889. Dubtrack.AvatarUsersRegistered.add(a.user);
  3890. var d = new Dubtrack.Model.chat(a);
  3891. this.model.add(d)
  3892. }
  3893. }
  3894. },
  3895. displayChatHelp: function() {
  3896. return this.chatHelp || (this.chatHelp = new Dubtrack.View.helpModalMod), this.chatHelp.$el.show(), !1
  3897. },
  3898. keyPressAction: function(a) {
  3899. return c = a.which ? a.which : a.keyCode, 13 == c ? (this.sendMessage(), !1) : void 0
  3900. },
  3901. setDefaultSound: function(a) {
  3902. switch (this.chatSoundHtmlEl.removeClass("mute"), a) {
  3903. case "none":
  3904. this.renderSound = !0, this.chatSoundFilter = "none", this.chatSoundHtmlEl.html(dubtrack_lang.chat.sound_on);
  3905. break;
  3906. case "mention":
  3907. this.renderSound = !0, this.chatSoundFilter = "mention", this.chatSoundHtmlEl.html(dubtrack_lang.chat.sound_mention);
  3908. break;
  3909. case "off":
  3910. this.renderSound = !1, this.chatSoundFilter = "off", this.chatSoundHtmlEl.html(dubtrack_lang.chat.sound_off), this.chatSoundHtmlEl.addClass("mute");
  3911. break;
  3912. default:
  3913. this.renderSound = !0, this.chatSoundFilter = "none", this.chatSoundHtmlEl.html(dubtrack_lang.chat.sound_on)
  3914. }
  3915. return !1
  3916. },
  3917. setSoundOn: function() {
  3918. return this.$(".chat-option-buttons-sound .active").removeClass("active"), this.$(".setOnChatNotifications").addClass("active"), this.renderSound = !0, this.chatSoundFilter = "none", !1
  3919. },
  3920. setSoundOff: function() {
  3921. return this.$(".chat-option-buttons-sound .active").removeClass("active"), this.$(".setOffChatNotifications").addClass("active"), this.renderSound = !1, this.chatSoundFilter = "off", !1
  3922. },
  3923. setSoundMention: function() {
  3924. return this.$(".chat-option-buttons-sound .active").removeClass("active"), this.$(".setMentionChatNotifications").addClass("active"), this.renderSound = !0, this.chatSoundFilter = "mention", !1
  3925. },
  3926. setSound: function() {
  3927. switch (this.chatSoundHtmlEl.removeClass("mute"), this.chatSoundFilter) {
  3928. case "none":
  3929. this.renderSound = !0, this.chatSoundFilter = "mention", this.chatSoundHtmlEl.html(dubtrack_lang.chat.sound_mention);
  3930. break;
  3931. case "mention":
  3932. this.renderSound = !1, this.chatSoundFilter = "off", this.chatSoundHtmlEl.html(dubtrack_lang.chat.sound_off), this.chatSoundHtmlEl.addClass("mute");
  3933. break;
  3934. case "off":
  3935. this.renderSound = !0, this.chatSoundFilter = "none", this.chatSoundHtmlEl.html(dubtrack_lang.chat.sound_on);
  3936. break;
  3937. default:
  3938. this.renderSound = !0, this.chatSoundFilter = "none", this.chatSoundHtmlEl.html(dubtrack_lang.chat.sound_on)
  3939. }
  3940. return !1
  3941. },
  3942. displayHistory: function() {
  3943. var a = this;
  3944. b.ajax({
  3945. url: g.config.getChatHistory + g.roomModel.id,
  3946. data: {},
  3947. type: "GET",
  3948. success: function(b) {
  3949. _.each(b.data.chat_history, function(b) {
  3950. a.appendEl(b)
  3951. }), a.loadingHistory.hide(), a.createSound()
  3952. },
  3953. error: function() {
  3954. a.loadingHistory.hide(), a.createSound()
  3955. }
  3956. }, "json")
  3957. },
  3958. appendItem: function(a) {
  3959. var b;
  3960. switch (a.get("type")) {
  3961. case "chat-skip":
  3962. this.lastItemChatUser = !1, this.lastItemEl = !1, b = new Dubtrack.View.chatSkipItem({
  3963. model: a
  3964. }), b.$el.appendTo(this._messagesEl), this.playSound(!1);
  3965. break;
  3966. case "user-join":
  3967. this.lastItemChatUser = !1, this.lastItemEl = !1, b = new Dubtrack.View.chatJoinItem({
  3968. model: a
  3969. }), b.$el.appendTo(this._messagesEl), this.playSound(!1);
  3970. break;
  3971. case "user-kick":
  3972. this.lastItemChatUser = !1, this.lastItemEl = !1, b = new Dubtrack.View.chatKickedItem({
  3973. model: a
  3974. }), b.$el.appendTo(this._messagesEl), this.playSound(!1);
  3975. break;
  3976. case "user-ban":
  3977. this.lastItemChatUser = !1, this.lastItemEl = !1, b = new Dubtrack.View.chatBannedItem({
  3978. model: a
  3979. }), b.$el.appendTo(this._messagesEl), this.playSound(!1);
  3980. break;
  3981. case "user-unban":
  3982. this.lastItemChatUser = !1, this.lastItemEl = !1, b = new Dubtrack.View.chatUnbannedItem({
  3983. model: a
  3984. }), b.$el.appendTo(this._messagesEl), this.playSound(!1);
  3985. break;
  3986. case "user-setrole":
  3987. this.lastItemChatUser = !1, this.lastItemEl = !1, b = new Dubtrack.View.chatSetRoleItem({
  3988. model: a
  3989. }), b.$el.appendTo(this._messagesEl), this.playSound(!1);
  3990. break;
  3991. case "user-unsetrole":
  3992. this.lastItemChatUser = !1, this.lastItemEl = !1, b = new Dubtrack.View.chatUnsetRoleItem({
  3993. model: a
  3994. }), b.$el.appendTo(this._messagesEl), this.playSound(!1);
  3995. break;
  3996. case "room_playlist-queue-remove-user-song":
  3997. this.lastItemChatUser = !1, this.lastItemEl = !1, b = new Dubtrack.View.removedSongFromQueueItem({
  3998. model: a
  3999. }), b.$el.appendTo(this._messagesEl), this.playSound(!1);
  4000. break;
  4001. case "room_playlist-queue-remove-user":
  4002. this.lastItemChatUser = !1, this.lastItemEl = !1, b = new Dubtrack.View.removedFromQueueItem({
  4003. model: a
  4004. }), b.$el.appendTo(this._messagesEl), this.playSound(!1);
  4005. break;
  4006. case "room_playlist-queue-reorder":
  4007. this.lastItemChatUser = !1, this.lastItemEl = !1, b = new Dubtrack.View.reorderQueueItem({
  4008. model: a
  4009. }), b.$el.appendTo(this._messagesEl), this.playSound(!1);
  4010. break;
  4011. case "room-lock-queue":
  4012. this.lastItemChatUser = !1, this.lastItemEl = !1, b = new Dubtrack.View.lockRoomQueueItem({
  4013. model: a
  4014. }), b.$el.appendTo(this._messagesEl), this.playSound(!1);
  4015. break;
  4016. case "user-pause-queue":
  4017. this.lastItemChatUser = !1, this.lastItemEl = !1, b = new Dubtrack.View.pauseUserQueueItem({
  4018. model: a
  4019. }), b.$el.appendTo(this._messagesEl), this.playSound(!1);
  4020. break;
  4021. case "room-welcome-message":
  4022. this.lastItemChatUser = !1, this.lastItemEl = !1, b = new Dubtrack.View.welcomeMessageChatItem({
  4023. model: a
  4024. }), b.$el.appendTo(this._messagesEl), this.playSound(!1);
  4025. break;
  4026. default:
  4027. this.refreshImage && a.set({
  4028. refreshVersion: this.refreshImage
  4029. }), b = new Dubtrack.View.chatItem({
  4030. model: a
  4031. });
  4032. var c = a.get("user"),
  4033. d = a.get("message");
  4034. if (/^\/me.*\S+/.test(d)) return this.lastItemChatUser = !1, this.lastItemEl = !1, b = new Dubtrack.View.chatMeCommand({
  4035. model: a
  4036. }), b.$el.appendTo(this._messagesEl), void this.playSound(!1);
  4037. if (Dubtrack.session && Dubtrack.session.id != c._id && Dubtrack.room && Dubtrack.room.users && Dubtrack.room.users.getIfmuted(c._id)) return;
  4038. this.lastItemEl && this.lastItemChatUser && c._id == this.lastItemChatUser._id && this.lastItemEl.$el.is(":visible") ? (this.lastItemEl.$(".text").append("<p>" + a.get("message") + "</p>"), this.lastItemEl.model.set("id", a.get("chatid")), this.lastItemEl.updateTime(a.get("time")), this.lastItemEl.$el.removeClass("deleted-message")) : (this.lastItemChatUser = c, this.lastItemEl = b, b.$el.appendTo(this._messagesEl), b.render());
  4039. var e = new RegExp("@everyone\\b", "g"),
  4040. f = new RegExp("@mods\\b", "g"),
  4041. g = new RegExp("@djs\\b", "g");
  4042. if (Dubtrack.loggedIn) try {
  4043. var h = new RegExp("@" + Dubtrack.session.get("username") + "\\b", "g"),
  4044. i = h.test(a.get("message")),
  4045. j = e.test(a.get("message")) && (Dubtrack.helpers.isDubtrackAdmin(c._id) || Dubtrack.room.users.getIfRoleHasPermission(c._id, "chat-mention")),
  4046. k = f.test(a.get("message")) && (Dubtrack.helpers.isDubtrackAdmin(Dubtrack.session.id) || Dubtrack.room.users.getIfRoleHasPermission(Dubtrack.session.id, "chat-mention")),
  4047. l = g.test(a.get("message")) && (Dubtrack.helpers.isDubtrackAdmin(c._id) || Dubtrack.room.users.getIfRoleHasPermission(c._id, "chat-mention")) && Dubtrack.room.player && Dubtrack.room.player.activeQueueCollection && Dubtrack.room.player.activeQueueCollection.findWhere({
  4048. userid: Dubtrack.session.id
  4049. });
  4050. this.playSound(i || j || k || l)
  4051. } catch (m) {} else this.playSound(!1)
  4052. }
  4053. this.scrollToBottom || (this.$("#new-messages-counter").show(), this.newMessageCounter++, this.newMessageCounter > 1 ? this.$("#new-messages-counter .messages-display").html(this.newMessageCounter + " new messages") : this.$("#new-messages-counter .messages-display").html(this.newMessageCounter + " new message"))
  4054. },
  4055. createSound: function() {
  4056. if (!this.chatSound) {
  4057. this.chatSound = !0, this.mentionChatSound = !0;
  4058. var a = this;
  4059. soundManager.setup({
  4060. url: "/assets/swf/",
  4061. flashVersion: 9,
  4062. onready: function() {
  4063. a.chatSound = soundManager.createSound({
  4064. id: "chatsound",
  4065. autoPlay: !1,
  4066. url: Dubtrack.config.urls.mediaBaseUrl + "/assets/music/notification.mp3",
  4067. onerror: function() {
  4068. a.chatSound = !1
  4069. }
  4070. }), a.mentionChatSound = soundManager.createSound({
  4071. id: "chatmentionsound",
  4072. autoPlay: !1,
  4073. url: "/assets/music/user_ping.mp3",
  4074. onerror: function() {
  4075. a.chatSound = !1
  4076. }
  4077. })
  4078. }
  4079. })
  4080. }
  4081. },
  4082. scollBottomChat: function() {
  4083. if (this.scrollToBottom) {
  4084. this.$(".chat-messages").perfectScrollbar("update");
  4085. var a = this.$(".chat-messages")[0].scrollHeight;
  4086. this.$(".chat-messages").scrollTop(a), this.$(".chat-messages").perfectScrollbar("update")
  4087. }
  4088. },
  4089. playSound: function(a) {
  4090. if (this.scollBottomChat(), this.renderSound) {
  4091. if ("none" == this.chatSoundFilter) try {
  4092. this.chatSound && this.chatSound.play()
  4093. } catch (b) {}
  4094. if ("off" != this.chatSoundFilter && a) try {
  4095. this.mentionChatSound && this.mentionChatSound.play()
  4096. } catch (b) {}
  4097. }
  4098. },
  4099. systemMessageReceived: function(a) {
  4100. null !== a && "" !== a && (Chat._messagesEl.append(content), this.playSound(!1))
  4101. },
  4102. genMessageInfo: function(a) {
  4103. null !== a && "" !== a && this.playSound(!1)
  4104. },
  4105. sendMessage: function() {
  4106. var a = b("<div/>").text(b.trim(this._messageInputEl.val())).html();
  4107. if ("" !== a && null !== a) {
  4108. this._messageInputEl.val("");
  4109. var c, d, e;
  4110. if (0 === a.indexOf("/kick @")) return e = a.replace(/(@[A-Za-z0-9_.]+)/g, function(a) {
  4111. return d = a.replace("@", ""), a
  4112. }), void this.kickUser(d, b.trim(a.replace("/kick @" + d, "")));
  4113. if (0 === a.indexOf("/ban @")) return e = a.replace(/(@[A-Za-z0-9_.]+)/g, function(a) {
  4114. return d = a.replace("@", ""), a
  4115. }), void this.banUser(d, parseInt(b.trim(a.replace("/ban @" + d, "")), 10));
  4116. if (0 === a.indexOf("/unban @")) return e = a.replace(/(@[A-Za-z0-9_.]+)/g, function(a) {
  4117. return d = a.replace("@", ""), a
  4118. }), void this.unbanUser(d);
  4119. if (0 === a.indexOf("/setmod @")) return e = a.replace(/(@[A-Za-z0-9_.]+)/g, function(a) {
  4120. return d = a.replace("@", ""), a
  4121. }), void this.setRole(d, "setModUser");
  4122. if (0 === a.indexOf("/unsetmod @")) return e = a.replace(/(@[A-Za-z0-9_.]+)/g, function(a) {
  4123. return d = a.replace("@", ""), a
  4124. }), void this.unsetRole(d, "setModUser");
  4125. if (0 === a.indexOf("/setresdj @")) return e = a.replace(/(@[A-Za-z0-9_.]+)/g, function(a) {
  4126. return d = a.replace("@", ""), a
  4127. }), void this.setRole(d, "setDJUser");
  4128. if (0 === a.indexOf("/unsetresdj @")) return e = a.replace(/(@[A-Za-z0-9_.]+)/g, function(a) {
  4129. return d = a.replace("@", ""), a
  4130. }), void this.unsetRole(d, "setDJUser");
  4131. if (0 === a.indexOf("/setdj @")) return e = a.replace(/(@[A-Za-z0-9_.]+)/g, function(a) {
  4132. return d = a.replace("@", ""), a
  4133. }), void this.setRole(d, "setRoomDJUser");
  4134. if (0 === a.indexOf("/unsetdj @")) return e = a.replace(/(@[A-Za-z0-9_.]+)/g, function(a) {
  4135. return d = a.replace("@", ""), a
  4136. }), void this.unsetRole(d, "setRoomDJUser");
  4137. if (0 === a.indexOf("/setvip @")) return e = a.replace(/(@[A-Za-z0-9_.]+)/g, function(a) {
  4138. return d = a.replace("@", ""), a
  4139. }), void this.setRole(d, "setVIPUser");
  4140. if (0 === a.indexOf("/unsetvip @")) return e = a.replace(/(@[A-Za-z0-9_.]+)/g, function(a) {
  4141. return d = a.replace("@", ""), a
  4142. }), void this.unsetRole(d, "setVIPUser");
  4143. if (0 === a.indexOf("/setmanager @")) return e = a.replace(/(@[A-Za-z0-9_.]+)/g, function(a) {
  4144. return d = a.replace("@", ""), a
  4145. }), void this.setRole(d, "setManagerUser");
  4146. if (0 === a.indexOf("/unsetmanager @")) return e = a.replace(/(@[A-Za-z0-9_.]+)/g, function(a) {
  4147. return d = a.replace("@", ""), a
  4148. }), void this.unsetRole(d, "setManagerUser");
  4149. if (0 === a.indexOf("/setowner @")) return e = a.replace(/(@[A-Za-z0-9_.]+)/g, function(a) {
  4150. return d = a.replace("@", ""), a
  4151. }), void this.setRole(d, "setOwnerUser");
  4152. if (0 === a.indexOf("/unsetowner @")) return e = a.replace(/(@[A-Za-z0-9_.]+)/g, function(a) {
  4153. return d = a.replace("@", ""), a
  4154. }), void this.unsetRole(d, "setOwnerUser");
  4155. if (0 === a.indexOf("/unmute @")) return e = a.replace(/(@[A-Za-z0-9_.]+)/g, function(a) {
  4156. return d = a.replace("@", ""), a
  4157. }), void this.unmuteUser(d);
  4158. if (0 === a.indexOf("/mute @")) return e = a.replace(/(@[A-Za-z0-9_.]+)/g, function(a) {
  4159. return d = a.replace("@", ""), a
  4160. }), void this.muteUser(d);
  4161. if (0 === a.indexOf("/skip")) return void this.skipSong();
  4162. Date.now() - this.lastSentChatMessage < 1500 ? (this.chatMessageWarningCounter++, this.chatMessageWarningCounter > 4 && (this.model.add(new Dubtrack.Model.chat({
  4163. user: {
  4164. _force_updated: 1448781184094,
  4165. userInfo: {
  4166. _id: "565aa52e6fe207830052f580",
  4167. userid: "565aa52e6fe207830052f57f",
  4168. __v: 0
  4169. },
  4170. _id: "565aa52e6fe207830052f57f",
  4171. username: "dubtrack_bot",
  4172. status: 1,
  4173. roleid: 1,
  4174. dubs: 0,
  4175. created: 1448781102432,
  4176. __v: 0
  4177. },
  4178. message: "whoa @" + Dubtrack.session.get("username") + "! slow down or you will be temporarily blocked from chatting",
  4179. time: Date.now(),
  4180. realTimeChannel: Dubtrack.room.model.get("realTimeChannel"),
  4181. type: "chat-message"
  4182. })), this.chatMessageWarningCounter = 0)) : this.chatMessageWarningCounter = 0, this.lastSentChatMessage = Date.now(), c = new Dubtrack.Model.chat({
  4183. user: Dubtrack.session.toJSON(),
  4184. message: a,
  4185. time: Date.now(),
  4186. realTimeChannel: Dubtrack.room.model.get("realTimeChannel"),
  4187. type: "chat-message"
  4188. }), this.user_muted || (c.urlRoot = this.chatEndPointUrl, c.save(null, {
  4189. error: function(a, b) {
  4190. this.lastItemChatUser = !1, this.lastItemEl = !1;
  4191. var c = new Dubtrack.View.chatLoadingItem;
  4192. if (c.$el.appendTo(this._messagesEl), b && b.status && 429 == b.status) try {
  4193. var d = JSON.parse(b.responseText);
  4194. d && d.data && d.data.details && d.data.details.message ? c.$el.addClass("system-error").html("You reached chat quota limit, please wait " + d.data.details.message + " before retrying") : c.$el.addClass("system-error").html("You reached chat quota limit, please wait 10 mins before retrying")
  4195. } catch (e) {
  4196. c.$el.addClass("system-error").html("You reached chat quota limit, please wait 10 mins before retrying")
  4197. } else c.$el.addClass("system-error").html("An error occurred sending chat message");
  4198. try {
  4199. this.$(".chat-messages").scrollTop(0), this.$(".chat-messages").perfectScrollbar("update");
  4200. var f = this.$(".chat-messages")[0].scrollHeight;
  4201. this.$(".chat-messages").scrollTop(f), this.$(".chat-messages").perfectScrollbar("update")
  4202. } catch (e) {}
  4203. }.bind(this)
  4204. })), this.model.add(c)
  4205. }
  4206. },
  4207. deleteChatItem: function(a) {
  4208. if (a.chatid && a.user && a.user.username) {
  4209. this.$(".chat-main li.chat-id-" + a.chatid + " .text").html('<p class="deleted">chat message deleted by @' + a.user.username + "</p>"), this.$(".chat-main li.chat-id-" + a.chatid).addClass("deleted-message");
  4210. try {
  4211. this.$(".chat-messages").scrollTop(0), this.$(".chat-messages").perfectScrollbar("update");
  4212. var b = this.$(".chat-messages")[0].scrollHeight;
  4213. this.$(".chat-messages").scrollTop(b), this.$(".chat-messages").perfectScrollbar("update")
  4214. } catch (c) {}
  4215. }
  4216. },
  4217. deleteUserChat: function(a) {
  4218. if (a.userdid && a.user && a.user.username) {
  4219. this.$(".chat-main li.user-" + a.userdid + " .text").html('<p class="deleted">chat message deleted by @' + a.user.username + "</p>"), this.$(".chat-main li.user-" + a.userdid).addClass("deleted-message");
  4220. try {
  4221. this.$(".chat-messages").scrollTop(0), this.$(".chat-messages").perfectScrollbar("update");
  4222. var b = this.$(".chat-messages")[0].scrollHeight;
  4223. this.$(".chat-messages").scrollTop(b), this.$(".chat-messages").perfectScrollbar("update")
  4224. } catch (c) {}
  4225. }
  4226. },
  4227. removeBanUserChat: function(a) {
  4228. if (a.user && a.user.username && a.kickedUser) {
  4229. this.$(".chat-main li.user-" + a.kickedUser._id + " .text").html('<p class="deleted">user was banned by @' + a.user.username + "</p>"), this.$(".chat-main li.user-" + a.kickedUser._id).addClass("deleted-message");
  4230. try {
  4231. this.$(".chat-messages").scrollTop(0), this.$(".chat-messages").perfectScrollbar("update");
  4232. var b = this.$(".chat-messages")[0].scrollHeight;
  4233. this.$(".chat-messages").scrollTop(b), this.$(".chat-messages").perfectScrollbar("update")
  4234. } catch (c) {}
  4235. }
  4236. },
  4237. setUserCount: function(a) {
  4238. this.$(".room-user-counter").html(a), b(".mobile-users-counter").html(a)
  4239. },
  4240. setGuestCount: function(a) {
  4241. this.$(".room-guest-counter").html("+" + a)
  4242. },
  4243. skipSong: function() {
  4244. var a = new Dubtrack.View.chatLoadingItem;
  4245. if (a.$el.appendTo(this._messagesEl), Dubtrack.room && Dubtrack.room.player && Dubtrack.room.player.activeSong && Dubtrack.room.player.activeSong.get("song")) {
  4246. var b = Dubtrack.room.player.activeSong.get("song");
  4247. if (!b._id) return void a.$el.addClass("system-error").html("No active song");
  4248. var c = Dubtrack.config.apiUrl + Dubtrack.config.urls.skipSong.replace(":id", Dubtrack.room.model.id).replace(":songid", b._id);
  4249. Dubtrack.helpers.sendRequest(c, {
  4250. realTimeChannel: Dubtrack.room.model.get("realTimeChannel")
  4251. }, "post", function(b, c) {
  4252. b ? b.data && b.data.err && b.data.err.details && b.data.err.details.message ? a.$el.addClass("system-error").html(b.data.err.details.message) : a.$el.addClass("system-error").html("unauthorized action") : a.$el.hide()
  4253. }, this)
  4254. } else a.$el.addClass("system-error").html("No active song")
  4255. },
  4256. setRole: function(a, b) {
  4257. var c = new Dubtrack.View.chatLoadingItem;
  4258. return c.$el.appendTo(this._messagesEl), Dubtrack.config.urls[b] ? void Dubtrack.cache.users.getByUsername(a, function(d, e) {
  4259. (d || !e) && c.$el.addClass("system-error").html("Invalid user: @" + a);
  4260. var f = Dubtrack.config.apiUrl + Dubtrack.config.urls[b].replace(":roomid", Dubtrack.room.model.id);
  4261. f = f.replace(":id", e.id), Dubtrack.helpers.sendRequest(f, {
  4262. realTimeChannel: Dubtrack.room.model.get("realTimeChannel")
  4263. }, "post", function(a, b) {
  4264. a ? a.data && a.data.err && a.data.err.details && a.data.err.details.message ? c.$el.addClass("system-error").html(a.data.err.details.message) : c.$el.addClass("system-error").html("unauthorized action") : c.$el.hide()
  4265. }, this)
  4266. }) : void c.$el.addClass("system-error").html("Invalid action")
  4267. },
  4268. unsetRole: function(a, b) {
  4269. var c = new Dubtrack.View.chatLoadingItem;
  4270. return c.$el.appendTo(this._messagesEl), Dubtrack.config.urls[b] ? void Dubtrack.cache.users.getByUsername(a, function(d, e) {
  4271. (d || !e) && c.$el.addClass("system-error").html("Invalid user: @" + a);
  4272. var f = Dubtrack.config.apiUrl + Dubtrack.config.urls[b].replace(":roomid", Dubtrack.room.model.id);
  4273. f = f.replace(":id", e.id), Dubtrack.helpers.sendRequest(f, {
  4274. realTimeChannel: Dubtrack.room.model.get("realTimeChannel")
  4275. }, "delete", function(a, b) {
  4276. a ? a.data && a.data.err && a.data.err.details && a.data.err.details.message ? c.$el.addClass("system-error").html(a.data.err.details.message) : c.$el.addClass("system-error").html("unauthorized action") : c.$el.hide()
  4277. }, this)
  4278. }) : void c.$el.addClass("system-error").html("Invalid action")
  4279. },
  4280. unmuteUser: function(a) {
  4281. var b = new Dubtrack.View.chatLoadingItem;
  4282. b.$el.appendTo(this._messagesEl);
  4283. var c = this;
  4284. Dubtrack.cache.users.getByUsername(a, function(d, e) {
  4285. (d || !e) && b.$el.addClass("system-error").html("Invalid user: @" + a);
  4286. var f = Dubtrack.config.apiUrl + Dubtrack.config.urls.muteUser.replace(":roomid", Dubtrack.room.model.id);
  4287. f = f.replace(":id", e.id), Dubtrack.helpers.sendRequest(f, {
  4288. realTimeChannel: Dubtrack.room.model.get("realTimeChannel")
  4289. }, "delete", function(a, d) {
  4290. a ? a.data && a.data.err && a.data.err.details && a.data.err.details.message ? b.$el.addClass("system-error").html(a.data.err.details.message) : b.$el.addClass("system-error").html("unauthorized action") : (c.lastItemChatUser = !1, c.lastItemEl = !1, b.$el.html("user quietly unmuted"))
  4291. }, this)
  4292. })
  4293. },
  4294. muteUser: function(a) {
  4295. var b = new Dubtrack.View.chatLoadingItem;
  4296. b.$el.appendTo(this._messagesEl);
  4297. var c = this;
  4298. Dubtrack.cache.users.getByUsername(a, function(d, e) {
  4299. (d || !e) && b.$el.addClass("system-error").html("Invalid user: @" + a);
  4300. var f = Dubtrack.config.apiUrl + Dubtrack.config.urls.muteUser.replace(":roomid", Dubtrack.room.model.id);
  4301. f = f.replace(":id", e.id), Dubtrack.helpers.sendRequest(f, {
  4302. realTimeChannel: Dubtrack.room.model.get("realTimeChannel")
  4303. }, "post", function(a, d) {
  4304. a ? a.data && a.data.err && a.data.err.details && a.data.err.details.message ? b.$el.addClass("system-error").html(a.data.err.details.message) : b.$el.addClass("system-error").html("unauthorized action") : (c.lastItemChatUser = !1, c.lastItemEl = !1, b.$el.html("user quietly muted"))
  4305. }, this)
  4306. })
  4307. },
  4308. unbanUser: function(a) {
  4309. var b = new Dubtrack.View.chatLoadingItem;
  4310. b.$el.appendTo(this._messagesEl), Dubtrack.cache.users.getByUsername(a, function(c, d) {
  4311. (c || !d) && b.$el.addClass("system-error").html("Invalid user: @" + a);
  4312. var e = Dubtrack.config.apiUrl + Dubtrack.config.urls.banUser.replace(":roomid", Dubtrack.room.model.id);
  4313. e = e.replace(":id", d.id), Dubtrack.helpers.sendRequest(e, {
  4314. realTimeChannel: Dubtrack.room.model.get("realTimeChannel")
  4315. }, "delete", function(a, c) {
  4316. a ? a.data && a.data.err && a.data.err.details && a.data.err.details.message ? b.$el.addClass("system-error").html(a.data.err.details.message) : b.$el.addClass("system-error").html("unauthorized action") : b.$el.hide()
  4317. }, this)
  4318. })
  4319. },
  4320. banUser: function(a, b) {
  4321. var c = new Dubtrack.View.chatLoadingItem;
  4322. c.$el.appendTo(this._messagesEl), Dubtrack.cache.users.getByUsername(a, function(d, e) {
  4323. (d || !e) && c.$el.addClass("system-error").html("Invalid user: @" + a);
  4324. var f = Dubtrack.config.apiUrl + Dubtrack.config.urls.banUser.replace(":roomid", Dubtrack.room.model.id);
  4325. f = f.replace(":id", e.id), isNaN(b) && (b = 0), Dubtrack.helpers.sendRequest(f, {
  4326. time: b,
  4327. realTimeChannel: Dubtrack.room.model.get("realTimeChannel")
  4328. }, "post", function(a, b) {
  4329. a ? a.data && a.data.err && a.data.err.details && a.data.err.details.message ? c.$el.addClass("system-error").html(a.data.err.details.message) : c.$el.addClass("system-error").html("unauthorized action") : c.$el.hide()
  4330. }, this)
  4331. })
  4332. },
  4333. kickUser: function(a, b) {
  4334. var c = new Dubtrack.View.chatLoadingItem;
  4335. c.$el.appendTo(this._messagesEl), Dubtrack.cache.users.getByUsername(a, function(d, e) {
  4336. (d || !e) && c.$el.addClass("system-error").html("Invalid user: @" + a);
  4337. var f = Dubtrack.config.apiUrl + Dubtrack.config.urls.kickUser.replace(":roomid", Dubtrack.room.model.id);
  4338. f = f.replace(":id", e.id), Dubtrack.helpers.sendRequest(f, {
  4339. message: b,
  4340. realTimeChannel: Dubtrack.room.model.get("realTimeChannel")
  4341. }, "post", function(a, b) {
  4342. a ? a.data && a.data.err && a.data.err.details && a.data.err.details.message ? c.$el.addClass("system-error").html(a.data.err.details.message) : c.$el.addClass("system-error").html("unauthorized action") : c.$el.hide()
  4343. }, this)
  4344. })
  4345. }
  4346. }), Dubtrack.UserImagesBustings = {}, Dubtrack.View.chatItem = Backbone.View.extend({
  4347. tagName: "li",
  4348. events: {
  4349. "click a.username": "clickUsername",
  4350. "click .chatDelete": "deleteChat"
  4351. },
  4352. initialize: function() {
  4353. this.model.set("message", Dubtrack.helpers.text.convertHtmltoTags(this.model.get("message"), "Dubtrack.room.chat.scollBottomChat();")), this.model.set("message", Dubtrack.helpers.text.convertAttoLink(this.model.get("message"))), this.model.bind("change", this.setId, this);
  4354. var a = this.model.toJSON();
  4355. a.userImage = Dubtrack.config.apiUrl + "/user/" + a.user._id + "/image", a.refreshVersion && (a.userImage = a.userImage + "?v=" + a.refreshVersion), this.$el.html(_.template(Dubtrack.els.templates.chat.chatMessage, a)), Dubtrack.UserImagesBustings[a.user._id] && this.$(".image_row img").attr("src", Dubtrack.UserImagesBustings[a.user._id]), this.$el.addClass("user-" + a.user._id), Dubtrack.session && Dubtrack.session.id && Dubtrack.session.id == a.user._id && this.$el.addClass("current-chat-user"), Dubtrack.Events.bind("realtime:user-update-" + a.user._id, this.updateUser, this), this.setId()
  4356. },
  4357. render: function() {
  4358. var a = new Date(this.model.get("time"));
  4359. this.$(".timeinfo").html('<time class="timeago" datetime="' + a.toISOString() + '">' + a.toLocaleString() + "</time>"), this.$(".timeago").timeago(), this.$("img").load(function() {
  4360. try {
  4361. Dubtrack.room.chat.scollBottomChat()
  4362. } catch (a) {}
  4363. }), this.$("img").error(function() {
  4364. b(this).attr("src", "/assets/images/media/chat_image_load_error.png")
  4365. }), emojify.run(this.el)
  4366. },
  4367. setId: function() {
  4368. var a = this.model.get("chatid");
  4369. a && this.$el.addClass("chat-id-" + a)
  4370. },
  4371. updateTime: function(a) {
  4372. var c = new Date(a);
  4373. this.$(".timeago").timeago("update", c.toISOString()), this.$("img").load(function() {
  4374. try {
  4375. Dubtrack.room.chat.scollBottomChat()
  4376. } catch (a) {}
  4377. }), this.$("img").error(function() {
  4378. b(this).attr("src", "/assets/images/media/chat_image_load_error.png")
  4379. }), emojify.run(this.el)
  4380. },
  4381. navigateAvatar: function(a) {
  4382. var c = b(a.target).data();
  4383. return "username" in c && g.app.navigate("/" + c.username, {
  4384. trigger: !0
  4385. }), !1
  4386. },
  4387. updateUser: function(a) {
  4388. if (a && a.img && a.img.url) {
  4389. var b = this.model.get("user");
  4390. b && (Dubtrack.UserImagesBustings[b._id] = a.img.url), this.$(".image_row img").attr("src", a.img.url)
  4391. }
  4392. },
  4393. clickUsername: function() {
  4394. var a = this.model.get("user");
  4395. if (a) {
  4396. var b = Dubtrack.room.chat._messageInputEl.val();
  4397. b.length > 0 ? Dubtrack.room.chat._messageInputEl.val(Dubtrack.room.chat._messageInputEl.val() + "@" + a.username + " ") : Dubtrack.room.chat._messageInputEl.val("@" + a.username + " "), Dubtrack.room.chat._messageInputEl.focus()
  4398. }
  4399. return !1
  4400. },
  4401. deleteChat: function() {
  4402. var a = this.model.get("chatid");
  4403. if (a) {
  4404. var b = a.split("-").shift();
  4405. if (b === Dubtrack.session.id || Dubtrack.helpers.isDubtrackAdmin(Dubtrack.session.id) || Dubtrack.room.users && Dubtrack.room.users.getIfRoleHasPermission(Dubtrack.session.id, "delete-chat")) {
  4406. this.$(".text").html('<p class="deleted">loading...</p>');
  4407. var c = Dubtrack.config.apiUrl + Dubtrack.config.urls.deleteChat.replace(":id", Dubtrack.room.model.id).replace(":chatid", a);
  4408. Dubtrack.helpers.sendRequest(c, {}, "delete", function(a, b) {
  4409. a && this.$(".text").html('<p class="deleted">you don\'t have permissions to do this</p>')
  4410. }.bind(this))
  4411. } else this.close()
  4412. }
  4413. },
  4414. beforeClose: function() {
  4415. this.$("time.timeago").timeago("dispose")
  4416. }
  4417. }), Dubtrack.View.systemChatItem = Backbone.View.extend({
  4418. tagName: "li",
  4419. attributes: {
  4420. "class": "system"
  4421. },
  4422. events: {},
  4423. initialize: function() {
  4424. this.$el.html(dubtrack_lang.global.loading)
  4425. },
  4426. beforeClose: function() {}
  4427. }), Dubtrack.View.chatMeCommand = Dubtrack.View.chatItem.extend({
  4428. attributes: {
  4429. "class": "chat-me-command-joined"
  4430. },
  4431. initialize: function() {
  4432. this.model.bind("change", this.setId, this);
  4433. var a = this.model.get("user"),
  4434. b = this.model.get("message");
  4435. b && (b = b.replace(/^\/me\s/, "")), b && b.length > 0 && this.$el.html("<div class='chatDelete'><span class='icon-close'></span></div><div class='text'>@" + a.username + " " + b + "</div>"), emojify.run(this.el), this.setId()
  4436. },
  4437. render: function() {}
  4438. }), Dubtrack.View.chatLoadingItem = Dubtrack.View.systemChatItem.extend({
  4439. attributes: {
  4440. "class": "chat-system-loading"
  4441. }
  4442. }), Dubtrack.View.chatJoinItem = Dubtrack.View.systemChatItem.extend({
  4443. attributes: {
  4444. "class": "chat-system-joined"
  4445. },
  4446. initialize: function() {
  4447. var a = this.model.get("user");
  4448. this.$el.html("@" + a.username + " joined the room")
  4449. }
  4450. }), Dubtrack.View.chatSkipItem = Dubtrack.View.systemChatItem.extend({
  4451. initialize: function() {
  4452. var a = this.model.get("username");
  4453. a ? this.$el.html("song skipped by @" + a) : this.$el.html("song skipped by a moderator")
  4454. }
  4455. }), Dubtrack.View.chatKickedItem = Dubtrack.View.systemChatItem.extend({
  4456. initialize: function() {
  4457. var a = this.model.get("kickedUser"),
  4458. b = this.model.get("user");
  4459. this.$el.html("@" + a.username + " was kicked out of the room by @" + b.username)
  4460. }
  4461. }), Dubtrack.View.chatUnbannedItem = Dubtrack.View.systemChatItem.extend({
  4462. initialize: function() {
  4463. var a = this.model.get("kickedUser"),
  4464. b = this.model.get("user");
  4465. this.$el.html("@" + a.username + " was unbanned from the room by @" + b.username)
  4466. }
  4467. }), Dubtrack.View.chatUnsetRoleItem = Dubtrack.View.systemChatItem.extend({
  4468. initialize: function() {
  4469. var a = this.model.get("modUser"),
  4470. b = this.model.get("user"),
  4471. c = this.model.get("role_object");
  4472. this.$el.html("@" + a.username + " was removed as a " + c.label + " by @" + b.username)
  4473. }
  4474. }), Dubtrack.View.chatSetRoleItem = Dubtrack.View.systemChatItem.extend({
  4475. initialize: function() {
  4476. var a = this.model.get("modUser"),
  4477. b = this.model.get("user"),
  4478. c = this.model.get("role_object");
  4479. this.$el.html("@" + a.username + " was made a " + c.label + " by @" + b.username)
  4480. }
  4481. }), Dubtrack.View.chatBannedItem = Dubtrack.View.systemChatItem.extend({
  4482. initialize: function() {
  4483. var a = this.model.get("kickedUser"),
  4484. b = this.model.get("user"),
  4485. c = "@" + a.username + " was banned from the room by @" + b.username,
  4486. d = parseInt(this.model.get("time"), 10);
  4487. d && 0 !== d && (c += " for " + d + " minutes"), this.$el.html(c)
  4488. }
  4489. }), Dubtrack.View.removedSongFromQueueItem = Dubtrack.View.systemChatItem.extend({
  4490. initialize: function() {
  4491. var a = this.model.get("removedUser"),
  4492. b = this.model.get("user"),
  4493. c = "@" + b.username + " removed a song queued by @" + a.username;
  4494. this.$el.html(c)
  4495. }
  4496. }), Dubtrack.View.removedFromQueueItem = Dubtrack.View.systemChatItem.extend({
  4497. initialize: function() {
  4498. var a = this.model.get("removedUser"),
  4499. b = this.model.get("user"),
  4500. c = "@" + b.username + " removed @" + a.username + " from the queue";
  4501. this.$el.html(c)
  4502. }
  4503. }), Dubtrack.View.reorderQueueItem = Dubtrack.View.systemChatItem.extend({
  4504. initialize: function() {
  4505. var a = this.model.get("user"),
  4506. b = "@" + a.username + " reordered the queue";
  4507. this.$el.html(b)
  4508. }
  4509. }), Dubtrack.View.lockRoomQueueItem = Dubtrack.View.systemChatItem.extend({
  4510. initialize: function() {
  4511. var a = this.model.get("user"),
  4512. b = this.model.get("room");
  4513. b && b.lockQueue ? message = "@" + a.username + " locked the queue" : message = "@" + a.username + " unlocked the queue", this.$el.html(message)
  4514. }
  4515. }), Dubtrack.View.pauseUserQueueItem = Dubtrack.View.systemChatItem.extend({
  4516. initialize: function() {
  4517. var a = this.model.get("user"),
  4518. b = this.model.get("user_queue");
  4519. b && b.queuePaused ? message = "@" + a.username + " paused their queue" : message = "@" + a.username + " resumed their queue", this.$el.html(message)
  4520. }
  4521. }), Dubtrack.View.welcomeMessageChatItem = Dubtrack.View.systemChatItem.extend({
  4522. attributes: {
  4523. "class": "chat-welcome-message"
  4524. },
  4525. initialize: function() {
  4526. if (Dubtrack.room) {
  4527. var a = Dubtrack.room.model.get("welcomeMessage"),
  4528. b = Dubtrack.room.model.get("name"),
  4529. c = Dubtrack.session.get("username");
  4530. a && a.length > 0 ? (b || (b = ""), c || (c = ""), a = a.replace("{roomname}", b), a = a.replace("{username}", c), this.$el.html(Dubtrack.helpers.text.convertHtmltoTags(a)), emojify.run(this.el)) : this.$el.remove()
  4531. } else this.$el.remove()
  4532. }
  4533. }), Dubtrack.View.comment = Backbone.View.extend({
  4534. tagName: "section",
  4535. attributes: {
  4536. "class": "comments-main"
  4537. },
  4538. events: {
  4539. "click .loadMoreComments": "displayAllComments",
  4540. "click .comments-textarea-container button": "postComment"
  4541. },
  4542. initialize: function() {
  4543. this.$el.html(_.template(Dubtrack.els.templates.comments.commentsContainer)), this.collection = new Dubtrack.Collection.Comments, this.collection.bind("add", this.appendEl, this), this.commentsLoaded = !1, Dubtrack.Events.bind("realtime:comment-add", this.addRealTimeComment, this), Dubtrack.Events.bind("realtime:comment-remove", this.removeRealTimeComment, this)
  4544. },
  4545. render: function(a) {
  4546. this.collection.url = a;
  4547. var b = this;
  4548. return this.collection.fetch({
  4549. success: function() {
  4550. b.commentsLoaded = !0
  4551. },
  4552. error: function() {
  4553. b.commentsLoaded = !0
  4554. }
  4555. }), this
  4556. },
  4557. removeRealTimeComment: function(a) {
  4558. var b = this.collection.findWhere({
  4559. _id: a.comment._id
  4560. });
  4561. b && b.viewEl && b.viewEl.close()
  4562. },
  4563. addRealTimeComment: function(a) {
  4564. var b = new Dubtrack.Model.Comments(a.comment);
  4565. this.collection.add(b)
  4566. },
  4567. appendEl: function(a) {
  4568. var b = new Dubtrack.View.commentItem({
  4569. model: a
  4570. });
  4571. a.viewEl = b, this.commentsLoaded ? this.$(".comments-list").prepend(b.$el) : this.$(".comments-list").append(b.$el)
  4572. },
  4573. postComment: function() {
  4574. var a = b.trim(this.$(".comments-textarea-container textarea").val()),
  4575. c = this;
  4576. if ("" !== a && null !== a) {
  4577. this.$(".comments-textarea-container textarea").val(""), this.$(".comments-textarea-container button").html(dubtrack_lang.global.loading);
  4578. var d = new Dubtrack.Model.Comments({
  4579. comment: a
  4580. });
  4581. return d.url = this.collection.url, d.parse = Dubtrack.helpers.parse, d.save({}, {
  4582. success: function() {
  4583. c.$(".comments-textarea-container button").html("Post a comment"), c.collection.add(d)
  4584. },
  4585. error: function() {
  4586. c.$(".comments-textarea-container button").html("Error creating comment")
  4587. }
  4588. }), !1
  4589. }
  4590. },
  4591. beforeClose: function() {
  4592. _.each(this.collection.models, function(a) {
  4593. a.viewEl && a.viewEl.close()
  4594. })
  4595. }
  4596. }), Dubtrack.View.commentItem = Backbone.View.extend({
  4597. tagName: "section",
  4598. attributes: {
  4599. "class": "comment-item"
  4600. },
  4601. events: {
  4602. "click a.delete": "deleteComment",
  4603. "click span.icon-arrow-up": "dubUp",
  4604. "click span.icon-arrow-down": "dubDown",
  4605. "click a.icon-flag": "flagComment"
  4606. },
  4607. initialize: function() {
  4608. Dubtrack.Events.bind("realtime:comment-update-" + this.model.id, this.updateDubsRealTime, this), Dubtrack.cache.users.get(this.model.get("userid"), this.renderUser, this)
  4609. },
  4610. renderUser: function(a, b) {
  4611. if (a) return void this.close();
  4612. this.user = b;
  4613. var c = this.model.toJSON();
  4614. c.user = this.user.toJSON(), c.date = new Date(c.created), this.$el.html(_.template(Dubtrack.els.templates.comments.commentsItem, c)), this.$(".timeago").timeago()
  4615. },
  4616. updateDubsRealTime: function(a) {
  4617. a && a.comment && this.$("span.comment-dubs-total").html(a.comment.updubs - a.comment.downdubs)
  4618. },
  4619. deleteComment: function() {
  4620. return this.model.destroy(), this.close(), !1
  4621. },
  4622. beforeClose: function() {
  4623. this.$("time.timeago").timeago("dispose")
  4624. },
  4625. dubDown: function() {
  4626. if (this.$("span.icon-arrow-down").hasClass("dubvoted")) return !1;
  4627. var a = Dubtrack.config.apiUrl + Dubtrack.config.urls.commentsDubs.replace(":id", this.model.id),
  4628. b = this;
  4629. return this.$(".dubvoted").removeClass("dubvoted"), this.$("span.icon-arrow-down").addClass("dubvoted"), Dubtrack.helpers.sendRequest(a, {
  4630. type: "downdub"
  4631. }, "post", function(a, c) {
  4632. c && c.data && c.data.comment && b.$("span.comment-dubs-total").html(c.data.comment.updubs - c.data.comment.downdubs)
  4633. }, this), !1
  4634. },
  4635. dubUp: function() {
  4636. if (this.$("span.icon-arrow-up").hasClass("dubvoted")) return !1;
  4637. var a = Dubtrack.config.apiUrl + Dubtrack.config.urls.commentsDubs.replace(":id", this.model.id),
  4638. b = this;
  4639. return this.$(".dubvoted").removeClass("dubvoted"), this.$("span.icon-arrow-up").addClass("dubvoted"), Dubtrack.helpers.sendRequest(a, {
  4640. type: "updub"
  4641. }, "post", function(a, c) {
  4642. c && c.data && c.data.comment && b.$("span.comment-dubs-total").html(c.data.comment.updubs - c.data.comment.downdubs)
  4643. }, this), !1
  4644. },
  4645. flagComment: function() {
  4646. var a = Dubtrack.config.apiUrl + Dubtrack.config.urls.commentsFlag.replace(":id", this.model.id),
  4647. b = this;
  4648. return Dubtrack.helpers.sendRequest(a, {}, "post", function(a, c) {
  4649. b.$("a.icon-flag").html(" thank you!")
  4650. }, this), !1
  4651. }
  4652. }), scDubsPlayerView = Backbone.View.extend({
  4653. tagName: "div",
  4654. className: "player soundcloud",
  4655. events: {
  4656. "click .pause": "pause",
  4657. "click .play": "play",
  4658. "click .progressContainer": "setPosition",
  4659. "click .replay": "replay",
  4660. "click canvas": "play"
  4661. },
  4662. initialize: function() {},
  4663. render: function(a, c, e, f, g, h) {
  4664. var i = b(this.el);
  4665. Dubtrack.els.controls(i, this), this.playerWidth = g ? g : Dubtrack.config.player.playerEmbedWidth, this.playerHeight = h ? h : Dubtrack.config.player.playerEmbedHeight, this.canvasContEl = b("<div/>", {
  4666. id: this.id
  4667. }).html('<img src="' + Dubtrack.config.urls.mediaBaseUrl + '/assets/images/media/dubtrack-player.png" alt="" />').addClass("playerImage SCplayerImage").appendTo(this.$el), this.buildVolume(), this.scPlayer && this.scPlayer.destruct(), this.replayEl.hide(), "soundcloud" == e && (a += -1 == a.indexOf("secret_token") ? "?" : "&", a = a + "consumer_key=" + Dubtrack.config.keys.soundcloud);
  4668. var j = this;
  4669. return this.playEl.css("display", "block"), Dubtrack.playerController && (this.main_player_volume = Dubtrack.playerController.volume), soundManager.setup({
  4670. url: "/assets/swf/",
  4671. flashVersion: 9,
  4672. onready: function() {
  4673. j.loadingEl.hide(), j.playEl.css("display", "block"), j.scPlayer = soundManager.createSound({
  4674. id: c,
  4675. url: a,
  4676. autoLoad: !0,
  4677. autoPlay: !1,
  4678. stream: !0,
  4679. onerror: function() {
  4680. j.errorEl.show()
  4681. },
  4682. whileplaying: function() {
  4683. j.progressEl.css({
  4684. width: parseInt(this.position * parseInt(j.progressOuterEl.outerWidth(), 10) / this.duration, 10)
  4685. })
  4686. },
  4687. onfinish: function() {
  4688. j.pauseEl.hide(), j.playEl.css("display", "block"), j.replayEl.show(), Dubtrack.room.player && Dubtrack.room.player.setVolumeRemote(Dubtrack.playerController.volume)
  4689. },
  4690. onbufferchange: function() {
  4691. d() || (this.isBuffering ? j.bufferingEl.show() : j.bufferingEl.hide())
  4692. }
  4693. })
  4694. }
  4695. }), f && j.play(), this
  4696. },
  4697. replay: function() {
  4698. this.setPosition(0), this.play()
  4699. },
  4700. play: function() {
  4701. if (this.scPlayer) try {
  4702. Dubtrack.room.player && Dubtrack.room.player.setVolumeRemote(0, !0), this.playEl.hide(), this.pauseEl.css("display", "block"), this.scPlayer.play(), this.replayEl.hide()
  4703. } catch (a) {}
  4704. return !1
  4705. },
  4706. pause: function() {
  4707. if (this.scPlayer) try {
  4708. Dubtrack.room.player ? Dubtrack.room.player.setVolumeRemote(Dubtrack.playerController.volume) : Dubtrack.room.player.setVolumeRemote(self.main_player_volume), this.pauseEl.hide(), this.playEl.css("display", "block"), this.scPlayer.pause()
  4709. } catch (a) {}
  4710. return !1
  4711. },
  4712. setPosition: function(a) {
  4713. this.scPlayer && (this.scPlayer.stop(), this.scPlayer.setPosition(parseInt(a.offsetX / this.progressOuterEl.outerWidth() * this.scPlayer.duration)), this.playEl.hide(), this.pauseEl.css("display", "block"), this.scPlayer.play())
  4714. },
  4715. setVolume: function(a) {
  4716. this.scPlayer && this.scPlayer.setVolume(parseInt(a))
  4717. },
  4718. buildVolume: function() {
  4719. var a = this.volumeContainer.find(".volume-control"),
  4720. b = this.volumeContainer.find(".tooltip"),
  4721. c = this;
  4722. b.hide(), a.slider({
  4723. range: "min",
  4724. min: 1,
  4725. value: 100,
  4726. start: function(a, c) {
  4727. b.fadeIn("fast")
  4728. },
  4729. slide: function(d, e) {
  4730. var f = a.slider("value"),
  4731. g = c.volumeContainer.find(".volume");
  4732. b.css("left", f).text(e.value), 5 >= f ? g.css("background-position", "0 0") : 25 >= f ? g.css("background-position", "0 -25px") : 75 >= f ? g.css("background-position", "0 -50px") : g.css("background-position", "0 -75px"), c.setVolume(f)
  4733. },
  4734. stop: function(a, c) {
  4735. b.fadeOut("fast")
  4736. }
  4737. })
  4738. },
  4739. setVolume: function(a) {
  4740. this.scPlayer && (this.scPlayer.unmute(), this.scPlayer.setVolume(parseInt(a)))
  4741. },
  4742. beforeClose: function() {
  4743. Dubtrack.room.player && Dubtrack.room.player.setVolumeRemote(Dubtrack.playerController.volume), this.scPlayer && (this.scPlayer.destruct(), this.scPlayer.stop()), this.remove(), this.unbind()
  4744. }
  4745. });
  4746. var i = Backbone.View.extend({
  4747. tagName: "div",
  4748. className: "player youtube",
  4749. events: {
  4750. "click .pause": "pause",
  4751. "click .play": "play",
  4752. "click .progressContainer": "setPlayer",
  4753. "click .replay": "replay"
  4754. },
  4755. initialize: function() {},
  4756. render: function(a, c, d, e, f) {
  4757. var g = b(this.el);
  4758. Dubtrack.els.controls(g, this), this.id = c, this.playerEl = b("<div/>", {
  4759. id: c
  4760. }).appendTo(g), this.videoId = a, this.replayEl.hide(), this.mainYTimg = b("<div/>", {
  4761. "class": "playerImage"
  4762. }).html('<img src="http://img.youtube.com/vi/' + a + '/0.jpg" alt="">').appendTo(g);
  4763. var h = this;
  4764. return this.mainYTimg.on("click", function() {
  4765. h.play()
  4766. }), this.buildVolume(), this.playerWidth = e ? e : Dubtrack.config.player.playerEmbedWidth, this.playerHeight = f ? f : Dubtrack.config.player.playerEmbedHeight, Dubtrack.playerController && (this.main_player_volume = Dubtrack.playerController.volume), this
  4767. },
  4768. buildPlayer: function(a) {
  4769. var b = this;
  4770. this.intervalUpdate = null, this.player = new YT.Player(this.id, {
  4771. width: b.playerWidth,
  4772. height: b.playerHeight,
  4773. videoId: b.videoId,
  4774. playerVars: Dubtrack.config.player.youtube.playerParams,
  4775. events: {
  4776. onReady: function() {
  4777. b.loadingEl.hide(), b.intervalLoaded && clearTimeout(b.intervalLoaded), b.updateytplayerloaded(), b.pause(), a && b.play()
  4778. },
  4779. onStateChange: function(a) {
  4780. switch (a.data) {
  4781. case -1:
  4782. break;
  4783. case 0:
  4784. b.mainYTimg.show(), b.replayEl.show(), Dubtrack.room.player && Dubtrack.room.player.setVolumeRemote(Dubtrack.playerController.volume);
  4785. break;
  4786. case 1:
  4787. b.play();
  4788. break;
  4789. case 2:
  4790. b.pause(), b.bufferingEl.hide();
  4791. break;
  4792. case 3:
  4793. b.bufferingEl.show()
  4794. }
  4795. },
  4796. onError: function(a) {
  4797. b.errorEl.html("ERROR: " + a.data), b.errorEl.show()
  4798. }
  4799. }
  4800. })
  4801. },
  4802. onPlayerStateChange: function(a) {},
  4803. replay: function() {
  4804. this.player && (this.mainYTimg.hide(), this.setPlayer(0))
  4805. },
  4806. play: function() {
  4807. if (this.player) try {
  4808. Dubtrack.room.player && Dubtrack.room.player.setVolumeRemote(0, !0), this.mainYTimg.hide(), this.bufferingEl.hide(), this.replayEl.hide(), this.playEl.hide(), this.pauseEl.show(), this.player.playVideo(), this.updateytplayerInfo(), this.intervalLoaded || this.updateytplayerloaded()
  4809. } catch (a) {}
  4810. return !1
  4811. },
  4812. pause: function() {
  4813. if (this.player) try {
  4814. Dubtrack.room.player ? Dubtrack.room.player.setVolumeRemote(Dubtrack.playerController.volume) : Dubtrack.room.player.setVolumeRemote(self.main_player_volume), this.pauseEl.hide(), this.playEl.show(), this.player.pauseVideo(), clearInterval(this.intervalUpdate)
  4815. } catch (a) {}
  4816. return !1
  4817. },
  4818. updateytplayerloaded: function() {
  4819. if (this.player) {
  4820. var a = this;
  4821. this.intervalLoaded = setInterval(function() {
  4822. a.loadedEl.css({
  4823. width: parseInt(100 * a.player.getVideoLoadedFraction(), 10) + "%"
  4824. }), a.player.getVideoLoadedFraction() >= 1 && (clearInterval(a.intervalLoaded), delete a.intervalLoaded)
  4825. }, 1e3)
  4826. }
  4827. },
  4828. updateytplayerInfo: function() {
  4829. if (this.player) {
  4830. var a = this;
  4831. this.intervalUpdate = setInterval(function() {
  4832. a.progressEl.css({
  4833. width: parseInt(a.player.getCurrentTime() * parseInt(a.progressOuterEl.outerWidth(), 10) / a.player.getDuration(), 10)
  4834. })
  4835. }, 1e3)
  4836. }
  4837. },
  4838. setPlayer: function(a) {
  4839. this.play(), this.player.seekTo(a.offsetX / this.progressOuterEl.outerWidth() * this.player.getDuration(), !0)
  4840. },
  4841. buildVolume: function() {
  4842. var a = this.volumeContainer.find(".volume-control"),
  4843. b = this.volumeContainer.find(".tooltip"),
  4844. c = this;
  4845. b.hide(), a.slider({
  4846. range: "min",
  4847. min: 1,
  4848. value: 100,
  4849. start: function(a, c) {
  4850. b.fadeIn("fast")
  4851. },
  4852. slide: function(d, e) {
  4853. var f = a.slider("value"),
  4854. g = c.volumeContainer.find(".volume");
  4855. b.css("left", f).text(e.value), 5 >= f ? g.css("background-position", "0 0") : 25 >= f ? g.css("background-position", "0 -25px") : 75 >= f ? g.css("background-position", "0 -50px") : g.css("background-position", "0 -75px"), c.setVolume(f)
  4856. },
  4857. stop: function(a, c) {
  4858. b.fadeOut("fast")
  4859. }
  4860. })
  4861. },
  4862. setVolume: function(a) {
  4863. this.player && (this.player.unMute(), this.player.setVolume(a))
  4864. },
  4865. beforeClose: function() {
  4866. if (Dubtrack.room.player && Dubtrack.room.player.setVolumeRemote(Dubtrack.playerController.volume), this.player) {
  4867. try {
  4868. this.player.stop(), this.player.destroy()
  4869. } catch (a) {}
  4870. clearInterval(this.intervalUpdate)
  4871. }
  4872. }
  4873. });
  4874. DubsView = Backbone.View.extend({
  4875. tagName: "div",
  4876. events: {
  4877. "click a.dubs-link": "filter",
  4878. "keyup input#dub_text": "search"
  4879. },
  4880. initialize: function() {
  4881. this.dubsItemEl = new Array, b(this.el).html(tpl.get("dubsContainer")), this.model.bind("add", this.appendEl, this), this.model.bind("reset", this.render, this), this.dubsListEl = b(this.el).find("ul#top-dubs"), b(this.el).addClass("avatar_bg"), this.type = "day", this.render()
  4882. },
  4883. render: function() {
  4884. return this.dubsListEl.html(""), _.each(this.model.models, function(a) {
  4885. this.appendEl(a)
  4886. }, this), this
  4887. },
  4888. runPlugins: function() {
  4889. 1 === this.model.models.length && ($view = this.dubsItemEl[0], $view && $view.loadComments())
  4890. },
  4891. filter: function(a) {
  4892. a.preventDefault();
  4893. b(this.el).find(" a.active ").removeClass("active");
  4894. var c = b(a.target).data();
  4895. b(a.target).addClass("active");
  4896. var d = c.type;
  4897. g.elements.displayloading(dubtrack_lang.dubs.loading), this.dubsListEl.html(""), this.type = d;
  4898. a.target.value;
  4899. return g.app.dubsListCollection.url = g.config.dubsUrl + "/date/" + d, g.app.dubsListCollection.fetch({
  4900. success: function() {
  4901. g.app.navigate("/dubs/" + d), g.elements.mainLoading.hide()
  4902. }
  4903. }), !1
  4904. },
  4905. search: function(a) {
  4906. var d = this;
  4907. if (c = a.which ? a.which : a.keyCode, 13 == c || !b(a.target).hasValue()) {
  4908. g.elements.displayloading(dubtrack_lang.dubs.loading), d.dubsListEl.html("");
  4909. var e = a.target.value;
  4910. b(a.target).hasValue() ? g.app.dubsListCollection.url = g.config.searchDubsUrl + "/dub_text/" + escape(e.replace(/[^a-zA-Z 0-9]+/g, "")) : g.app.dubsListCollection.url = g.config.dubsUrl + "/date/" + this.type, g.app.dubsListCollection.fetch({
  4911. data: {
  4912. dub_text: e
  4913. },
  4914. success: function() {
  4915. g.elements.mainLoading.hide()
  4916. }
  4917. })
  4918. }
  4919. },
  4920. buidPlayers: function() {
  4921. _.each(this.dubsItemEl, function(a) {
  4922. a.buidPlayers()
  4923. })
  4924. },
  4925. stopPlayers: function() {
  4926. _.each(this.dubsItemEl, function(a) {
  4927. a.stopPlayer()
  4928. })
  4929. },
  4930. appendEl: function(a) {
  4931. var c = new DubsItemView({
  4932. model: a
  4933. });
  4934. b(c.render().el).appendTo(this.dubsListEl), this.dubsItemEl.push(c)
  4935. }
  4936. }), DubsItemView = Backbone.View.extend({
  4937. tagName: "li",
  4938. events: {
  4939. "click div.img": "loadComments",
  4940. "click div.content": "loadComments",
  4941. "click div.buttons": "loadComments"
  4942. },
  4943. initialize: function() {},
  4944. render: function() {
  4945. return this.$el.addClass("dub_cont"), b(_.template(tpl.get("dubsItem"), this.model.toJSON())).appendTo(this.$el), this.commentsAjax = this.$el.find(".ajax"), this
  4946. },
  4947. buildPlayer: function() {
  4948. switch (this.PlayerContainer = this.$el.find("div.playerDubContainer"), this.model.get("type")) {
  4949. case "youtube":
  4950. this.id = this.model.get("url") + "_" + this.model.get("type"), this.buildYT();
  4951. break;
  4952. case "soundcloud":
  4953. case "dubtrack":
  4954. this.id = this.model.get("url_play") + "_" + this.model.get("type"), this.buildSoundCloud()
  4955. }
  4956. },
  4957. loadComments: function() {
  4958. this.commentsAjax.html('<div class="loadingComments">' + dubtrack_lang.dubs.loadingDetails + "...</div>"), this.commentsCollection = new CommentsCollection, this.commentsCollection.url = "/api/dubs/viewallcomments/format/json/id/" + this.model.get("url") + "/type/" + this.model.get("type");
  4959. var a = {
  4960. type: this.model.get("type"),
  4961. url: this.model.get("url"),
  4962. comment: ""
  4963. },
  4964. b = this;
  4965. return this.commentsCollection.fetch({
  4966. success: function() {
  4967. b.commentsAjax.html(""), b.commentsView = new CommentsView({
  4968. model: b.commentsCollection
  4969. }), b.commentsAjax.append(b.commentsView.render(g.config.saveDubComment, a).el)
  4970. }
  4971. }), g.app.dubsView && g.app.dubsView.stopPlayers(), this.player || (this.buildPlayer(), this.buidPlayers()), !1
  4972. },
  4973. stopPlayer: function() {
  4974. this.player && this.player.pause()
  4975. },
  4976. buidPlayers: function() {
  4977. "youtube" == this.model.get("type") && this.player.buildPlayer()
  4978. },
  4979. buildYT: function() {
  4980. this.player = new i, this.PlayerContainer.append(this.player.render(this.model.get("url"), this.id + "_video").el)
  4981. },
  4982. buildSoundCloud: function() {
  4983. this.player = new scDubsPlayerView, this.PlayerContainer.append(this.player.render(this.model.get("url_play"), this.id + "_audio", this.model.get("type")).el)
  4984. },
  4985. beforeClose: function() {
  4986. this.player.close()
  4987. }
  4988. }), f.help.mainView = Backbone.View.extend({
  4989. tagName: "div",
  4990. currentStep: 0,
  4991. events: {
  4992. "click .btn-tour": "takeTour",
  4993. "click .btn-close": "closeHelp",
  4994. "click .close": "closeHelp"
  4995. },
  4996. initialize: function() {},
  4997. render: function() {
  4998. return this.modalEl = this.$el.html(tpl.get("helpModal")).show().appendTo("body"), this.screenEl = b("<div/>", {
  4999. "class": "help-modal"
  5000. }).appendTo("body"), this
  5001. },
  5002. step: function() {
  5003. if (b("body,html").scrollTop(0), f.help.global.interval && clearInterval(f.help.global.interval), this.toolTipView && (f.help.messages[this.currentStep].closeCall && f.help.messages[this.currentStep].closeCall.call(), this.toolTipView.close()), this.currentStep++, f.help.messages[this.currentStep]) {
  5004. var a = new f.help.toolTipItemModel(f.help.messages[this.currentStep]);
  5005. this.toolTipView = new f.help.toolTipItem({
  5006. model: a
  5007. }).render(), f.help.messages[this.currentStep].callback && f.help.messages[this.currentStep].callback.call()
  5008. } else this.currentStep = 0, this.modalEl.show()
  5009. },
  5010. takeTour: function() {
  5011. return this.modalEl.hide(), this.step(), !1
  5012. },
  5013. closeHelp: function() {
  5014. return this.close(), !1
  5015. },
  5016. displayStep: function(a) {
  5017. this.toolTipView && (f.help.messages[this.currentStep].closeCall && f.help.messages[this.currentStep].closeCall.call(), this.toolTipView.close()), this.currentStep = a - 1, this.step()
  5018. },
  5019. beforeClose: function() {
  5020. this.toolTipView && (f.help.messages[this.currentStep].closeCall && f.help.messages[this.currentStep].closeCall.call(), this.toolTipView.close()), this.screenEl.remove()
  5021. }
  5022. }), Dubtrack.View.helpModalMod = Backbone.View.extend({
  5023. events: {
  5024. "click .btn-close": "closeHelp",
  5025. "click .close": "closeHelp"
  5026. },
  5027. initialize: function() {
  5028. this.modalEl = this.$el.html(Dubtrack.els.templates.help.chat).show().appendTo("body"), this.screenEl = b("<div/>", {
  5029. "class": "help-modal"
  5030. }).appendTo("body")
  5031. },
  5032. closeHelp: function() {
  5033. return this.close(), !1
  5034. },
  5035. beforeClose: function() {
  5036. this.screenEl.remove()
  5037. }
  5038. }), f.help.toolTipItem = Backbone.View.extend({
  5039. tagName: "div",
  5040. events: {
  5041. "click button.btn-next": "next",
  5042. "click button.btn-finish": "closeHelp",
  5043. "click button.btn-close": "closeObject"
  5044. },
  5045. initialize: function() {
  5046. this.$el.addClass("popover fade top in")
  5047. },
  5048. render: function() {
  5049. return this.$el.html(_.template(tpl.get("tooltip"), this.model.toJSON())).addClass(this.model.get("styles")).show().appendTo("body"), this
  5050. },
  5051. closeObject: function() {
  5052. return this.close(), !1
  5053. },
  5054. closeHelp: function() {
  5055. f.help.helpViewRoute && f.help.helpViewRoute.close()
  5056. },
  5057. next: function() {
  5058. f.help.helpViewRoute && f.help.helpViewRoute.step()
  5059. }
  5060. }), f.help.global = {
  5061. next: '<button class="btn btn-small btn-primary btn-next">' + dubtrack_lang.help.next + "</button>",
  5062. finish: '<button class="btn btn-small btn-finish">' + dubtrack_lang.help.finish + "</button>",
  5063. interval: !1
  5064. }, f.help.messages = {
  5065. 1: {
  5066. styles: "help cornerRight",
  5067. title: dubtrack_lang.help.how_to_play,
  5068. content: dubtrack_lang.help.how_to_play_des + f.help.global.next,
  5069. callback: function() {
  5070. b("#playerController").addClass("help")
  5071. },
  5072. closeCall: function() {
  5073. b("#playerController").removeClass("help")
  5074. }
  5075. },
  5076. 2: {
  5077. styles: "help bottom cornerRight step2",
  5078. title: dubtrack_lang.help.select_source,
  5079. content: dubtrack_lang.help.select_source_des + f.help.global.next,
  5080. callback: function() {
  5081. g.app.navigate("/browser", {
  5082. trigger: !0
  5083. }), b("#browser").addClass("help")
  5084. },
  5085. closeCall: function() {
  5086. b("#browser").removeClass("help")
  5087. }
  5088. },
  5089. 3: {
  5090. styles: "help bottom cornerRight step3",
  5091. title: dubtrack_lang.help.search,
  5092. content: dubtrack_lang.help.search_des + f.help.global.next,
  5093. callback: function() {
  5094. g.app.navigate("/browser", {
  5095. trigger: !0
  5096. }), b("#browser").addClass("help");
  5097. var a = "dubtrack.fm",
  5098. c = 0;
  5099. f.help.global.interval = setInterval(function() {
  5100. b("#youtube-search").val(b("#youtube-search").val() + a[c]), c++, c >= a.length && (clearInterval(f.help.global.interval), b("#youtube-search").focus())
  5101. }, 300)
  5102. },
  5103. closeCall: function() {
  5104. b("#browser").removeClass("help")
  5105. }
  5106. },
  5107. 4: {
  5108. styles: "help bottom step4",
  5109. title: dubtrack_lang.help.add,
  5110. content: dubtrack_lang.help.add_des + f.help.global.next,
  5111. callback: function() {
  5112. g.app.mainBrowserView && (g.app.mainBrowserView.setYoutube(), b("#youtube-search").val("dubtrack.fm"), g.app.mainBrowserView.search()), g.app.navigate("/browser", {
  5113. trigger: !0
  5114. }), b("#browser").addClass("help")
  5115. },
  5116. closeCall: function() {
  5117. b("#browser").removeClass("help"), g.app.mainBrowserView.close()
  5118. }
  5119. },
  5120. 5: {
  5121. styles: "help cornerRight step5",
  5122. title: dubtrack_lang.help.queue,
  5123. content: dubtrack_lang.help.queue_des + f.help.global.next,
  5124. callback: function() {
  5125. g.app.navigate("/", {
  5126. trigger: !0
  5127. }), b("#playerController").addClass("help"), b("b.queueInfo").show().html("#")
  5128. },
  5129. closeCall: function() {
  5130. b("b.queueInfo").hide(), b("#playerController").removeClass("help")
  5131. }
  5132. },
  5133. 6: {
  5134. styles: "help cornerRight step6",
  5135. title: dubtrack_lang.help.favorites,
  5136. content: dubtrack_lang.help.favorites_des + f.help.global.next,
  5137. callback: function() {
  5138. b("#playerController").addClass("help")
  5139. },
  5140. closeCall: function() {
  5141. b("#playerController").removeClass("help")
  5142. }
  5143. },
  5144. 7: {
  5145. styles: "help step7",
  5146. title: dubtrack_lang.help.upvote,
  5147. content: dubtrack_lang.help.upvote_des + f.help.global.next,
  5148. callback: function() {
  5149. b("#playerController").addClass("help")
  5150. },
  5151. closeCall: function() {
  5152. b("#playerController").removeClass("help")
  5153. }
  5154. },
  5155. 8: {
  5156. styles: "help bottom cornerRight step8",
  5157. title: dubtrack_lang.help.lobby,
  5158. content: dubtrack_lang.help.lobby_des + f.help.global.next,
  5159. callback: function() {
  5160. b("#header_global").addClass("help")
  5161. },
  5162. closeCall: function() {
  5163. b("#header_global").removeClass("help")
  5164. }
  5165. },
  5166. 9: {
  5167. styles: "help bottom step9",
  5168. title: dubtrack_lang.help.top_dubs,
  5169. content: dubtrack_lang.help.top_dubs_des + f.help.global.next,
  5170. callback: function() {
  5171. b("#header_global").addClass("help")
  5172. },
  5173. closeCall: function() {
  5174. b("#header_global").removeClass("help")
  5175. }
  5176. },
  5177. 10: {
  5178. styles: "help bottom step10",
  5179. title: dubtrack_lang.help.profile,
  5180. content: dubtrack_lang.help.profile_des + f.help.global.next,
  5181. callback: function() {
  5182. b("#header_global").addClass("help")
  5183. },
  5184. closeCall: function() {
  5185. b("#header_global").removeClass("help")
  5186. }
  5187. },
  5188. 11: {
  5189. styles: "help bottom cornerLeft step11",
  5190. title: dubtrack_lang.help.notifications,
  5191. content: dubtrack_lang.help.notifications_des + f.help.global.next,
  5192. callback: function() {
  5193. b("#header_global").addClass("help")
  5194. },
  5195. closeCall: function() {
  5196. b("#header_global").removeClass("help")
  5197. }
  5198. },
  5199. 12: {
  5200. styles: "help bottom cornerLeft step12",
  5201. title: dubtrack_lang.help.friends,
  5202. content: dubtrack_lang.help.friends_des + f.help.global.next,
  5203. callback: function() {
  5204. b("#header_global").addClass("help")
  5205. },
  5206. closeCall: function() {
  5207. b("#header_global").removeClass("help")
  5208. }
  5209. },
  5210. 13: {
  5211. styles: "help bottom step13",
  5212. title: dubtrack_lang.help.share,
  5213. content: dubtrack_lang.help.share_des + f.help.global.finish,
  5214. callback: function() {
  5215. b("#header_global").addClass("help")
  5216. },
  5217. closeCall: function() {
  5218. b("#header_global").removeClass("help")
  5219. }
  5220. }
  5221. }, NoticiationView = Backbone.View.extend({
  5222. tagName: "div",
  5223. events: {
  5224. "click a.loadMore": "loadMore"
  5225. },
  5226. initialize: function() {
  5227. this.$el.html(tpl.get("notificationCont")), this.model.bind("add", this.addItem, this), this.model.bind("reset", this.render, this), this.loadMoreEl = this.$el.find("a.loadMore"), this.notificationEl = this.$el.find("ul#notifications_list"), this.$el.addClass("avatar_cont")
  5228. },
  5229. render: function() {
  5230. return this.ytplayers = new Array, _.each(this.model.models, function(a) {
  5231. this.addItem(a)
  5232. }, this), this
  5233. },
  5234. addItem: function(a) {
  5235. switch (a.get("type")) {
  5236. case "dj_update":
  5237. break;
  5238. case "dub_comment":
  5239. this.buildComment(a.toJSON());
  5240. break;
  5241. case "wall_comment":
  5242. this.wallPost(a.toJSON());
  5243. break;
  5244. case "wall_post":
  5245. this.wallPost(a.toJSON());
  5246. break;
  5247. case "following_post":
  5248. g.user.loggedIn && (a.attributes.userid == g.user.id || a.attributes.id_rel == g.user.id) && this.buildFollowing(a.toJSON())
  5249. }
  5250. this.notificationEl.find(".timeago").timeago()
  5251. },
  5252. wallPost: function(a) {
  5253. var c = b("<li/>", {
  5254. id: "li" + a.id_rel
  5255. }).appendTo(this.notificationEl),
  5256. d = new WallpostModel({
  5257. id: a.id_rel
  5258. });
  5259. d.fetch({
  5260. success: function(a) {
  5261. if ("" != d.get("message")) {
  5262. b(new WallpostItemView({
  5263. model: d
  5264. }).render().el).appendTo(c)
  5265. }
  5266. }
  5267. })
  5268. },
  5269. buildFollowing: function(a) {
  5270. var c = b("<li/>", {
  5271. id: "li" + a.id_rel
  5272. }).appendTo(this.notificationEl);
  5273. a.img = g.helpers.getProfileImg(a.oauth_uid, a.username, a.oauth_provider), a.img_rel = g.helpers.getProfileImg(a.user_rel_info.oauth_uid, a.user_rel_info.username, a.user_rel_info.oauth_provider);
  5274. var d = "notificationFollowing";
  5275. a.id_rel == g.user.id && (d = "notificationFollowing");
  5276. b(_.template(tpl.get(d), a)).appendTo(c)
  5277. },
  5278. loadMore: function() {
  5279. this.loadMoreEl.html(dubtrack_lang.global.loading);
  5280. var a = this;
  5281. return this.model.fetchPage(function() {
  5282. a.loadMoreEl.html(dubtrack_lang.notification.loadMore)
  5283. }), !1
  5284. },
  5285. buildComment: function(a) {
  5286. for (var c = a.url.split("/"), d = "", e = "", f = 0; f < c.length; ++f) "type" == c[f] && (d = c[f + 1]), "id" == c[f] && (e = c[f + 1]), ++f;
  5287. var h = e;
  5288. if ("youtube" == d) {
  5289. if (_.contains(this.ytplayers, e)) return;
  5290. this.ytplayers.push(e)
  5291. } else h = a.song_details.url_play;
  5292. a.img = g.helpers.getProfileImg(a.oauth_uid, a.username, a.oauth_provider);
  5293. var i = b(_.template(tpl.get("notificationComment"), a)).appendTo(this.notificationEl),
  5294. j = i.find(".notificationsPlayer");
  5295. this.buildPlayer(j, h, d, e), this.player && this.buidPlayers(d);
  5296. i.find(".notificationsPlayer");
  5297. this.commentsView && this.commentsView.close();
  5298. var k = new CommentsCollection;
  5299. k.url = "/api/dubs/viewallcomments/format/json/id/" + e + "/type/" + d;
  5300. var l = {
  5301. type: d,
  5302. url: e,
  5303. comment: ""
  5304. };
  5305. k.fetch({
  5306. success: function() {
  5307. var a = new CommentsView({
  5308. model: k
  5309. }),
  5310. c = b(a.render(g.config.saveDubComment, l).el).appendTo(i.find("div.comments_main"));
  5311. c.css("minHeight", 0)
  5312. }
  5313. })
  5314. },
  5315. buildPlayer: function(a, b, c, d) {
  5316. var e = "";
  5317. switch (c) {
  5318. case "youtube":
  5319. e = "notification_" + b + "_" + c, this.buildYT(a, e, b);
  5320. break;
  5321. case "soundcloud":
  5322. case "dubtrack":
  5323. e = "notification_" + d + "_" + c, this.buildSoundCloud(a, e, b, c)
  5324. }
  5325. },
  5326. buildYT: function(a, b, c) {
  5327. this.player = new i, a.append(this.player.render(c, b, 500, 300).el)
  5328. },
  5329. buildSoundCloud: function(a, b, c, d) {
  5330. this.player = new scDubsPlayerView, a.append(this.player.render(c, b, d, 500, 300).el)
  5331. },
  5332. stopPlayer: function() {
  5333. this.player && this.player.pause()
  5334. },
  5335. buidPlayers: function(a) {
  5336. "youtube" == a && this.player.buildPlayer()
  5337. },
  5338. beforeClose: function() {
  5339. this.player.close()
  5340. }
  5341. }), Dubtrack.View.roomUsers = Backbone.View.extend({
  5342. el: b("#avatar"),
  5343. allowed_dj: 0,
  5344. intervalId: !1,
  5345. roomId: !1,
  5346. events: {
  5347. "click a.loadRoomAva": "loadRoomAva",
  5348. "click a.modLink": "loadModsAva",
  5349. "keyup .input-room-users-search input": "filterRoomUsers"
  5350. },
  5351. initialize: function() {
  5352. var a = this;
  5353. this.$el.html(_.template(Dubtrack.els.templates.rooms.avatarsContainer, {})), Dubtrack.Events.bind("realtime:user-join", this.userJoin, this), Dubtrack.Events.bind("realtime:user-leave", this.userLeave, this), Dubtrack.Events.bind("realtime:user-setrole", this.setRole, this), Dubtrack.Events.bind("realtime:user-unsetrole", this.unsetRole, this), Dubtrack.Events.bind("realtime:room_playlist-dub", this.realTimeDub, this), Dubtrack.Events.bind("realtime:user-mute", this.setMuted, this), Dubtrack.Events.bind("realtime:user-unmute", this.setunMuted, this), Dubtrack.Events.bind("realtime:room-lock-queue", this.removeAllDJs, this), Dubtrack.Events.bind("realtime:user-setrole", this.receiveMessage, this), Dubtrack.Events.bind("realtime:user-unsetrole", this.receiveMessage, this), Dubtrack.Events.bind("realtime:user-pause-queue", this.updateUserQueue, this), Dubtrack.Events.bind("realtime:user-pause-queue", this.updateUserQueue, this), Dubtrack.Events.bind("realtime:user-pause-queue", this.updateUserQueue, this), Dubtrack.Events.bind("realtime:pubnub-presence", this.setTotalUsers, this);
  5354. var b = Dubtrack.config.urls.roomUsers.replace("{id}", this.model.id);
  5355. this.collection = new Dubtrack.Collection.RoomUser, this.collection.url = Dubtrack.config.apiUrl + b, this.collection.comparator = function(a) {
  5356. return -parseInt(a.get("dubs"), 10)
  5357. }, this.collection.bind("add", this.addUser, this), this.collection.bind("remove", this.removeEl, this), this.collection.bind("change", this.updateDubs, this), this.intervalId = setInterval(function() {
  5358. a.autoLoad()
  5359. }, 72e4), this.autoLoad(), this.uuids = [], this.rt_users = [], this.avatarContainer = this.$el.find("ul#avatar-list"), this.currentTabEl = this.$el.find(".currentBar"), this.avatarFriendsEl = this.$el.find(".friendsElAvatar"), this.tabsContainerEl = this.$el.find(".tabsContainer"), this.avatarModsEl = this.$el.find(".modsElAvatar"), this.loadingEl = this.$el.find(".loadingAva"), this.setTotalUsersDebouce = _.debounce(this.setTotalUsers.bind(this), 2e3), this.$("#main-user-list-room").perfectScrollbar({
  5360. wheelSpeed: 30,
  5361. suppressScrollX: !0,
  5362. wheelPropagation: !1
  5363. })
  5364. },
  5365. setTotalUsers: function() {
  5366. Dubtrack.realtime.channelPresence(function(a) {
  5367. a && a.uuids && (this.uuids = a.uuids), this.rt_users = [];
  5368. var b = !1;
  5369. if (_.each(this.uuids, function(a) {
  5370. a.match(/^[0-9a-fA-F]{24}$/) && (this.rt_users.push(a), Dubtrack.loggedIn && Dubtrack.session && Dubtrack.session.id == a && (b = !0))
  5371. }.bind(this)), Dubtrack.loggedIn && Dubtrack.session && !b && this.rt_users.push(Dubtrack.session.id), Dubtrack.room && Dubtrack.room.chat) {
  5372. Dubtrack.room.chat.setUserCount(this.rt_users.length);
  5373. var c = this.uuids.length - this.rt_users.length;
  5374. Dubtrack.room.chat.setGuestCount(c >= 0 ? c : 0)
  5375. }
  5376. })
  5377. },
  5378. filterRoomUsers: function() {
  5379. var a = b.trim(this.$(".input-room-users-search input").val());
  5380. return "" === a || null === a ? void this.$("#avatar-list li").show() : (this.avatarContainer.find("li").hide(), void b.each(this.$("#avatar-list li:regex(class, .*user-" + a.toLowerCase() + ".*)"), function() {
  5381. b(this).show()
  5382. }))
  5383. },
  5384. updateDubs: function(a) {
  5385. a && a.viewEl && a.viewEl.$(".dubs span").html(a.get("dubs"))
  5386. },
  5387. resetEl: function() {
  5388. this.collection.sort(), this.avatarContainer.empty(), this.setTotalUsersDebouce.call(this), _.each(this.collection.models, function(a) {
  5389. this.appendEl(a)
  5390. }, this), this.$("#main-user-list-room").perfectScrollbar("update")
  5391. },
  5392. userJoin: function(a) {
  5393. if (a && a.user) {
  5394. var b = new Dubtrack.Model.RoomUser(a.roomUser);
  5395. b.set("user", a.user), b.set("_user", a.user), this.collection.add(b)
  5396. }
  5397. },
  5398. userLeave: function(a) {
  5399. var b = this.collection.findWhere({
  5400. userid: a.user._id
  5401. });
  5402. b && this.collection.remove(b)
  5403. },
  5404. addUser: function(a) {
  5405. this.appendEl(a)
  5406. },
  5407. appendEl: function(a) {
  5408. a.viewEl = new Dubtrack.View.roomUsersItem({
  5409. model: a
  5410. }).render(), this.avatarContainer.append(a.viewEl.$el), this.setTotalUsersDebouce.call(this), this.$("#main-user-list-room").perfectScrollbar("update"), Dubtrack.loggedIn && a.get("userid") == Dubtrack.session.id && this.timeoutErrorUserLeave && clearTimeout(this.timeoutErrorUserLeave)
  5411. },
  5412. displayActiveUsers: function() {
  5413. this.avatarContainer.find("li").hide(), Dubtrack.realtime.channelPresence(function(a) {
  5414. a && a.uuids && (this.uuids = a.uuids), this.rt_users = [], _.each(this.uuids, function(a) {
  5415. a.match(/^[0-9a-fA-F]{24}$/) && (this.rt_users.push(a), this.avatarContainer.find("li.userid-" + a).show())
  5416. }.bind(this))
  5417. }.bind(this))
  5418. },
  5419. appendFeatureItem: function(a) {},
  5420. removeEl: function(a) {
  5421. a.viewEl.close();
  5422. Dubtrack.helpers.cookie.get("dubtrack-room-id");
  5423. Dubtrack.loggedIn && a.get("userid") == Dubtrack.session.id && this.collection.fetch({
  5424. update: !0,
  5425. success: function() {
  5426. var a = this.collection.findWhere({
  5427. userid: Dubtrack.session.id
  5428. });
  5429. a || (this.timeoutErrorUserLeave = setTimeout(function() {
  5430. Dubtrack.helpers.displayError("Warning", "You were removed from this room, simply refresh this page to rejoin :)<br><br>Opening multiple tabs of this site can trigger this error, email us if you have any questions at support@dubtrack.fm", !0)
  5431. }, 5e3))
  5432. }.bind(this)
  5433. }), this.setTotalUsersDebouce.call(this), this.$("#main-user-list-room").perfectScrollbar("update")
  5434. },
  5435. fetchDubs: function() {
  5436. var a = Dubtrack.config.apiUrl + Dubtrack.config.urls.dubsPlaylistActive.replace(":id", this.model.id).replace(":playlistid", "active");
  5437. Dubtrack.helpers.sendRequest(a, {}, "get", function(a, b) {
  5438. a || (_.each(b.data.downDubs, function(a) {
  5439. Dubtrack.room.users.setDubUser(a.userid, a.type)
  5440. }), _.each(b.data.upDubs, function(a) {
  5441. Dubtrack.room.users.setDubUser(a.userid, a.type)
  5442. }))
  5443. }, this)
  5444. },
  5445. loadRoomAva: function() {
  5446. return Dubtrack.room && Dubtrack.room.$el && Dubtrack.room.$el.removeClass("display-users-rooms"), !1
  5447. },
  5448. realTimeDub: function(a) {
  5449. var b = a.user && "_id" in a.user ? a.user._id : !1;
  5450. b && this.setDubUser(b, a.dubtype)
  5451. },
  5452. setDubUser: function(a, b) {
  5453. var c = this.collection.findWhere({
  5454. userid: a
  5455. });
  5456. c && c.viewEl.$el.removeClass("downdub").removeClass("updub").addClass(b)
  5457. },
  5458. removeCurrentDJ: function() {
  5459. this.$("li.currentDJ").removeClass("currentDJ")
  5460. },
  5461. removeDubs: function() {
  5462. this.$("li.updub").removeClass("updub"), this.$("li.downdub").removeClass("downdub")
  5463. },
  5464. setCurrentDJ: function(a) {
  5465. var b = this.collection.findWhere({
  5466. userid: a
  5467. });
  5468. b && b.viewEl && b.viewEl.$el && b.viewEl.$el.addClass("currentDJ")
  5469. },
  5470. updateUserQueue: function(a) {
  5471. var b = a.user_queue && "userid" in a.user_queue ? a.user_queue.userid : !1;
  5472. if (b) {
  5473. var c = this.collection.findWhere({
  5474. userid: b
  5475. });
  5476. c && c.set("queuePaused", a.user_queue.queuePaused)
  5477. }
  5478. },
  5479. removeAllDJs: function() {
  5480. this.$("li.dj").removeClass("dj")
  5481. },
  5482. setRole: function(a) {
  5483. var b = a.modUser && "_id" in a.modUser ? a.modUser._id : !1;
  5484. if (b) {
  5485. var c = this.collection.findWhere({
  5486. userid: b
  5487. });
  5488. c && c.viewEl && c.viewEl.$el && (c.set("roleid", a.role_object), c.viewEl.$el.removeClass("mod co-owner manager vip resident-dj"), c.viewEl.$el.addClass(a.role_object.type))
  5489. }
  5490. },
  5491. unsetRole: function(a) {
  5492. var b = a.modUser && "_id" in a.modUser ? a.modUser._id : !1;
  5493. if (b) {
  5494. var c = this.collection.findWhere({
  5495. userid: b
  5496. });
  5497. c && c.viewEl && c.viewEl.$el && (c.set("roleid", null), c.viewEl.$el.removeClass("mod co-owner manager vip resident-dj"))
  5498. }
  5499. },
  5500. setMuted: function(a) {
  5501. var b = a.mutedUser && "_id" in a.mutedUser ? a.mutedUser._id : !1;
  5502. if (b) {
  5503. var c = this.collection.findWhere({
  5504. userid: b
  5505. });
  5506. c && c.viewEl && c.viewEl.$el && c.set("muted", !0)
  5507. }
  5508. },
  5509. setunMuted: function(a) {
  5510. var b = a.mutedUser && "_id" in a.mutedUser ? a.mutedUser._id : !1;
  5511. if (b) {
  5512. var c = this.collection.findWhere({
  5513. userid: b
  5514. });
  5515. c && c.viewEl && c.viewEl.$el && c.set("muted", !1)
  5516. }
  5517. },
  5518. getIfMod: function(a) {
  5519. var b = this.collection.findWhere({
  5520. userid: a
  5521. });
  5522. if (b) {
  5523. var c = b.get("roleid");
  5524. if (c && "52d1ce33c38a06510c000001" == c._id) return !0
  5525. }
  5526. return !1
  5527. },
  5528. getIfResidentDJ: function(a) {
  5529. var b = this.collection.findWhere({
  5530. userid: a
  5531. });
  5532. if (b) {
  5533. var c = b.get("roleid");
  5534. if (c && "5615feb8e596154fc2000002" == c._id) return !0
  5535. }
  5536. return !1
  5537. },
  5538. getIfDJ: function(a) {
  5539. var b = this.collection.findWhere({
  5540. userid: a
  5541. });
  5542. if (b) {
  5543. var c = b.get("roleid");
  5544. if (c && "564435423f6ba174d2000001" == c._id) return !0
  5545. }
  5546. return !1
  5547. },
  5548. getIfVIP: function(a) {
  5549. var b = this.collection.findWhere({
  5550. userid: a
  5551. });
  5552. if (b) {
  5553. var c = b.get("roleid");
  5554. if (c && "5615fe1ee596154fc2000001" == c._id) return !0
  5555. }
  5556. return !1
  5557. },
  5558. getIfManager: function(a) {
  5559. var b = this.collection.findWhere({
  5560. userid: a
  5561. });
  5562. if (b) {
  5563. var c = b.get("roleid");
  5564. if (c && "5615fd84e596150061000003" == c._id) return !0
  5565. }
  5566. return !1
  5567. },
  5568. getRoleType: function(a) {
  5569. var b = this.collection.findWhere({
  5570. userid: a
  5571. });
  5572. if (b) {
  5573. var c = b.get("roleid");
  5574. if (c) return c.type
  5575. }
  5576. return ""
  5577. },
  5578. getIfOwner: function(a) {
  5579. var b = this.collection.findWhere({
  5580. userid: a
  5581. });
  5582. if (b) {
  5583. var c = b.get("roleid");
  5584. if (c && "5615fa9ae596154a5c000000" == c._id) return !0
  5585. }
  5586. return !1
  5587. },
  5588. getIfRoleHasPermission: function(a, b) {
  5589. var c = this.collection.findWhere({
  5590. userid: a
  5591. });
  5592. if (c) {
  5593. var d = c.get("roleid");
  5594. if (d && d.rights && _.contains(d.rights, b)) return !0
  5595. }
  5596. return !1
  5597. },
  5598. getIfHasRole: function(a) {
  5599. var b = this.collection.findWhere({
  5600. userid: a
  5601. });
  5602. if (b) {
  5603. var c = b.get("roleid");
  5604. if (c && c._id) return !0
  5605. }
  5606. return !1
  5607. },
  5608. getIfmuted: function(a) {
  5609. var b = this.collection.findWhere({
  5610. userid: a
  5611. });
  5612. return b ? b.get("muted") : !1
  5613. },
  5614. getIfQueueIsActive: function(a) {
  5615. var b = this.collection.findWhere({
  5616. userid: a
  5617. });
  5618. return b && b.get("queuePaused") ? !0 : !1
  5619. },
  5620. getDubs: function(a) {
  5621. var b = this.collection.findWhere({
  5622. userid: a
  5623. });
  5624. return b ? b.get("dubs") : 0
  5625. },
  5626. autoLoad: function() {
  5627. var a = this;
  5628. this.collection.fetch({
  5629. update: !0,
  5630. success: function() {
  5631. a.loadedInitialDubs || (a.loadedInitialDubs = !0, a.fetchDubs(), a.resetEl())
  5632. }
  5633. })
  5634. },
  5635. beforeClose: function() {
  5636. this.intervalId && clearInterval(this.intervalId)
  5637. }
  5638. }), Dubtrack.View.roomUsersItem = Backbone.View.extend({
  5639. tagName: "li",
  5640. events: {
  5641. click: "clickEvent"
  5642. },
  5643. initialize: function() {
  5644. this.$el.attr({
  5645. rel: this.model.get("dubs")
  5646. }), this.model.bind("reset", this.render, this), Dubtrack.Events.bind("realtime:user_update_" + this.model.get("userid"), this.dubUpdate, this)
  5647. },
  5648. render: function() {
  5649. this.$el.html(_.template(Dubtrack.els.templates.rooms.avatarsContainerItem, this.model.toJSON())), this.pictureEl = this.$(".picture"), this.usernameEl = this.$("p.username");
  5650. var a = this.model.get("_user");
  5651. Dubtrack.helpers.isDubtrackAdmin(this.model.get("userid")) && this.$el.addClass("admin"), this.model.get("userid") == Dubtrack.room.model.get("userid") && this.$el.addClass("creator");
  5652. var c = this.model.get("roleid");
  5653. if (c && (this.$el.addClass(c.type), this.model.get("userid") == Dubtrack.session.id && (Dubtrack.room && Dubtrack.room.player && Dubtrack.room.player.skipElBtn.show(), Dubtrack.room.users.getIfOwner(this.model.get("userid")) ? b("#main_player .edit-room").show() : b("#main_player .edit-room").hide())), Dubtrack.session && this.model.get("userid") == Dubtrack.session.id) {
  5654. var d = Dubtrack.room.player.activeSong.get("user");
  5655. d && d.id == this.model.get("userid") && (this.$el.addClass("currentDJ"), Dubtrack.room && Dubtrack.room.player && Dubtrack.room.player.skipElBtn.show()), (Dubtrack.helpers.isDubtrackAdmin(Dubtrack.session.id) || Dubtrack.room.users.getIfRoleHasPermission(Dubtrack.session.id, "ban")) && b("#main_player .display-mods-controls").css("display", "inline-block")
  5656. }
  5657. if (a && "object" == typeof a) {
  5658. var e = Dubtrack.cache.users.add(a);
  5659. this.renderUser(null, e)
  5660. } else Dubtrack.cache.users.get(this.model.get("userid"), this.renderUser, this);
  5661. return this
  5662. },
  5663. dubUpdate: function(a) {
  5664. this.$(".dubs span").html(a.user.dubs)
  5665. },
  5666. renderUser: function(a, b) {
  5667. this.user = b;
  5668. try {
  5669. this.usernameEl.html(b.get("username"));
  5670. b.get("userInfo");
  5671. this.$el.addClass("user-" + this.user.get("username").toLowerCase()), this.$el.addClass("userid-" + this.user.id)
  5672. } catch (c) {
  5673. this.$el.remove()
  5674. }
  5675. },
  5676. clickEvent: function() {
  5677. return Dubtrack.helpers.displayUser(this.user.get("_id"), this.$el), !1
  5678. },
  5679. setOffline: function() {
  5680. this.$el.append(b("<div/>", {
  5681. "class": "offline"
  5682. }).html(dubtrack_lang.avatar.offline))
  5683. }
  5684. }), Dubtrack.View.SoundCloudPlayer = Backbone.View.extend({
  5685. tagName: "div",
  5686. id: null,
  5687. url: null,
  5688. events: {},
  5689. initialize: function() {},
  5690. render: function(a, c, d, e, f) {
  5691. var g = this;
  5692. this.id = "playeryt-" + Date.now(), this.url = a, this.loadBg = f, this.$el.addClass("playerElement soundcloud"), f && this.$el.addClass("hiddenPlayer");
  5693. var h = "https://d3byct92ei5n7c.cloudfront.net/hhberclba/image/upload/c_fill,h_460,w_900/tiqxlzynh3rxrkwvzeak.jpg";
  5694. try {
  5695. var i = Dubtrack.room.player.activeSong.get("songInfo");
  5696. i && i.images && i.images.thumbnail && (h = i.images.thumbnail.replace("large", "original"))
  5697. } catch (j) {}
  5698. return this.canvasContEl = b("<div/>", {
  5699. id: this.id
  5700. }).html('<img src="' + h + '" alt="" onerror="this.src=\'https://d3byct92ei5n7c.cloudfront.net/hhberclba/image/upload/c_fill,h_460,w_900/tiqxlzynh3rxrkwvzeak.jpg\'" />').css({
  5701. position: "absolute",
  5702. top: 0,
  5703. left: 0,
  5704. width: "100%",
  5705. height: "100%"
  5706. }).appendTo(this.$el), a += -1 == a.indexOf("secret_token") ? "?" : "&", a = a + "consumer_key=" + Dubtrack.config.keys.soundcloud, soundManager.destroySound("dubtrack_main_player"), g.scPlayer = soundManager.createSound({
  5707. id: "dubtrack_main_player",
  5708. url: a,
  5709. autoLoad: !0,
  5710. autoPlay: g.loadBg ? !1 : !0,
  5711. stream: !0,
  5712. from: 1e3 * c,
  5713. position: 1e3 * c,
  5714. usePeakData: !0,
  5715. volume: g.loadBg ? 0 : Dubtrack.playerController.volume,
  5716. onplay: function() {
  5717. g.setVolume(Dubtrack.playerController.volume, !0), e.loadingEl.hide(), e.bufferingEl.hide(), e.errorElBtn.hide(), e.playing = !0
  5718. },
  5719. onload: function() {
  5720. g.setVolume(Dubtrack.playerController.volume)
  5721. },
  5722. onerror: function() {
  5723. e.loadingEl.hide(), e.bufferingEl.hide(), e.errorElBtn.show(), this.playing = !1
  5724. },
  5725. onfinish: function() {
  5726. d && d.call()
  5727. },
  5728. onbufferchange: function() {}
  5729. }), this
  5730. },
  5731. play: function() {
  5732. this.loadBg = !1, this.$el.removeClass("hiddenPlayer"), this.scPlayer && this.scPlayer.play(), this.setVolume(Dubtrack.playerController.volume)
  5733. },
  5734. setPlaybackQuality: function(a) {},
  5735. sync: function(a) {
  5736. this.scPlayer && this.scPlayer.setPosition(1e3 * a)
  5737. },
  5738. getCurrentTime: function() {
  5739. try {
  5740. if (this.scPlayer) return this.scPlayer.position / 1e3
  5741. } catch (a) {}
  5742. },
  5743. beforeClose: function() {
  5744. try {
  5745. this.scPlayer.destruct(), this.scPlayer = null
  5746. } catch (a) {}
  5747. b("#" + this.id).remove()
  5748. },
  5749. stop: function() {
  5750. try {
  5751. if (this.scPlayer) return this.scPlayer.destruct(), this.scPlayer.stop()
  5752. } catch (a) {}
  5753. },
  5754. setVolume: function(a) {
  5755. a = parseInt(a, 10), this.scPlayer && (a > 2 ? this.scPlayer.unmute() : this.scPlayer.mute(), this.scPlayer.setVolume(a))
  5756. }
  5757. }), Dubtrack.View.YoutubePlayer = Backbone.View.extend({
  5758. tagName: "div",
  5759. id: null,
  5760. url: null,
  5761. initialize: function() {},
  5762. loadVideo: function(a, b, c, d, f) {
  5763. if (!this.player) return this.render(a, b, c, d, f);
  5764. this.url = a;
  5765. var g = Dubtrack.config.player.youtube.youtubeVars;
  5766. b >= 0 && (g.start = b);
  5767. try {
  5768. this.player.loadVideoById({
  5769. width: Dubtrack.config.player.playerWidth,
  5770. height: Dubtrack.config.player.playerHeight,
  5771. startSeconds: b,
  5772. videoId: a,
  5773. playerVars: g,
  5774. events: {
  5775. onReady: function(a) {
  5776. d.errorElBtn.hide(), d.loadingEl.hide(), self.setVolume(Dubtrack.playerController.volume), self.setPlaybackQuality(d.playbackQuality), e() || self.play()
  5777. },
  5778. onError: function(a) {
  5779. d.loadingEl.hide(), d.playing = !1
  5780. },
  5781. onStateChange: function(a) {
  5782. switch (a.data) {
  5783. case 0:
  5784. c && c.call();
  5785. break;
  5786. case 1:
  5787. d.loadingEl.hide(), d.bufferingEl.hide(), d.playing = !0, d.autoplayStarted = !0;
  5788. break;
  5789. case 3:
  5790. d.bufferingEl.show(), d.playing = !1;
  5791. break;
  5792. case 2:
  5793. self.play()
  5794. }
  5795. }
  5796. }
  5797. })
  5798. } catch (h) {}
  5799. },
  5800. render: function(a, c, d, f, g) {
  5801. var h = this;
  5802. this.id = "playeryt-" + Date.now(), this.url = a, this.ytPlayerContainer = b("<div/>", {
  5803. id: this.id
  5804. }).appendTo(this.$el), this.loadBg = g, this.$el.addClass("playerElement youtube"), g && this.$el.addClass("hiddenPlayer");
  5805. var i = Dubtrack.config.player.youtube.youtubeVars;
  5806. c >= 0 && (i.start = c), f.loadingEl.hide();
  5807. try {
  5808. this.player = new YT.Player(this.id, {
  5809. width: Dubtrack.config.player.playerWidth,
  5810. height: Dubtrack.config.player.playerHeight,
  5811. startSeconds: c,
  5812. videoId: a,
  5813. playerVars: i,
  5814. events: {
  5815. onReady: function(a) {
  5816. a && a.target && (h.player = a.target), f.errorElBtn.hide(), h.setVolume(Dubtrack.playerController.volume), h.setPlaybackQuality(f.playbackQuality), e() || h.play()
  5817. },
  5818. onError: function(a) {
  5819. f.playing = !1
  5820. },
  5821. onStateChange: function(a) {
  5822. switch (a.data) {
  5823. case 0:
  5824. d && d.call();
  5825. break;
  5826. case 1:
  5827. f.loadingEl.hide(), f.bufferingEl.hide(), f.playing = !0, f.autoplayStarted = !0;
  5828. break;
  5829. case 3:
  5830. f.bufferingEl.show(), f.playing = !1;
  5831. break;
  5832. case 2:
  5833. h.play()
  5834. }
  5835. }
  5836. }
  5837. })
  5838. } catch (j) {
  5839. setTimeout(function() {
  5840. h.render(a, c, d, f, g)
  5841. }, 1e3)
  5842. }
  5843. return this
  5844. },
  5845. play: function() {
  5846. if (this.loadBg = !1, this.$el.removeClass("hiddenPlayer"), this.player) {
  5847. var a = this.player;
  5848. try {
  5849. a.playVideo()
  5850. } catch (b) {}
  5851. }
  5852. return this.setVolume(Dubtrack.playerController.volume, !0), !1
  5853. },
  5854. sync: function(a) {
  5855. this.player && this.player.seekTo(a, !0)
  5856. },
  5857. setPlaybackQuality: function(a) {
  5858. this.player && this.player.setPlaybackQuality(a)
  5859. },
  5860. getAvailableQualityLevels: function() {
  5861. return this.player ? this.player.getAvailableQualityLevels() : []
  5862. },
  5863. getCurrentTime: function() {
  5864. try {
  5865. if (this.player) return this.player.getCurrentTime()
  5866. } catch (a) {}
  5867. },
  5868. stop: function() {
  5869. try {
  5870. if (this.player) return this.player.stopVideo()
  5871. } catch (a) {}
  5872. },
  5873. beforeClose: function() {
  5874. try {
  5875. this.player.destroy(), this.player = null
  5876. } catch (a) {}
  5877. b("#" + this.id).remove()
  5878. },
  5879. setVolume: function(a) {
  5880. if (a = parseInt(a, 10), this.player) try {
  5881. a > 2 ? this.player.unMute() : this.player.mute(), this.player.setVolume(a)
  5882. } catch (b) {}
  5883. }
  5884. }), Dubtrack.View.Player = Backbone.View.extend({
  5885. el: b("#main_player"),
  5886. voteCount: 0,
  5887. playbackQuality: "default",
  5888. events: {
  5889. "click .placeholder": "displayQueueBrowser",
  5890. "click .skip-el": "skipSong",
  5891. "click .playbtn-el": "playCurrentSong",
  5892. "click .refresh-el": "reloadVideo",
  5893. "click .player-controller-container .mute": "mutePlayer",
  5894. "click .play-song-link": "displayBrowserSearch",
  5895. "click .videoquality-el": "changeYTQuality",
  5896. "click .hideVideo-el": "hideVideo",
  5897. "click .display-queue": "displayRoomQueue",
  5898. "click .edit-room": "editRoom",
  5899. "click .display-mods-controls": "displayModsControl",
  5900. "click .room-info-display": "diplayRoomInfo",
  5901. "click .displayVideo-el": "displayPlayer"
  5902. },
  5903. initialize: function() {
  5904. this.playing = !1, this.autoplayStarted = !1, this.loadingEl = this.$(".loading-el"), this.bufferingEl = this.$(".buferring-el").html(dubtrack_lang.player.buffering), this.playElBtn = this.$(".playbtn-el"), this.queueInfo = b(".queue-info"), this.hideVideoElBtn = this.$(".hideVideo-el"), this.qualityElBtn = this.$(".videoquality-el"), this.displayRoomQueueEl = this.$(".display-queue"), this.refreshElBtn = this.$(".refresh-el"), this.skipElBtn = this.$(".skip-el"), this.errorElBtn = b("<div/>", {
  5905. "class": "loading"
  5906. }).html(dubtrack_lang.player.error).css({
  5907. display: "none"
  5908. }).appendTo(g.config.playerContainer), this.placeHolder = this.$(".placeholder"), this.customEmbedIframeDiv = this.$("#custom_iframe_embed"), this.customEmbedIframeErrorDiv = this.$("#custom_iframe_embed_error");
  5909. var a = Dubtrack.config.urls.roomPlaylist.replace(":id", this.model.id);
  5910. this.activeQueueCollection = new Dubtrack.Collection.RoomActiveQueue, this.activeQueueCollection.url = Dubtrack.config.apiUrl + a, Dubtrack.Events.bind("realtime:room-update", this.roomUpdate, this);
  5911. this.minEl = Dubtrack.playerController.$(".min"), this.secEl = Dubtrack.playerController.$(".sec"), this.progressEl = Dubtrack.playerController.$(".progressBg"), this.currentDjName = Dubtrack.playerController.$(".currentDJSong"), this.pictureEl = Dubtrack.playerController.$(".imgEl");
  5912. var c = Dubtrack.config.urls.roomPlaylistActive.replace(":id", this.model.id);
  5913. this.activeSong = new Dubtrack.Model.ActiveQueue, this.activeSong.url = Dubtrack.config.apiUrl + c, this.room_type = null, this.activeSong.parse = Dubtrack.helpers.parse, Dubtrack.Events.bind("realtime:room_playlist-update", this.realTimeUpdate, this), Dubtrack.user.loggedIn && this.displayRoomQueueEl.show(), this.modsViewEl = new Dubtrack.View.ModsView, Dubtrack.session && Dubtrack.room && Dubtrack.room.users && (Dubtrack.helpers.isDubtrackAdmin(Dubtrack.session.id) || Dubtrack.room.users.getIfRoleHasPermission(Dubtrack.session.id, "ban")) && this.$(".display-mods-controls").css("display", "inline-block"), Dubtrack.helpers.cookie.get("dubtrack-room-volume") && this.setVolume(Dubtrack.helpers.cookie.get("dubtrack-room-volume")), this.fetchSong()
  5914. },
  5915. skipSong: function() {
  5916. return this.skipElBtn.hide(), Dubtrack.room.chat.skipSong(), !1
  5917. },
  5918. displayPlayer: function() {
  5919. return this.$("#mods-controllers").hide(), this.$("#room-info-display").hide(), this.$(".player_container").show(), this.$(".player_header .active").removeClass("active"), this.$(".player_header .displayVideo-el").addClass("active"), !1
  5920. },
  5921. displayModsControl: function() {
  5922. return this.$(".player_container").hide(), this.$("#room-info-display").hide(), this.$("#mods-controllers").show(), this.$(".player_header .active").removeClass("active"), this.$(".player_header .display-mods-controls").addClass("active"), !1
  5923. },
  5924. diplayRoomInfo: function() {
  5925. return this.$(".player_container").hide(), this.$("#mods-controllers").hide(), this.$("#room-info-display").show(), this.$(".player_header .active").removeClass("active"), this.$(".player_header .room-info-display").addClass("active"), this.roomInfoView || (this.roomInfoView = new Dubtrack.View.RoomInfo({
  5926. model: this.model
  5927. }).render()), !1
  5928. },
  5929. editRoom: function() {
  5930. return Dubtrack.session && Dubtrack.room.users && Dubtrack.room.users.getIfOwner(Dubtrack.session.get("_id")) && (this.roomUpdateView && this.roomUpdateView.close(), this.roomUpdateView = new f.room.roomFormUpdateViewUpdate({
  5931. model: Dubtrack.room.model
  5932. }).render(), this.roomUpdateView.$el.appendTo("body")), !1
  5933. },
  5934. hideVideo: function() {
  5935. var a;
  5936. this.istoggleVideo ? (this.istoggleVideo = !1, b("#room-main-player-container").css("visibility", "visible"), b("#room-main-player-container iframe").css("visibility", "visible"), this.hideVideoElBtn.removeClass("active"), a = "off") : (this.istoggleVideo = !0, b("#room-main-player-container").css("visibility", "hidden"), b("#room-main-player-container iframe").css("visibility", "hidden"), this.hideVideoElBtn.addClass("active"), a = "on")
  5937. },
  5938. roomUpdate: function(a) {
  5939. a && a.room && this.room_type != a.room.roomType && this.render()
  5940. },
  5941. displayRoomQueue: function() {
  5942. return Dubtrack.app.navigate("/browser/room-queue", {
  5943. trigger: !0
  5944. }), !1
  5945. },
  5946. displayBrowserSearch: function() {
  5947. return Dubtrack.app.navigate("/browser/search", {
  5948. trigger: !0
  5949. }), !1
  5950. },
  5951. mutePlayer: function() {
  5952. return this.muted_player ? (this.muted_player = !1, this.volumeBeforeMuted && this.volumeBeforeMuted > 2 ? (this.setVolume(this.volumeBeforeMuted), Dubtrack.playerController.volumeSliderEl.slider("value", this.volumeBeforeMuted)) : (this.setVolume(100), Dubtrack.playerController.volumeSliderEl.slider("value", 100))) : (this.muted_player = !0, this.volumeBeforeMuted = Dubtrack.playerController.volume, this.setVolume(0), Dubtrack.playerController.volumeSliderEl.slider("value", 0)), !1
  5953. },
  5954. render: function() {
  5955. var a = this.activeSong.get("songInfo"),
  5956. c = this.activeSong.get("song"),
  5957. d = "";
  5958. if (this.skipElBtn.hide(), this.qualityElBtn.removeClass("show"), this.refreshElBtn.removeClass("show"), this.hideVideoElBtn.removeClass("show"), this.refreshTimeout && clearTimeout(this.refreshTimeout), this.queue_timeout && clearTimeout(this.queue_timeout), this.videoend_timeout && clearTimeout(this.videoend_timeout), this.customEmbedIframeDiv.empty(), this.$("#room-main-player-container #room-main-player-container-youtube").hide(), this.$("#room-main-player-container #room-main-player-container-soundcloud").hide(), this.activePlayerDelegate && this.activePlayerDelegate.stop(), this.activePlayerDelegate = null, "iframe" != Dubtrack.room.model.get("roomType")) {
  5959. if (this.room_type = "room", b(".custom-embed-info").hide(), b(".remove-if-iframe").addClass("display-block"), b(".infoContainer").addClass("display-block"), b("body").addClass("no-song-playing"), this.customEmbedIframeDiv.hide(), this.customEmbedIframeErrorDiv.hide(), this.$("#room-main-player-container").show(), null !== a && (Dubtrack.playerController.$(".currentSong").html(a.name), Dubtrack.cache.users.get(c.userid, this.renderUser, this), b("body").removeClass("no-song-playing"), d = a.type, Dubtrack.session && Dubtrack.session.id)) {
  5960. (Dubtrack.helpers.isDubtrackAdmin(Dubtrack.session.id) || Dubtrack.room.users && Dubtrack.room.users.getIfRoleHasPermission(Dubtrack.session.id, "skip")) && this.skipElBtn.show();
  5961. var e = this.activeSong.get("user");
  5962. e && e.id == Dubtrack.session.id && this.skipElBtn.show()
  5963. }
  5964. switch (d) {
  5965. case "youtube":
  5966. this.placeHolder.hide(), this.buildYT(), this.playCurrent();
  5967. break;
  5968. case "soundcloud":
  5969. case "dubtrack":
  5970. this.placeHolder.hide(), this.buildSoundCloud(), this.playCurrent();
  5971. break;
  5972. default:
  5973. this.loadingEl.hide(), Dubtrack.playerController.$(".currentSong").html(dubtrack_lang.player.no_one_is_playing), this.placeHolder.show(), this.currentDjName.hide(), this.pictureEl.hide()
  5974. }
  5975. return Dubtrack.playerController.update(), this.fetchQueueInfo(), this
  5976. }
  5977. this.room_type = "iframe", this.placeHolder.hide(), Dubtrack.playerController.$(".currentTime").hide(), this.YTplayerDelegate && this.YTplayerDelegate.close(), this.SCplayerDelegate && this.SCplayerDelegate.close(), this.YTplayerDelegate = null, this.SCplayerDelegate = null, b(".remove-if-iframe").removeClass("display-block"), Dubtrack.playerController.$(".currentSong").html(""), b(".custom-embed-info").show(), this.pictureEl.hide(), this.currentDjName.hide(), this.loadingEl.hide(), b(".infoContainer").removeClass("display-block"), this.$("#room-main-player-container").hide(), this.intervalCounter && clearInterval(this.intervalCounter), this.progressEl.css("width", "0%");
  5978. var f = Dubtrack.room.model.get("roomEmbed"),
  5979. g = /(http:\/\/|https:\/\/|\/\/)(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/,
  5980. h = /(twitch\.tv)\/([^\&\?\/]+)/;
  5981. if (f && g.test(f))
  5982. if (h.test(f)) {
  5983. var i = f.match(h);
  5984. try {
  5985. if (i[2]) {
  5986. var j = i[2];
  5987. this.customEmbedIframeErrorDiv.hide(), this.customEmbedIframeDiv.show().html('<div id="custom_iframe_overlay"></div><object type="application/x-shockwave-flash" data="https://www-cdn.jtvnw.net/swflibs/TwitchPlayer.swff?channel=' + j + '" width="100%" height="100%" id="live_embed_player_flash"> <param name="movie" value="https://www-cdn.jtvnw.net/swflibs/TwitchPlayer.swff?channel=' + j + '"> <param name="quality" value="high"> <param name="allowFullScreen" value="true"> <param name="allowScriptAccess" value="always"> <param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer"> <param name="autoplay" value="true"> <param name="autostart" value="true"> <param name="flashvars" value="hostname=www.twitch.tv&amp;start_volume=' + Dubtrack.playerController.volume + "&amp;channel=" + j + '&amp;auto_play=true"> <embed src="https://www-cdn.jtvnw.net/swflibs/TwitchPlayer.swff?channel=' + j + '" flashvars="hostname=www.twitch.tv&amp;start_volume=' + Dubtrack.playerController.volume + "&amp;channel=" + j + '&amp;auto_play=true" width="100%" height="100%" type="application/x-shockwave-flash"> </object>')
  5988. }
  5989. } catch (k) {
  5990. this.customEmbedIframeErrorDiv.show()
  5991. }
  5992. } else this.customEmbedIframeErrorDiv.hide(), f = f.replace("http:", "https:"), this.customEmbedIframeDiv.show().html('<div id="custom_iframe_overlay"></div><iframe src="' + f + '" width="100%" height="100%" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>');
  5993. else this.customEmbedIframeErrorDiv.show()
  5994. },
  5995. displayQueueBrowser: function() {
  5996. return Dubtrack.app.navigate("/browser/queue", {
  5997. trigger: !0
  5998. }), !1
  5999. },
  6000. playCurrent: function() {
  6001. var a = (this.activeSong.get("songInfo"), this.activeSong.get("song")),
  6002. b = this.activeSong.get("startTime"),
  6003. c = a.songLength / 1e3;
  6004. return b > c ? this.videoEnd() : ((Dubtrack.helpers.isDubtrackAdmin(Dubtrack.session.id) || Dubtrack.room.users && Dubtrack.room.users.getIfRoleHasPermission(Dubtrack.session.id, "skip")) && this.skipElBtn.show(), this.activePlayerDelegate && this.activePlayerDelegate.play(), void this.setTimer(b, c))
  6005. },
  6006. playCurrentSong: function() {
  6007. return this.playElBtn.hide(), this.activePlayerDelegate && this.activePlayerDelegate.play(), !1
  6008. },
  6009. loadComments: function() {},
  6010. renderUser: function(a, b) {
  6011. if (!a) {
  6012. this.activeSong.set("user", b);
  6013. b.get("userInfo");
  6014. Dubtrack.room && Dubtrack.room.users && Dubtrack.room.users.setCurrentDJ(b.get("_id")), this.pictureEl.html(Dubtrack.helpers.image.getImage(b.get("_id"), b.get("username"), !1, !0)).show(), this.currentDjName.html(b.get("username") + " is playing").show()
  6015. }
  6016. },
  6017. realTimeUpdate: function(a) {
  6018. var b = this.activeSong.get("song");
  6019. (null === b || b._id != a.song._id) && (this.activePlayerDelegate && this.activePlayerDelegate.stop(), this.activeSong.set({
  6020. song: a.song,
  6021. songInfo: a.songInfo,
  6022. startTime: a.startTime,
  6023. user: null
  6024. }), this.refresh(), this.render())
  6025. },
  6026. refresh: function() {
  6027. this.playing = !1, b("li.downdub").removeClass("downdub"), b("li.updub").removeClass("updub"), b(".shared").removeClass("shared"), this.$("#room-main-player-container #room-main-player-container-youtube").hide(), this.$("#room-main-player-container #room-main-player-container-soundcloud").hide(), this.activePlayerDelegate = null, this.loadingEl.show(), b("body").addClass("no-song-playing"), this.bufferingEl.hide(), this.progressEl.css("width", 0), Dubtrack.playerController.$(".currentTime").hide(), Dubtrack.playerController.$(".currentSong").html(dubtrack_lang.global.loading), this.pictureEl.empty(), this.currentDjName.empty(), Dubtrack.room && Dubtrack.room.users && Dubtrack.room.users.removeCurrentDJ(), Dubtrack.room && Dubtrack.room.users && Dubtrack.room.users.removeDubs(), this.intervalCounter && clearInterval(this.intervalCounter), this.videoend_timeout && clearTimeout(this.videoend_timeout)
  6028. },
  6029. fetchQueueInfo: function() {},
  6030. changeYTQuality: function() {
  6031. if (!this.YTplayerDelegate) return !1;
  6032. var a = 0,
  6033. b = this.YTplayerDelegate.getAvailableQualityLevels();
  6034. if (!(b.length < 1)) {
  6035. switch (this.playbackQuality) {
  6036. case "default":
  6037. this.qualityElBtn.addClass("active-hd"), this.playbackQuality = "highres", a = 0;
  6038. break;
  6039. default:
  6040. this.qualityElBtn.removeClass("active-hd"), this.playbackQuality = "default", a = b.length - 1
  6041. }
  6042. return a >= 0 && this.YTplayerDelegate.setPlaybackQuality(b[a]), !1
  6043. }
  6044. },
  6045. reloadVideo: function() {
  6046. return this.activeSong.set({
  6047. song: null,
  6048. songInfo: null,
  6049. user: null,
  6050. startTime: null
  6051. }), this.refresh(), this.fetchSong(), !1
  6052. },
  6053. videoEnd: function() {
  6054. this.skipElBtn.hide(), this.playing = !1
  6055. },
  6056. fetchSong: function() {
  6057. var a = this;
  6058. this.refresh(), this.activeSong.fetch({
  6059. success: function(b, c) {
  6060. a.render()
  6061. },
  6062. error: function() {
  6063. a.activeSong.set({
  6064. song: null,
  6065. songInfo: null,
  6066. user: null,
  6067. startTime: null
  6068. }), a.render()
  6069. }
  6070. })
  6071. },
  6072. loadQueueNumber: function() {},
  6073. getStarTime: function() {
  6074. var a = this.activeSong.get("startTime"),
  6075. b = this.activeSong.get("song");
  6076. return -1 == a ? (a = 0, this.activeSong.set({
  6077. startTime: a,
  6078. played: Date.now()
  6079. })) : (isNaN(a) || !a) && (a = parseInt((Date.now() - b.played) / 1e3, 10), 0 > a && (a = 0), this.activeSong.set({
  6080. startTime: a
  6081. })), a
  6082. },
  6083. buildYT: function() {
  6084. this.SCplayerDelegate && (this.SCplayerDelegate.stop(), this.SCplayerDelegate.close()), this.$("#room-main-player-container #room-main-player-container-soundcloud").empty();
  6085. var a = this.activeSong.get("song"),
  6086. c = this.activeSong.get("songInfo"),
  6087. d = this.getStarTime();
  6088. this.$("#room-main-player-container #room-main-player-container-youtube").show(), this.YTplayerDelegate ? this.YTplayerDelegate.loadVideo(c.fkid, d, function() {
  6089. this.videoend_timeout && clearTimeout(this.videoend_timeout), this.videoend_timeout = setTimeout(function() {
  6090. this.videoEnd()
  6091. }.bind(this), 1e4)
  6092. }.bind(this), this, !0) : (this.YTplayerDelegate = new Dubtrack.View.YoutubePlayer, this.YTplayerDelegate.$el.appendTo(this.$("#room-main-player-container #room-main-player-container-youtube")), this.YTplayerDelegate.render(c.fkid, d, function() {
  6093. this.videoend_timeout && clearTimeout(this.videoend_timeout), this.videoend_timeout = setTimeout(function() {
  6094. this.videoEnd()
  6095. }.bind(this), 1e4)
  6096. }.bind(this), this, !0)), this.activePlayerDelegate = this.YTplayerDelegate, this.playElBtn.hide(), this.qualityElBtn.addClass("show"), this.refreshElBtn.addClass("show"), this.hideVideoElBtn.addClass("show"), a.songLength / 1e3 == 99999 && (d = -1), this.istoggleVideo && (b("#room-main-player-container").css("visibility", "hidden"), b("#room-main-player-container iframe").css("visibility", "hidden"))
  6097. },
  6098. buildSoundCloud: function() {
  6099. this.$("#room-main-player-container #room-main-player-container-youtube").hide(), this.SCplayerDelegate && (this.SCplayerDelegate.stop(), this.SCplayerDelegate.close()), this.YTplayerDelegate && this.YTplayerDelegate.stop(), this.$("#room-main-player-container #room-main-player-container-soundcloud").empty(), this.refreshElBtn.addClass("show"), this.$("#room-main-player-container #room-main-player-container-soundcloud").show();
  6100. var a = (this.activeSong.get("song"), this.activeSong.get("songInfo")),
  6101. b = this.getStarTime(),
  6102. c = this.$el.innerWidth(),
  6103. d = this.$el.innerHeight();
  6104. e() && (this.loadingEl.hide(), this.playElBtn.show()), this.SCplayerDelegate = new Dubtrack.View.SoundCloudPlayer, this.SCplayerDelegate.$el.appendTo(this.$("#room-main-player-container #room-main-player-container-soundcloud")), this.SCplayerDelegate.render(a.streamUrl, b, function() {
  6105. this.videoend_timeout && clearTimeout(this.videoend_timeout), this.videoend_timeout = setTimeout(function() {
  6106. this.videoEnd()
  6107. }.bind(this), 1e4)
  6108. }.bind(this), this, c, d, !0), this.activePlayerDelegate = this.SCplayerDelegate
  6109. },
  6110. setTimer: function(a, b) {
  6111. if (Dubtrack.playerController.$(".currentTime").show(), this.videoLength = b, this.intervalCounter && clearInterval(this.intervalCounter), 99999 == b) return this.playingLive = !0, this.minEl.html(""), void this.secEl.html("LIVE");
  6112. this.playingLive = !1;
  6113. var c = b - a,
  6114. d = Math.floor(c / 60),
  6115. e = parseInt(c - 60 * d, 10);
  6116. if (!(0 >= c)) {
  6117. this.minEl.html("0".substring(d >= 10) + d), this.secEl.html("0".substring(e >= 10) + e);
  6118. var f = this;
  6119. this.intervalCounter = setInterval(function() {
  6120. f.setTimerCounter()
  6121. }, 1e3)
  6122. }
  6123. },
  6124. setTimerCounter: function() {
  6125. var a = this.activeSong.get("song"),
  6126. b = 0;
  6127. b = this.activePlayerDelegate && !this.playing ? parseInt((Date.now() - a.played) / 1e3, 10) : this.getCurrentTime();
  6128. var c = this.videoLength - b,
  6129. d = Math.floor(c / 60),
  6130. e = parseInt(c - 60 * d, 10),
  6131. f = this.activeSong.get("songInfo");
  6132. if (!(0 >= c)) {
  6133. this.minEl.html("0".substring(d >= 10) + d), this.secEl.html("0".substring(e >= 10) + e);
  6134. var g = 100 * b / (f.songLength / 1e3);
  6135. this.progressEl.css("width", g + "%")
  6136. }
  6137. },
  6138. setVolume: function(a) {
  6139. this.player_volume_level = a, Dubtrack.playerController.volume = a, a > 2 ? (this.$(".player-controller-container .mute").removeClass("sound-muted"), this.muted_player = !1) : (this.$(".player-controller-container .mute").addClass("sound-muted"), this.muted_player = !0), this.activePlayerDelegate && this.activePlayerDelegate.setVolume(a)
  6140. },
  6141. setVolumeRemote: function(a) {
  6142. this.activePlayerDelegate && this.activePlayerDelegate.setVolume(a)
  6143. },
  6144. sync: function(a) {
  6145. this.activePlayerDelegate && this.playing && this.activePlayerDelegate.sync(a)
  6146. },
  6147. getCurrentTime: function() {
  6148. return this.activePlayerDelegate ? this.activePlayerDelegate.getCurrentTime() : void 0
  6149. },
  6150. beforeClose: function() {
  6151. this.YTplayerDelegate && this.YTplayerDelegate.close(), this.SCplayerDelegate && this.SCplayerDelegate.close(), this.YTplayerDelegate = null, this.SCplayerDelegate = null, this.intervalCounter && clearInterval(this.intervalCounter), this.videoend_timeout && clearTimeout(this.videoend_timeout), this.playerControls && this.playerControls.close(), g.config.playerMainContainer.html(b("<div/>", {
  6152. "class": "player_container"
  6153. })), g.config.playerContainer = g.config.playerMainContainer.find("div.player_container")
  6154. }
  6155. }), Dubtrack.View.Room = Backbone.View.extend({
  6156. el: b("#main-room"),
  6157. videoChatCollapsed: !1,
  6158. events: {
  6159. "click button.view-users": "displayUsers",
  6160. "click #mobile-room-menu a": "setMenuActive"
  6161. },
  6162. initialize: function() {
  6163. if (this.currentMobileClass = "", this.roomInfoView = null, Dubtrack.Events.bind("realtime:room-update", this.roomUpdate, this), Dubtrack.Events.bind("realtime:user-kick", this.userKickedOut, this), Dubtrack.Events.bind("realtime:user-ban", this.userBannedOut, this), Dubtrack.helpers.cookie.set("dubtrack-room", this.model.get("roomUrl"), 60), Dubtrack.helpers.cookie.set("dubtrack-room-id", this.model.get("_id"), 60), Dubtrack.loggedIn) {
  6164. var a = Dubtrack.config.apiUrl + Dubtrack.config.urls.roomBeacon.replace(":id", this.model.id).replace(":userid", Dubtrack.session.id);
  6165. b(window).bind("beforeunload", function() {
  6166. b.ajax({
  6167. url: a,
  6168. async: !1
  6169. })
  6170. }), b(window).bind("unload", function() {
  6171. b.ajax({
  6172. url: a,
  6173. async: !1
  6174. })
  6175. })
  6176. }
  6177. Dubtrack.realtime.subscribe(this.model.get("realTimeChannel").toLowerCase(), function() {}.bind(this))
  6178. },
  6179. setMenuActive: function(a) {
  6180. var c = b(a.target);
  6181. c.is("a") || (c = c.parents("a"));
  6182. var d = c.data("display");
  6183. return d && (this.$el.removeClass(this.currentMobileClass), this.currentMobileClass = d, this.$el.addClass(this.currentMobileClass), this.$("#mobile-room-menu a.active").removeClass("active"), c.addClass("active")), !1
  6184. },
  6185. displayUsers: function() {
  6186. return this.$el.addClass("display-users-rooms"), !1
  6187. },
  6188. roomUpdate: function(a) {
  6189. if (a && a.room) {
  6190. var c = this.model.get("background");
  6191. a.room.background && a.room.background.public_id && c && c.public_id && c.public_id != a.room.background.public_id && this.updateBackground(!0), b("#roomNameMenu").html(a.room.name), this.model.set(a.room)
  6192. }
  6193. },
  6194. updateBackground: function(a) {
  6195. b.backstretch("destroy", !1);
  6196. var c = Dubtrack.config.urls.roomImage;
  6197. c = Dubtrack.config.apiUrl + c.replace(":id", this.model.get("_id")), a && (c += "?v" + Date.now()), b.backstretch(c)
  6198. },
  6199. render: function() {
  6200. var a = Dubtrack.config.urls.roomUsers.replace("{id}", this.model.id);
  6201. this.urlUsersRoom = Dubtrack.config.apiUrl + a, this.joinRoom(), this.renderChat(), this.player || Dubtrack.player_initialized || (Dubtrack.player_initialized = !0, this.player = new Dubtrack.View.Player({
  6202. model: this.model
  6203. })), Dubtrack.loggedIn ? b("#create-room-div").show() : b("#create-room-div").hide(), Dubtrack.session && Dubtrack.room.users && Dubtrack.room.users.getIfOwner(Dubtrack.session.get("_id")) ? (b("#create-room-div").hide(), b("#edit-room-div").show()) : (b("#create-room-div").show(), b("#edit-room-div").hide());
  6204. var c = this.model.get("background");
  6205. c && this.updateBackground(!1), this.$(".room-feautre-title span").html("Top users in " + this.model.get("name")), b("#main-room-active-link").attr("href", "/join/" + this.model.get("roomUrl")).addClass("active-room").find(".room-name").html(this.model.get("name")), b("#main-menu-left .room-active-link").attr("href", "/join/" + this.model.get("roomUrl")).css("display", "block").find("span.current-room").html(this.model.get("name")), b(".rewindProfile a").attr("href", "/join/" + this.model.get("roomUrl")), b(".close").attr("href", "/join/" + this.model.get("roomUrl"))
  6206. },
  6207. displayRoom: function() {
  6208. this.$el.show()
  6209. },
  6210. userKickedOut: function(a) {
  6211. var b = a.kickedUser && "_id" in a.kickedUser ? a.kickedUser._id : !1;
  6212. if (Dubtrack.session && b && b === Dubtrack.session.get("_id")) {
  6213. var c = "You were kicked out of the room";
  6214. Dubtrack.helpers.displayError("Warning", c, !1, "Dubtrack.room.leaveRoom();"), setTimeout(function() {
  6215. this.leaveRoom()
  6216. }.bind(this), 3e4);
  6217. try {
  6218. Dubtrack.room.chat.mentionChatSound && Dubtrack.room.chat.mentionChatSound.play()
  6219. } catch (d) {}
  6220. }
  6221. },
  6222. userBannedOut: function(a) {
  6223. var b = a.kickedUser && "_id" in a.kickedUser ? a.kickedUser._id : !1;
  6224. if (Dubtrack.session && b && b === Dubtrack.session.get("_id")) {
  6225. var c = "You were banned from this room",
  6226. d = parseInt(a.time, 10);
  6227. d && 0 !== d && (c += " for " + d + " minutes"), Dubtrack.helpers.displayError("Warning", c, !1, "Dubtrack.room.leaveRoom();"), setTimeout(function() {
  6228. this.leaveRoom()
  6229. }.bind(this), 3e4);
  6230. try {
  6231. Dubtrack.room.chat.mentionChatSound && Dubtrack.room.chat.mentionChatSound.play()
  6232. } catch (e) {}
  6233. }
  6234. },
  6235. leaveRoom: function() {
  6236. Dubtrack.helpers.cookie["delete"]("dubtrack-room"), Dubtrack.helpers.cookie["delete"]("dubtrack-room-id");
  6237. var a = Dubtrack.config.apiUrl + Dubtrack.config.urls.roomBeacon.replace(":id", this.model.id).replace(":userid", Dubtrack.session.id);
  6238. b.ajax({
  6239. url: a
  6240. }).always(function() {
  6241. window.onbeforeunload = null, window.location = "/"
  6242. })
  6243. },
  6244. renderChat: function() {
  6245. this.chat || (this.chat = new Dubtrack.View.chat)
  6246. },
  6247. joinRoom: function() {
  6248. if (!this.joinedRoom) {
  6249. this.joinedRoom = !0;
  6250. var a = this;
  6251. Dubtrack.loggedIn ? Dubtrack.helpers.sendRequest(this.urlUsersRoom, {}, "post", function(c, d) {
  6252. if (a.loadRoomUsers(), c) switch (Dubtrack.playerController.$(".remove-if-banned").remove(), b("body").addClass("not-logged-in"), a.chat.$(".pusher-chat-widget-input").html(""), c.code) {
  6253. case 401:
  6254. try {
  6255. a.chat.$(".pusher-chat-widget-input").html("<p>" + c.data.err.details.message + "</p>"), Dubtrack.helpers.displayError("[" + c.code + "] " + dubtrack_lang.global.error, c.data.err.details.message + ". <b><u>You won't be able to chat or play songs</u></b>", !1)
  6256. } catch (e) {}
  6257. Dubtrack.realtime.destroy(), Dubtrack.loggedIn = !1, Dubtrack.realtime.subscribe(a.model.get("realTimeChannel").toLowerCase(), function() {
  6258. Dubtrack.loggedIn = !0
  6259. });
  6260. break;
  6261. default:
  6262. Dubtrack.helpers.displayError(dubtrack_lang.global.error, "An unexpected error occurred joining room", !0)
  6263. } else d && d.data && d.data.user && d.data.user.muted && (a.chat.user_muted = !0)
  6264. }) : this.loadRoomUsers()
  6265. }
  6266. },
  6267. loadRoomUsers: function() {
  6268. this.users ? this.users.autoLoad() : this.users = new Dubtrack.View.roomUsers({
  6269. model: this.model
  6270. })
  6271. },
  6272. setTopUsers: function() {}
  6273. }), Dubtrack.View.RoomPassword = Backbone.View.extend({
  6274. attributes: {
  6275. id: "warning"
  6276. },
  6277. events: {
  6278. submit: "submitForm"
  6279. },
  6280. render: function(a, b) {
  6281. return this.$el.html("<form><h3>" + a + "</h3><p>" + b + "<input type='password' name='warning-password' id='warning-password' /></p><input type='submit' id='warning-input-submit' value='Join room' /></form>"), this.$el.appendTo("body"), this
  6282. },
  6283. resetFields: function() {
  6284. this.$("#warning-password").val("").focus(), this.$("#warning-input-submit").val("Join Room")
  6285. },
  6286. submitForm: function() {
  6287. this.$("#warning-input-submit").val("Loading...");
  6288. var a = this.$("#warning-password").val();
  6289. return a && a.length > 0 && Dubtrack.room.joinRoom({
  6290. "password-room": a
  6291. }), !1
  6292. }
  6293. }), f.room.roomFormUpdateViewUpdate = Backbone.View.extend({
  6294. attributes: {
  6295. id: "roomFormUpdate"
  6296. },
  6297. events: {
  6298. "click .btn-primary": "saveForm",
  6299. "click .cancel": "closeAction",
  6300. "click .closebtn": "closeAction",
  6301. "change select#roomTypeSelect": "roomTypeChange",
  6302. "change select#roomDisplaySelect": "roomDisplayChange",
  6303. "submit form": "saveForm",
  6304. "keyup #roomEmbedInput": "replaceIframe"
  6305. },
  6306. render: function() {
  6307. this.$el.html(_.template(Dubtrack.els.templates.rooms.roomFormUpdate, this.model.toJSON())), b(".dubtrack_overlay").show(), this.create_form = this.model.isNew();
  6308. var a = this;
  6309. if (this.create_form) this.$("#background-room-update").hide();
  6310. else {
  6311. var c = Dubtrack.config.urls.roomImage;
  6312. c = c.replace(":id", this.model.get("_id")), this.$("#fileupload").fileupload({
  6313. url: Dubtrack.config.apiUrl + c,
  6314. dataType: "json",
  6315. start: function() {
  6316. a.$(".btn-primary").html("loading...")
  6317. },
  6318. done: function(a, b) {},
  6319. always: function() {
  6320. a.$(".btn-primary").html("Save"), a.$("#progress .bar").css({
  6321. width: "0%"
  6322. })
  6323. },
  6324. progress: function(b, c) {
  6325. var d = parseInt(c.loaded / c.total * 100, 10);
  6326. a.$("#progress .bar").css({
  6327. width: d + "%"
  6328. })
  6329. }
  6330. })
  6331. }
  6332. return this.roomTypeChange(), this.roomDisplayChange(), this
  6333. },
  6334. replaceIframe: function() {
  6335. var a = this.$("#roomEmbedInput").val();
  6336. try {
  6337. if ($iframe = b(a), $iframe) {
  6338. var c = $iframe.attr("src");
  6339. c && (this.$("#roomEmbedInput").val(c), a = c)
  6340. }
  6341. } catch (d) {}
  6342. this.displayCustomIframe()
  6343. },
  6344. saveForm: function(a) {
  6345. a.preventDefault();
  6346. var b = this.$("input#roomName").val(),
  6347. c = this.$("input#maxLengthSongName").val(),
  6348. d = this.$("#roomTypeSelect").val(),
  6349. e = this.$("#lockQueueSelect").val();
  6350. if (description = this.$("#roomDescription").val(), roomEmbed = this.$("#roomEmbedInput").val(), welcomeMessage = this.$("#welcomeMessage").val(), roomDisplay = this.$("#roomDisplaySelect").val(), roomPassword = this.$("#roomPassword").val(), metaDescription = this.$("#metaDescription").val(), b && " " !== b) {
  6351. this.$(".btn-primary").html("loading...");
  6352. var f = this;
  6353. this.model.save({
  6354. name: b,
  6355. roomDisplay: roomDisplay,
  6356. maxLengthSong: c,
  6357. roomType: d,
  6358. roomEmbed: roomEmbed,
  6359. description: description,
  6360. lockQueue: e,
  6361. welcomeMessage: welcomeMessage,
  6362. metaDescription: metaDescription,
  6363. roomPassword: roomPassword
  6364. }, {
  6365. success: function(a, b) {
  6366. if (200 === b.code)
  6367. if (f.create_form) {
  6368. var c = f.model.get("roomUrl");
  6369. c && (window.location = "/join/" + c)
  6370. } else f.close()
  6371. },
  6372. error: function() {
  6373. f.create_form ? f.$(".btn-primary").html("room limit reached, you cannot create more rooms") : f.$(".btn-primary").html("an unexpected error occurred, please try again later")
  6374. }
  6375. })
  6376. }
  6377. return !1
  6378. },
  6379. displayCustomIframe: function() {
  6380. var a = this.$("#roomEmbedInput").val(),
  6381. b = /(http:\/\/|https:\/\/|\/\/)(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/,
  6382. c = /(twitch\.tv)\/([^\&\?\/]+)/;
  6383. if (a && b.test(a))
  6384. if (c.test(a)) {
  6385. var d = a.match(c);
  6386. try {
  6387. if (d[2]) {
  6388. var e = d[2];
  6389. this.$("#iframe-embed-preview").html('<object type="application/x-shockwave-flash" data="https://www-cdn.jtvnw.net/swflibs/TwitchPlayer.swff?channel=' + e + '" width="100%" height="100%"> <param name="movie" value="https://www-cdn.jtvnw.net/swflibs/TwitchPlayer.swff?channel=' + e + '"> <param name="quality" value="high"> <param name="allowFullScreen" value="true"> <param name="allowScriptAccess" value="always"> <param name="pluginspage" value="http://www.macromedia.com/go/getflashplayer"> <param name="autoplay" value="true"> <param name="autostart" value="true"> <param name="flashvars" value="hostname=www.twitch.tv&amp;start_volume=25&amp;channel=' + e + '&amp;auto_play=true"> <embed src="https://www-cdn.jtvnw.net/swflibs/TwitchPlayer.swff?channel=' + e + '" flashvars="hostname=www.twitch.tv&amp;start_volume=25&amp;channel=' + e + '&amp;auto_play=true" width="100%" height="100%" type="application/x-shockwave-flash"> </object>')
  6390. }
  6391. } catch (f) {}
  6392. } else a = a.replace("http:", "https:"), this.$("#iframe-embed-preview").html('<iframe width="100%" height="100%" src="' + a + '" frameborder="0" allowfullscreen></iframe>');
  6393. else this.$("#iframe-embed-preview").html("<h3>Invalid iframe url</h3>")
  6394. },
  6395. roomTypeChange: function() {
  6396. "iframe" == this.$("#roomTypeSelect").val() ? (this.$("#iframeEmbedField").show(), this.displayCustomIframe()) : (this.$("#iframeEmbedField").hide(), this.$("#iframe-embed-preview").empty())
  6397. },
  6398. roomDisplayChange: function() {
  6399. "private" == this.$("#roomDisplaySelect").val() ? (this.$("#room-password-control-group").show(), this.displayCustomIframe()) : this.$("#room-password-control-group").hide()
  6400. },
  6401. closeAction: function() {
  6402. return this.close(), !1
  6403. },
  6404. beforeClose: function() {
  6405. this.$("#iframe-embed-preview").empty(), b(".dubtrack_overlay").hide()
  6406. }
  6407. }), Dubtrack.View.RoomInfo = Backbone.View.extend({
  6408. el: b("#room-info-display"),
  6409. initialize: function() {
  6410. Dubtrack.Events.bind("realtime:room-update", this.roomUpdate, this)
  6411. },
  6412. render: function() {
  6413. var a = this.model.toJSON();
  6414. return a.description && (a.description = Dubtrack.helpers.text.convertHtmltoTags(a.description).replace(/(?:\r\n|\r|\n)/g, "<br />")), this.$(".room-info-display-wrapper").html(_.template(Dubtrack.els.templates.rooms.roomModalView, a)), this.$(".room-info-display-wrapper").perfectScrollbar({
  6415. wheelSpeed: 30,
  6416. suppressScrollX: !0,
  6417. wheelPropagation: !1
  6418. }), this
  6419. },
  6420. roomUpdate: function(a) {
  6421. a && a.room && (this.model.set(a.room), this.render())
  6422. }
  6423. }), Dubtrack.View.RoomList = Backbone.View.extend({
  6424. el: b("#room-list"),
  6425. events: {
  6426. "keyup .room-lobby-header .room-search input": "triggerSearch",
  6427. "click .room-lobby-header .create-room": "createRoom"
  6428. },
  6429. initialize: function() {
  6430. this.model.bind("add", this.appendEl, this), this.model.bind("reset", this.render, this), this.roomListEl = this.$("#container-room-list"), this.$("#room-scroll-container").perfectScrollbar({
  6431. wheelSpeed: 20,
  6432. suppressScrollX: !0,
  6433. wheelPropagation: !1,
  6434. onscrollCallback: function(a, b) {
  6435. 300 > b - a && b > 500 && this.loadMoreItems()
  6436. }.bind(this)
  6437. }), this.render()
  6438. },
  6439. render: function() {
  6440. return this.roomListEl.empty(), this.offsetSearchItems = 0, this.moreItemsToLoad = !1, this.loadingMoreItems = !1, _.each(this.model.models, function(a) {
  6441. this.appendEl(a)
  6442. }, this), Dubtrack.els.displayloading(dubtrack_lang.room.searching), this
  6443. },
  6444. fetchUserRooms: function() {},
  6445. triggerSearch: function(a) {
  6446. var c = b.trim(this.$(".room-lobby-header .room-search input").val());
  6447. this.searchTimeoutTrigger && clearTimeout(this.searchTimeoutTrigger), c && "" !== c && null !== c && c.length > 2 ? this.searchTimeoutTrigger = setTimeout(function() {
  6448. this.search(c)
  6449. }.bind(this), 700) : 0 === c.length && (this.searchTimeoutTrigger = setTimeout(function() {
  6450. this.search("")
  6451. }.bind(this), 300))
  6452. },
  6453. loadMoreItems: function() {
  6454. if (!this.loadingMoreItems && Dubtrack.roomList.collection) {
  6455. this.loadingMoreItems = !0;
  6456. var a = new Dubtrack.Collection.Room;
  6457. this.query && this.query.length > 0 ? a.url = Dubtrack.config.apiUrl + Dubtrack.config.urls.roomSearch.replace(":term", this.query.replace(/[^a-zA-Z 0-9]+/g, "")) : a.url = Dubtrack.config.apiUrl + Dubtrack.config.urls.room, Dubtrack.els.displayloading(dubtrack_lang.room.searching), this.offsetSearchItems = this.offsetSearchItems + 20, a.fetch({
  6458. data: {
  6459. offset: this.offsetSearchItems
  6460. },
  6461. success: function() {
  6462. _.each(a.models, function(a) {
  6463. this.model.add(a)
  6464. }.bind(this)), Dubtrack.els.mainLoading.hide(), this.loadingMoreItems = !1
  6465. }.bind(this),
  6466. error: function() {
  6467. this.loadingMoreItems = !1, Dubtrack.els.mainLoading.hide()
  6468. }.bind(this)
  6469. })
  6470. }
  6471. },
  6472. search: function(a) {
  6473. this.loadingMoreItems || (this.$("#room-scroll-container").scrollTop(0), Dubtrack.els.displayloading(dubtrack_lang.room.searching), this.offsetSearchItems = 0, this.moreItemsToLoad = !1, this.userRoomsCollection && this.userRoomsCollection.reset(), this.model.reset(), this.roomListEl.empty(), this.userRoomsCollection = new Dubtrack.Collection.Room, this.query = a, this.query && this.query.length > 0 ? this.userRoomsCollection.url = Dubtrack.config.apiUrl + Dubtrack.config.urls.roomSearch.replace(":term", this.query.replace(/[^a-zA-Z 0-9]+/g, "")) : this.userRoomsCollection.url = Dubtrack.config.apiUrl + Dubtrack.config.urls.room, this.userRoomsCollection.fetch({
  6474. success: function() {
  6475. _.each(this.userRoomsCollection.models, function(a) {
  6476. this.model.add(a)
  6477. }.bind(this)), Dubtrack.els.mainLoading.hide(), this.loadingMoreItems = !1
  6478. }.bind(this),
  6479. error: function() {
  6480. this.loadingMoreItems = !1, Dubtrack.els.mainLoading.hide()
  6481. }.bind(this)
  6482. }))
  6483. },
  6484. createRoom: function() {
  6485. if (Dubtrack.loggedIn) {
  6486. var a = new Dubtrack.Model.Room;
  6487. a.parse = Dubtrack.helpers.parse, this.roomUpdate = new f.room.roomFormUpdateViewUpdate({
  6488. model: a
  6489. }).render(), this.roomUpdate.$el.appendTo("body")
  6490. } else Dubtrack.app.navigate("/login", {
  6491. trigger: !0
  6492. });
  6493. return !1
  6494. },
  6495. appendEl: function(a) {
  6496. var b = new Dubtrack.View.RoomListItem({
  6497. model: a
  6498. }).render();
  6499. Dubtrack.loggedIn && a.get("userid") == Dubtrack.session.id ? b.$el.addClass("userRoom").prependTo(this.roomListEl) : b.$el.appendTo(this.roomListEl), this.$("#room-scroll-container").perfectScrollbar("update")
  6500. },
  6501. beforeClose: function() {}
  6502. }), Dubtrack.View.ModsView = Backbone.View.extend({
  6503. el: b("#mods-controllers"),
  6504. events: {
  6505. "click .mod-controllers-headers .display-mods-controls": "displayControls",
  6506. "click .mod-controllers-headers .display-ban-list": "displayBanList",
  6507. "click .mod-controllers-headers .display-mute-list": "displayMuteList",
  6508. "click .mod-controllers-headers .display-staff-list": "displayStaffList"
  6509. },
  6510. initialize: function() {
  6511. this.roomBanListView = (new Dubtrack.View.RoomBanList).render(), this.roomMuteListView = (new Dubtrack.View.RoomMuteList).render(), this.roomStaffListView = (new Dubtrack.View.RoomStaffList).render(), this.$(".mods-controllers-commands-list .mods-controller-container").perfectScrollbar({
  6512. wheelSpeed: 30,
  6513. suppressScrollX: !0,
  6514. wheelPropagation: !1
  6515. })
  6516. },
  6517. displayBanList: function() {
  6518. return this.$(".mod-controllers-headers .active").removeClass("active"), this.$(".mod-controllers-headers .display-ban-list").addClass("active"), this.$(".show-controller").removeClass("show-controller"), this.$(".mods-controllers-ban-list").addClass("show-controller"), this.roomBanListView.fetchUsers(), !1
  6519. },
  6520. displayMuteList: function() {
  6521. return this.$(".mod-controllers-headers .active").removeClass("active"), this.$(".mod-controllers-headers .display-mute-list").addClass("active"), this.$(".show-controller").removeClass("show-controller"), this.$(".mods-controllers-mute-list").addClass("show-controller"), this.roomMuteListView.fetchUsers(), !1
  6522. },
  6523. displayStaffList: function() {
  6524. return this.$(".mod-controllers-headers .active").removeClass("active"), this.$(".mod-controllers-headers .display-staff-controls").addClass("active"), this.$(".show-controller").removeClass("show-controller"), this.$(".mods-controllers-staff-list").addClass("show-controller"), this.roomStaffListView.fetchUsers(), this.roomStaffListView.setClasses(), !1
  6525. },
  6526. displayControls: function() {
  6527. return this.$(".mod-controllers-headers .active").removeClass("active"), this.$(".mod-controllers-headers .display-mods-controls").addClass("active"), this.$(".show-controller").removeClass("show-controller"), this.$(".mods-controllers-commands-list").addClass("show-controller"), !1
  6528. }
  6529. }), Dubtrack.View.RoomBanList = Backbone.View.extend({
  6530. el: b("#mods-controllers .mods-controllers-ban-list"),
  6531. initialize: function() {
  6532. this.collection = new Dubtrack.Collection.RoomUser, this.collection.bind("add", this.addUser, this), this.collection.bind("remove", this.removeEl, this), this.collection.bind("reset", this.resetItems, this), this.userlistEl = this.$(".user-list"), this.$(".mods-controller-container").perfectScrollbar({
  6533. wheelSpeed: 30,
  6534. suppressScrollX: !0,
  6535. wheelPropagation: !1
  6536. })
  6537. },
  6538. render: function() {
  6539. return this.collection.url = Dubtrack.config.apiUrl + Dubtrack.config.urls.roomBanUsers.replace(":id", Dubtrack.room.model.id), this.viewItems = Dubtrack.View.roomBanUsersItem, this
  6540. },
  6541. addUser: function(a) {
  6542. this.appendEl(a)
  6543. },
  6544. resetItems: function(a) {
  6545. this.$("li").remove()
  6546. },
  6547. appendEl: function(a) {
  6548. a.viewEl = new this.viewItems({
  6549. model: a
  6550. }).render(), a.viewEl && this.userlistEl.append(a.viewEl.$el), this.$(".mods-controller-container").perfectScrollbar("update")
  6551. },
  6552. removeEl: function(a) {
  6553. a.viewEl.close(), this.$(".mods-controller-container").perfectScrollbar("update")
  6554. },
  6555. fetchUsers: function() {
  6556. this.$(".user-list li").show(), b("#mods-controllers .loading").show(), this.collection.reset(), this.collection.fetch({
  6557. update: !0,
  6558. success: function() {
  6559. b("#mods-controllers .loading").hide()
  6560. },
  6561. error: function() {
  6562. b("#mods-controllers .loading").hide()
  6563. }
  6564. })
  6565. }
  6566. }), Dubtrack.View.RoomMuteList = Dubtrack.View.RoomBanList.extend({
  6567. el: b("#mods-controllers .mods-controllers-mute-list"),
  6568. render: function() {
  6569. return this.collection.url = Dubtrack.config.apiUrl + Dubtrack.config.urls.roomMuteUsers.replace(":id", Dubtrack.room.model.id), this.viewItems = Dubtrack.View.roomMuteUsersItem, this
  6570. }
  6571. }), Dubtrack.View.RoomStaffList = Dubtrack.View.RoomBanList.extend({
  6572. el: b("#mods-controllers .mods-controllers-staff-list"),
  6573. render: function() {
  6574. return this.collection.url = Dubtrack.config.apiUrl + Dubtrack.config.urls.roomStaffUsers.replace(":id", Dubtrack.room.model.id), this.viewItems = Dubtrack.View.roomStaffUsersItem, this
  6575. },
  6576. setClasses: function() {
  6577. this.$el.removeClass("co-owner vip resident-dj dj manager mod creator"), this.$el.addClass(Dubtrack.room.users.getRoleType(Dubtrack.session.id)), (Dubtrack.room.model.get("userid") == Dubtrack.session.id || Dubtrack.helpers.isDubtrackAdmin(Dubtrack.session.id)) && this.$el.addClass("creator")
  6578. }
  6579. }), Dubtrack.View.roomBanUsersItem = Backbone.View.extend({
  6580. tagName: "li",
  6581. events: {
  6582. "click .actions": "clickAction"
  6583. },
  6584. render: function() {
  6585. return this.$el.html(_.template(Dubtrack.els.templates.rooms.roomBanListItem, this.model.toJSON())), this
  6586. },
  6587. clickAction: function() {
  6588. var a = this.model.get("_user");
  6589. return Dubtrack.room.chat.unbanUser(a.username), this.$el.hide(), !1
  6590. }
  6591. }), Dubtrack.View.roomMuteUsersItem = Dubtrack.View.roomBanUsersItem.extend({
  6592. render: function() {
  6593. return this.$el.html(_.template(Dubtrack.els.templates.rooms.roomMuteListItem, this.model.toJSON())), this
  6594. },
  6595. clickAction: function() {
  6596. var a = this.model.get("_user");
  6597. return Dubtrack.room.chat.unmuteUser(a.username), this.$el.hide(), !1
  6598. }
  6599. }), Dubtrack.View.roomStaffUsersItem = Dubtrack.View.roomBanUsersItem.extend({
  6600. render: function() {
  6601. var a = this.model.get("roleid"),
  6602. b = this.model.get("_user");
  6603. return Dubtrack.session.id == b._id ? (this.close(), null) : (this.$el.html(_.template(Dubtrack.els.templates.rooms.roomStaffListItem, this.model.toJSON())), this.$el.addClass(a.type), this)
  6604. },
  6605. clickAction: function() {
  6606. var a = "setModUser",
  6607. b = this.model.get("roleid");
  6608. switch (b.type) {
  6609. case "co-owner":
  6610. a = "setOwnerUser";
  6611. break;
  6612. case "vip":
  6613. a = "setVIPUser";
  6614. break;
  6615. case "resident-dj":
  6616. a = "setDJUser";
  6617. break;
  6618. case "dj":
  6619. a = "setRoomDJUser";
  6620. break;
  6621. case "manager":
  6622. a = "setManagerUser"
  6623. }
  6624. var c = this.model.get("_user");
  6625. return Dubtrack.room.chat.unsetRole(c.username, a), this.$el.hide(), !1
  6626. }
  6627. }), Dubtrack.View.RoomListItem = Backbone.View.extend({
  6628. tagName: "section",
  6629. events: {
  6630. "click a.join": "clickAction",
  6631. "click .description": "clickAction",
  6632. "click .image": "clickAction",
  6633. "click .navigate": "navigate"
  6634. },
  6635. initialize: function() {
  6636. this.$el.addClass("room-item")
  6637. },
  6638. render: function() {
  6639. var a = this.model.toJSON();
  6640. this.$el.html(_.template(Dubtrack.els.templates.rooms.roomListItem, a)), g.roomModel && ($id = g.roomModel.get("room.id"), $id && $id === this.model.get("id") && b(this.el).addClass("activeRoom"));
  6641. var c = this.model.get("_user");
  6642. return c && "object" == typeof c ? (Dubtrack.cache.users.add(c), c = new Dubtrack.Model.User(c), this.renderUser(null, c)) : Dubtrack.cache.users.get(this.model.get("userid"), this.renderUser, this), this
  6643. },
  6644. renderUser: function(a, b) {
  6645. this.user = b, this.$(".user-info").show().find("a").attr("href", b.get("username")).html(b.get("username"));
  6646. b.get("userInfo")
  6647. },
  6648. clickAction: function(a) {
  6649. return Dubtrack.app.navigate("/join/" + this.model.get("roomUrl"), {
  6650. trigger: !0
  6651. }), !1
  6652. },
  6653. navigate: function(a) {
  6654. return el = b(a.target), el.is("a") || (el = el.parents("a")), $href = el.attr("href"), $href && g.app.navigate($href, {
  6655. trigger: !0
  6656. }), !1
  6657. }
  6658. }), Dubtrack.View.Profile = Backbone.View.extend({
  6659. el: b("#profileMainSection"),
  6660. events: {
  6661. "click .follow": "follow",
  6662. "click .unfollow": "unfollow",
  6663. "click a.readlessLink": "readLess",
  6664. "click a.readmoreLink": "readMore",
  6665. "click a.loadMoreWallPosts": "loadMoreWallPosts",
  6666. "click a.navigate": "navigate",
  6667. "click .followersCount": "loadFollowers",
  6668. "click .followingCount": "loadFollowing",
  6669. "click .updatePictureGif": "openGifCreator",
  6670. "click .infoProfile h2 span.editUsername": "displayEditForm",
  6671. "click .infoProfile h2 span.cancelUsername": "closeEditForm",
  6672. "keyup .infoProfile h2 input": "keyUpCheckforUsername",
  6673. "click .infoProfile h2 span.saveUsername": "updateUserName",
  6674. "click .rewindProfile a": "closeProfile"
  6675. },
  6676. initialize: function() {
  6677. this.render()
  6678. },
  6679. render: function() {
  6680. this.currentPage = 0, this.$el.show();
  6681. var a = this.model.toJSON();
  6682. a.imgProfile = Dubtrack.helpers.image.getImage(a._id, a.username, !0), this.$el.html(_.template(Dubtrack.els.templates.profile.profileView, a)), Dubtrack.Events.bind("realtime:user-update-" + a._id, this.updateImage, this), this.socialEl = this.$("ul#ulSocial");
  6683. this.model.get("links");
  6684. return this.displayBarCurrent = this.$("span.progress"), this.loadingTabsEl = this.$(".tabLoading"), this.loadDetails(), this
  6685. },
  6686. closeProfile: function(a) {
  6687. a && a.preventDefault(), Dubtrack.room && Dubtrack.room.model ? Dubtrack.app.navigate("/join/" + Dubtrack.room.model.get("roomUrl"), {
  6688. trigger: !0
  6689. }) : Dubtrack.app.navigate("/lobby", {
  6690. trigger: !0
  6691. })
  6692. },
  6693. closeEditForm: function() {
  6694. return this.$(".infoProfile h2").removeClass("edit_username"), !1
  6695. },
  6696. displayEditForm: function() {
  6697. return this.$(".infoProfile h2").addClass("edit_username"), this.$(".infoProfile h2 input").focus(), !1
  6698. },
  6699. keyUpCheckforUsername: function() {
  6700. this.timeoutCheckForusername && clearTimeout(this.timeoutCheckForusername);
  6701. var a = this;
  6702. this.timeoutCheckForusername = setTimeout(function() {
  6703. a.checkForUsername()
  6704. }, 500)
  6705. },
  6706. updateUserName: function() {
  6707. var a = b.trim(this.$(".infoProfile h2 input").val());
  6708. if ("" !== a && null !== a) {
  6709. var c = this;
  6710. return this.$(".infoProfile h2 span.saveUsername").html(Dubtrack.config.loadingEls), b.ajax({
  6711. url: Dubtrack.config.apiUrl + Dubtrack.config.urls.updateUsername,
  6712. method: "post",
  6713. xhrFields: {
  6714. withCredentials: !0
  6715. },
  6716. data: {
  6717. username: a
  6718. }
  6719. }).success(function(d) {
  6720. d.data.username ? (c.$(".infoProfile h2 .check_username_info").removeClass("error").hide(), c.$(".infoProfile h2").removeClass("edit_username"), c.$(".infoProfile h2 span.usernameContainer").html(d.data.username), b(".user-header-menu button.user-info-button span").html(d.data.username), Dubtrack.session.set("username", d.data.username), Dubtrack.app.navigate("/" + d.data.username, {
  6721. trigger: !1
  6722. })) : c.$(".infoProfile h2 .check_username_info").html(a + " is taken").addClass("error").show()
  6723. }).always(function() {
  6724. c.$(".infoProfile h2 span.saveUsername").html('save <i class="icon-disk"></i>')
  6725. }).error(function() {
  6726. c.$(".infoProfile h2 .check_username_info").html(a + " is taken").addClass("error").show()
  6727. }), !1
  6728. }
  6729. },
  6730. checkForUsername: function() {
  6731. var a = b.trim(this.$(".infoProfile h2 input").val());
  6732. if ("" === a || null === a) return void this.$(".infoProfile h2 .check_username_info").hide();
  6733. this.$(".infoProfile h2 .check_username_info").removeClass("error").hide();
  6734. var c = this;
  6735. b.ajax({
  6736. url: Dubtrack.config.apiUrl + Dubtrack.config.urls.queryUsernameAvailability,
  6737. method: "get",
  6738. xhrFields: {
  6739. withCredentials: !0
  6740. },
  6741. data: {
  6742. username: a
  6743. }
  6744. }).success(function(a) {
  6745. a.data.taken ? c.$(".infoProfile h2 .check_username_info").html(a.data.username + " is taken").addClass("error").show() : c.$(".infoProfile h2 .check_username_info").html(a.data.username + " is available").show()
  6746. })
  6747. },
  6748. updateImage: function(a) {},
  6749. updateImageWithSource: function(a) {
  6750. var b = this.model.toJSON();
  6751. this.$(".pictureContainer img").attr("src", "");
  6752. var c = "http://api.dubtrack.fm/user/" + b._id + "/image/large?lastmod=" + Date.now();
  6753. this.$(".pictureContainer img").attr("src", c)
  6754. },
  6755. openGifCreator: function() {
  6756. return window.open("/imgur/index.html#&client_id=94daca23890c704", "Dubtrack FM - GIF creator", "height=590,width=340,resizable=no,location=no,scrollbars=no"), !1
  6757. },
  6758. navigate: function(a) {
  6759. return $href = b(a.target).attr("href"), $href && Dubtrack.app.navigate($href, {
  6760. trigger: !0
  6761. }), !1
  6762. },
  6763. loadDetails: function() {
  6764. this.profileSidebar = b(_.template(Dubtrack.els.templates.profile.profileSidebar, this.model.toJSON())).appendTo(this.$el), this.followersEl = this.$("#followersEl"), this.notificationsEl = this.$("#userNotifications"), this.loadFollowers()
  6765. },
  6766. follow: function(a) {
  6767. var b = Dubtrack.config.apiUrl + Dubtrack.config.urls.userFollowing.replace(":id", this.model.get("_id"));
  6768. return Dubtrack.helpers.sendRequest(b, {}, "post", function(a) {
  6769. this.loadFollowers()
  6770. }.bind(this)), this.$("button.unfollow").show(), this.$("button.follow").hide(), !1
  6771. },
  6772. unfollow: function(a) {
  6773. var b = Dubtrack.config.apiUrl + Dubtrack.config.urls.userFollowing.replace(":id", this.model.get("_id"));
  6774. return Dubtrack.helpers.sendRequest(b, {}, "delete", function(a) {
  6775. this.loadFollowers()
  6776. }.bind(this)), this.$("button.unfollow").hide(), this.$("button.follow").show(), !1
  6777. },
  6778. loadFollowers: function() {
  6779. this.followersEl.find("span.active").removeClass("active"), this.$(".followersCount").addClass("active"), this.$(".followingContainer").css("left", "0"), this.$(".followingContainer .avatarFollower").empty(), this.follows = new Dubtrack.Collection.UserFollowing;
  6780. var a = Dubtrack.config.apiUrl + Dubtrack.config.urls.userFollowing.replace(":id", this.model.get("_id"));
  6781. this.follows.url = a;
  6782. var b = this;
  6783. return this.follows.reset({}), this.follows.fetch({
  6784. success: function(a, c) {
  6785. _.each(b.follows.models, function(a) {
  6786. new Dubtrack.View.ProfileItemFollower({
  6787. model: a
  6788. }).render(a.get("userid")).$el.appendTo(b.$(".followingContainer .avatarFollower")), Dubtrack.loggedIn && a.get("userid") == Dubtrack.session.id && (b.$("button.follow").hide(), b.$("button.unfollow").show())
  6789. }), b.$(".followingContainer .total-followers").text(b.follows.models.length)
  6790. }
  6791. }), !1
  6792. },
  6793. loadFollow: function(a, c) {
  6794. this.ulFollowers = b("<ul/>", {
  6795. "class": "messages wall-post-list"
  6796. }).appendTo(b(this.el).find("div.content-main")), b.ajax({
  6797. url: g.config.getFollowing + "id/" + this.model.get("id") + "/mode/" + a,
  6798. data: {},
  6799. type: "GET",
  6800. success: function(d) {
  6801. try {
  6802. d.success && b.each(d.data.users, function() {
  6803. this.img = g.helpers.getProfileImg(this.oauth_uid, this.username, this.oauth_provider), 1 === a && (this.userid = this.follow_by), b(_.template(tpl.get("followingListItem"), this)).appendTo(c)
  6804. })
  6805. } catch (e) {}
  6806. },
  6807. error: function() {}
  6808. }, "json")
  6809. },
  6810. loadPlaylists: function() {
  6811. return this.$(".contentMainProfile .active").removeClass("active"), this.$("#playlistContent").addClass("active"), this.$("li.playlistEl").addClass("active"), this.moveProgress(), !1
  6812. },
  6813. moveProgress: function() {
  6814. this.displayBarCurrent.css("left", 33.33 * b(this.el).find(".contentMainProfile li.active").index() + "%")
  6815. }
  6816. }), Dubtrack.View.ProfileItemFollower = Backbone.View.extend({
  6817. tagName: "li",
  6818. initialize: function() {},
  6819. render: function(a) {
  6820. return Dubtrack.cache.users.get(a, this.renderUser, this), this
  6821. },
  6822. renderUser: function(a, b) {
  6823. this.user = b;
  6824. b.get("userInfo");
  6825. this.$el.html(Dubtrack.helpers.image.getImage(b.id, b.get("username")))
  6826. }
  6827. }), Dubtrack.View.Message = {}, Dubtrack.View.Message.SearchUserItem = Dubtrack.View.SearchUserItem.extend({
  6828. events: {
  6829. click: "selectItem"
  6830. },
  6831. render: function(a, b) {
  6832. return this.user = a, this.parentView = b, this.$el.attr("data-userid", a._id), this.$el.html(_.template(Dubtrack.els.templates.search.searchUser, a)), this
  6833. },
  6834. selectItem: function() {
  6835. this.parentView && this.parentView.selectItem(this.user)
  6836. }
  6837. }), Dubtrack.View.Message.Main = Backbone.View.extend({
  6838. el: b("#private-messages"),
  6839. events: {
  6840. "click .main-message-list .message-list .message-item": "loadMessagesDetails",
  6841. "click .message-details .message-header": "loadMessages",
  6842. "click .main-message-list .user_selected_items .result-item": "removeItem",
  6843. "keyup input#new-message-input": "renderSearchResults",
  6844. "click #create-new-message": "createMessage"
  6845. },
  6846. initialize: function() {
  6847. this.message_main_list = new Dubtrack.View.Message.MainList, this.message_main_list_details = new Dubtrack.View.Message.MainListDetails, this.model = new Dubtrack.Model.Search, this.collectionItems = new Backbone.Collection, this.listenTo(this.collectionItems, "add", this.addUserToCreateMessage), this.model.bind("change", this.render, this), this.model.bind("reset", this.render, this), this.search_results = this.$(".search-results"), this.search_results_users = this.$(".search-results-users");
  6848. var a = this;
  6849. b(window).on("click", function(c) {
  6850. var d = b(c.target).parents(".message-header");
  6851. 0 === d.length && (a.search_results.hide(), a.$("input#new-message-input").val(""))
  6852. })
  6853. },
  6854. addUserToCreateMessage: function(a) {
  6855. var b = a.toJSON();
  6856. b.username += " <b>remove</b>", this.$(".user_selected_items").append((new Dubtrack.View.Message.SearchUserItem).render(b, this).$el)
  6857. },
  6858. removeItem: function(a) {
  6859. var c = b(a.target);
  6860. c.is(".result-item") || (c = c.parents(".result-item"));
  6861. var d = c.attr("data-userid");
  6862. return d && (this.collectionItems.remove(d), this.$(".user_selected_items").empty(), _.each(this.collectionItems.models, function(a) {
  6863. this.addUserToCreateMessage(a)
  6864. }, this)), !1
  6865. },
  6866. loadMessages: function() {
  6867. return this.collectionItems.reset(), this.$el.removeClass("view-message-details"), this.message_main_list.loadMessages(), !1
  6868. },
  6869. loadMessagesDetails: function(a) {
  6870. var c = b(a.target);
  6871. c.is("li.message-item") || (c = c.parents("li.message-item"));
  6872. var d = c.attr("data-messageid");
  6873. return d && (this.$el.addClass("view-message-details"), this.message_main_list_details.loadMessages(d)), !1
  6874. },
  6875. render: function() {
  6876. this.search_results_users.empty();
  6877. var a = this.model.get("users"),
  6878. b = this;
  6879. a && a.length > 0 ? _.each(a, function(a) {
  6880. a._id != Dubtrack.session.get("_id") && b.appendUserItem(a)
  6881. }) : this.search_results_users.append('<div class="result-item"><span class="count">No results found</span></div>')
  6882. },
  6883. appendUserItem: function(a) {
  6884. this.search_results_users.append((new Dubtrack.View.Message.SearchUserItem).render(a, this).$el)
  6885. },
  6886. renderSearchResults: function(a) {
  6887. if (c = a.which ? a.which : a.keyCode, 13 == c) return this.createMessage(), !1;
  6888. if (9 == c) return !1;
  6889. var d = b.trim(this.$("input#new-message-input").val());
  6890. if ("" === d || null === d) return void this.search_results.hide();
  6891. this.search_results.show();
  6892. this.model.fetch({
  6893. data: {
  6894. query: d
  6895. }
  6896. })
  6897. },
  6898. selectItem: function(a) {
  6899. return this.collectionItems.length > 10 ? !1 : (this.search_results.hide(), this.$("input#new-message-input").val("").focus(), void this.collectionItems.add(a))
  6900. },
  6901. createMessage: function() {
  6902. if (this.collectionItems.length < 1) return !1;
  6903. var a = [];
  6904. return _.each(this.collectionItems.models, function(b) {
  6905. a.push(b.get("_id"))
  6906. }), this.createMessageIds(a), !1
  6907. },
  6908. createMessageIds: function(a) {
  6909. var c = Dubtrack.config.apiUrl + Dubtrack.config.urls.messages,
  6910. d = this;
  6911. return b("#private-messages .loading").show(), this.$(".user_selected_items").empty(), this.collectionItems.reset(), Dubtrack.helpers.sendRequest(c, {
  6912. usersid: a
  6913. }, "post", function(a, c) {
  6914. b("#private-messages .loading").hide(), c && c.data && c.data._id && (d.$el.addClass("view-message-details"), d.message_main_list_details.loadMessages(c.data._id))
  6915. }), !1
  6916. }
  6917. }), Dubtrack.View.Message.MainList = Backbone.View.extend({
  6918. el: b("#private-messages .main-message-list"),
  6919. events: {},
  6920. initialize: function() {
  6921. this.collection = new Dubtrack.Collection.Message, this.listenTo(this.collection, "add", this.addMessage), this.listenTo(this.collection, "reset", this.resetMessages), this.items_container = this.$(".message-list"), this.loadPerfectScrollbar()
  6922. },
  6923. loadMessages: function() {
  6924. this.$(".private-message-info").hide(), b("#private-messages .loading").show(), this.loadPerfectScrollbar(), this.main_items_loaded_check = !1;
  6925. var a = this;
  6926. this.collection.reset(), this.items_container.empty(), this.collection.fetch({
  6927. update: !0,
  6928. success: function() {
  6929. b("#private-messages .loading").hide(), a.main_items_loaded_check = !0, 0 === a.collection.length && a.$(".private-message-info").show()
  6930. }
  6931. })
  6932. },
  6933. loadPerfectScrollbar: function() {
  6934. this.perfectscrollbar_loaded && this.$(".message-list-wrapper-inner").perfectScrollbar("destroy"), this.perfectscrollbar_loaded = !0, this.$(".message-list-wrapper-inner").scrollTop(0), this.$(".message-list-wrapper-inner").perfectScrollbar({
  6935. wheelSpeed: 50,
  6936. suppressScrollX: !0,
  6937. wheelPropagation: !1
  6938. })
  6939. },
  6940. addMessage: function(a) {
  6941. this.$(".private-message-info").hide();
  6942. var b = new Dubtrack.View.Message.MainListItem({
  6943. model: a
  6944. });
  6945. a.set("_view", b), this.main_items_loaded_check ? this.items_container.prepend(b.$el) : this.items_container.append(b.$el), this.$(".message-list-wrapper-inner").perfectScrollbar("update")
  6946. },
  6947. removeMessage: function(a) {
  6948. if (this.model) {
  6949. var b = this.model.get("_view");
  6950. b && b.remove()
  6951. }
  6952. },
  6953. resetMessages: function() {
  6954. this.items_container.empty(), this.collection.each(this.addMessage, this)
  6955. }
  6956. }), Dubtrack.View.Message.MainListDetails = Dubtrack.View.Message.MainList.extend({
  6957. el: b("#private-messages .message-details"),
  6958. events: {
  6959. "keydown input#message-input": "keyPressAction"
  6960. },
  6961. loadMessages: function(a) {
  6962. this.messageid = a, this.main_items_loaded = !1, this.last_view = !1, this.last_model = !1, this.loadPerfectScrollbar(), this.$("input#message-input").focus(), b("#private-messages .loading").show(), this.$(".private-message-details-info").hide();
  6963. var c = Dubtrack.config.apiUrl + Dubtrack.config.urls.messages_items.replace(":id", this.messageid);
  6964. this.collection.url = c;
  6965. var d = this;
  6966. this.collection.reset(), this.collection.fetch({
  6967. success: function() {
  6968. b("#private-messages .loading").hide(), d.main_items_loaded = !0, d.setMessageAsRead(), 0 === d.collection.length && d.$(".private-message-details-info").show()
  6969. }
  6970. }), Dubtrack.Events.bind("realtime:new-message", this.newMessage, this)
  6971. },
  6972. setMessageAsRead: function() {
  6973. var a = Dubtrack.config.apiUrl + Dubtrack.config.urls.messages_read.replace(":id", this.messageid);
  6974. Dubtrack.helpers.sendRequest(a, {}, "post", function(a, b) {
  6975. Dubtrack.layout.getNewMessages()
  6976. })
  6977. },
  6978. addMessage: function(a) {
  6979. this.$(".private-message-details-info").hide();
  6980. var b = new Dubtrack.View.Message.MainListDetailsItem({
  6981. model: a
  6982. });
  6983. a.set("_view", b), this.main_items_loaded ? this.items_container.append(b.$el) : this.items_container.prepend(b.$el), this.last_view = b, this.last_model = a, this.scollBottom()
  6984. },
  6985. newMessage: function(a) {
  6986. var c = this;
  6987. this.messageid && a.userid != Dubtrack.session.get("_id") && a.messageid == this.messageid && b("#private-messages").hasClass("view-message-details") ? this.collection.fetch({
  6988. remove: !1,
  6989. success: function() {
  6990. c.setMessageAsRead()
  6991. }
  6992. }) : b("#private-messages").hasClass("view-message-details") || Dubtrack.layout.getNewMessages()
  6993. },
  6994. keyPressAction: function(a) {
  6995. return c = a.which ? a.which : a.keyCode, 13 == c ? (this.sendMessage(), !1) : void 0
  6996. },
  6997. scollBottom: function() {
  6998. this.$(".message-list-wrapper-inner").perfectScrollbar("update");
  6999. var a = this.$(".message-list-wrapper-inner")[0].scrollHeight;
  7000. this.$(".message-list-wrapper-inner").scrollTop(a), this.$(".message-list-wrapper-inner").perfectScrollbar("update")
  7001. },
  7002. sendMessage: function() {
  7003. var a = b("<div/>").text(b.trim(this.$("input#message-input").val())).html();
  7004. if ("" !== a && null !== a) {
  7005. this.$("input#message-input").val(""), this.main_items_loaded = !0;
  7006. var c = new Dubtrack.Model.MessageItem({
  7007. created: Date.now(),
  7008. message: a,
  7009. userid: Dubtrack.session.get("_id"),
  7010. messageid: "",
  7011. _message: {},
  7012. _user: Dubtrack.session.toJSON()
  7013. }),
  7014. d = Dubtrack.config.apiUrl + Dubtrack.config.urls.messages_items.replace(":id", this.messageid);
  7015. c.urlRoot = d, c.parse = Dubtrack.helpers.parse, c.save({
  7016. message: a
  7017. }, {
  7018. success: function() {
  7019. c.set("_user", Dubtrack.session.toJSON())
  7020. }
  7021. }), this.collection.add(c)
  7022. }
  7023. }
  7024. }), Dubtrack.View.Message.MainListItem = Backbone.View.extend({
  7025. tagName: "li",
  7026. className: "message-item",
  7027. events: {},
  7028. template: Dubtrack.els.templates.messages.message,
  7029. initialize: function() {
  7030. this.listenTo(this.model, "change", this.render), this.render()
  7031. },
  7032. render: function() {
  7033. if (!this.model.get("name")) {
  7034. var a = this.model.get("usersid"),
  7035. b = [];
  7036. if (a) {
  7037. _.each(a, function(a) {
  7038. a._id != Dubtrack.session.get("_id") && b.push(a.username)
  7039. });
  7040. var c = b.join();
  7041. this.model.set("name", c)
  7042. }
  7043. }
  7044. var d = this.model.get("usersid"),
  7045. e = "",
  7046. f = this.model.toJSON();
  7047. d && (_.each(d, function(a) {
  7048. a._id != Dubtrack.session.get("_id") && (e += '<figure class="media">' + Dubtrack.helpers.image.getImage(a._id, a.username) + "</figure>")
  7049. }), this.$el.addClass("display-" + d.length + "-users"));
  7050. var g = this.model.get("users_read"),
  7051. h = !0;
  7052. g && (_.each(g, function(a) {
  7053. return a == Dubtrack.session.get("_id") ? void(h = !1) : void 0
  7054. }), h ? this.$el.addClass("new-message") : this.$el.removeClass("new-message")), f.image_str = e, this.$el.attr("data-messageid", this.model.get("_id")), this.$el.html(_.template(this.template, f));
  7055. var i = new Date(this.model.get("latest_message"));
  7056. this.$(".message-time").html('<time class="timeago" datetime="' + i.toISOString() + '">' + i.toLocaleString() + "</time>"), this.$(".timeago").timeago()
  7057. }
  7058. }), Dubtrack.View.Message.MainListDetailsItem = Dubtrack.View.Message.MainListItem.extend({
  7059. template: Dubtrack.els.templates.messages.messageItem,
  7060. initialize: function() {
  7061. this.render()
  7062. },
  7063. render: function() {
  7064. this.$el.attr("data-messageid", this.model.get("_id")), this.model.set("message", Dubtrack.helpers.text.convertHtmltoTags(this.model.get("message"), "Dubtrack.layout.menu_right.message_view.message_main_list_details.scollBottom();")), this.model.set("message", Dubtrack.helpers.text.convertAttoLink(this.model.get("message"))), this.$el.html(_.template(this.template, this.model.toJSON()));
  7065. var a = new Date(this.model.get("created"));
  7066. this.$(".message-time").html('<time class="timeago" datetime="' + a.toISOString() + '">' + a.toLocaleString() + "</time>"), this.$(".timeago").timeago(), this.$("img").load(function() {
  7067. Dubtrack.layout.menu_right.message_view.message_main_list_details.scollBottom()
  7068. }), this.$("img").error(function() {
  7069. b(this).attr("src", "/assets/images/media/chat_image_load_error.png")
  7070. })
  7071. },
  7072. appendText: function(a, b, c) {
  7073. var d = new Date(a);
  7074. this.$(".message-time").html('<time class="timeago" datetime="' + d.toISOString() + '">' + d.toLocaleString() + "</time>"), this.$(".timeago").timeago(), c ? this.$(".message-content p").prepend(b + "<br>") : this.$(".message-content p").append("<br>" + b)
  7075. }
  7076. }), f.profile.linkCounter = 0, f.profile.editView = Backbone.View.extend({
  7077. tagName: "div",
  7078. events: {
  7079. "click .close": "closeAction",
  7080. "click .cancel": "closeAction",
  7081. "click .btn-primary": "saveAction",
  7082. "keyup .dt_username_input": "keyup_dtuseranme"
  7083. },
  7084. initialize: function() {
  7085. b(this.el).attr("id", "dubuserForm").addClass("form")
  7086. },
  7087. render: function() {
  7088. return this.formEl = b(_.template(tpl.get("profileFormUpdate"), this.model.toJSON())).appendTo(b(this.el)), this.dj_details = this.model.get("dj_details"), this.model.bind("change", this.saveModel, this), this.linkEl = b(this.el).find("#inputLinkContent"), this.username_messageEl = b(this.el).find("#username_message"), this.LinksView = new Array, this.renderLink(), this
  7089. },
  7090. renderLink: function() {
  7091. var a = this.model.get("links");
  7092. _.each(a, function(a) {
  7093. b("<input/>", {
  7094. "class": "input-xlarge",
  7095. name: "updateLink[" + a.id + "]",
  7096. value: a.link,
  7097. type: "text"
  7098. }).appendTo(this.linkEl)
  7099. }, this), this.appendEl()
  7100. },
  7101. keyup_dtuseranme: function(a) {
  7102. clearTimeout(this.timeout);
  7103. var c = a.target.value;
  7104. if (this.username_messageEl.removeClass("success error").html("dubtrack.fm/" + c), this.dj_details.username === c) return void this.username_messageEl.addClass("success");
  7105. var d = this;
  7106. this.timeout = setTimeout(function() {
  7107. b.ajax({
  7108. url: g.config.checkusername,
  7109. data: {
  7110. dt_username: c
  7111. },
  7112. type: "POST",
  7113. success: function(a) {
  7114. try {
  7115. a.success ? d.username_messageEl.addClass("success").html("dubtrack.fm/" + a.data.username + " " + dubtrack_lang.profile.is_available) : d.username_messageEl.addClass("error").html("dubtrack.fm/" + a.data.username + " " + dubtrack_lang.profile.is_taken)
  7116. } catch (b) {}
  7117. },
  7118. error: function() {}
  7119. }, "json")
  7120. }, 1e3)
  7121. },
  7122. appendEl: function() {
  7123. f.profile.linkCounter++;
  7124. var a = (new f.profile.profileInput).render(this, "", f.profile.linkCounter);
  7125. return b(a.el).appendTo(this.linkEl), this.LinksView.push(a), !1
  7126. },
  7127. removeLink: function() {
  7128. if (f.profile.linkCounter > 1) {
  7129. var a = this.LinksView[f.profile.linkCounter - 1];
  7130. "" === b(this.LinksView[f.profile.linkCounter - 2].el).val() && (a.close(), this.LinksView.pop(), f.profile.linkCounter--)
  7131. }
  7132. },
  7133. runPlugins: function() {},
  7134. saveAction: function() {
  7135. return b(this.el).find(".btn-primary").html(dubtrack_lang.global.loading), this.model.set(b(this.el).find("form").serializeObject()), !1
  7136. },
  7137. saveModel: function() {
  7138. var a = this;
  7139. b.ajax({
  7140. url: g.config.saveUserId,
  7141. data: b(this.el).find("form").serialize(),
  7142. type: "POST",
  7143. success: function(c) {
  7144. b(a.el).find(".btn-primary").html(dubtrack_lang.profile.save);
  7145. try {
  7146. c.success && ("username" in c.data ? (b("#header_dtusername").html(c.data.username), b("#dt_username_a").attr("href", "/" + c.data.username), g.app.navigate("/" + c.data.username, {
  7147. trigger: !0
  7148. })) : g.app.navigate("/" + a.dj_details.username, {
  7149. trigger: !0
  7150. }))
  7151. } catch (d) {}
  7152. },
  7153. error: function() {}
  7154. }, "json")
  7155. },
  7156. closeAction: function() {
  7157. return this.close(), !1
  7158. }
  7159. }), f.profile.profileInput = Backbone.View.extend({
  7160. tagName: "input",
  7161. events: {
  7162. focus: "createLink",
  7163. blur: "removeLink"
  7164. },
  7165. initialize: function() {
  7166. b(this.el).addClass("createLink input-xlarge"), b(this.el).attr({
  7167. type: "text",
  7168. name: "userLink[]"
  7169. })
  7170. },
  7171. render: function(a, c, d) {
  7172. return this.parentView = a, b(this.el).attr({
  7173. value: c
  7174. }), this.elId = d, this
  7175. },
  7176. createLink: function() {
  7177. return this.elId === f.profile.linkCounter && this.parentView.appendEl(), !1
  7178. },
  7179. removeLink: function() {
  7180. return this.elId === f.profile.linkCounter - 1 && this.parentView.removeLink(this.elId), !1
  7181. }
  7182. }), UserView = Backbone.View.extend({
  7183. tagName: "div",
  7184. events: {},
  7185. initialize: function() {
  7186. this.model.bind("add", this.appendEl, this), this.model.bind("reset", this.render, this), this.render()
  7187. },
  7188. render: function(a) {
  7189. return _.each(this.model.models, function(a) {
  7190. this.appendEl(a)
  7191. }, this), this
  7192. },
  7193. appendEl: function(a, b) {}
  7194. }), WallpostView = Backbone.View.extend({
  7195. tagName: "ul",
  7196. events: {},
  7197. initialize: function() {
  7198. this.model.bind("add", this.appendEl, this), b(this.el).addClass("messages wall-post-list")
  7199. },
  7200. render: function(a) {
  7201. return this.userIdPost = a, this.replyView = (new WallPostReplyView).render(this), b(this.replyView.el).appendTo(b(this.el)), _.each(this.model.models, function(a) {
  7202. this.appendEl(a)
  7203. }, this), this
  7204. },
  7205. prependEl: function(a) {
  7206. b(new WallpostItemView({
  7207. model: a
  7208. }).render().el).prependTo(b(this.el))
  7209. },
  7210. appendEl: function(a) {
  7211. b(new WallpostItemView({
  7212. model: a
  7213. }).render().el).appendTo(b(this.el))
  7214. }
  7215. }), WallPostReplyView = Backbone.View.extend({
  7216. tagName: "li",
  7217. model: Backbone.Model.UserModel,
  7218. paramas: {},
  7219. urlSaveComment: "",
  7220. events: {
  7221. "click button": "submit"
  7222. },
  7223. initialize: function() {
  7224. b(this.el).addClass("replyEl"), this.model = g.user
  7225. },
  7226. render: function(a) {
  7227. return this.parentView = a, g.user.loggedIn ? (b(_.template(tpl.get("commentsReply"), this.model.toJSON())).appendTo(b(this.el)), b(this.el).find("textarea").autogrow()) : b(this.el).html('<div class="replyLogin">' + dubtrack_lang.comments.login_to_post + ' <a href="/login/facebook" class="facebook">' + dubtrack_lang.global.loginFB + '</a><a href="/login/twitter" class="twitter">' + dubtrack_lang.global.loginTW + "</a></div>"), this
  7228. },
  7229. submit: function(a) {
  7230. var c = this,
  7231. d = b(this.el).find("textarea");
  7232. if (d.hasValue()) {
  7233. var e = d.val();
  7234. d.val(""), b(a.target).html("..."), b.ajax({
  7235. url: g.config.saveWall,
  7236. data: {
  7237. message: e,
  7238. post_userid: c.parentView.userIdPost
  7239. },
  7240. type: "POST",
  7241. success: function(d) {
  7242. try {
  7243. b(a.target).html(dubtrack_lang.comments.submit);
  7244. var e = new WallpostModel(d.data.wall_post);
  7245. b(new WallpostItemView({
  7246. model: e
  7247. }).render().el).show().insertAfter(b(c.el))
  7248. } catch (f) {}
  7249. },
  7250. error: function() {}
  7251. }, "json")
  7252. } else d.focus();
  7253. return !1
  7254. },
  7255. beforeClose: function() {}
  7256. }), WallpostItemView = Backbone.View.extend({
  7257. tagName: "li",
  7258. events: {
  7259. "click a.updub": "updub",
  7260. "click a.downdub": "downdub",
  7261. "click a.wallremovemain": "deleteAction"
  7262. },
  7263. initialize: function() {},
  7264. render: function() {
  7265. return this.model.set({
  7266. img: g.helpers.getProfileImg(this.model.get("oauth_uid"), this.model.get("username"), this.model.get("oauth_provider")),
  7267. totaldubs: parseInt(this.model.get("updub")) - parseInt(this.model.get("downdub"))
  7268. }), $type_wall = this.model.get("type_wall"), "dt_wall" === $type_wall ? ($to = this.model.get("to"), this.model.set({
  7269. img_rel_to: g.helpers.getProfileImg($to.oauth_uid, $to.username, $to.oauth_provider)
  7270. }), b(_.template(tpl.get("wallpostRel"), this.model.toJSON())).appendTo(b(this.el))) : b(_.template(tpl.get("wallpost"), this.model.toJSON())).appendTo(b(this.el)), b(this.el).find("div.timeago").timeago(), this.loadComments(), this
  7271. },
  7272. updub: function() {
  7273. return this.dub("updub"), !1
  7274. },
  7275. downdub: function() {
  7276. return this.dub("downdub"), !1
  7277. },
  7278. dub: function(a) {
  7279. var c = this,
  7280. d = b(this.el).find("span.walldubs_main"),
  7281. e = d.html();
  7282. return d.html("..."), b.ajax({
  7283. url: g.config.dubWallPost,
  7284. data: {
  7285. id: this.model.get("id"),
  7286. type: a
  7287. },
  7288. type: "POST",
  7289. success: function(a) {
  7290. try {
  7291. if (a.success) {
  7292. b(c.el).find("a.wallupdub").html(a.data.wall_post.updub), b(c.el).find("a.walldowndub").html(a.data.wall_post.downdub);
  7293. var f = parseInt(a.data.wall_post.updub) - parseInt(a.data.wall_post.downdub);
  7294. d.html(f), c.model.set({
  7295. updub: a.data.wall_post.updub,
  7296. downdub: a.data.wall_post.downdub,
  7297. totaldubs: f
  7298. })
  7299. } else d.html(e)
  7300. } catch (g) {
  7301. d.html(e)
  7302. }
  7303. },
  7304. error: function() {}
  7305. }, "json"), !1
  7306. },
  7307. deleteAction: function() {
  7308. b(this.el).fadeOut();
  7309. var a = this;
  7310. return b.ajax({
  7311. url: g.config.deleteWall,
  7312. data: {
  7313. id: this.model.get("id")
  7314. },
  7315. type: "POST",
  7316. success: function(c) {
  7317. try {
  7318. b(a.el).remove()
  7319. } catch (d) {}
  7320. },
  7321. error: function() {}
  7322. }, "json"), !1
  7323. },
  7324. loadComments: function() {
  7325. var a = b("<div/>", {
  7326. "class": "loading"
  7327. }).html(dubtrack_lang.avatar.loadingComments).appendTo(b(this.el));
  7328. this.commentsView && this.commentsView.close(), this.commentsCollection = new CommentsCollection, this.commentsCollection.url = "/api/users/getwall_comments/id/" + this.model.get("id");
  7329. var c = {
  7330. type: "wall_posts",
  7331. url: this.model.get("id"),
  7332. comment: ""
  7333. },
  7334. d = this;
  7335. this.commentsCollection.fetch({
  7336. success: function() {
  7337. a.remove(), d.commentsView = new CommentsView({
  7338. model: d.commentsCollection
  7339. });
  7340. var e = b(d.commentsView.render(g.config.saveDubComment, c).el).appendTo(b(d.el));
  7341. e.css("minHeight", 0)
  7342. }
  7343. })
  7344. },
  7345. beforeClose: function() {}
  7346. }), DubtrackRoute = Backbone.Router.extend({
  7347. initialize: function() {
  7348. b.backstretch("destroy", !1), b.backstretch("https://dubtrack-fm.s3.amazonaws.com/assets/images/backgrounds/2048.jpg"), Dubtrack.helpers.navigateHistoryTags(b("body"))
  7349. },
  7350. routes: {
  7351. "(/)": "emptyRoute",
  7352. "lobby(/)": "roomList",
  7353. "search(/)": "roomList",
  7354. "browser(/)": "browser",
  7355. "browser/search(/)": "browser",
  7356. "browser/queue(/)": "browserQueue",
  7357. "browser/room-queue(/)": "browserRoomQueue",
  7358. "browser/history(/)": "browserHistory",
  7359. "browser/tracks(/)": "browserTracks",
  7360. "browser/upload(/)": "browserUpload",
  7361. "browser/:function/:id": "browserFunction",
  7362. "join/:id(/)": "join",
  7363. "dubs/:type(/)": "dubsLoader",
  7364. "avatar/:id(/)": "avatarDisplay",
  7365. "avatar/:id/edit(/)": "avatarEdit",
  7366. "notifications(/)": "notifications",
  7367. "login(/)": "login",
  7368. "forgot(/)": "forgotPassword",
  7369. "password(/)": "forgotPassword",
  7370. "signup(/)": "createAccount",
  7371. ":user(/)": "emptyRoute",
  7372. "*notFound": "notFound"
  7373. },
  7374. notFound: function() {
  7375. this.before(function() {
  7376. Dubtrack.els.mainLoading.hide(), Dubtrack.helpers.displayError("404 - Page not found", "the requested page doesn't exist", !1)
  7377. }).bind(this)
  7378. },
  7379. emptyRoute: function(a) {
  7380. if (!a || " " === a || "_=_" === a) {
  7381. var b = Dubtrack.helpers.cookie.get("dubtrack-room");
  7382. return b ? this.navigate("join/" + b, {
  7383. trigger: !0
  7384. }) : this.roomList(), !1
  7385. }
  7386. switch (a) {
  7387. case "lobby":
  7388. this.roomList();
  7389. break;
  7390. case "search":
  7391. case "browser":
  7392. this.browser();
  7393. break;
  7394. case "notifications":
  7395. this.notifications();
  7396. break;
  7397. default:
  7398. this.avatarDisplay(a)
  7399. }
  7400. },
  7401. containers: {},
  7402. notifications: function() {
  7403. var a = this;
  7404. this.before(function() {
  7405. document.title = dubtrack_lang.titles.notifications + " | Dubtrack.fm", b("#dt_mainplayer").addClass("inactive"), Dubtrack.els.displayloading(dubtrack_lang.notification.loading), this.notificationCollection ? (a.containers.notificationsSection.removeClass("inactive"), Dubtrack.els.mainLoading.hide()) : (a.notificationCollection = new NotificationCollection, a.notificationCollection.fetch({
  7406. success: function(c) {
  7407. var d = new NoticiationView({
  7408. model: a.notificationCollection
  7409. });
  7410. a.containers.notificationsSection = b("<section/>", {
  7411. "class": "dt_section",
  7412. id: "notificationsSection"
  7413. }).appendTo(g.config.mainSectionEl), a.notificationContainer = b(d.el).appendTo(a.containers.notificationsSection), d.render(), Dubtrack.els.mainLoading.hide()
  7414. }
  7415. }))
  7416. })
  7417. },
  7418. roomList: function() {
  7419. b("#create-room-div").show(), b("#edit-room-div").hide(), this.before(function() {
  7420. document.title = dubtrack_lang.titles.lobby + " | Dubtrack.fm", Dubtrack.els.displayloading(dubtrack_lang.room.searching), Dubtrack.roomList.collection ? (Dubtrack.roomList.list_view.$el.show(), Dubtrack.roomList.collection.reset(), Dubtrack.roomList.collection.fetch({
  7421. success: function() {
  7422. Dubtrack.els.mainLoading.hide()
  7423. }
  7424. })) : (Dubtrack.roomList.collection = new Dubtrack.Collection.Room, Dubtrack.roomList.collection.fetch({
  7425. success: function() {
  7426. Dubtrack.roomList.list_view = new Dubtrack.View.RoomList({
  7427. model: Dubtrack.roomList.collection
  7428. }), Dubtrack.roomList.list_view.$el.show(), Dubtrack.els.mainLoading.hide()
  7429. }
  7430. }))
  7431. })
  7432. },
  7433. browserQueue: function() {
  7434. var a = this;
  7435. this.browser(function() {
  7436. a.browserView.displayDetails("queue")
  7437. })
  7438. },
  7439. browserRoomQueue: function() {
  7440. var a = this;
  7441. this.browser(function() {
  7442. a.browserView.displayDetails("room_queue")
  7443. })
  7444. },
  7445. browserHistory: function() {
  7446. var a = this;
  7447. this.browser(function() {
  7448. a.browserView.displayDetails("history")
  7449. })
  7450. },
  7451. browserTracks: function() {
  7452. var a = this;
  7453. this.browser(function() {
  7454. a.browserView.displayDetails("tracks")
  7455. })
  7456. },
  7457. browserUpload: function() {
  7458. var a = this;
  7459. this.browser(function() {
  7460. a.browserView.displayDetails("upload")
  7461. })
  7462. },
  7463. browserFunction: function(a, b) {
  7464. var c = this;
  7465. switch (a) {
  7466. case "user":
  7467. this.browser(function() {
  7468. c.browserView.displayDetails("user", b)
  7469. });
  7470. break;
  7471. default:
  7472. this.browser(function() {
  7473. c.browserView.displayDetails("user", b)
  7474. })
  7475. }
  7476. },
  7477. login: function() {
  7478. return Dubtrack.loggedIn ? void Dubtrack.app.navigate("/", {
  7479. trigger: !0
  7480. }) : void this.before(function() {
  7481. Dubtrack.layout.main_login_window.displayWindow("login_window")
  7482. })
  7483. },
  7484. createAccount: function() {
  7485. return Dubtrack.loggedIn ? void Dubtrack.app.navigate("/", {
  7486. trigger: !0
  7487. }) : void this.before(function() {
  7488. try {
  7489. grecaptcha.reset()
  7490. } catch (a) {}
  7491. Dubtrack.layout.main_login_window.displayWindow("signup_window")
  7492. })
  7493. },
  7494. forgotPassword: function() {
  7495. return Dubtrack.loggedIn ? void Dubtrack.app.navigate("/", {
  7496. trigger: !0
  7497. }) : void this.before(function() {
  7498. var a = Dubtrack.helpers.getParameterByName("token");
  7499. a ? (Dubtrack.layout.main_login_window.change_window.token = a, Dubtrack.layout.main_login_window.displayWindow("change_window")) : Dubtrack.layout.main_login_window.displayWindow("forgot_window")
  7500. })
  7501. },
  7502. browser: function(a, b) {
  7503. if (!Dubtrack.loggedIn) return Dubtrack.els.mainLoading.hide(), Dubtrack.app.navigate("/login", {
  7504. trigger: !0
  7505. });
  7506. var c = this;
  7507. if (!Dubtrack.room.model && !b) {
  7508. var d = Dubtrack.helpers.cookie.get("dubtrack-room");
  7509. return void(d && this.join(d, function() {
  7510. c.browser.call(c, a, !0)
  7511. }))
  7512. }
  7513. this.browserView ? (c.browserView.displayBrowser(), a && a.call(c)) : this.loadUserPlaylists(function() {
  7514. c.browserView = new Dubtrack.View.Browser({
  7515. model: Dubtrack.user.playlist
  7516. }), c.browserView.displayBrowser(), a ? a.call(c) : c.browserView.displayDetails()
  7517. })
  7518. },
  7519. avatarDisplay: function(a) {
  7520. var b = this;
  7521. this.before(function() {
  7522. document.title = a + " | Dubtrack.fm", Dubtrack.els.displayloading(dubtrack_lang.avatar.loading);
  7523. var c = new Dubtrack.Model.User({
  7524. _id: a
  7525. });
  7526. c.parse = Dubtrack.helpers.parse, c.fetch({
  7527. success: function(a, d) {
  7528. Dubtrack.els.mainLoading.hide(), d.data ? b.profileView ? (b.profileView.model = c, b.profileView.render()) : b.profileView = new Dubtrack.View.Profile({
  7529. model: c
  7530. }) : Dubtrack.helpers.displayError(dubtrack_lang.avatar.profileNotfound, dubtrack_lang.avatar.profileNotfound_des, !1)
  7531. },
  7532. error: function(a, b) {
  7533. Dubtrack.els.mainLoading.hide();
  7534. try {
  7535. var c = b.statusCode();
  7536. c && 404 == c.status ? Dubtrack.helpers.displayError("404 - Page not found", "the requested page doesn't exist", !1) : Dubtrack.helpers.displayError(dubtrack_lang.global.error, dubtrack_lang.global.error_des, !0)
  7537. } catch (d) {
  7538. Dubtrack.helpers.displayError(dubtrack_lang.global.error, dubtrack_lang.global.error_des, !0)
  7539. }
  7540. }
  7541. })
  7542. })
  7543. },
  7544. avatarEdit: function(a) {
  7545. if (this.avatarModel) {
  7546. var c = this.avatarModel.get("dj_details");
  7547. if (g.user.id !== c.id) return !1;
  7548. this.AvatarEditView = new f.profile.editView({
  7549. model: this.avatarModel
  7550. }).render(), b(this.AvatarEditView.el).appendTo(f.elements.body), this.AvatarEditView.runPlugins()
  7551. } else g.app.navigate("/avatar/" + a, {
  7552. trigger: !0
  7553. })
  7554. },
  7555. loadUserPlaylists: function(a) {
  7556. if (this.mainPlaylistCollection) a && a();
  7557. else {
  7558. Dubtrack.els.displayloading(dubtrack_lang.playlist.loading_playlists);
  7559. var b = this;
  7560. Dubtrack.user.playlist = new Dubtrack.Collection.Playlist, Dubtrack.user.playlist.fetch({
  7561. success: function() {
  7562. Dubtrack.els.mainLoading.hide(), a && a.call(b)
  7563. }
  7564. })
  7565. }
  7566. },
  7567. help: function() {
  7568. f.help.helpViewRoute && f.help.helpViewRoute.close(), f.help.helpViewRoute = (new f.help.mainView).render()
  7569. },
  7570. join: function(a, c, d) {
  7571. if (b(".dubtrack-section").hide(), b("#login-model-window").hide(), b("html").removeClass("menu-left-in").removeClass("menu-right-in"), Dubtrack.room && Dubtrack.room.model) Dubtrack.room.model.get("roomUrl") === a ? (Dubtrack.room.displayRoom(), document.title = Dubtrack.room.model.get("name") + " | Dubtrack.fm", Dubtrack.session && Dubtrack.session.get("_id") === Dubtrack.room.model.get("userid") ? (b("#create-room-div").hide(), b("#edit-room-div").show()) : (b("#create-room-div").show(), b("#edit-room-div").hide())) : window.location = "/join/" + a;
  7572. else {
  7573. var e = this,
  7574. f = new Dubtrack.Model.Room({
  7575. _id: a
  7576. });
  7577. f.parse = Dubtrack.helpers.parse, f.fetch({
  7578. success: function(a, b) {
  7579. Dubtrack.els.mainLoading.hide(), Dubtrack.room = new Dubtrack.View.Room({
  7580. model: f
  7581. }), Dubtrack.room.render(), d || (Dubtrack.room.displayRoom(), document.title = Dubtrack.room.model.get("name") + " | Dubtrack.fm"), c && c.call(e)
  7582. },
  7583. error: function() {
  7584. Dubtrack.els.mainLoading.hide(), Dubtrack.helpers.displayError(dubtrack_lang.global.error, "This room doesnt exists :("), Dubtrack.app.navigate("/lobby", {
  7585. trigger: !0
  7586. }), c && c.call(e)
  7587. }
  7588. })
  7589. }
  7590. },
  7591. before: function(a, c) {
  7592. if (b(".dubtrack-section").hide(), b("#login-model-window").hide(), b("html").removeClass("menu-left-in").removeClass("menu-right-in"), !Dubtrack.room.model) {
  7593. var d = Dubtrack.helpers.cookie.get("dubtrack-room");
  7594. d && this.join(d, !1, !0)
  7595. }
  7596. Dubtrack.views.user_popover && Dubtrack.views.user_popover.$el.hide(), a && a.call(this)
  7597. },
  7598. navigate: function(a, c) {
  7599. if (c)
  7600. if ("replace" in c) {
  7601. if (!c.replace) try {
  7602. ga("set", "page", a), ga("send", "pageview")
  7603. } catch (d) {}
  7604. } else ga("set", "page", a), ga("send", "pageview");
  7605. return "undefined" != typeof window._atrk_fired && "undefined" != typeof window.atrk && (window._atrk_fired = !1, window.atrk()), b(".menu-expand").removeClass("active"), Backbone.Router.prototype.navigate.call(this, a, c)
  7606. }
  7607. }), Dubtrack.cache = {
  7608. users: {
  7609. collection: new Dubtrack.Collection.User,
  7610. get: function(a, b, c) {
  7611. if ("function" != typeof b) throw new Error("DT Cache user collection callback has to be a function");
  7612. c || (c = this);
  7613. var d = Dubtrack.cache.users.collection.get(a);
  7614. return d ? b.call(c, null, d) : (d = new Dubtrack.Model.User({
  7615. _id: a
  7616. }), d.parse = Dubtrack.helpers.parse, void d.fetch({
  7617. success: function() {
  7618. Dubtrack.cache.users.collection.add(d), b.call(c, null, d)
  7619. },
  7620. error: function() {
  7621. b.call(c, !0, null)
  7622. }
  7623. }))
  7624. },
  7625. getByUsername: function(a, b, c) {
  7626. var d = Dubtrack.cache.users.collection.findWhere({
  7627. username: a
  7628. });
  7629. return d ? b.call(c, null, d) : void Dubtrack.cache.users.get(a, b, c)
  7630. },
  7631. add: function(a) {
  7632. var b = new Dubtrack.Model.User(a);
  7633. return Dubtrack.cache.users.collection.add(b), b
  7634. }
  7635. },
  7636. songs: {
  7637. collection: new Dubtrack.Collection.Song,
  7638. get: function(a, b, c) {
  7639. if ("function" != typeof b) throw new Error("DT Cache song collection callback has to be a function");
  7640. c || (c = this);
  7641. var d = Dubtrack.cache.songs.collection.get(a);
  7642. return d ? b.call(c, null, d) : (d = new Dubtrack.Model.Song({
  7643. _id: a
  7644. }), d.parse = Dubtrack.helpers.parse, void d.fetch({
  7645. success: function() {
  7646. Dubtrack.cache.songs.collection.add(d), b.call(c, null, d)
  7647. }
  7648. }))
  7649. },
  7650. add: function(a) {
  7651. var b = new Dubtrack.Model.Song(a);
  7652. return Dubtrack.cache.songs.collection.add(b), b
  7653. }
  7654. }
  7655. }
  7656. }(window, jQuery);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement