dart.js 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137
  1. var $ = function(_undefind) {
  2. function Selector(elements) {
  3. this.length = elements.length;
  4. for (var i = 0, l = this.length; l > i; i++) this[i] = elements[i];
  5. }
  6. function $(selector) {
  7. return tag.test(selector) ? new Selector([ document.createElementNS("http://www.w3.org/2000/svg", tag.exec(selector)[1]) ]) : "string" == typeof selector ? new Selector(document.querySelectorAll(selector)) : selector instanceof NodeList ? new Selector(selector) : selector instanceof Element ? new Selector([ selector ]) : selector.addEventListener ? new Selector([ selector ]) : selector instanceof Selector ? selector : new Selector([]);
  8. }
  9. var fn = Selector.prototype;
  10. fn.each = function(callback) {
  11. for (var i = 0, l = this.length; l > i; i++) callback(this[i], i);
  12. return this;
  13. }, fn.on = function(eventName, eventHandler) {
  14. return this.each(function(el) {
  15. el.addEventListener(eventName, eventHandler);
  16. });
  17. }, fn.off = function(eventName, eventHandler) {
  18. return this.each(function(el) {
  19. el.removeEventListener(eventName, eventHandler);
  20. });
  21. }, fn.trigger = function(eventName, data) {
  22. return this.each(function(el) {
  23. event = new CustomEvent(eventName, data), el.dispatchEvent(event);
  24. });
  25. }, fn.css = function(name, value) {
  26. if (Object(name) === name) {
  27. for (var prop in name) this.css(prop, name[prop]);
  28. return this;
  29. }
  30. return null != value ? this.each(function(el) {
  31. el.style[name] = value;
  32. }) : this.length ? getComputedStyle(this[0]).getPropertyValue(name) : _undefind;
  33. }, fn.show = function() {
  34. return this.css("display", "block");
  35. }, fn.hide = function() {
  36. return this.css("display", "none");
  37. }, fn.text = function(text) {
  38. return null != text ? this.each(function(el) {
  39. el.textContent = text;
  40. }) : this.length ? this[0].textContent : _undefind;
  41. }, fn.html = function(html) {
  42. return null != html ? this.each(function(el) {
  43. for (;el.firstChild; ) el.removeChild(el.firstChild);
  44. var fragment = document.createElement("div");
  45. fragment.innerHTML = "<svg>" + html + "</svg>";
  46. for (var svg = fragment.firstChild, node = svg.firstChild; node; ) el.appendChild(node.cloneNode(!0)),
  47. node = node.nextSibling;
  48. }) : this.length ? this[0].innerHTML : _undefind;
  49. }, fn.remove = function() {
  50. return this.each(function(el) {
  51. el.parentNode && el.parentNode.removeChild(el);
  52. });
  53. }, fn.attr = function(name, value) {
  54. if (Object(name) === name) {
  55. for (var prop in name) this.attr(prop, name[prop]);
  56. return this;
  57. }
  58. return null != value ? this.each(function(el) {
  59. el.setAttribute(name, value);
  60. }) : this.length ? this[0].getAttribute(name) : _undefind;
  61. }, fn.removeAttr = function(name) {
  62. return this.each(function(el) {
  63. el.removeAttribute(name);
  64. });
  65. }, fn.append = function(target) {
  66. return this.each(function(el) {
  67. target instanceof Selector ? target.each(function(child) {
  68. el.appendChild(child);
  69. }) : el.appendChild(target);
  70. });
  71. }, fn.empty = function() {
  72. return this.each(function(el) {
  73. for (;el.firstChild; ) el.removeChild(el.firstChild);
  74. });
  75. }, fn.eq = function(idx) {
  76. return new Selector(idx >= this.length ? [] : [ this[idx] ]);
  77. }, fn.find = function(selector) {
  78. var result = [];
  79. return this.each(function(el) {
  80. Array.prototype.push.apply(result, el.querySelectorAll(selector));
  81. }), new Selector(result);
  82. }, fn.parent = function() {
  83. var result = [];
  84. return this.each(function(el) {
  85. result.push(el.parentNode);
  86. }), new Selector(result);
  87. }, fn.first = function() {
  88. return new Selector(this.length ? [ this[0] ] : []);
  89. }, fn.last = function() {
  90. return new Selector(this.length ? [ this[this.length - 1] ] : []);
  91. }, fn.clone = function() {
  92. var result = [];
  93. return this.each(function(el) {
  94. result.push(el.cloneNode(!0));
  95. }), new Selector(result);
  96. }, fn.width = function() {
  97. return this.length ? this[0].getBoundingClientRect().width : _undefind;
  98. }, fn.height = function() {
  99. return this.length ? this[0].getBoundingClientRect().height : _undefind;
  100. }, fn.position = function() {
  101. if (this.length) {
  102. var clientRect = this[0].getBoundingClientRect();
  103. return {
  104. top: clientRect.top,
  105. right: clientRect.right,
  106. bottom: clientRect.bottom,
  107. left: clientRect.left
  108. };
  109. }
  110. return _undefind;
  111. };
  112. var defaultAnim = {
  113. "class": "anim",
  114. begin: "indefinite"
  115. }, anim = function(anim) {
  116. return $("<animate/>").attr(anim);
  117. };
  118. fn.animate = function(anims) {
  119. var callbacks = [], thenable = {
  120. then: function(complete) {
  121. return callbacks.push(complete), thenable;
  122. }
  123. };
  124. return anims = $.extend({}, defaultAnim, anims), this.each(function(el) {
  125. var $el = $(el), $anim = $el.find(".anim");
  126. $anim.length ? $anim.attr(anims) : ($el.append(anim(anims)[0]), $anim = $el.find(".anim")),
  127. el.timerId = setTimeout(function() {
  128. $el.attr(anims.attributeName, anims.to), $el.removeAttr("animated"), callbacks.forEach(function(c) {
  129. c();
  130. }), callbacks = [];
  131. }, 1e3 * parseFloat(anims.dur)), $el.attr("animated", !0), $anim[0].beginElement();
  132. }), thenable;
  133. };
  134. var animDelay = 62.5;
  135. fn.move = function(anims) {
  136. return this.each(function(el) {
  137. function tick() {
  138. if (!el.paused) {
  139. var cur = from + step;
  140. (to > from ? to >= cur : cur >= to) ? ($el.attr(property, cur), from = cur) : clearInterval(timer);
  141. }
  142. }
  143. var property = anims.attributeName, dur = anims.dur, to = parseInt(anims.to), $el = $(el), from = parseInt($el.attr(property)), step = (to - from) / (1e3 * dur / animDelay);
  144. el.timer = setInterval(tick, animDelay);
  145. });
  146. };
  147. var defaultTrf = {
  148. "class": "trf",
  149. type: "translate",
  150. dur: "0.3",
  151. calcMode: "spline",
  152. keySplines: "0.215 0.61 0.355 1",
  153. additive: "replace",
  154. attributeName: "transform",
  155. begin: "indefinite",
  156. keyTimes: "0; 1"
  157. }, trf = function(trf) {
  158. return $("<animateTransform/>").attr(trf);
  159. };
  160. fn.transform = function(trfs) {
  161. var callbacks = [], thenable = {
  162. then: function(complete) {
  163. return callbacks.push(complete), thenable;
  164. }
  165. };
  166. return trfs = $.extend({}, defaultTrf, trfs), this.each(function(el) {
  167. var $el = $(el), $anim = $el.find(".trf");
  168. $anim.length ? $anim.attr(trfs) : ($el.append(trf(trfs)[0]), $anim = $el.find(".trf")),
  169. el.timerId = setTimeout(function() {
  170. $el.attr("transform", trfs.type + "(" + trfs.to + ")"), $el.removeAttr("animated"),
  171. callbacks.forEach(function(c) {
  172. c();
  173. }), callbacks = [];
  174. }, 1e3 * parseFloat(trfs.dur) - 20), $el.attr("animated", !0), $anim[0].beginElement();
  175. }), thenable;
  176. }, fn.stop = function() {
  177. return this.each(function(el) {
  178. $(el).find(".anim, .trf").each(function(anim) {
  179. anim.endElement();
  180. }), clearTimeout(el.timerId), clearInterval(el.timer);
  181. });
  182. }, fn.pause = function() {
  183. return $("svg")[0].pauseAnimations(), this.each(function(el) {
  184. el.paused = !0;
  185. });
  186. }, fn.resume = function() {
  187. return $("svg")[0].unpauseAnimations(), this.each(function(el) {
  188. el.paused = !1;
  189. });
  190. };
  191. var tag = /^<(.+)\/>$/;
  192. return $.extend = function(target) {
  193. for (var obj, properties, i = 1, l = arguments.length; l > i; i++) {
  194. obj = arguments[i], properties = Object.keys(obj);
  195. for (var property, j = properties.length; j--; ) property = properties[j], target[property] = obj[property];
  196. }
  197. return target;
  198. }, $.inherit = function(child, parent) {
  199. function ctor() {
  200. this.constructor = child, this.__super__ = parent.prototype;
  201. }
  202. return ctor.prototype = parent.prototype, child.prototype = new ctor(), child;
  203. }, $.mixin = function(plagin) {
  204. $.extend(fn, plagin);
  205. }, $.timestamp = 1400668550599, $.load = function(url, complete) {
  206. url = url + "?q=" + $.timestamp;
  207. var result = localStorage.getItem(url);
  208. if (null == result) {
  209. var xhr = new XMLHttpRequest();
  210. xhr.open("GET", url, !0), xhr.onload = function() {
  211. localStorage.setItem(url, xhr.responseText), complete(xhr.responseText);
  212. }, xhr.send();
  213. } else complete(result);
  214. }, $.rand = function(min, max) {
  215. return min + Math.floor(Math.random() * (max - min + 1));
  216. }, $;
  217. }(),
  218. Core = function() {
  219. var scope = {
  220. apiUrl: "ws://localhost:8080/ws/",
  221. gameId: 1000001,
  222. defaultSessionId: "7hc6Vl0CpxvngjiQQWDspxUtKmhF1zCbT155+M73XhFcKw9e6jkNWLSLM8up4ZQbSUGJXKOphb0YNu4yDRKZkbkiyY1yZukqXFj4nAfvSUNuWx0352VWfLlKZWldHb1na7d7sA==",
  223. CARD_SOURCE: "../app/svg/Card.svg",
  224. CARD_SMALL_SOURCE: "../app/svg/Card-small.svg",
  225. CARD_COLORS: [ "#CE290F", "#3B5998", "#48AF5E", "#F8E81C" ],
  226. SKIN_NAMES: [ "Alina", "Gabrielo", "Mustafa" ]
  227. };
  228. return function(module) {
  229. module(scope);
  230. };
  231. }();
  232. Core(function(scope) {
  233. function Controller() {
  234. this.proxyAll(), this.refreshElements();
  235. }
  236. var isIE = window.navigator.msPointerEnabled;
  237. $.extend(Controller.prototype, {
  238. proxy: function(func) {
  239. return func.bind(this);
  240. },
  241. proxyAll: function() {
  242. if (this.proxies) for (var method, i = this.proxies.length; i--; ) method = this.proxies[i],
  243. this[method] = this.proxy(this[method]);
  244. },
  245. withDelay: function(func, timeout) {
  246. return setTimeout(this.proxy(func), timeout || 0);
  247. },
  248. $: function(selector) {
  249. return this.$el.find(selector);
  250. },
  251. refreshElements: function() {
  252. if (this.elements) for (var element in this.elements) this[element] = this.$(this.elements[element]);
  253. },
  254. on: function(eventType, handler) {
  255. return this.$el.on(eventType, handler), this;
  256. },
  257. off: function(eventType, handler) {
  258. return this.$el.off(eventType, handler), this;
  259. },
  260. clientX: function(e) {
  261. return isIE ? e.pageX : document.createTouch ? e.changedTouches[0].clientX : e.clientX;
  262. },
  263. clientY: function(e) {
  264. return isIE ? e.pageY : document.createTouch ? e.changedTouches[0].clientY : e.clientY;
  265. },
  266. intersect: function(x, y) {
  267. var pos = this.$el.position();
  268. return pos.top < y && pos.bottom > y && pos.left < x && pos.right > x;
  269. }
  270. }), scope.Controller = Controller;
  271. }),
  272. Core(function(scope) {
  273. function ApiProvider(options) {
  274. options = options || {}, this.url = options.url, this.sessionId = options.sessionId,
  275. this.gameId = options.gameId, this.proxies = [ "init", "handleMessage", "actionTake" ],
  276. this.proxyAll(), this.socket = new WebSocket(this.url), this.$socket = $(this.socket),
  277. this.$socket.on("open", this.init), this.$socket.on("message", this.handleMessage);
  278. }
  279. var eventMap = [ "okey_game_info", "okey_game_started", "okey_game_player_state", "okey_next_turn", "okey_tile_discarded", "okey_tile_taken", "okey_revealed", "player_left", "game_paused" ],
  280. session = /\('session_attach'\),'([^)]+)'\)/,
  281. userName = /document.user\s?=\s?'([^']+)'/;
  282. $.extend(ApiProvider.prototype, {
  283. proxy: function(func) {
  284. return func.bind(this);
  285. },
  286. proxyAll: function() {
  287. if (this.proxies) for (var method, i = this.proxies.length; i--; ) method = this.proxies[i],
  288. this[method] = this.proxy(this[method]);
  289. },
  290. on: function(eventType, handler) {
  291. this.$socket.on(eventType, handler);
  292. },
  293. off: function(eventType, handler) {
  294. this.$socket.off(eventType, handler);
  295. },
  296. init: function() {
  297. this.socket.send([ "N2O", "" ]), setInterval(this.proxy(function() {
  298. this.socket.send("PING");
  299. }), 4e3);
  300. },
  301. handleMessage: function(e) {
  302. var msg = JSON.parse(e.data);
  303. if (msg.eval) {
  304. var curSession, user;
  305. (curSession = session.exec(msg.eval)) && (this.sessionId = curSession[1]), (user = userName.exec(msg.eval)) && (scope.user = user[1]);
  306. }
  307. msg.data ? (msg = dec(msg.data), this.emitEvent(this.beutify(this.parse(msg)))) : msg.eval && (this.socket.send(enc(tuple(atom("client"), tuple(atom("session_attach"), this.sessionId)))),
  308. this.socket.send(enc(tuple(atom("client"), tuple(atom("join_game"), this.gameId)))));
  309. },
  310. parse: function(msg) {
  311. if (Array.isArray(msg)) {
  312. if (msg.every(function(el, i) {
  313. return i % 2 == 0 || Object(el.value) === el.value;
  314. }) || msg.length % 2 != 0) {
  315. for (var result = [], i = 0, l = msg.length; l > i; i++) result.push(this.parse(msg[i]));
  316. return result;
  317. }
  318. if (msg.length > 2 && msg.every(function(el) {
  319. return null != el && "object" != typeof el || null != el.value && "object" != typeof el.value;
  320. })) {
  321. var result = {};
  322. return result[this.parse(msg[0])] = this.parse(msg.slice(1)), result;
  323. }
  324. for (var result = {}, i = 0, l = msg.length; l > i; i += 2) {
  325. {
  326. this.parse(msg[i]);
  327. }
  328. result[this.parse(msg[i])] = this.parse(msg[i + 1]);
  329. }
  330. return result;
  331. }
  332. return msg.value && Object(msg.value) === msg.value && msg.value[0] && msg.value.length ? this.parse(msg.value[0]) : null != msg.value ? msg.value : msg;
  333. },
  334. beutify: function(msg) {
  335. var result = {};
  336. for (var prop in msg) {
  337. var tempObj = msg[prop];
  338. if (Array.isArray(tempObj)) {
  339. for (var obj, i = tempObj.length; i--; ) if (obj = tempObj[i], Array.isArray(obj)) result[obj[0]] = obj[1]; else if (Object(obj) === obj) for (var p in obj) result[p] = obj[p]; else result[i] = obj;
  340. msg[prop] = result;
  341. }
  342. }
  343. return msg;
  344. },
  345. emitEvent: function(msg) {
  346. for (var event, i = eventMap.length; i--; ) event = eventMap[i], msg[event] && this.$socket.trigger(event, {
  347. detail: msg[event]
  348. });
  349. },
  350. actionTake: function(card) {
  351. var from = null != card.value ? 1 : 0;
  352. this.socket.send(enc(tuple(atom("client"), tuple(atom("game_action"), this.gameId, atom("okey_take"), {
  353. pile: from
  354. }))));
  355. },
  356. actionDiscard: function(card) {
  357. this.socket.send(enc(tuple(atom("client"), tuple(atom("game_action"), this.gameId, atom("okey_discard"), {
  358. tile: tuple(atom("OkeyPiece"), scope.CARD_COLORS.indexOf(card.color) + 1, card.value)
  359. }))));
  360. },
  361. reveal: function(card, hand) {
  362. this.socket.send(enc(tuple(atom("client"), tuple(atom("game_action"), this.gameId, atom("okey_reveal"), {
  363. discarded: tuple(atom("OkeyPiece"), scope.CARD_COLORS.indexOf(card.color) + 1, card.value),
  364. hand: hand
  365. }))));
  366. },
  367. pause: function(resume) {
  368. this.socket.send(enc(tuple(atom("client"), tuple(atom("pause_game"), atom("undefined"), this.gameId, atom(resume ? "resume" : "pause")))));
  369. }
  370. }), scope.ApiProvider = ApiProvider;
  371. }),
  372. Core(function(scope) {
  373. function culcShift() {
  374. sizeX = $svg[0].viewBox.baseVal.width / innerWidth, sizeY = $svg[0].viewBox.baseVal.height / innerHeight,
  375. size = Math.max(sizeX, sizeY) || 1;
  376. }
  377. function Draggable(root, options) {
  378. options = options || {}, this.$el = $(root), this.revert = options.revert, this.elements = {},
  379. this.proxies = [ "onDown", "onMove", "onUp" ], this.__super__.constructor.call(this),
  380. this.enable();
  381. }
  382. var sizeX, sizeY, size, moved, $svg = $("svg");
  383. culcShift(), $(window).on("resize", culcShift), $(window).on("orientationchange", culcShift),
  384. $.inherit(Draggable, scope.Controller), $.extend(Draggable.prototype, {
  385. storeTrf: function() {
  386. var trf = this.$el.attr("transform");
  387. this.initTrf = trf ? trf.slice(10, -1).split(/\s+/) : [ 0, 0 ];
  388. },
  389. disable: function() {
  390. this.$el.off(document.createTouch ? "touchstart" : "mousedown", this.onDown), this.$el.css({
  391. cursor: "default"
  392. });
  393. },
  394. enable: function() {
  395. this.$el.on(document.createTouch ? "touchstart" : "mousedown", this.onDown), this.$el.attr("style", "cursor: -moz-grab; cursor: -webkit-grab; cursor: grab;");
  396. },
  397. onDown: function(e, silent) {
  398. e.preventDefault(), moved || (moved = !1, this.$el.attr("style", "cursor: -moz-grabbing; cursor: -webkit-grabbing; cursor: grabbing;"),
  399. this.$el[0].parentNode.appendChild(this.$el[0]), this.x = this.clientX(e), this.y = this.clientY(e),
  400. this.trf = this.$el.attr("transform"), this.trf && (this.trf = this.trf.slice(10, -1).split(/\s+/)),
  401. this.storeTrf(), silent || (document.createTouch ? (this.$el.on("touchmove", this.onMove),
  402. this.$el.on("touchend", this.onUp)) : ($("body").on("mousemove", this.onMove), $("body").on("mouseup", this.onUp)),
  403. this.$el.trigger("dragstart")));
  404. },
  405. onMove: function(e, silent) {
  406. e.preventDefault(), moved = !0, this.dx = ((this.curX = this.clientX(e)) - this.x) * size,
  407. this.dy = ((this.curY = this.clientY(e)) - this.y) * size, this.trf && (this.dx += 0 | this.trf[0],
  408. this.dy += 0 | this.trf[1]), this.$el.attr("transform", "translate(" + this.dx + " " + this.dy + ")"),
  409. silent || this.$el.trigger("dragmove", {
  410. detail: {
  411. x: this.curX,
  412. y: this.curY,
  413. event: e
  414. }
  415. });
  416. },
  417. onUp: function(e, silent) {
  418. if (e.preventDefault(), this.$el.attr("style", "cursor: -moz-grab; cursor: -webkit-grab; cursor: grab;"),
  419. moved) {
  420. for (var droped, item, dropList = scope.Droppable.list, i = 0, l = dropList.length; l > i; i++) if (item = dropList[i],
  421. item.intersect(this.curX, this.curY)) {
  422. droped = item.drop(this, this.curX, this.curY);
  423. break;
  424. }
  425. droped || (this.$el.transform({
  426. from: [ this.dx, this.dy ].join(" "),
  427. to: this.initTrf.join(" ")
  428. }), silent || this.$el.trigger("revert")), silent || this.$el.trigger("dragstop", {
  429. detail: {
  430. x: this.curX,
  431. y: this.curY,
  432. event: e
  433. }
  434. }), moved = !1;
  435. }
  436. document.createTouch ? (this.$el.off("touchmove", this.onMove), this.$el.off("touchend", this.onUp)) : ($("body").off("mousemove", this.onMove),
  437. $("body").off("mouseup", this.onUp));
  438. }
  439. }),
  440. scope.Draggable = Draggable,
  441. $.mixin({
  442. draggable: function() {
  443. return this.each(function(el) {
  444. new Draggable(el);
  445. });
  446. }
  447. });
  448. }),
  449. Core(function(scope) {
  450. function Droppable(root, options) {
  451. options = options || {}, this.$el = $(root), this.accept = options.accept || function() {
  452. return !0;
  453. }, this.onDrop = options.drop || function() {}, this.elements = {}, this.proxies = [],
  454. this.__super__.constructor.call(this), this.activate();
  455. }
  456. Droppable.list = [], $.inherit(Droppable, scope.Controller), $.extend(Droppable.prototype, {
  457. drop: function(target, x, y) {
  458. return this.accept(target, x, y) ? (this.onDrop(target, x, y), !0) : !1;
  459. },
  460. activate: function() {
  461. Droppable.list.push(this);
  462. },
  463. release: function() {
  464. var i;
  465. ~(i = Droppable.list.indexOf(this)) && Droppable.list.splice(i, 1);
  466. }
  467. }),
  468. scope.Droppable = Droppable,
  469. $.mixin({
  470. droppable: function(options) {
  471. return this.each(function(el) {
  472. new Droppable(el, options);
  473. });
  474. }
  475. });
  476. }),
  477. Core(function(scope) {
  478. function Timer(root, options) {
  479. options = options || {}, this.duration = options.duration, this.curTime = this.duration,
  480. this.$el = $(root), this.elements = {
  481. $value: "#value",
  482. $progress: "#progress"
  483. }, this.proxies = [ "tick" ], this.__super__.constructor.call(this), this.$value.text(this.duration),
  484. defHeight = this.$progress.attr("height");
  485. }
  486. var defHeight;
  487. $.inherit(Timer, scope.Controller), $.extend(Timer.prototype, {
  488. from: function(time) {
  489. this.$value.text(this.curTime = Math.round(time / 1e3));
  490. },
  491. start: function() {
  492. this.$progress.move({
  493. attributeName: "height",
  494. to: "0",
  495. dur: this.curTime
  496. }), this.timerId = this.withDelay(this.tick, 1e3);
  497. },
  498. tick: function() {
  499. return this.paused ? void (this.timerId = this.withDelay(this.tick, 1e3)) : void (this.curTime-- > 0 && (this.$value.text(this.curTime),
  500. this.timerId = this.withDelay(this.tick, 1e3)));
  501. },
  502. reset: function() {
  503. this.$progress.stop().attr({
  504. height: defHeight
  505. }), this.$value.text(this.curTime = this.duration), clearTimeout(this.timerId);
  506. },
  507. pause: function() {
  508. this.paused = !0, this.$progress.pause();
  509. },
  510. resume: function() {
  511. this.paused = !1, this.$progress.resume();
  512. }
  513. }),
  514. scope.Timer = Timer;
  515. }),
  516. Core(function(scope) {
  517. function Player(options) {
  518. options = options || {}, this.name = options.name, this.position = options.position,
  519. this.noSkin = options.noSkin, this.skin = options.skin || scope.SKIN_NAMES[$.rand(0, scope.SKIN_NAMES.length - 1)],
  520. this.$el = $("#player-" + this.position), this.elements = {
  521. $timer: "#timer",
  522. $name: "#name",
  523. $nameWrapper: "#name rect",
  524. $nameText: "#name text"
  525. }, this.proxies = [ "loadSkin" ], this.__super__.constructor.call(this), this.$el.show(),
  526. this.$timer.hide(), this.$name.show(), this.$nameText.text(this.name);
  527. var nameWrapperWidth = this.$nameText.width() / $("#Page-1").width() * 100 + 2 * (this.$nameText.position().left - this.$nameWrapper.position().left) / $("#Page-1").width() * 100;
  528. this.$nameWrapper.attr({
  529. width: nameWrapperWidth + "%"
  530. }), this.initTimer(), "me" == this.position || this.noSkin || $.load("../app/svg/" + [ "Person", this.position, this.skin ].join("-") + ".svg", this.loadSkin);
  531. }
  532. $.inherit(Player, scope.Controller), $.extend(Player.prototype, {
  533. loadSkin: function(result) {
  534. var $result = $("<g/>").html(result);
  535. this.$el.append($result[0].firstChild), this.unselect();
  536. },
  537. initTimer: function() {
  538. this.timer = new scope.Timer(this.$timer, {
  539. duration: 30
  540. });
  541. },
  542. select: function() {
  543. this.$nameWrapper.attr({
  544. fill: "#517ECE"
  545. }), this.$nameText.attr({
  546. fill: "#FFFFFF"
  547. }), this.$timer.show(), this.$("#Selection").show(), this.timer.start();
  548. },
  549. unselect: function() {
  550. this.$nameWrapper.attr({
  551. fill: "#FFFFFF"
  552. }), this.$nameText.attr({
  553. fill: "#48AF5E"
  554. }), this.$timer.hide(), this.$("#Selection").hide(), this.timer.reset();
  555. }
  556. }), scope.Player = Player;
  557. }),
  558. Core(function(scope) {
  559. function Hand(root, options) {
  560. options = options || {}, this.$el = $(root), this.elements = {
  561. $topCard: "#top-card",
  562. $rollUp: "#roll-up",
  563. $rollDown: "#roll-down",
  564. $container: "#container",
  565. $back: "#back",
  566. $cards: "#cards"
  567. }, this.proxies = [ "show", "hide" ], this.__super__.constructor.call(this), this.$rollUp.on("click", this.show),
  568. this.$rollDown.on("click", this.hide), this.cards = [];
  569. }
  570. var trfsMap = [ {
  571. backHeight: 74,
  572. containerTrf: "0 -44",
  573. cardTrf: "0 -38"
  574. }, {
  575. backHeight: 124,
  576. containerTrf: "0 -94",
  577. cardTrf: "0 -89"
  578. }, {
  579. backHeight: 174,
  580. containerTrf: "0 -144",
  581. cardTrf: "0 -139"
  582. } ],
  583. defCardTrf = "0 20";
  584. $.inherit(Hand, scope.Controller), $.extend(Hand.prototype, {
  585. take: function() {
  586. var card = this.cards.pop();
  587. return this.render(), card && card.$el.remove(), card;
  588. },
  589. discard: function(tile) {
  590. var card = new scope.Card({
  591. color: scope.CARD_COLORS[tile[1] - 1],
  592. value: tile[2]
  593. });
  594. this.cards.push(card), this.render(), card.drag(), card.dragHandler.disable(), this.$topCard.append(card.$el[0]);
  595. },
  596. pop: function() {
  597. this.cards.pop(), this.render();
  598. },
  599. show: function() {
  600. var count = this.cards.length - 1;
  601. count > 0 && (this.$container.transform({
  602. to: trfsMap[4 > count ? count - 1 : 2].containerTrf,
  603. from: "0 50",
  604. dur: .355,
  605. calcMode: "linear"
  606. }), this.$back.animate({
  607. attributeName: "height",
  608. to: trfsMap[4 > count ? count - 1 : 2].backHeight,
  609. dur: .355
  610. }), this.$cards.find("g").each(function(el, i) {
  611. 3 > i && $(el).transform({
  612. to: trfsMap[i].cardTrf,
  613. from: "0 20",
  614. dur: .6,
  615. calcmode: "linear"
  616. });
  617. }), this.shown = !0);
  618. },
  619. hide: function() {
  620. var count = this.cards.length - 1;
  621. count > 0 && (this.$container.transform({
  622. to: "0 50",
  623. from: trfsMap[4 > count ? count - 1 : 2].containerTrf,
  624. dur: .5,
  625. calcMode: "linear"
  626. }), this.$back.animate({
  627. attributeName: "height",
  628. to: 0,
  629. dur: .5
  630. }), this.$cards.find("g").each(function(el, i) {
  631. 3 > i && $(el).transform({
  632. to: defCardTrf,
  633. from: trfsMap[4 > count ? count - 1 : 2].cardTrf,
  634. dur: .6,
  635. calcmode: "linear"
  636. });
  637. }), this.shown = !1);
  638. },
  639. render: function() {
  640. var history = this.cards.slice(0, this.cards.length - 1);
  641. this.$cards.empty(), this.shown && this.hide(), history.reverse().forEach(function(card) {
  642. card = card.clone(), card.template(scope.CARD_SMALL_SOURCE), card.$el.attr("transform", "translate(" + defCardTrf + ")"),
  643. this.$cards.append(card.$el[0]);
  644. }, this);
  645. },
  646. clear: function() {
  647. this.cards.forEach(function(card) {
  648. card.$el.remove();
  649. }), this.cards = [], this.render();
  650. }
  651. }), scope.Hand = Hand;
  652. }),
  653. Core(function(scope) {
  654. function Card(options) {
  655. options = options || {}, this.value = options.value, this.color = options.color,
  656. this.selected = !1, this.pos = {}, this.elements = {
  657. $circle: "circle",
  658. $text: "text",
  659. $overlay: ".overlay"
  660. }, this.proxies = [ "toggle", "selectGroup", "dragGroup", "clearGroup", "revertGroup" ],
  661. this.template(scope.CARD_SOURCE), this.$el.on("mousedown", this.toggle), this.$el.on("revert", this.revertGroup),
  662. this.$el.on("dragstop", this.clearGroup), this.$overlay.on("mousedown", this.selectGroup);
  663. }
  664. var selStart = !1;
  665. $(window).on("keydown", function(e) {
  666. e.ctrlKey && (selStart = !0);
  667. }), $(window).on("keyup", function() {
  668. selStart = !1;
  669. }), Card.selected = [], Card.uncheckAll = function() {
  670. for (var i = Card.selected.length; i--; ) Card.selected[i].uncheck();
  671. }, $("body").on("mousedown", Card.uncheckAll), $.inherit(Card, scope.Controller),
  672. $.extend(Card.prototype, {
  673. template: function(source) {
  674. $.load(source, this.proxy(this.load));
  675. },
  676. load: function(result) {
  677. this.$el = (this.$el || $("<g/>")).attr({
  678. "class": "card"
  679. }).css({
  680. cursor: "default"
  681. }).html(result), this.__super__.constructor.call(this), this.render();
  682. },
  683. render: function() {
  684. null == this.value && null == this.color ? (this.$circle.hide(), this.$text.hide()) : 0 == this.value ? (this.$circle.hide(),
  685. this.$text.show().attr({
  686. fill: this.color,
  687. y: 36
  688. }).text("*")) : (this.$circle.show().attr("fill", this.color), this.$text.show().attr("fill", this.color).text(this.value));
  689. },
  690. drag: function() {
  691. this.dragHandler = new scope.Draggable(this.$el), this.dragHandler.owner = this;
  692. },
  693. centerX: function() {
  694. var pos = this.$el.position(), width = this.$el.width();
  695. return Math.round(pos.left + width / 2);
  696. },
  697. toggle: function(e) {
  698. e.stopPropagation(), selStart ? this.nearSelectGroup() ? this.selected && !this.betweenSelected() ? this.uncheck() : this.check() : (Card.uncheckAll(),
  699. this.check()) : ~Card.selected.indexOf(this) || Card.uncheckAll();
  700. },
  701. check: function() {
  702. this.$overlay.css("display", ""), this.selected = !0, deck.cards[this.pos.y][this.pos.x] = null,
  703. Card.selected.push(this);
  704. },
  705. uncheck: function() {
  706. this.$overlay.css("display", "none"), this.selected = !1, deck.cards[this.pos.y][this.pos.x] = this;
  707. var i;
  708. ~(i = Card.selected.indexOf(this)) && Card.selected.splice(i, 1);
  709. },
  710. selectGroup: function(e) {
  711. if (!selStart) {
  712. for (var card, i = 0, l = Card.selected.length; l > i; i++) card = Card.selected[i],
  713. card != this && card.dragHandler.onDown(e, !0);
  714. this.$el.on("dragmove", this.dragGroup);
  715. }
  716. },
  717. dragGroup: function(e) {
  718. for (var card, i = 0, l = Card.selected.length; l > i; i++) card = Card.selected[i],
  719. card != this && card.dragHandler.onMove(e.detail.event, !0);
  720. },
  721. clearGroup: function() {
  722. this.$el.off("dragmove", this.dragGroup), selStart || Card.uncheckAll();
  723. },
  724. nearSelectGroup: function() {
  725. return Card.selected.some(function(card) {
  726. return Math.abs(card.pos.x - this.pos.x) <= 1 && card.pos.y == this.pos.y;
  727. }, this);
  728. },
  729. betweenSelected: function() {
  730. Card.selected.sort(function(a, b) {
  731. return (a.pos.x < b.pos.x) - (b.pos.x < a.pos.x);
  732. });
  733. var idx = Card.selected.indexOf(this);
  734. return -1 != idx && 0 != idx && idx != Card.selected.length - 1;
  735. },
  736. revertGroup: function() {
  737. for (var card, i = 0, l = Card.selected.length; l > i; i++) card = Card.selected[i],
  738. card != this && card.$el.transform({
  739. from: [ card.dragHandler.dx, card.dragHandler.dy ].join(" "),
  740. to: card.dragHandler.initTrf.join(" ")
  741. }), scope.deck.cards[card.pos.y][card.pos.x] = card;
  742. },
  743. clone: function() {
  744. return new Card({
  745. color: this.color,
  746. value: this.value
  747. });
  748. },
  749. log: function() {}
  750. }), scope.Card = Card;
  751. }),
  752. Core(function(scope) {
  753. function Deck(root, options) {
  754. options = options || {}, this.$el = $(root), this.elements = {
  755. $dropPlace: "#deck"
  756. }, this.proxies = [ "select", "track", "place" ], this.cards = [ [], [] ], this.trfs = [ [], [] ],
  757. this.__super__.constructor.call(this), this.$dropPlace.droppable({
  758. accept: this.place
  759. });
  760. }
  761. var padding = {
  762. top: 5,
  763. left: 5
  764. };
  765. $.inherit(Deck, scope.Controller);
  766. var prevX, prevY, selected;
  767. $.extend(Deck.prototype, {
  768. each: function(callback) {
  769. for (var i = 0; 15 > i; i++) for (var j = 0; 2 > j; j++) if (callback.call(this, this.cards[j][i], i, j) === !1) return;
  770. },
  771. fill: function(tiles) {
  772. var count = 0;
  773. this.each(function(c, i, j) {
  774. if (null != c && (this.cards[j][i] = null, c.$el.remove()), 0 == j && count < tiles.length) {
  775. var tile = tiles[count], card = new scope.Card({
  776. color: scope.CARD_COLORS[tile[1] - 1],
  777. value: tile[2]
  778. });
  779. card.pos = {
  780. x: i,
  781. y: j
  782. }, card.on("dragstart", this.select), card.on("dragmove", this.track), this.cards[j][i] = card,
  783. count++;
  784. }
  785. this.trfs[j][i] = {
  786. x: 42 * i + padding.left,
  787. y: 71 * j + padding.top
  788. };
  789. });
  790. },
  791. render: function() {
  792. this.each(function(card, i, j) {
  793. null != card && (card.$el.attr("transform", "translate(" + this.trfs[j][i].x + " " + this.trfs[j][i].y + ")"),
  794. card.drag(), this.$el.append(card.$el[0]));
  795. });
  796. },
  797. track: function(e) {
  798. this.each(function(card, i, j) {
  799. if (card && card.$el[0] != e.target && card.intersect(e.detail.x, e.detail.y) && !card.$el.attr("animated") && scope.Card.selected.length < 2) {
  800. var shift = e.detail.x > card.centerX() ? i + 1 : i - 1;
  801. return shift = shift > 14 ? shift - 2 : shift, shift = 0 > shift ? shift + 2 : shift,
  802. prevX = i, prevY = j, this.move({
  803. i: i,
  804. j: j
  805. }, {
  806. i: shift,
  807. j: j
  808. }), !1;
  809. }
  810. });
  811. },
  812. move: function(fst, snd) {
  813. var card, trfs = this.trfs, i = snd.i, cond = function(i) {
  814. return fst.i < snd.i ? 14 >= i : i >= 0;
  815. }, _cond = function(j, i) {
  816. return fst.i < snd.i ? i > j : j > i;
  817. }, op = function() {
  818. fst.i < snd.i ? i++ : i--;
  819. }, _op = function() {
  820. fst.i < snd.i ? j++ : j--;
  821. }, direction = function(j) {
  822. return fst.i < snd.i ? j + (scope.Card.selected.length || 1) : j - (scope.Card.selected.length || 1);
  823. }, _direction = function(j) {
  824. return fst.i < snd.i ? j - 1 : j + 1;
  825. };
  826. if (scope.Card.selected.length < 2) for (;cond(i); op()) if (null == this.cards[snd.j][i] || this.cards[snd.j][i] == selected) {
  827. for (var j = _direction(i); _cond(j, i); _op()) card = this.cards[fst.j][j], card != selected && (card.$el.transform({
  828. from: [ trfs[fst.j][j].x, trfs[fst.j][j].y ].join(" "),
  829. to: [ trfs[fst.j][direction(j)].x, trfs[fst.j][direction(j)].y ].join(" ")
  830. }), selected && (selected.dragHandler.initTrf = [ trfs[fst.j][j].x, trfs[fst.j][j].y ]),
  831. ((this.cards[fst.j][j] = this.cards[fst.j][direction(j)]) || {}).pos = {
  832. x: j,
  833. y: fst.j
  834. }, (this.cards[fst.j][direction(j)] = card).pos = {
  835. x: direction(j),
  836. y: fst.j
  837. });
  838. break;
  839. }
  840. },
  841. select: function(e) {
  842. selected = null, this.each(function(card) {
  843. return card && card.$el[0] == e.target ? (selected = card, !1) : void 0;
  844. });
  845. },
  846. place: function(target, x, y) {
  847. var trfs = this.trfs, pos = this.$dropPlace.position(), width = this.$dropPlace.width(), height = this.$dropPlace.height(), placeWidth = Math.round(width / 15), placeHeight = Math.round(height / 2), truePosX = Math.floor((x - pos.left) / placeWidth), posY = Math.floor((y - pos.top) / placeHeight);
  848. scope.Card.selected.sort(function(a, b) {
  849. return (a.pos.x > b.pos.x) - (b.pos.x > a.pos.x);
  850. });
  851. var dropResult, idx = scope.Card.selected.indexOf(target.owner), cards = scope.Card.selected.length ? scope.Card.selected.concat() : [ target.owner ];
  852. if (cards.every(function(card, i) {
  853. return posX = truePosX + (i - idx) * (card != target.owner), null == this.cards[posY][posX] || this.cards[posY][posX] == card;
  854. }, this)) for (var card, i = 0, l = cards.length; l > i; i++) card = cards[i], posX = truePosX + (i - idx) * (card != target.owner),
  855. (dropResult = null == this.cards[posY][posX] || this.cards[posY][posX] == selected) && (this.cards[posY][posX] != card && (null != card.pos.x && null != card.pos.y ? this.cards[card.pos.y][card.pos.x] = this.cards[card.pos.y][card.pos.x] == card ? null : this.cards[card.pos.y][card.pos.x] : (this.$el.trigger("take", {
  856. detail: {
  857. card: card
  858. }
  859. }), this.justTaken = !0), (this.cards[posY][posX] = card).pos = {
  860. x: posX,
  861. y: posY
  862. }), function(card) {
  863. card.$el.transform({
  864. from: card.$el.attr("transform").slice(10, -1),
  865. to: [ trfs[posY][posX].x, trfs[posY][posX].y ].join(" ")
  866. }).then(function() {
  867. card.dragHandler.storeTrf();
  868. });
  869. }(card));
  870. return dropResult;
  871. },
  872. remove: function(tile) {
  873. return selected && selected.color == scope.CARD_COLORS[tile[1] - 1] && selected.value == tile[2] ? (this.cards[selected.pos.y][selected.pos.x] = null,
  874. selected.$el.remove(), selected.off("dragmove", this.track), !1) : void this.each(function(card, i, j) {
  875. return card && card.color == scope.CARD_COLORS[tile[1] - 1] && card.value == tile[2] ? (this.cards[j][i] = null,
  876. card.$el.remove(), card.off("dragmove", this.track), !1) : void 0;
  877. });
  878. },
  879. insert: function(tile) {
  880. this.justTaken ? this.justTaken = !1 : this.each(function(card, i, j) {
  881. return card ? void 0 : (card = new scope.Card({
  882. color: scope.CARD_COLORS[tile[1] - 1],
  883. value: tile[2]
  884. }), card.pos = {
  885. x: i,
  886. y: j
  887. }, card.on("dragstart", this.select), card.on("dragmove", this.track), this.cards[j][i] = card,
  888. card.$el.attr("transform", "translate(" + this.trfs[j][i].x + " " + this.trfs[j][i].y + ")"),
  889. card.drag(), this.$el.append(card.$el[0]), !1);
  890. });
  891. },
  892. length: function() {
  893. var count = 0;
  894. return this.each(function(card) {
  895. null != card && (count += 1);
  896. }), count;
  897. },
  898. hand: function(discarded) {
  899. return result = [ [], [] ], this.each(function(card, i, j) {
  900. card && card != discarded && result[j].push(tuple(atom("OkeyPiece"), scope.CARD_COLORS.indexOf(card.color) + 1, card.value));
  901. }), result;
  902. },
  903. dir: function() {
  904. for (var i = 0; 15 > i; i++) this.cards[0][i] && this.cards[0][i].log();
  905. for (var i = 0; 15 > i; i++) this.cards[1][i] && this.cards[1][i].log();
  906. }
  907. }), scope.deck = new Deck("#deck-root");
  908. }),
  909. Core(function(scope) {
  910. $.load(scope.CARD_SOURCE, function() {
  911. function fadeOut() {
  912. $(this).animate({
  913. attributeName: "opacity",
  914. from: 1,
  915. to: 0,
  916. dur: .3
  917. });
  918. }
  919. function fadeIn() {
  920. $(this).animate({
  921. attributeName: "opacity",
  922. from: 0,
  923. to: 1,
  924. dur: .3
  925. });
  926. }
  927. function addFadeOut() {
  928. $(this).on(document.createTouch ? "touchend" : "mouseup", fadeOut);
  929. }
  930. function removeFadeOut() {
  931. $(this).off(document.createTouch ? "touchend" : "mouseup", fadeOut);
  932. }
  933. function createCentralCard() {
  934. centralCard = new scope.Card(), centralCard.$el.attr({
  935. opacity: 0,
  936. transform: "translate(298 -115)"
  937. }).on(document.createTouch ? "touchstart" : "mousedown", fadeIn).on(document.createTouch ? "touchend" : "mouseup", fadeOut),
  938. centralCard.drag(), centralCard.dragHandler.enable(), centralCard.on("dragstart", deck.select).on("dragmove", removeFadeOut).on("dragstop", addFadeOut).on("dragmove", deck.track).on("revert", fadeOut),
  939. deck.$el.append(centralCard.$el[0]);
  940. }
  941. function init(e) {
  942. if (ended = !1, scope.deck.fill(e.detail.tiles), scope.deck.render(), centralCard.dragHandler.disable(),
  943. centralCard.$el.off(document.createTouch ? "touchstart" : "mousedown", fadeIn).off(document.createTouch ? "touchend" : "mouseup", fadeOut),
  944. e.detail.gosterge && "null" != e.detail.gosterge) {
  945. var gosterge = new scope.Card({
  946. color: scope.CARD_COLORS[e.detail.gosterge[1] - 1],
  947. value: e.detail.gosterge[2]
  948. });
  949. gosterge.$el.attr("transform", "translate(16 0)"), $gosterge.append(gosterge.$el);
  950. }
  951. var piles = e.detail.piles;
  952. if (piles && "null" != piles) for (var i = 0; i < piles.length, pile; i++) {
  953. pile = piles[i];
  954. for (var name in pile) for (var playerPile = pile[name], hand = playersLeftHandsMap[name], j = playerPile.length; j--; ) hand.discard(playerPile[j]);
  955. }
  956. e.detail.whos_move && "null" != e.detail.whos_move && (e.detail.next_turn_in && "null" != e.detail.next_turn_in && playersMap[e.detail.whos_move].timer.from(e.detail.next_turn_in),
  957. e.detail.paused && (playersMap[e.detail.whos_move].timer.pause(), $overlay.show()),
  958. playersMap[e.detail.whos_move].select());
  959. }
  960. window.deck = scope.deck;
  961. var centralCard, apiProvider = new scope.ApiProvider({
  962. url: scope.apiUrl,
  963. gameId: scope.gameId,
  964. sessionId: scope.defaultSessionId
  965. });
  966. createCentralCard(), deck.on("take", function(e) {
  967. e.detail.card.$el.off(document.createTouch ? "touchstart" : "mousedown", fadeIn).off(document.createTouch ? "touchend" : "mouseup", fadeOut),
  968. centralCard.off("dragmove", removeFadeOut).off("dragstop", addFadeOut).off("revert", fadeOut),
  969. ~playersLeftHandsMap[scope.user].cards.indexOf(e.detail.card) && playersLeftHandsMap[scope.user].pop(),
  970. apiProvider.actionTake(e.detail.card);
  971. });
  972. var $gosterge = $("#gosterge"), ended = !0;
  973. apiProvider.on("okey_game_started", init), apiProvider.on("okey_game_player_state", init);
  974. var playersPositions = [ [ "me", "right", "center", "left" ], [ "left", "me", "right", "center" ], [ "center", "left", "me", "right" ], [ "right", "center", "left", "me" ] ], playersMap = {}, playersRightHandsMap = {}, playersLeftHandsMap = {};
  975. apiProvider.on("okey_game_info", function(e) {
  976. if (!scope.started) {
  977. for (var playerInfo, players = e.detail.players, i = 0; i < players.length; i++) if (playerInfo = players[i].PlayerInfo,
  978. playerInfo[0] == scope.user) {
  979. playersPositions = playersPositions[i];
  980. break;
  981. }
  982. for (var playerInfo, i = 0, l = players.length; l > i; i++) {
  983. playerInfo = players[i].PlayerInfo, playersMap[playerInfo[0]] = playersMap[playerInfo[0]] || new scope.Player({
  984. position: playersPositions[i],
  985. name: [ playerInfo[2], playerInfo[3] ].join(" ")
  986. });
  987. var prevPlayer = i == players.length - 1 ? players[0] : players[i + 1];
  988. for (var prop in playersLeftHandsMap) playersLeftHandsMap[prop].clear();
  989. playersLeftHandsMap[prevPlayer.PlayerInfo[0]] = playersRightHandsMap[playerInfo[0]] = new scope.Hand("#" + [ "player", playersPositions[i], "hand" ].join("-")),
  990. "me" == playersPositions[i] && playersRightHandsMap[playerInfo[0]].$el.droppable({
  991. accept: function() {
  992. return playerTurn && deck.length() > 14;
  993. },
  994. drop: function(target) {
  995. apiProvider.actionDiscard(target.owner);
  996. }
  997. });
  998. }
  999. scope.started = !0;
  1000. }
  1001. }), window.playersRightHandsMap = playersRightHandsMap, window.playersLeftHandsMap = playersLeftHandsMap;
  1002. var playerTurn = !1;
  1003. apiProvider.on("okey_next_turn", function(e) {
  1004. for (var playerName in playersMap) playersMap[playerName].unselect();
  1005. if (playersMap[e.detail.player].select(), e.detail.player == scope.user) {
  1006. playerTurn = !0;
  1007. var cards = playersLeftHandsMap[e.detail.player].cards;
  1008. if (cards.length) {
  1009. var card = cards[cards.length - 1];
  1010. deck.$el.append(card.$el[0]), card.$el.attr({
  1011. transform: "translate(16 -65)"
  1012. }), card.dragHandler.enable(), card.on("dragstart", deck.select), card.on("dragmove", deck.track);
  1013. }
  1014. deck.length() < 15 ? (centralCard.dragHandler.enable(), centralCard.$el.on(document.createTouch ? "touchstart" : "mousedown", fadeIn).on(document.createTouch ? "touchend" : "mouseup", fadeOut),
  1015. centralCard.on("dragmove", removeFadeOut).on("dragstop", addFadeOut).on("revert", fadeOut)) : (centralCard.dragHandler.disable(),
  1016. centralCard.$el.off(document.createTouch ? "touchstart" : "mousedown", fadeIn).off(document.createTouch ? "touchend" : "mouseup", fadeOut));
  1017. } else playerTurn = !1, centralCard.dragHandler.disable(), centralCard.$el.off(document.createTouch ? "touchstart" : "mousedown", fadeIn).off(document.createTouch ? "touchend" : "mouseup", fadeOut);
  1018. }), apiProvider.on("okey_tile_discarded", function(e) {
  1019. if ("object" == typeof e.detail.tile) {
  1020. var c = new scope.Card({
  1021. color: scope.CARD_COLORS[e.detail.tile[1] - 1],
  1022. value: e.detail.tile[2]
  1023. });
  1024. c.log();
  1025. }
  1026. e.detail.player == scope.user && deck.remove(e.detail.tile), playersRightHandsMap[e.detail.player].discard(e.detail.tile);
  1027. });
  1028. var $pile = $("#pile"), $fullPile = $pile.find("g").clone(), $wholeCards = $("#whole-cards"), $fullWholeCards = $("#whole-cards > g").clone();
  1029. apiProvider.on("okey_tile_taken", function(e) {
  1030. if ("object" == typeof e.detail.revealed) {
  1031. var c = new scope.Card({
  1032. color: scope.CARD_COLORS[e.detail.revealed[1] - 1],
  1033. value: e.detail.revealed[2]
  1034. });
  1035. c.log();
  1036. }
  1037. if (e.detail.pile && !deck.justTaken && playersLeftHandsMap[e.detail.player].take(),
  1038. 0 === e.detail.pile && e.detail.player == scope.user && (centralCard.color = scope.CARD_COLORS[e.detail.revealed[1] - 1],
  1039. centralCard.value = e.detail.revealed[2], centralCard.render(), createCentralCard()),
  1040. 0 === e.detail.pile) {
  1041. var $topCard = $pile.find("g");
  1042. if ($topCard.length > 1) $topCard.last().remove(); else {
  1043. $topCard.last().remove(), $pile.append($fullPile);
  1044. var $miniPile = $wholeCards.find("g");
  1045. $miniPile.length ? $miniPile.first().remove() : $wholeCards.append($fullWholeCards);
  1046. }
  1047. }
  1048. e.detail.player == scope.user && deck.insert(e.detail.revealed), centralCard.dragHandler.disable(),
  1049. centralCard.$el.off(document.createTouch ? "touchstart" : "mousedown", fadeIn).off(document.createTouch ? "touchend" : "mouseup", fadeOut);
  1050. var cards = playersLeftHandsMap[scope.user].cards;
  1051. if (cards.length) {
  1052. var card = cards[cards.length - 1];
  1053. card.dragHandler.disable();
  1054. }
  1055. }), apiProvider.on("okey_revealed", function(e) {
  1056. ended = !0, alert(e.detail.player), deck.fill([]);
  1057. for (var hand in playersLeftHandsMap) playersLeftHandsMap[hand].clear();
  1058. for (var playerName in playersMap) playersMap[playerName].unselect();
  1059. $gosterge.remove();
  1060. }), apiProvider.on("player_left", function(e) {
  1061. var playerInfo = e.detail.replacement.PlayerInfo;
  1062. playersMap[playerInfo[0]] = new scope.Player({
  1063. position: playersMap[e.detail.player].position,
  1064. name: [ playerInfo[2], playerInfo[3] ].join(" "),
  1065. noSkin: !0
  1066. }), delete playersMap[e.detail.player], playersRightHandsMap[playerInfo[0]] = playersRightHandsMap[e.detail.player],
  1067. delete playersRightHandsMap[e.detail.player], playersLeftHandsMap[playerInfo[0]] = playersLeftHandsMap[e.detail.player],
  1068. delete playersLeftHandsMap[e.detail.player];
  1069. }), $("#pause").on("click", function() {
  1070. apiProvider.pause();
  1071. });
  1072. var whoPausedGame, $overlay = $("#overlay");
  1073. $overlay.on("click", function() {
  1074. whoPausedGame == scope.user && apiProvider.pause(!0);
  1075. }), apiProvider.on("game_paused", function(e) {
  1076. if (whoPausedGame = e.detail[3], "pause" == e.detail[2]) {
  1077. $overlay.show();
  1078. for (var player in playersMap) playersMap[player].timer.pause();
  1079. var player = playersMap[e.detail[3]];
  1080. $overlay.find("text").text(player.name + " paused the game");
  1081. } else {
  1082. $overlay.hide();
  1083. for (var player in playersMap) playersMap[player].timer.resume();
  1084. }
  1085. }), $("#table-ellipse").droppable({
  1086. accept: function(target) {
  1087. return 1 === apiProvider.socket.readyState && deck.length() > 14 && target.owner != centralCard && !ended && scope.Card.selected.length <= 1;
  1088. },
  1089. drop: function(target) {
  1090. apiProvider.reveal(target.owner, deck.hand(target.owner));
  1091. }
  1092. });
  1093. });
  1094. var leftFlag = !1;
  1095. $("#Left-Menu").css("cursor", "pointer").on("click", function() {
  1096. leftFlag ? ($("#Tournaments").transform({
  1097. to: "10 575",
  1098. from: "44 465"
  1099. }), $("#Promos").transform({
  1100. to: "10 575",
  1101. from: "122 538"
  1102. }), leftFlag = !1) : ($("#Tournaments").transform({
  1103. from: "10 575",
  1104. to: "44 465"
  1105. }), $("#Promos").transform({
  1106. from: "10 575",
  1107. to: "122 538"
  1108. }), leftFlag = !0);
  1109. });
  1110. var rightFlag = !1;
  1111. $("#Right-Menu").css("cursor", "pointer").on("click", function() {
  1112. rightFlag ? ($("#Play").transform({
  1113. to: "975 575",
  1114. from: "946, 461"
  1115. }), $("#Create").transform({
  1116. to: "975 575",
  1117. from: "864 526"
  1118. }), rightFlag = !1) : ($("#Play").transform({
  1119. from: "975 575",
  1120. to: "946, 461"
  1121. }), $("#Create").transform({
  1122. from: "975 575",
  1123. to: "864 526"
  1124. }), rightFlag = !0);
  1125. });
  1126. });