{"version":3,"file":"static/chunks/IM-a05a2a74932a3e58.js","mappings":"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","sources":["webpack://_N_E/./lib/vendor/im/VendorIM.js"],"sourcesContent":["import HostConfig from '$LIB/Host.config';\nimport {vendorSettings, getTokenFromGatewayImpl} from '../vendorSettingIM';\nimport md5 from \"crypto-js/md5\";\nimport aes from 'crypto-js/aes';\nimport ecb from 'crypto-js/mode-ecb';\nimport pkcs7 from 'crypto-js/pad-pkcs7';\nimport base64 from 'crypto-js/enc-base64';\nimport moment from 'moment';\nimport {\n IMAPIStatus,\n IMWagerStatus,\n IMBetType,\n IMEventType,\n IMPeriodType,\n IMRBPeriodNames,\n IMSports,\n IMOddsType, IMDeltaAction, IMWagerSortWay,\n} from \"./IMConsts\";\nimport SportData from '../data/SportData'\nimport MarketData from \"../data/MarketData\";\nimport LeagueData from \"../data/LeagueData\";\nimport EventData from \"../data/EventData\";\nimport LineData from \"../data/LineData\";\nimport SelectionData from \"../data/SelectionData\";\nimport OddsData from \"../data/OddsData\";\nimport {\n CashOutStatusType,\n EventChangeType,\n OddsType,\n SelectionStatusType,\n SortWays, VendorConfigs,\n VendorErrorType, VendorMarketNames, VendorMarkets,\n WagerType\n} from \"../data/VendorConsts\";\nimport EventChangeData from \"../data/EventChangeData\";\nimport PollingResult from \"../data/PollingResult\";\nimport SearchEventData from \"../data/SearchEventData\";\nimport SearchLeagueData from \"../data/SearchLeagueData\";\nimport BetSettingData from \"../data/BetSettingData\";\nimport BetSelectionResultData from \"../data/BetSelectionResultData\";\nimport BetResultData from \"../data/BetResultData\";\nimport WagerData from \"../data/WagerData\";\nimport WagerItemData from \"../data/WagerItemData\";\nimport AnnouncementData from \"../data/AnnouncementData\";\nimport BetInfoData from \"../data/BetInfoData\";\nimport VendorError from \"../data/VendorError\";\nimport {Decimal} from \"decimal.js\";\nimport SelectionChangeData from \"../data/SelectionChangeData\";\nimport {fetchRequest} from \"../../SportRequest\";\nimport {ApiPort} from \"../../SPORTAPI\";\nimport VendorBase from \"../data/VendorBase\";\nimport natureCompare from 'natural-compare';\nimport EventInfo from \"../data/EventInfo\";\nimport BetStatusData from \"../data/BetStatusData\";\nimport {vendorStorage} from '../vendorStorage';\nimport SearchSportData from \"../data/SearchSportData\";\nimport CashOutResultData from \"../data/CashOutResultData\";\nimport { v4 as uuidv4 } from 'uuid';\n\nconst promiseWithTimeout = (targetPromise, timeout = 600000, timeoutMsg = '请求超时!!!') => {\n let timeout_fn = null;\n let timeout_promise = new Promise(function(resolve, reject) {\n timeout_fn = function() {\n reject(timeoutMsg);\n };\n });\n let timeout_handler = setTimeout(function() {\n timeout_fn();\n }, timeout);\n let abortable_promise =\n Promise.race([ targetPromise, timeout_promise ])\n .then(result => {\n if (timeout_handler) {\n clearTimeout(timeout_handler);\n }\n return result;\n })\n\n return abortable_promise;\n}\n\n/**\n * IM 體育接口\n */\nclass VendorIM extends VendorBase {\n //Singleton\n constructor () {\n if (!VendorIM._instance) {\n super({\n MaxParlay: 10, //串關最多選幾個\n VendorName: 'IM', //供應商名稱\n VendorPage: '/sports-im', //主頁鏈接\n EventIdType: 'int', //EventId數據形態: int/string\n HasLeagueIcon: true, //是否有聯賽Icon\n HasTeamIcon: true, //是否有隊伍Icon\n HasCashOut: true, //是否支持提前兌現\n });\n console.log('VendorIM new instance');\n VendorIM._instance = this;\n }\n return VendorIM._instance;\n }\n\n _getUID() {\n const thisKey = 'IM_UID';\n if (typeof window !== \"undefined\") {\n const thisUID = vendorStorage.getItem(thisKey);\n if (thisUID) {\n return thisUID\n } else {\n const newUID = uuidv4();\n vendorStorage.setItem(thisKey,newUID);\n return newUID;\n }\n }\n return '';\n }\n\n _getLoginInfo(){\n if (typeof window !== \"undefined\") {\n if (vendorStorage.getItem(\"loginStatus\") == 1) {\n const token = JSON.parse(vendorStorage.getItem(\"IM_Token\"));\n const memberCode = JSON.parse(vendorStorage.getItem(\"IM_MemberCode\"));\n const memberType = JSON.parse(vendorStorage.getItem(\"IM_MemberType\")); //用戶水位\n if (token && memberCode) return {token, memberCode, memberType};\n }\n }\n return null\n }\n\n //獲取用戶水位\n _getMemberType() {\n let memberType = 'A';\n if (typeof window !== \"undefined\") {\n if (vendorStorage.getItem(\"loginStatus\") == 1) {\n const thisMemberType = JSON.parse(vendorStorage.getItem(\"IM_MemberType\")); //用戶水位\n if (thisMemberType) {\n memberType = thisMemberType;\n }\n }\n }\n return memberType;\n }\n\n //獲取用戶水位\n _queryIMmemberType() {\n const loginInfo = this._getLoginInfo();\n //查詢用戶等級\n //console.log('===getLoginInfo',loginInfo);\n if (loginInfo.token && loginInfo.memberCode && !loginInfo.memberType) {\n let params = {};\n params['TimeStamp'] = this._getTimestamp();\n params['Token'] = loginInfo.token;\n params['MemberCode'] = loginInfo.memberCode;\n\n const apiName = 'GETMEMBERBYTOKEN'\n const fetchParams = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: JSON.stringify(params),\n };\n\n const url = HostConfig.Config.IMApi + apiName;\n\n promiseWithTimeout(\n fetch(url, fetchParams)\n .then(function(response) {\n return response.json();\n }).then(function(jsonData){\n console.log('===GetMemberByToken',jsonData)\n if (jsonData && jsonData.SpreadGroup) {\n vendorStorage.setItem(\n \"IM_MemberType\",\n JSON.stringify(jsonData.SpreadGroup)\n );\n }\n }).catch(e => {})\n ,\n 60*1000, //1分超時\n ).catch(e => console.log('_queryIMmemberType query timeout error'));\n }\n }\n\n //從gateway獲取登入token\n getTokenFromGateway() {\n return getTokenFromGatewayImpl(this);\n }\n\n //等待登入完成\n _checkAndWaitLogin(){\n return new Promise(resolve => {\n if (vendorStorage.getItem(\"loginStatus\") == 1) {\n if (this.loginPromise) {\n this.loginPromise.then(r => resolve(r)); // 如果在登入中,等待登入完成\n } else {\n //沒有loginPromise則檢查緩存數據\n const loginInfo = this._getLoginInfo();\n if (loginInfo) {\n //有數據,返回\n resolve(loginInfo.token);\n } else {\n //沒有緩存數據,可能登入後還沒來得及拿到token就刷新了,嘗試重新獲取\n this.getTokenFromGateway().then(r => resolve(r))\n }\n }\n } else {\n resolve(true); //沒登入(guest view)不需處理\n }\n })\n }\n\n /**\n * 生成調用接口的timestamp\n */\n _getTimestamp() {\n const key = md5(HostConfig.Config.IMAccessCode);\n\n //格式 Wed, 19 Jun 2019 07:59:41 GMT\n let currentTimeStamp = moment().utcOffset(0).format(\"ddd, DD MMM YYYY HH:mm:ss [GMT]\");\n const cipher = aes.encrypt(currentTimeStamp, key, {\n mode: ecb,\n padding: pkcs7,\n iv: '',\n });\n // 将加密后的数据转换成 Base64\n const base64Cipher = cipher.ciphertext.toString(base64);\n //console.log(key,currentTimeStamp, base64Cipher);\n return base64Cipher;\n }\n\n //儲存接口Delta數值\n _APIDeltas = {}\n\n _getDeltaKey(name, params = {}) {\n let params4md5 = Object.assign({},params);\n //清掉 額外添加 或是 查詢過程中會變化 的參數\n delete params4md5['TimeStamp'];\n delete params4md5['Delta'];\n delete params4md5['Token'];\n const paramsMD5 = md5(JSON.stringify(params4md5)).toString();\n //console.log('params4md5',params4md5,'md5value---',paramsMD5,'---md5value');\n return name + '_' + paramsMD5;\n }\n\n /**\n * 清理delta緩存,相當於刷新數據\n * 注意這個清理函數是異步 所以需要await,不然還沒清完就往後執行了,會出現奇怪的問題\n *\n * @param apiName 等同_imFetch的參數\n * @param params 等同_imFetch的參數\n * @private\n */\n async ClearDeltaCache(apiName, params) {\n //這裡也是抄的_imFetch的處理code\n if (!params['TimeStamp']) {\n params['TimeStamp'] = this._getTimestamp();\n }\n if (!params['LanguageCode']) {\n params['LanguageCode'] = vendorSettings.LanguageCode;\n }\n\n if(this._supportLoginAPIs[apiName]) {\n await this._checkAndWaitLogin();\n\n const loginInfo = this._getLoginInfo();\n\n if (loginInfo !== null) {\n if (!params['Token']) {\n params['Token'] = loginInfo.token;\n }\n\n if (!params['MemberCode']) {\n params['MemberCode'] = loginInfo.memberCode;\n }\n }\n }\n\n //支持delta查詢的API\n const deltaName = this._DeltaAPIMapping[apiName];\n if (deltaName) {\n const thisDeltaKey = this._getDeltaKey(deltaName,params);\n\n //console.log('===ClearDeltaCache',thisDeltaKey,deltaName,JSON.stringify(params));\n\n //清理delta數據\n if (this._APIDeltas[thisDeltaKey]) {\n //等待上一個相同參數的請求完成(加上超時處理,避免卡住數據不更新)\n if (\n this._APIDeltas[thisDeltaKey].queryPromise\n //&& retryCount <=0 //排除delta過期重試retryCount>0的,不然會死鎖卡住\n ) {\n await promiseWithTimeout(\n this._APIDeltas[thisDeltaKey].queryPromise,\n 60*1000, //1分超時\n '请求超时2'\n ).catch(e => console.log('_imFetch await before cancel',apiName, params ,'get error:', e));\n //.catch(e => {});\n }\n\n delete this._APIDeltas[thisDeltaKey];\n }\n }\n }\n\n /**\n * 調用IM接口\n *\n * @param apiName\n * @param params\n * @param method\n * @param retryCount\n * @returns {Promise}\n * @private\n */\n async _imFetch(apiName, params, method='POST' , retryCount = 0) {\n\n //紀錄原始的參數,遇到delta過期時 使用\n const originAPIName = apiName;\n const originParams = JSON.parse(JSON.stringify(params));\n\n if (!params['TimeStamp']) {\n params['TimeStamp'] = this._getTimestamp();\n }\n if (!params['LanguageCode']) {\n params['LanguageCode'] = vendorSettings.LanguageCode;\n }\n\n if(this._supportLoginAPIs[apiName]\n ) {\n await this._checkAndWaitLogin();\n\n const loginInfo = this._getLoginInfo();\n\n if (loginInfo !== null) {\n if (!params['Token']) {\n params['Token'] = loginInfo.token;\n }\n\n if (!params['MemberCode']) {\n params['MemberCode'] = loginInfo.memberCode;\n }\n\n if (loginInfo.token && loginInfo.memberCode && !loginInfo.memberType) {\n this._queryIMmemberType(); //獲取用戶水位\n }\n }\n }\n\n //支持delta查詢的API\n const deltaName = this._DeltaAPIMapping[apiName];\n const thisDeltaKey = this._getDeltaKey(deltaName,params);\n if (deltaName) {\n //檢查是否已有數據\n if (!this._APIDeltas[thisDeltaKey]) {\n this._APIDeltas[thisDeltaKey] = { delta: null, params: null, full: null};\n } else {\n //等待上一個相同參數的請求完成(加上超時處理,避免卡住數據不更新)\n if (\n this._APIDeltas[thisDeltaKey].queryPromise\n && retryCount <=0 //排除delta過期重試retryCount>0的,不然會死鎖卡住\n ) {\n await promiseWithTimeout(\n this._APIDeltas[thisDeltaKey].queryPromise,\n 60*1000, //1分超時\n '请求超时1'\n ).catch(e => console.log('_imFetch await',apiName,'get error:', e, JSON.stringify(params)));\n //.catch(e => {});\n }\n\n //結束後有可能被清空\n if (!this._APIDeltas[thisDeltaKey] || !this._APIDeltas[thisDeltaKey].delta ) {\n this._APIDeltas[thisDeltaKey] = { delta: null, params: null, full: null};\n } else {\n //使用保存的delta數值\n params['Delta'] = this._APIDeltas[thisDeltaKey].delta;\n //改成調用delta接口\n apiName = deltaName;\n }\n }\n }\n\n let that = this;\n let thisQueryPromise = new Promise(function(resolve, reject) {\n if (apiName === 'GETEVENTINFOMBT') {\n const thisUuid = that._getUID();\n if (thisUuid && thisUuid.length > 1) {\n params.uuid = thisUuid;\n }\n }\n\n const fetchParams = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: JSON.stringify(params),\n };\n\n const url = HostConfig.Config.IMApi + apiName;\n\n let cachedKey = '';\n\n //GETEVENTINFOMBT緩存1分鐘\n if (apiName === 'GETEVENTINFOMBT') {\n let clonedParams = JSON.parse(JSON.stringify(params));\n delete clonedParams['TimeStamp'];\n delete clonedParams['uuid'];\n\n cachedKey = 'CACHE_GETEVENTINFOMBT_' + md5(JSON.stringify(clonedParams)).toString();\n\n ///console.log('===== GETEVENTINFOMBT',JSON.parse(JSON.stringify(clonedParams)),cachedKey);\n const cachedJsonData = vendorStorage.getItem(cachedKey);\n if (cachedJsonData) {\n const cachedInfo = JSON.parse(cachedJsonData);\n //檢查是否過期\n const nowTime = new Date().getTime();\n if (nowTime > cachedInfo.expTime) {\n //console.log('===== GETEVENTINFOMBT remove expired cache',cachedKey,moment(cachedInfo.expTime).toISOString(),' <= ',moment(nowTime).toISOString());\n vendorStorage.removeItem(cachedKey) //過期刪除\n } else {\n //console.log('===== GETEVENTINFOMBT using cache',cachedKey,moment(cachedInfo.expTime).toISOString(),' > ',moment().toISOString());\n resolve(cachedInfo.data); //未過期直接用\n return;\n }\n } else {\n //console.log('===== GETEVENTINFOMBT do not have cache',cachedKey,moment().toISOString());\n }\n }\n\n promiseWithTimeout(\n fetch(url, fetchParams)\n .then(function(response) {\n return response.json();\n }).then(function(jsonData){\n //console.log('_imFetch',apiName, method ,fetchParams,'getData', jsonData);\n\n if (jsonData && jsonData.StatusCode && jsonData.StatusCode === IMAPIStatus.OK) {\n //保存Delta數值\n if (jsonData.Delta && deltaName) {\n\n //判斷是不是 delta查詢\n jsonData.isDeltaQuery = false;\n if (params['Delta']) {\n jsonData.isDeltaQuery = true; //額外加一個參數,後面數據處理會用到\n }\n\n jsonData.deltaKey = thisDeltaKey; //後面數據處理會用到\n\n //初始化配置\n that._APIDeltas[thisDeltaKey].delta = jsonData.Delta; //保存delta數值\n that._APIDeltas[thisDeltaKey].params = params; //保存查詢參數\n }\n\n if (apiName === 'GETEVENTINFOMBT') {\n const cacheObject = {\n data: jsonData,\n expTime: ((new Date()).getTime() + 75 * 1000), //GETEVENTINFOMBT緩存1分鐘=>用75秒保險\n params,\n };\n vendorStorage.setItem(cachedKey,JSON.stringify(cacheObject));\n //console.log('===== GETEVENTINFOMBT save cache',cachedKey,moment(cacheObject.expTime).toISOString(), ' > ' ,moment().toISOString());\n }\n\n resolve(jsonData);\n } else if (jsonData && jsonData.StatusCode && jsonData.StatusCode === IMAPIStatus.DeltaExpire) {\n //處理delta過期 - 重新調用主查詢\n delete that._APIDeltas[thisDeltaKey]; //刪除delta數據\n\n //最多重試3次 避免無窮循環\n if (retryCount >= 3) {\n //重試超過3次,按一般錯誤方式返回\n let thiserror = new VendorError();\n if (jsonData && jsonData.StatusCode) {\n thiserror = VendorError.fromIMError(jsonData.StatusCode,jsonData.StatusDesc)\n }\n console.log('_imFetch',apiName, method ,fetchParams,'get error:', thiserror);\n reject(thiserror);\n } else {\n //重試次數+1\n let thisRetryCount = retryCount + 1;\n console.log('_imFetch',apiName, method ,fetchParams,'delta expire retry', thisRetryCount);\n that._imFetch(originAPIName, originParams, method, thisRetryCount)\n .then(jsonData => { resolve(jsonData) })\n .catch(error => reject(error));\n }\n\n } else {\n let thiserror = new VendorError();\n if (jsonData && jsonData.StatusCode) {\n //特別處理投注錯誤信息\n if (jsonData.StatusCode === 350) { //投注檢查失敗,每個投注選項,分別列出無效原因\n resolve(jsonData); //直接視為成功,在投注檢查函數(getbetInfo)裡面處理\n return true;\n } else if (jsonData.StatusCode === 370) { //查滾球注單狀態失敗\n resolve(jsonData); //直接視為成功,在_getWagerStatusPolling輪詢裡面處理\n return true;\n } else if (jsonData.StatusCode === 1000) { //投注失敗\n if (jsonData.WagerSelectionInfos && jsonData.WagerSelectionInfos.length>0) {\n const errorInfo = jsonData.WagerSelectionInfos[0];\n //直接從BetStatusMessage拿出錯誤碼\n thiserror = VendorError.fromIMError(parseInt(errorInfo.BetStatusMessage), jsonData.StatusDesc);\n }\n } else {\n thiserror = VendorError.fromIMError(jsonData.StatusCode, jsonData.StatusDesc)\n }\n }\n console.log('_imFetch',apiName, method ,fetchParams,'get error:', thiserror);\n reject(thiserror);\n }\n })\n ,\n 2*60*1000, //2分超時\n '_imFetch请求超时'\n ).catch((error) => {\n console.log('_imFetch',apiName, method ,fetchParams,'has error', error);\n reject(error);\n })\n });\n\n if (deltaName) {\n if (!this._APIDeltas[thisDeltaKey]) {\n this._APIDeltas[thisDeltaKey] = {delta: null, params: null, full: null};\n }\n this._APIDeltas[thisDeltaKey].queryPromise = thisQueryPromise;\n }\n\n return thisQueryPromise;\n }\n\n //接口函數定義\n _APIs = {\n //2.1 索取所有体育计数\n getAllSportCount : (IsCombo=false) => this._imFetch('GETALLSPORTCOUNT', {IsCombo}),\n\n //2.2 索取所有竞赛计数 注意IsCombo 必須為 true 或 false\n getAllCompetitionCount: (SportId = IMSports.SOCCER, Market = VendorMarkets.EARLY, IsCombo = false,IncludeCloseEvent = false) =>\n this._imFetch('GETALLCOMPETITIONCOUNT', {SportId, Market, IsCombo, IncludeCloseEvent}),\n\n //2.3 索取赛事和主要玩法资料\n getEventInfoMBT:\n (SportId = IMSports.SOCCER, Market = VendorMarkets.EARLY, BetTypeIds = [IMBetType.HANDICAP,IMBetType.OVERUNDER], MarketlineLevels = [1], EventGroupTypeIds = [1] ) =>\n this._imFetch('GETEVENTINFOMBT', {SportId, Market, BetTypeIds, MarketlineLevels, EventGroupTypeIds }),\n\n //2.4 索取 DELTA 赛事和主要玩法详情\n getDeltaEventInfoMBT: (SportId = IMSports.SOCCER, Market = VendorMarkets.EARLY, BetTypeIds = [IMBetType.HANDICAP,IMBetType.OVERUNDER], MarketlineLevels = [1], Delta = 'Y') =>\n this._imFetch('GETDELTAEVENTINFOMBT', {SportId, Market, BetTypeIds, MarketlineLevels, Delta} ),\n\n //2.5 索取其他玩法资料\n getMLInfoOBT: (SportId= IMSports.SOCCER, Market= VendorMarkets.EARLY) =>\n this._imFetch('GETMLINFOOBT', {SportId, Market}),\n\n //2.6 索取 DELTA 其他玩法详情\n getDeltaMLInfoOBT: (SportId= IMSports.SOCCER, Market= VendorMarkets.EARLY, Delta= 'Y') =>\n this._imFetch('GETDELTAMLINFOOBT', {SportId, Market, Delta} ),\n\n //2.7 以页数索取赛事资料\n getEventInfoBYPAGE:\n (SportId = IMSports.SOCCER, Market = VendorMarkets.EARLY, Page = 1, PageRecords = 30,\n OrderBy = 1, BetTypeIds = [IMBetType.HANDICAP,IMBetType.OVERUNDER], MarketlineLevels = [1], EventGroupTypeIds = [1],\n IsCombo = false,) =>\n this._imFetch('GETEVENTINFOBYPAGE', {SportId, Market, Page, PageRecords, OrderBy, BetTypeIds, MarketlineLevels, EventGroupTypeIds, IsCombo }),\n\n //2.8 索取特定比賽資料 注意IsCombo 必須為 true 或 false 注意OddsType必帶,這個不像 GETEVENTINFOMBT 會返回全部OddsType,只會返回指定的盤口\n getSelectedEventInfo: (SportId= IMSports.SOCCER, EventIds= [123,456], OddsType= IMOddsType.HK, IsCombo= false, IncludeGroupEvents= true) =>\n this._imFetch('GETSELECTEDEVENTINFO', {SportId, EventIds, OddsType , IsCombo, IncludeGroupEvents}),\n\n //2.9 索取虚拟赛事列表\n getVSEventInfo: (SportId= IMSports.VIRTUALSOCCER, Season= 123, MatchDay= 123) =>\n this._imFetch('GETVSEVENTINFO', {SportId, Season, MatchDay}),\n\n //2.10 索取 DELTA 虚拟赛事列表\n getDeltaVSEventInfo: (SportId= IMSports.VIRTUALSOCCER, Season= 123, MatchDay= 123, Delta= 'Y') =>\n this._imFetch('GETDELTAVSEVENTINFO', {SportId, Season, MatchDay, Delta}, ),\n\n //2.11 索取虚拟赛事资料\n getVSEventDetails: (SportId= IMSports.VIRTUALSOCCER, EventId= 123) =>\n this._imFetch('GETVSEVENTDETAILS', {SportId, EventId}),\n\n //2.12 索取优胜冠军赛事\n getOutRightEvents: (SportId= IMSports.SOCCER) =>\n this._imFetch('GETOUTRIGHTEVENTS', {SportId}),\n\n //2.13 索取 DELTA 优胜冠军赛事\n getDeltaOutRightEventInfo: (SportId= IMSports.SOCCER, Delta= 'Y') =>\n this._imFetch('GETDELTAOUTRIGHTEVENTINFO', {SportId, Delta}),\n\n //2.14 索取现场赛果\n getLiveResults: (SportId= IMSports.SOCCER, ViewingCompetitionIds = []) =>\n this._imFetch('GETLIVERESULTS', {SportId, ViewingCompetitionIds} ),\n\n //2.15 SEARCH 搜索\n search : (filter, SportId= null, IsCombo=false, EventGroupTypeIds = [1]) =>\n this._imFetch('SEARCH', SportId ? {filter,SportId,IsCombo,EventGroupTypeIds} : {filter,IsCombo,EventGroupTypeIds}),\n\n //2.16 索取本地化翻譯\n getLocalizations: (LocalizationType= IMLocalizationType.ALL) =>\n this._imFetch('GETLOCALIZATIONS', {LocalizationType}),\n\n //2.17 索取 DELTA 本地化翻譯\n getDeltaLocalizations : (LocalizationType= IMLocalizationType.ALL, Delta= 'Y') =>\n this._imFetch('GETDELTALOCALIZATIONS ', {LocalizationType, Delta}, ),\n\n //2.18 索取完整赛果\n getCompletedResults: (SportId= IMSports.SOCCER, EventTypeId= IMEventType.FIXTURE, StartDate= '2020-09-15', EndDate= '2020-09-16') =>\n this._imFetch('GETCOMPLETEDRESULTS', {SportId, EventTypeId, StartDate, EndDate} ),\n\n //2.19 LOGOUT\n logOut: () =>\n this._imFetch('LOGOUT', {} ),\n\n //2.20 索取投注信息\n getBetInfo: (WagerType= WagerType.SINGLE, Selections= []) =>\n this._imFetch('GETBETINFO', {WagerType, WagerSelectionInfos: Selections} ),\n\n //2.21 投注\n placeBet: (WagerType= WagerType.SINGLE, Selections= [], ComboSelections = [], IsComboAcceptAnyOdds= false) =>\n this._imFetch('PLACEBET', {WagerType, WagerSelectionInfos: Selections, ComboSelections, IsComboAcceptAnyOdds, CustomerIP:'127.0.0.1', ServerIP:'192.168.88.88'} ),\n\n //2.22 索取投注明细\n getBetList: (BetConfirmationStatus= [IMWagerStatus.PENDING,IMWagerStatus.CONFIRMED,IMWagerStatus.REJECTED, IMWagerStatus.CANCELLED]) =>\n this._imFetch('GETBETLIST', {BetConfirmationStatus} ),\n\n //2.23 索取投注账目\n getStatement: (StartDate= '2020-09-15', EndDate= '2020-09-16', StartTime = '00:00:00', EndTime= '23:59:59', DateType = IMWagerSortWay.BETDATE) =>\n this._imFetch('GETSTATEMENT', {StartDate, EndDate, StartTime, EndTime, DateType} ),\n\n //2.24 索取余额\n getBalance: () =>\n this._imFetch('GETBALANCE', {} ),\n\n //2.25 索取待处理赌注状态\n getPendingWagerStatus: (WagerIds= []) =>\n this._imFetch('GETPENDINGWAGERSTATUS', {WagerIds} ),\n\n //2.26 索取通告\n getAnnouncement: () =>\n this._imFetch('GETANNOUNCEMENT', {OrderBy : 2} ), //1升序 2降序\n\n //2.27 索取会员信息\n getMemberByToken: () =>\n this._imFetch('GETMEMBERBYTOKEN', {} ),\n\n //2.28 索取用户自定义\n getUserPreferences: () =>\n this._imFetch('GETUSERPREFERENCES', {} ),\n\n //TODO 用戶自定義應該用不到,後面看是否需要\n //2.29UPDATEUSERPREFERENCES 更新用户自定义\n //2.30GETFAVOURITEEVENT 索取所有收藏赛事资料\n //2.31ADDFAVOURITEEVENT 加收藏赛事\n //2.32REMOVEFAVOURITEEVENT 删除收藏赛事\n\n //2.33 提前兑现 DELTA\n getDeltaBetTrade: (WagerIds= []) =>\n this._imFetch('GETDELTABETTRADE', {WagerIds} ),\n\n //2.34 SUBMITBUYBACK 提交回购 (提前兌現)\n submitBuyBack: (WagerId, BuyBackPricing, PricingId) =>\n this._imFetch('SUBMITBUYBACK', {WagerId, BuyBackPricing, PricingId}),\n\n //2.35 索取赛事直播资料\n getLiveStreamingInfo: (SportId= IMSports.SOCCER, EventId= 123) =>\n this._imFetch('GETLIVESTREAMINGINFO', {SportId, EventId}),\n\n //TODO 用途不明,待確認\n //2.36 GETCOMPANYBYID 以 COMPANYID 索取公司设定\n };\n\n //哪些接口使用delta,主查詢和delta查詢 都配置指向delta查詢\n _DeltaAPIMapping = {\n //2.3 索取赛事和主要玩法资料\n GETEVENTINFOMBT:'GETDELTAEVENTINFOMBT',\n //2.4 索取 DELTA 赛事和主要玩法详情\n GETDELTAEVENTINFOMBT: 'GETDELTAEVENTINFOMBT',\n //2.5 索取其他玩法资料\n GETMLINFOOBT:'GETDELTAMLINFOOBT',\n //2.6 索取 DELTA 其他玩法详情,\n GETDELTAMLINFOOBT:'GETDELTAMLINFOOBT',\n //2.9 索取虚拟赛事列表\n GETVSEVENTINFO:'GETDELTAVSEVENTINFO',\n //2.10 索取 DELTA 虚拟赛事列表\n GETDELTAVSEVENTINFO:'GETDELTAVSEVENTINFO',\n //2.12 索取优胜冠军赛事\n GETOUTRIGHTEVENTS:'GETDELTAOUTRIGHTEVENTINFO',\n //2.13 索取 DELTA 优胜冠军赛事\n GETDELTAOUTRIGHTEVENTINFO:'GETDELTAOUTRIGHTEVENTINFO',\n //2.16 索取本地化翻譯\n GETLOCALIZATIONS:'GETDELTALOCALIZATIONS',\n //2.17 索取 DELTA 本地化翻譯\n GETDELTALOCALIZATIONS:'GETDELTALOCALIZATIONS',\n }\n\n //哪些接口支持登入後查詢(自動帶MemberCode和Token)\n _supportLoginAPIs = {\n GETEVENTINFOMBT:true,\n GETDELTAEVENTINFOMBT:true,\n GETEVENTINFOBYPAGE:true,\n GETSELECTEDEVENTINFO:true,\n GETVSEVENTINFO:true,\n GETDELTAVSEVENTINFO:true,\n GETOUTRIGHTEVENTS:true,\n GETDELTAOUTRIGHTEVENTINFO:true,\n LOGOUT:true,\n GETBETINFO:true,\n PLACEBET:true,\n GETBETLIST:true,\n GETSTATEMENT:true,\n GETBALANCE:true,\n GETPENDINGWAGERSTATUS:true,\n GETMEMBERBYTOKEN:true,\n GETUSERPREFERENCES:true,\n UPDATEUSERPREFERENCES:true,\n GETFAVOURITEEVENT:true,\n ADDFAVOURITEEVENT:true,\n REMOVEFAVOURITEEVENT:true,\n GETDELTABETTRADE:true,\n SUBMITBUYBACK:true,\n }\n\n //獲取體育項目,返回為 PollingResult 格式\n async getSports() {\n //獲取收藏賽事\n const favEvents = await this.getFavouriteEvents();\n\n return this._APIs.getAllSportCount()\n .then(jsonData => {\n const data = jsonData.SportCount;\n const SportDatas = data.map(item => {\n\n const favEventsForThisSport = favEvents.filter(favItem => item.SportId === favItem.SportId);\n\n const targetEventGroup = item.EventGroupTypes[0]; //只獲取主要的count\n\n return new SportData(\n item.SportId,\n item.SportName,\n targetEventGroup.Count,\n [ //順序 滾球 今天 關注 早盤 優勝冠軍\n new MarketData(VendorMarkets.RUNNING, VendorMarketNames[VendorMarkets.RUNNING], targetEventGroup.RBFECount ),\n new MarketData(VendorMarkets.FAVOURITE, VendorMarketNames[VendorMarkets.FAVOURITE], favEventsForThisSport.length ),\n //今日包含滾球\n new MarketData(VendorMarkets.TODAY, VendorMarketNames[VendorMarkets.TODAY], (targetEventGroup.TodayFECount ?? 0) + (targetEventGroup.RBFECount ?? 0) ),\n new MarketData(VendorMarkets.EARLY, VendorMarketNames[VendorMarkets.EARLY], targetEventGroup.EarlyFECount ),\n new MarketData(VendorMarkets.OUTRIGHT, VendorMarketNames[VendorMarkets.OUTRIGHT], targetEventGroup.ORCount ),\n ]\n )\n });\n return new PollingResult(SportDatas);\n })\n }\n\n //獲取聯賽(好像沒有用)\n getLeagues(SportId = IMSports.SOCCER, MarketId = VendorMarkets.EARLY) {\n //注意聯賽在IM 叫 Competition 統一修正為 League\n return this._APIs.getAllCompetitionCount(SportId, MarketId)\n .then(jsonData => {\n const data = jsonData.CompetitionCount;\n return data.map(item => {\n return new LeagueData(\n item.CompetitionId,\n item.CompetitionName,\n item.Count,\n item.SportId,\n item.Market,\n )\n });\n })\n }\n\n //獲取比賽列表 返回為 PollingResult 格式(支持比對數據變化)\n //extraConfigs.MaxCount 支持指定獲取前幾個賽事 banner使用 這個IM無法用,接口不支持,不影響 就是會多返回數據\n async getEvents(SportId = IMSports.SOCCER, MarketId = VendorMarkets.EARLY, sortWay = SortWays.LeagueName, startDate = null, endDate = null\n , extraConfigs = {}) {\n\n const OddsType = this.getMemberSetting().oddsType;\n const MemberType = this._getMemberType(); //水位\n\n //獲取收藏賽事\n const favEvents = await this.getFavouriteEvents();\n const favEventsForThisSport = favEvents.filter(item => item.SportId === SportId);\n const favEventIdsForThisSport = favEventsForThisSport.map(item => item.EventId);\n\n let queryPromise = null;\n\n //關注(收藏)\n if(MarketId === VendorMarkets.FAVOURITE) {\n\n //沒數據直接返回空\n if (favEventsForThisSport.length <=0) {\n return new Promise(resolve => resolve(new PollingResult([])));\n }\n\n //轉成EventInfo格式\n const favEventInfos = favEventsForThisSport.map(fe => {\n return new EventInfo(fe.EventId,fe.SportId,(fe.IsOutRightEvent === true ? true : false));\n })\n\n queryPromise = this.getEventsDetail(favEventInfos).then(async pr => {\n pr.NewData.map(item => {\n if (item.IsOutRightEvent) {\n //猜冠軍,自動切selection只保留前4個\n if (item.Lines && item.Lines.length > 0) {\n item.Lines.map(l => {\n if (l.Selections && l.Selections.length > 4) {\n l.Selections = l.Selections.filter((s,index) => index < 4);\n }\n })\n }\n } else {\n //一般比賽 這裡拿到的是全投注線的,只需要讓球跟大小\n item.Lines = item.Lines.filter(l => l.BetTypeId === IMBetType.HANDICAP || l.BetTypeId === IMBetType.OVERUNDER);\n item.updateLineGroupCount();\n }\n })\n\n //移除 沒有數據的 關注比賽\n let existEventIds = [];\n const AllEventDatas = pr.NewData;\n if (AllEventDatas && AllEventDatas.length >0) {\n existEventIds = AllEventDatas.map(e => e.EventId);\n }\n const notExistEventIds = favEventsForThisSport.filter(e => existEventIds.indexOf(e.EventId) === -1).map(e => e.EventId);\n let hasDeletedFavourite = false; //關注比賽 是否有被刪除\n if (notExistEventIds && notExistEventIds.length >0) {\n hasDeletedFavourite = await this.removeFavouriteEvent(notExistEventIds);\n }\n if (hasDeletedFavourite){ //關注比賽 有被刪除\n //強制刷新 體育計數\n if (typeof window !== \"undefined\" && window.eventListing_updateSportsCount) {\n window.eventListing_updateSportsCount(this.configs.VendorName);\n }\n }\n\n return pr;\n });\n\n } else if (MarketId === VendorMarkets.OUTRIGHT) { //優勝冠軍\n\n queryPromise = this._getOutRightEvents(SportId, null, true);\n\n } else {\n queryPromise = this._APIs.getEventInfoMBT(SportId, MarketId)\n .then(async jsonData => {\n\n if (!jsonData.isDeltaQuery) {\n //主查詢\n\n //考慮沒有盤口的情況,返回空數組\n if (!jsonData.Sports || jsonData.Sports.length <= 0) {\n //記得額外儲存一個空的主查詢結果,不然後面調用delta查詢 會報錯\n if (jsonData.deltaKey && this._APIDeltas[jsonData.deltaKey]) {\n this._APIDeltas[jsonData.deltaKey].full = [];\n }\n return new PollingResult([]);\n }\n\n const data = jsonData.Sports[0].Events;\n const SportId = jsonData.Sports[0].SportId;\n const EventDatas = data.map((item, index) => {\n //console.log('handle',index, item.EventId)\n return EventData.createFromIMSource(item, SportId, favEvents, OddsType, MemberType);\n });\n\n //儲存主查詢結果\n if (jsonData.deltaKey && this._APIDeltas[jsonData.deltaKey]) {\n this._APIDeltas[jsonData.deltaKey].full = EventDatas;\n }\n\n const cloneEventDatas = EventDatas.map(ed => EventData.clone(ed)); //複製一份 不要和保存的內容共用實例\n\n return new PollingResult(cloneEventDatas);\n } else {\n //Delta查詢\n //拿出之前存的主查詢結果\n let SavedEventDatas = [];\n if (jsonData.deltaKey && this._APIDeltas[jsonData.deltaKey] && this._APIDeltas[jsonData.deltaKey].full) {\n SavedEventDatas = this._APIDeltas[jsonData.deltaKey].full;\n }\n\n //更新收藏狀態(下面只會處理變更項目,不會更新全部數據,所以要在這裡 直接全部處理)\n SavedEventDatas.map(item => {\n if (favEventIdsForThisSport.indexOf(item.EventId) !== -1) {\n item.IsFavourite = true;\n } else {\n item.IsFavourite = false;\n }\n });\n\n let hasDeletedFavourite = false; //關注比賽 是否有被刪除\n\n const data = jsonData.DeltaChanges;\n let deleteEventIds = [];\n const EventChanges = data.map((item, index) => {\n if (item.Action === IMDeltaAction.DELETE) {\n deleteEventIds.push(item.EventId);\n //刪除比賽\n return new EventChangeData(\n item.EventId,\n EventChangeType.Delete\n );\n } else {\n const existEvents = SavedEventDatas.filter(existItem => {\n return existItem.EventId === item.EventId\n })\n const newEventSource = JSON.parse(item.Value);\n //console.log('newEventSource',newEventSource);\n const newEvent = EventData.createFromIMSource(newEventSource[0].Events[0], newEventSource[0].SportId, favEvents, OddsType, MemberType);\n if (!existEvents || existEvents.length <= 0) {\n //新增比賽\n return new EventChangeData(\n item.EventId,\n EventChangeType.New,\n null,\n newEvent,\n );\n } else {\n //修改比賽\n return new EventChangeData(\n item.EventId,\n EventChangeType.Update,\n existEvents[0],\n newEvent,\n );\n }\n }\n });\n\n if (deleteEventIds && deleteEventIds.length > 0) {\n //刪除收藏\n //console.log('====remove fav event from getEvents->queryPromise for VendorMarkets.NORMALs')\n hasDeletedFavourite = await this.removeFavouriteEvent(deleteEventIds);\n }\n\n if (hasDeletedFavourite){ //關注比賽 有被刪除\n //強制刷新 體育計數\n if (typeof window !== \"undefined\" && window.eventListing_updateSportsCount) {\n window.eventListing_updateSportsCount(this.configs.VendorName);\n }\n }\n\n //套用差異更新\n //刪除\n const DeletedEventIds = EventChanges.map(change => {\n if (change.ChangeType === EventChangeType.Delete) {\n return change.EventId;\n }\n })\n if (DeletedEventIds && DeletedEventIds.length > 0) {\n SavedEventDatas = SavedEventDatas.filter(event => {\n return (DeletedEventIds.indexOf(event.EventId) === -1);\n })\n }\n\n EventChanges.map(change => {\n //更新\n if (change.ChangeType === EventChangeType.Update) {\n let targetIndex = null;\n SavedEventDatas.map((event, index) => {\n if (event.EventId === change.EventId) {\n targetIndex = index;\n }\n })\n\n if (targetIndex !== null) {\n SavedEventDatas[targetIndex] = change.NewValue;\n }\n\n //新增\n } else if (change.ChangeType === EventChangeType.New) {\n SavedEventDatas.push(change.NewValue);\n }\n })\n\n //儲存套用差異更新後的結果\n if (jsonData.deltaKey && this._APIDeltas[jsonData.deltaKey]) {\n this._APIDeltas[jsonData.deltaKey].full = SavedEventDatas;\n }\n\n const cloneEventDatas = SavedEventDatas.map(ed => EventData.clone(ed)); //複製一份 不要和保存的內容共用實例\n\n return new PollingResult(cloneEventDatas, EventChanges);\n }\n })\n .then(result => { //按配置的時間區段過濾\n if ((startDate == null && endDate == null) || MarketId !== VendorMarkets.EARLY) {\n return result;\n }\n\n const Events = result.NewData;\n const Changes = result.Changes;\n //console.log(startDate,endDate);\n const filteredEvents = Events !== null ? Events.filter(item => {\n if (endDate == null) {\n return (startDate <= item.EventDateLocal);\n } else {\n return (startDate <= item.EventDateLocal) && (item.EventDateLocal <= endDate);\n }\n }) : []\n\n const filteredChanges = Changes.filter(item => {\n if (item.ChangeType !== EventChangeType.Delete) {\n if (endDate == null) {\n return (startDate <= item.NewValue.EventDateLocal);\n } else {\n return (startDate <= item.NewValue.EventDateLocal) && (item.NewValue.EventDateLocal <= endDate);\n }\n }\n });\n\n return new PollingResult(filteredEvents, filteredChanges);\n })\n }\n\n return queryPromise\n .then(result => {\n //處理排序\n result.NewData = EventData.sortEvents(result.NewData, sortWay);\n\n //排序投注線\n if (result.NewData && result.NewData.length > 0) {\n result.NewData.map(item => {\n item.sortLines();\n })\n }\n\n return result;\n })\n }\n\n //獲取優勝冠軍賽事 返回為 PollingResult 格式(支持比對數據變化)\n //IM強制歐洲盤,所以沒有盤口可選\n //排序在getEvents統一處理\n //因為IM沒有提供單個查詢的函數,這裏額外加一個eventIds參數,用來過濾數據,獲取特定單個或多個\n //ForListing用來提供列表頁的數據,自動切selection只保留前4個\n async _getOutRightEvents(SportId = IMSports.SOCCER, eventIds = null, ForListing = false) {\n\n if (eventIds !== null && eventIds.length > 0) {\n eventIds = eventIds.map(e => parseInt(e)); //轉換一下\n }\n\n const OddsType = this.getMemberSetting().oddsType;\n const MemberType = this._getMemberType(); //水位\n\n //獲取收藏賽事\n const favEvents = await this.getFavouriteEvents();\n const favEventsForThisSport = favEvents.filter(item => item.SportId === SportId);\n const favEventIdsForThisSport = favEventsForThisSport.map(item => item.EventId);\n\n return this._APIs.getOutRightEvents(SportId)\n .then(async jsonData => {\n //注意優勝冠軍的接口不一樣,返回結構也和Events不一樣 都要特別處理\n\n if (!jsonData.isDeltaQuery) {\n //主查詢\n\n //考慮沒有盤口的情況,返回空數組\n if (!jsonData.Events || jsonData.Events.length <= 0) { //直接返回Events 沒有Sports這層\n //記得額外儲存一個空的主查詢結果,不然後面調用delta查詢 會報錯\n if (jsonData.deltaKey && this._APIDeltas[jsonData.deltaKey]) {\n this._APIDeltas[jsonData.deltaKey].full = [];\n }\n return new PollingResult([]);\n }\n\n const data = jsonData.Events;\n const EventDatas = data.map((item, index) => {\n //console.log('handle',index, item.EventId)\n return EventData.createFromIMOutRightSource(item, SportId, favEvents, OddsType, MemberType);\n });\n\n //儲存主查詢結果\n if (jsonData.deltaKey && this._APIDeltas[jsonData.deltaKey]) {\n this._APIDeltas[jsonData.deltaKey].full = EventDatas;\n }\n\n //複製一份 不要和保存的內容共用實例\n let cloneEventDatas = EventDatas.map(ed => EventData.clone(ed));\n\n //過濾\n if (eventIds !== null && eventIds.length > 0) {\n cloneEventDatas = cloneEventDatas.filter(ed => eventIds.indexOf(ed.EventId) !== -1 );\n }\n\n return new PollingResult(cloneEventDatas);\n } else {\n //Delta查詢\n //拿出之前存的主查詢結果\n let SavedEventDatas = [];\n if (jsonData.deltaKey && this._APIDeltas[jsonData.deltaKey] && this._APIDeltas[jsonData.deltaKey].full) {\n SavedEventDatas = this._APIDeltas[jsonData.deltaKey].full;\n }\n\n //更新收藏狀態(下面只會處理變更項目,不會更新全部數據,所以要在這裡 直接全部處理)\n SavedEventDatas.map(item => {\n if (favEventIdsForThisSport.indexOf(item.EventId) !== -1) {\n item.IsFavourite = true;\n } else {\n item.IsFavourite = false;\n }\n });\n\n //優勝冠軍的delta分開 InsertUpdateEvent 和 RemoveEvent\n\n let hasDeletedFavourite = false; //關注比賽 是否有被刪除\n let deleteEventIds = [];\n const RemoveChanges = jsonData.RemoveEvent.map(item => {\n deleteEventIds.push(item);\n //刪除比賽\n return new EventChangeData(\n item, //優勝冠軍給的是 直接 item = EventId\n EventChangeType.Delete\n );\n })\n\n if (deleteEventIds && deleteEventIds.length > 0) {\n //刪除收藏\n //console.log('====remove fav event from _getOutRightEvents')\n hasDeletedFavourite = await this.removeFavouriteEvent(deleteEventIds);\n }\n\n if (hasDeletedFavourite){ //關注比賽 有被刪除\n //強制刷新 體育計數\n if (typeof window !== \"undefined\" && window.eventListing_updateSportsCount) {\n window.eventListing_updateSportsCount(this.configs.VendorName);\n }\n }\n\n const InsertUpdateChanges = jsonData.InsertUpdateEvent.map(item => {\n const existEvents = SavedEventDatas.filter(existItem => {\n return existItem.EventId === item.EventId\n })\n //console.log('newEventSource',newEventSource);\n const newEvent = EventData.createFromIMOutRightSource(item, SportId, favEvents, OddsType, MemberType);\n if (!existEvents || existEvents.length <= 0) {\n //新增比賽\n return new EventChangeData(\n item.EventId,\n EventChangeType.New,\n null,\n newEvent,\n );\n } else {\n //修改比賽\n return new EventChangeData(\n item.EventId,\n EventChangeType.Update,\n existEvents[0],\n newEvent,\n );\n }\n });\n\n let EventChanges = InsertUpdateChanges.concat(RemoveChanges);\n\n //套用差異更新\n //刪除\n const DeletedEventIds = EventChanges.map(change => {\n if (change.ChangeType === EventChangeType.Delete) {\n return change.EventId;\n }\n })\n if (DeletedEventIds && DeletedEventIds.length > 0) {\n SavedEventDatas = SavedEventDatas.filter(event => {\n return (DeletedEventIds.indexOf(event.EventId) === -1);\n })\n }\n\n EventChanges.map(change => {\n //更新\n if (change.ChangeType === EventChangeType.Update) {\n let targetIndex = null;\n SavedEventDatas.map((event, index) => {\n if (event.EventId === change.EventId) {\n targetIndex = index;\n }\n })\n\n if (targetIndex !== null) {\n SavedEventDatas[targetIndex] = change.NewValue;\n }\n\n //新增\n } else if (change.ChangeType === EventChangeType.New) {\n SavedEventDatas.push(change.NewValue);\n }\n })\n\n //儲存套用差異更新後的結果\n if (jsonData.deltaKey && this._APIDeltas[jsonData.deltaKey]) {\n this._APIDeltas[jsonData.deltaKey].full = SavedEventDatas;\n }\n\n //複製一份 不要和保存的內容共用實例\n let cloneEventDatas = SavedEventDatas.map(ed => EventData.clone(ed));\n\n //過濾\n if (eventIds !== null && eventIds.length > 0) {\n cloneEventDatas = cloneEventDatas.filter(ed => eventIds.indexOf(ed.EventId) !== -1 );\n EventChanges = EventChanges.filter(ec => eventIds.indexOf(ec.EventId) !== -1 )\n }\n\n return new PollingResult(cloneEventDatas, EventChanges);\n }\n }).then(pr => {\n //如果是 列表頁展示,自動切selection只保留前4個\n if (ForListing && pr.NewData && pr.NewData.length > 0) {\n pr.NewData.map(e => {\n if (e.Lines && e.Lines.length > 0) {\n e.Lines.map(l => {\n if (l.Selections && l.Selections.length > 4) {\n l.Selections = l.Selections.filter((s,index) => index < 4);\n }\n })\n }\n })\n }\n\n return pr;\n })\n //優勝冠軍沒有時間過濾\n }\n\n //獲取分頁後的賽事 返回為 PollingResult 格式(不支持比對數據變化)\n async getEventsPaged(SportId = IMSports.SOCCER, MarketId = VendorMarkets.EARLY, sortWay = SortWays.LeagueName, startDate = null, endDate = null,\n page =1, pageRecords= 30, extraConfigs = {}) {\n\n const OddsType = this.getMemberSetting().oddsType;\n const MemberType = this._getMemberType(); //水位\n\n //獲取收藏賽事\n const favEvents = await this.getFavouriteEvents();\n\n let pagedDataOrderBy = 2; //1 = 赛事日期时间顺序 2 = IM 体育顺序\n if (sortWay === SortWays.EventTime) {\n pagedDataOrderBy = 1;\n }\n return this._APIs.getEventInfoBYPAGE(SportId, MarketId, page, pageRecords, pagedDataOrderBy)\n .then(jsonData => {\n //考慮沒有盤口的情況,返回空數組\n if (!jsonData.Sports || jsonData.Sports.length <= 0) {\n return new PollingResult([]);\n }\n\n const data = jsonData.Sports[0].Events;\n const SportId = jsonData.Sports[0].SportId;\n const eventDatas = data.map((item, index) => {\n return EventData.createFromIMSource(item, SportId, favEvents, OddsType, MemberType);\n });\n\n return new PollingResult(eventDatas);\n })\n .then(result => { //按配置的時間區段過濾\n if ((startDate == null && endDate == null) || MarketId !== VendorMarkets.EARLY) {\n return result;\n }\n\n const Events = result.NewData;\n const filteredEvents = Events !== null ? Events.filter(item => {\n if (endDate == null) {\n return (startDate <= item.EventDateLocal);\n } else {\n return (startDate <= item.EventDateLocal) && (item.EventDateLocal <= endDate);\n }\n }) : []\n\n return new PollingResult(filteredEvents);\n })\n .then(result => {\n //處理排序\n result.NewData = EventData.sortEvents(result.NewData, sortWay);\n\n //排序投注線\n if (result.NewData && result.NewData.length > 0) {\n result.NewData.map(item => {\n item.sortLines();\n })\n }\n\n return result;\n })\n }\n\n //獲取 預緩存 賽事 返回為 PollingResult 格式(不支持比對數據變化)\n async getPreCacheEventsFromCacheAPI(SportId = IMSports.SOCCER, MarketId = VendorMarkets.EARLY, sortWay = SortWays.LeagueName, startDate = null, endDate = null) {\n const OddsType = this.getMemberSetting().oddsType;\n const MemberType = this._getMemberType(); //水位\n\n //獲取收藏賽事\n const favEvents = await this.getFavouriteEvents();\n const favEventsForThisSport = favEvents.filter(item => item.SportId === SportId);\n const favEventIdsForThisSport = favEventsForThisSport.map(item => item.EventId);\n\n const eventDatas = await fetch(HostConfig.Config.CacheApi + '/events/im/'\n + SportId + '/' + MarketId + '/' + sortWay\n + ((startDate !== null && MarketId === VendorMarkets.EARLY) ? ('/' + startDate) : '')\n + ((endDate !== null && MarketId === VendorMarkets.EARLY)? ('/' + endDate): '')\n )\n .then(response => response.json())\n .then(jsonData => {\n let events = [];\n if (jsonData && jsonData.data && jsonData.data.length > 0) {\n events = jsonData.data.map(ev => EventData.clone(ev, OddsType, MemberType)); //需要轉換一下\n //更新收藏狀態\n events.map(item => {\n if (favEventIdsForThisSport.indexOf(item.EventId) !== -1) {\n item.IsFavourite = true;\n } else {\n item.IsFavourite = false;\n }\n });\n }\n return events;\n }).catch(e => {\n console.log('===getPreCacheEventsFromCacheAPI has error',e);\n return null;\n })\n\n if (eventDatas) {\n return new PollingResult(eventDatas);\n } else {\n return null;\n }\n }\n\n //獲取歐洲杯比賽列表 返回為 PollingResult 格式(支持比對數據變化)\n async getEUROCUP202021Events() {\n const OddsType = this.getMemberSetting().oddsType;\n const MemberType = this._getMemberType(); //水位\n\n //獲取收藏賽事\n const favEvents = await this.getFavouriteEvents();\n const favEventsForThisSport = favEvents.filter(item => item.SportId === 1);\n const favEventIdsForThisSport = favEventsForThisSport.map(item => item.EventId);\n\n let eventDatas = await fetch(HostConfig.Config.CacheApi + '/eurocup202021')\n .then(response => response.json())\n .then(jsonData => {\n let events = [];\n if (jsonData && jsonData.eurocup202021 && jsonData.eurocup202021.length > 0) {\n events = jsonData.eurocup202021.map(ev => EventData.clone(ev, OddsType, MemberType)); //需要轉換一下\n //更新收藏狀態\n events.map(item => {\n if (favEventIdsForThisSport.indexOf(item.EventId) !== -1) {\n item.IsFavourite = true;\n } else {\n item.IsFavourite = false;\n }\n });\n }\n return events;\n })\n .catch(e => {\n console.log('===getEUROCUP202021Events has error',e);\n return [];\n })\n\n const cahceKey = 'getEUROCUP202021Events';\n const oldDatas = this._cacheGet(cahceKey);\n\n //比對差異\n let changes = [];\n if (oldDatas !== null) {\n let newEventIds = eventDatas.map(ev => ev.EventId);\n let oldEventMap = {}\n oldDatas.map(oev => {\n oldEventMap[oev.EventId] = oev;\n //已刪除\n if (newEventIds.indexOf(oev.EventId) === -1) {\n changes.push(new EventChangeData(oev.EventId, EventChangeType.Delete, oev));\n }\n });\n eventDatas.map(ev => {\n let oev = oldEventMap[ev.EventId];\n if (oev) {\n //變更 有變化的才紀錄\n if (JSON.stringify(oev) !== JSON.stringify(ev)) {\n changes.push(new EventChangeData(ev.EventId, EventChangeType.Update, oev, ev));\n }\n } else {\n //新增\n changes.push(new EventChangeData(ev.EventId, EventChangeType.New, null, ev));\n }\n })\n }\n\n //記錄新數據\n this._cacheSet(cahceKey,eventDatas)\n //複製一份 不要和保存的內容共用實例\n const cloneEventDatas = eventDatas.map(ev => EventData.clone(ev));\n return new PollingResult(cloneEventDatas,changes);\n }\n\n //獲取 單一個 比賽信息 返回為 PollingResult 格式(支持比對數據變化)\n async getEventDetail(SportId= IMSports.SOCCER, EventId, isOutRightEvent = false) {\n\n const OddsType = this.getMemberSetting().oddsType;\n const MemberType = this._getMemberType(); //水位\n\n //優勝冠軍另外查\n if (isOutRightEvent) {\n return this._getOutRightEvents(SportId,[EventId]).then(pr => {\n if (pr.NewData && pr.NewData.length > 0) {\n return new PollingResult(pr.NewData[0]); //只要返回單個\n } else {\n return new PollingResult(null);\n }\n })\n }\n\n return this._APIs.getSelectedEventInfo(SportId, [EventId], OddsType)\n .then(async jsonData => {\n\n //考慮沒有盤口的情況,返回空\n if (!jsonData.Sports || jsonData.Sports.length <= 0 || !jsonData.Sports[0] || jsonData.Sports[0].Events.length <=0) {\n return new PollingResult(null);\n }\n\n //獲取收藏賽事\n const favEvents = await this.getFavouriteEvents();\n\n //現在 getSelectedEventInfo 開啟了 IncludeGroupEvents=true\n //可能會返回多個,包含不同EventGroup的數據\n const mainEvents = jsonData.Sports[0].Events.filter(ev => ev.EventGroupTypeId === 1); //EventGroupTypeId === 1的才是主要比賽\n\n const item = (mainEvents && mainEvents.length > 0) ? mainEvents[0] : null;\n if (item) {\n const SportId = jsonData.Sports[0].SportId;\n const eventData = EventData.createFromIMSource(item,SportId,favEvents, OddsType, MemberType);\n\n //合併eventGroup的投注數據\n eventData.IMMergeSideEvents(jsonData.Sports[0].Events,favEvents, OddsType, MemberType);\n\n const deltaKey = this._getDeltaKey('GETSELECTEDEVENTINFO', {EventId});\n const oldEventData = this._APIDeltas[deltaKey];\n let eventChanges = [];\n if (oldEventData) {\n //有變化的才紀錄EventChangeData\n if (JSON.stringify(oldEventData) !== JSON.stringify(eventData)) {\n eventChanges.push(new EventChangeData(eventData.EventId, EventChangeType.Update, oldEventData, eventData));\n }\n } else {\n eventChanges.push(new EventChangeData(eventData.EventId, EventChangeType.New, null, eventData));\n }\n\n //保存查詢結果\n this._APIDeltas[deltaKey] = eventData;\n\n //複製一份 不要和保存的內容共用實例\n let thisEventData = EventData.clone(eventData);\n\n //排序投注線\n if (thisEventData) {\n thisEventData.IMSortLinesAndSelections();\n }\n\n return new PollingResult(thisEventData, eventChanges);\n } else {\n return new PollingResult(null);\n }\n })\n .catch(error => {\n //處理比賽結束 or 找不到數據\n if (typeof error === 'object' && error.isVendorError === true) {\n if (error.ErrorType === VendorErrorType.BET_Event_Error) {\n return new PollingResult(null);\n }\n } else {\n throw error;\n }\n })\n }\n\n //獲取多個比賽信息,傳入為EventInfo數組(支持不同體育項目和 一般/優勝冠軍 賽事混查), 返回為 PollingResult 格式(支持比對數據變化)\n async getEventsDetail(EventInfos = []) {\n\n const OddsType = this.getMemberSetting().oddsType;\n const MemberType = this._getMemberType(); //水位\n\n //支持傳入動態的EventInfo\n if (typeof EventInfos === 'function') {\n EventInfos = EventInfos();\n if (!!EventInfos && typeof EventInfos.then === 'function') {\n EventInfos = await EventInfos;\n }\n }\n\n //語法糖支持:單個改為數組\n if (!Array.isArray(EventInfos)) {\n EventInfos = [EventInfos];\n }\n\n //空查詢數據 直接返回\n if (EventInfos.length <=0) {\n return new Promise(resolve => resolve(new PollingResult([])));\n }\n\n //按體育和優勝冠軍分組\n let eventIdsBySportAndOutRight = {};\n EventInfos.map(item => {\n if (!eventIdsBySportAndOutRight[item.SportId]) {\n eventIdsBySportAndOutRight[item.SportId] = {normal: [], outright: []}; //裡面還要分 一般賽事 跟 優勝冠軍賽事\n }\n if (item.IsOutRightEvent) {\n eventIdsBySportAndOutRight[item.SportId].outright.push(item.EventId);\n } else {\n eventIdsBySportAndOutRight[item.SportId].normal.push(item.EventId);\n }\n })\n\n let promiseArr = [];\n for(let sportId in eventIdsBySportAndOutRight) {\n if (eventIdsBySportAndOutRight[sportId]) {\n //分體育項目\n\n //查優勝冠軍\n if (eventIdsBySportAndOutRight[sportId].outright && eventIdsBySportAndOutRight[sportId].outright.length >0) {\n const outrightPromise = this._getOutRightEvents(sportId,eventIdsBySportAndOutRight[sportId].outright);\n promiseArr.push(outrightPromise);\n }\n //查一般比賽\n if (eventIdsBySportAndOutRight[sportId].normal && eventIdsBySportAndOutRight[sportId].normal.length >0) {\n const normalPromise = this._APIs.getSelectedEventInfo(sportId, eventIdsBySportAndOutRight[sportId].normal, OddsType)\n .then(async jsonData => {\n\n //考慮沒有盤口的情況,返回空數組\n if (!jsonData.Sports || jsonData.Sports.length <= 0) {\n return new PollingResult([]);\n }\n\n //獲取收藏賽事\n const favEvents = await this.getFavouriteEvents();\n\n //現在 getSelectedEventInfo 開啟了 IncludeGroupEvents=true\n //可能會返回多個,包含不同EventGroup的數據\n\n const mainEvents = jsonData.Sports[0].Events.filter(ev => ev.EventGroupTypeId === 1); //EventGroupTypeId === 1的才是主要比賽\n\n let eventChanges = [];\n const eventDatas = mainEvents.map((item, index) => {\n //console.log('handle',index, item.EventId)\n const eventData = EventData.createFromIMSource(item, sportId, favEvents, OddsType, MemberType);\n\n //合併eventGroup的投注數據\n eventData.IMMergeSideEvents(jsonData.Sports[0].Events,favEvents, OddsType, MemberType);\n\n const deltaKey = this._getDeltaKey('GETSELECTEDEVENTINFO_getEventsDetail', {EventId: item.EventId}); //和一般的getEventDetail分開儲存\n const oldEventData = this._APIDeltas[deltaKey];\n if (oldEventData) {\n //有變化的才紀錄EventChangeData\n if (JSON.stringify(oldEventData) !== JSON.stringify(eventData)) {\n eventChanges.push(new EventChangeData(eventData.EventId, EventChangeType.Update, oldEventData, eventData));\n }\n } else {\n eventChanges.push(new EventChangeData(eventData.EventId, EventChangeType.New, null, eventData));\n }\n\n //保存查詢結果\n this._APIDeltas[deltaKey] = eventData;\n\n //複製一份 不要和保存的內容共用實例\n let thisEventData = EventData.clone(eventData);\n\n //排序投注線\n if (thisEventData) {\n thisEventData.IMSortLinesAndSelections();\n }\n\n return thisEventData;\n });\n\n return new PollingResult(eventDatas, eventChanges);\n })\n .catch(error => {\n //處理比賽結束 or 找不到數據\n if (typeof error === 'object' && error.isVendorError === true) {\n if (error.ErrorType === VendorErrorType.BET_Event_Error) {\n return new PollingResult([]);\n }\n } else {\n throw error;\n }\n })\n promiseArr.push(normalPromise);\n }\n }\n }\n\n return Promise.all(promiseArr).then(PRsArray => {\n let events = [];\n let changes = [];\n PRsArray.map(pr => {\n if (pr.NewData && pr.NewData.length > 0) {\n events = events.concat(pr.NewData);\n }\n if (pr.Changes && pr.Changes.length > 0) {\n changes = changes.concat(pr.Changes);\n }\n })\n\n return new PollingResult(events,changes);\n });\n }\n\n /**\n * 全局 輪詢獲取體育項目 30秒一次\n *\n * @param subscriberName 訂閱者名稱,用來處理重複訂閱的狀況\n * @param onUpdateCallback 輪詢後數據更新回調 (result) => {} result 為 PollingResult格式 {NewData:SportData數組, Changes:空數組}\n * @param uniqueName 用來判斷是否使用同一個輪詢,配置不同名字,可以同時開多個輪詢\n */\n getSportsPollingGlobal(subscriberName, onUpdateCallback, uniqueName = '') {\n return this._subscribeGlobalPolling('getSportsPolling', subscriberName, onUpdateCallback,{}, uniqueName, true);\n }\n\n /**\n * 輪詢獲取體育項目 30秒一次\n *\n * @param onUpdateCallback 輪詢後數據更新回調 (result) => {} result 為 PollingResult格式 {NewData:SportData數組, Changes:空數組}\n * @param uniqueName 用來判斷是否使用同一個輪詢,配置不同名字,可以同時開多個輪詢\n */\n getSportsPolling(onUpdateCallback, uniqueName = '') {\n const dataQuery = () => this.getSports();\n return this._registerPolling('getSportsPolling',{}, dataQuery, onUpdateCallback, 30, uniqueName, true);\n }\n\n /**\n * 全局 輪詢獲取比賽數據 10秒一次\n *\n * @param subscriberName 訂閱者名稱,用來處理重複訂閱的狀況\n * @param onUpdateCallback 輪詢後數據更新回調 (result) => {} result 為 PollingResult格式 {NewData:EventData數組, Changes:EventChangeData數組}\n * @param SportId 體育項目ID\n * @param MarketId 市場ID\n * @param sortWay 排序方式 1聯賽 2時間\n * @param startDate 比賽日期過濾 YYYY-MM-DD 格式(只有MarketId = 早盤(1)才有效)\n * @param endDate 比賽日期過濾 YYYY-MM-DD 格式(只有MarketId = 早盤(1)才有效)\n * @param uniqueName 用來判斷是否使用同一個輪詢,配置不同名字,可以同時開多個輪詢\n */\n getEventsPollingGlobal(subscriberName, onUpdateCallback, SportId = IMSports.SOCCER, MarketId = VendorMarkets.EARLY, sortWay = SortWays.LeagueName, startDate = null, endDate = null, uniqueName = '') {\n return this._subscribeGlobalPolling('getEventsPolling', subscriberName, onUpdateCallback,{SportId, MarketId, sortWay, startDate, endDate}, uniqueName, true);\n }\n\n /**\n * 輪詢獲取比賽數據 10秒一次\n *\n * @param onUpdateCallback 輪詢後數據更新回調 (result) => {} result 為 PollingResult格式 {NewData:EventData數組, Changes:EventChangeData數組}\n * @param SportId 體育項目ID\n * @param MarketId 市場ID\n * @param sortWay 排序方式 1聯賽 2時間\n * @param startDate 比賽日期過濾 YYYY-MM-DD 格式(只有MarketId = 早盤(1)才有效)\n * @param endDate 比賽日期過濾 YYYY-MM-DD 格式(只有MarketId = 早盤(1)才有效)\n * @param uniqueName 用來判斷是否使用同一個輪詢,配置不同名字,可以同時開多個輪詢\n */\n getEventsPolling(onUpdateCallback, SportId = IMSports.SOCCER, MarketId = VendorMarkets.EARLY, sortWay = SortWays.LeagueName, startDate = null, endDate = null, uniqueName = '') {\n const dataQuery = () => {\n if (MarketId === VendorMarkets.TODAY) { //今日包含滾球\n let favPromise = new Promise(resolve => resolve(null));\n if (!this.isAPIServer()) { //API服務器不需要查看關注比賽\n favPromise = this.getEvents(SportId, VendorMarkets.FAVOURITE, sortWay, startDate, endDate);\n }\n const runningPromise = this.getEvents(SportId, VendorMarkets.RUNNING, sortWay, startDate, endDate);\n const todayPromise = this.getEvents(SportId, VendorMarkets.TODAY, sortWay, startDate, endDate);\n\n return Promise.all([favPromise,runningPromise,todayPromise]).then(async values => {\n const prFav = values[0];\n const prRunning = values[1];\n const prToday = values[2];\n\n const runningEvents = prRunning.NewData ?? [];\n const runningChanges = prRunning.Changes ?? [];\n const todayEvents = prToday.NewData ?? [];\n const todayChanges = prToday.Changes ?? [];\n\n //順序 關注 => 滾球 => 今日\n const runningAndTodayEvents = runningEvents.concat(todayEvents);\n const runningAndTodayChanges = runningChanges.concat(todayChanges);\n\n //處理收藏賽事\n //等待查詢完成的時間差,可能會點擊新增/刪除收藏賽事,需要額外處理\n const currentFavEvents = await this.getFavouriteEvents();\n const currentFavEventsForThisSport = currentFavEvents.filter(item => item.SportId === SportId);\n const currentFavEventIdsForThisSport = currentFavEventsForThisSport.map(item => item.EventId);\n\n let favEvents = prFav ? (prFav.NewData ?? []) : [] ;\n\n const thisFavEventIds = favEvents.map(ev => ev.EventId);\n\n //處理新增收藏賽事\n let extraFavEventIds = currentFavEventIdsForThisSport.filter(evid => thisFavEventIds.indexOf(evid) === -1);\n if (extraFavEventIds && extraFavEventIds.length > 0) {\n //console.log('====extraFavEventIds',extraFavEventIds);\n //從現有數據找出對應比賽\n const extraFavEvents = runningAndTodayEvents.filter(ev => extraFavEventIds.indexOf(ev.EventId) !== -1)\n .map(ev => {\n ev.IsFavourite = true; //先加上星號,確保原本的數據也標記上\n //console.log('====extraFavEvent',ev.EventId,ev.LeagueName,ev.HomeTeamName,ev.AwayTeamName);\n return ev;\n })\n .map(ev => EventData.clone(ev)); //複製一份\n //添加額外的關注比賽\n favEvents = favEvents.concat(extraFavEvents);\n //重新排序\n EventData.sortEvents(favEvents,sortWay);\n }\n\n //處理刪除收藏賽事\n let deletedFavEventIds = thisFavEventIds.filter(evid => currentFavEventIdsForThisSport.indexOf(evid) === -1);\n if (deletedFavEventIds && deletedFavEventIds.length > 0) {\n //console.log('====deletedFavEventIds',deletedFavEventIds);\n //從現有數據找出對應比賽 移除星號\n runningAndTodayEvents.filter(ev => deletedFavEventIds.indexOf(ev.EventId) !== -1)\n .map(ev => {\n ev.IsFavourite = false; //移除星號\n //console.log('====deletedFavEvent',ev.EventId,ev.LeagueName,ev.HomeTeamName,ev.AwayTeamName);\n return ev;\n })\n //刪除關注比賽\n favEvents = favEvents.filter(ev => deletedFavEventIds.indexOf(ev.EventId) === -1);\n }\n\n if (favEvents && favEvents.length > 0) {\n favEvents.map(fev => fev.MarketIdForListing = VendorMarkets.FAVOURITE); //額外增加字段用於UI判斷\n }\n\n const favChanges = prFav ? (prFav.Changes ?? []) : [] ; //changes不用動,因為是by EventId去處理的\n\n //順序 關注 => 滾球 => 今日\n const eventDatas = favEvents.concat(runningAndTodayEvents);\n const eventChanges = favChanges.concat(runningAndTodayChanges);\n\n return new PollingResult(eventDatas,eventChanges);\n });\n } else {\n return this.getEvents(SportId, MarketId, sortWay, startDate, endDate);\n }\n }\n //分頁查詢 加速\n const preCacheQuery = () => {\n if (this.isAPIServer()) { //API服務器不需要preCache\n return new Promise(resolve => resolve(null));\n }\n\n if (MarketId === VendorMarkets.FAVOURITE || MarketId === VendorMarkets.OUTRIGHT) {\n //關注比賽 和 猜冠軍 不加速,因為無法直接用分頁查詢\n return new Promise(resolve => resolve(null));\n }\n\n if ([IMSports.SOCCER, IMSports.BASKETBALL].indexOf(SportId) === -1) {\n //只有足球和籃球支持緩存\n return new Promise(resolve => resolve(null));\n }\n\n //用緩存API 加速\n return this.getPreCacheEventsFromCacheAPI(SportId, MarketId, sortWay, startDate, endDate);\n }\n return this._registerPolling('getEventsPolling', {SportId, MarketId, sortWay, startDate, endDate}, dataQuery, onUpdateCallback, 10, uniqueName, true, 9*60, preCacheQuery);\n }\n\n /**\n * API專用 輪詢獲取比賽數據 10秒一次,每10分自動清理一次數據\n * 服務端專用,不會返回pollingkey\n *\n * @param onUpdateCallback 輪詢後數據更新回調 (result) => {} result 為 PollingResult格式 {NewData:EventData數組, Changes:EventChangeData數組}\n * @param SportId 體育項目ID\n * @param MarketId 市場ID\n * @param sortWay 排序方式 1聯賽 2時間\n * @param startDate 比賽日期過濾 YYYY-MM-DD 格式(只有MarketId = 早盤(1)才有效)\n * @param endDate 比賽日期過濾 YYYY-MM-DD 格式(只有MarketId = 早盤(1)才有效)\n * @param uniqueName 用來判斷是否使用同一個輪詢,配置不同名字,可以同時開多個輪詢\n */\n APIEventsPollingWithAutoClean(onUpdateCallback, SportId = IMSports.SOCCER, MarketId = VendorMarkets.EARLY, sortWay = SortWays.LeagueName, startDate = null, endDate = null, uniqueName = '') {\n const callWithAutoClean = async (imPollingKey = null, firstTime = false) => {\n if (imPollingKey) {\n //console.log('IM delete polling...');\n this.deletePolling(imPollingKey);\n }\n\n if (!firstTime) { //第一次 不清理數據\n const BetTypeIds = [IMBetType.HANDICAP, IMBetType.OVERUNDER];\n const MarketlineLevels = [1];\n const EventGroupTypeIds = [1];\n\n // const dumpDeltaInfo = () => {\n // let deltaInfo = { count: 0 }\n // for(let prop in this._APIDeltas) {\n // deltaInfo.count = deltaInfo.count + 1;\n // deltaInfo[prop] = {\n // full: this._APIDeltas[prop] && this._APIDeltas[prop].full ? this._APIDeltas[prop].full.length : 'null',\n // params: this._APIDeltas[prop] && this._APIDeltas[prop].params ? JSON.stringify(this._APIDeltas[prop].params) : 'null',\n // };\n // }\n // return deltaInfo;\n // }\n //\n // if (MarketId !== VendorMarkets.RUNNING) {\n // console.log('IM delta BEFORE clear', SportId, MarketId, dumpDeltaInfo())\n // }\n\n if (MarketId === VendorMarkets.TODAY) {\n //今日包含滾球,要一起清理\n await this.ClearDeltaCache('GETEVENTINFOMBT', {\n SportId,\n Market: VendorMarkets.RUNNING,\n BetTypeIds,\n MarketlineLevels,\n EventGroupTypeIds\n }).catch(e => console.log('ClearDeltaCache await RUNNING error:', e));\n await this.ClearDeltaCache('GETEVENTINFOMBT', {\n SportId,\n Market: VendorMarkets.TODAY,\n BetTypeIds,\n MarketlineLevels,\n EventGroupTypeIds\n }).catch(e => console.log('ClearDeltaCache await TODAY error:', e));\n\n } else if (MarketId === VendorMarkets.EARLY) {\n //早盤\n await this.ClearDeltaCache('GETEVENTINFOMBT', {\n SportId,\n Market: VendorMarkets.EARLY,\n BetTypeIds,\n MarketlineLevels,\n EventGroupTypeIds\n }).catch(e => console.log('ClearDeltaCache await EARLY error:', e));\n } else if (MarketId === VendorMarkets.OUTRIGHT) {\n //猜冠軍\n await this.ClearDeltaCache('GETOUTRIGHTEVENTS', {\n SportId,\n }).catch(e => console.log('ClearDeltaCache await OUTRIGHT error:', e));\n }\n\n // if (MarketId !== VendorMarkets.RUNNING) {\n // console.log('IM delta AFTER clear', SportId, MarketId, dumpDeltaInfo())\n // }\n }\n\n //console.log('IM start polling...');\n const thisPollingKey = this.getEventsPolling(onUpdateCallback,SportId,MarketId,sortWay,startDate,endDate,uniqueName);\n //暫定10分刷新一次\n setTimeout(() => callWithAutoClean(thisPollingKey), 10*60*1000);\n }\n callWithAutoClean(null, true);\n }\n\n\n /**\n * 全局 輪詢獲取 歐洲杯2020-21 比賽數據 10秒一次\n *\n * @param subscriberName 訂閱者名稱,用來處理重複訂閱的狀況\n * @param onUpdateCallback 輪詢後數據更新回調 (result) => {} result 為 PollingResult格式 {NewData:EventData數組, Changes:EventChangeData數組}\n * @param uniqueName 用來判斷是否使用同一個輪詢,配置不同名字,可以同時開多個輪詢\n */\n getEUROCUP202021EventsPollingGlobal(subscriberName, onUpdateCallback, uniqueName = '') {\n return this._subscribeGlobalPolling('getEUROCUP202021EventsPolling', subscriberName, onUpdateCallback,{}, uniqueName, false);\n }\n\n /**\n * 輪詢獲取 歐洲杯2020-21 比賽數據 10秒一次\n *\n * @param onUpdateCallback 輪詢後數據更新回調 (result) => {} result 為 PollingResult格式 {NewData:EventData數組, Changes:EventChangeData數組}\n * @param uniqueName 用來判斷是否使用同一個輪詢,配置不同名字,可以同時開多個輪詢\n */\n getEUROCUP202021EventsPolling(onUpdateCallback, uniqueName = '') {\n const dataQuery = () => this.getEUROCUP202021Events();\n return this._registerPolling('getEUROCUP202021EventsPolling', {}, dataQuery, onUpdateCallback, 10, uniqueName, true);\n }\n\n /**\n * 輪詢獲取 單個 比賽數據 10秒一次\n *\n * @param onUpdateCallback 輪詢後數據更新回調 (result) => {} result 為 PollingResult格式 {NewData: 單個EventData數據, Changes: EventChangeData 數組}\n * @param SportId 體育項目ID\n * @param EventId 比賽ID\n * @param isOutRightEvent 是否優勝冠軍賽事\n * @param uniqueName 用來判斷是否使用同一個輪詢,配置不同名字,可以同時開多個輪詢\n */\n getEventDetailPolling(onUpdateCallback, SportId = IMSports.SOCCER, EventId, isOutRightEvent = false, uniqueName = '') {\n const dataQuery = () => this.getEventDetail(SportId, EventId, isOutRightEvent);\n return this._registerPolling('getEventDetailPolling', {SportId, EventId, isOutRightEvent}, dataQuery, onUpdateCallback, 10, uniqueName, true);\n }\n\n /**\n * 全局 輪詢獲取 多個 比賽數據 10秒一次\n *\n * @param subscriberName 訂閱者名稱,用來處理重複訂閱的狀況\n * @param onUpdateCallback 輪詢後數據更新回調 (result) => {} result 為 PollingResult格式 {NewData: EventData數組, Changes: EventChangeData 數組}\n * @param EventInfos 要輪詢的比賽,EventInfo數組(支持不同體育項目和 一般/優勝冠軍 賽事混查)\n * @param uniqueName 用來判斷是否使用同一個輪詢,配置不同名字,可以同時開多個輪詢\n */\n getEventsDetailPollingGlobal(subscriberName, onUpdateCallback, EventInfos = [], uniqueName = '') {\n return this._subscribeGlobalPolling('getEventsDetailPolling', subscriberName, onUpdateCallback,{EventInfos}, uniqueName);\n }\n\n /**\n * 輪詢獲取 多個 比賽數據 10秒一次\n *\n * @param onUpdateCallback 輪詢後數據更新回調 (result) => {} result 為 PollingResult格式 {NewData: EventData數組, Changes: EventChangeData 數組}\n * @param EventInfos 要輪詢的比賽,EventInfo數組(支持不同體育項目和 一般/優勝冠軍 賽事混查)\n * @param uniqueName 用來判斷是否使用同一個輪詢,配置不同名字,可以同時開多個輪詢\n */\n getEventsDetailPolling(onUpdateCallback, EventInfos = [], uniqueName = '') {\n const dataQuery = () => this.getEventsDetail(EventInfos);\n return this._registerPolling('getEventsDetailPolling', {EventInfos}, dataQuery, onUpdateCallback, 10, uniqueName);\n }\n\n /**\n *\n * 聯賽搜尋,返回為SearchSportData數組\n *\n * @param keyword 關鍵字\n */\n async search(keyword) {\n if (!keyword || keyword.length <=0) {\n return [];\n }\n\n //檢查單個特殊符號\n if (keyword.length === 1) {\n const regex = /^[\\~\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)\\-\\_\\+\\=\\{\\}\\[\\]\\|\\\\\\:\\;\\\"\\'\\<\\,\\>\\.\\?\\/]$/gm;\n if (regex.exec(keyword) !== null) {\n return [];\n }\n }\n\n //加速:從緩存中優先獲取數據\n const cachedResultKey = 'search@' + keyword;\n const cachedResult = this._cacheGet(cachedResultKey , null);\n if (cachedResult) {\n return cachedResult;\n }\n\n let searchResult = await this._APIs.search(keyword);\n\n //大小寫不敏感\n const keywordUpper = keyword.toUpperCase();\n const keywordLower = keyword.toLowerCase();\n\n let sportDataMap = {};\n let leagueDataMap = {};\n //由數據生成 體育->聯賽->賽事\n if (searchResult && searchResult.Competitions && searchResult.Competitions.length > 0) {\n //因為查詢結果可能會返回不相關數據(可能時間也當關鍵字搜尋),只保留名稱符合的\n let leagueDatas = []\n for(let l of searchResult.Competitions){\n const existInLeagueName = (l.CompetitionName.indexOf(keyword) >= 0) || (l.CompetitionName.indexOf(keywordUpper) >= 0) || (l.CompetitionName.indexOf(keywordLower) >= 0);\n let cloneLeagueData = JSON.parse(JSON.stringify(l));\n if (existInLeagueName) {\n leagueDatas.push(cloneLeagueData); //聯賽名稱符合 就直接使用\n } else {\n if (l.Events && l.Events.length > 0) {\n const matchedEvents = l.Events.filter(ev => {\n const names = [ev.HomeTeam, ev.AwayTeam];\n const matchNames = names.filter(n =>\n (n.indexOf(keyword) >= 0) || (n.indexOf(keywordUpper) >= 0) || (n.indexOf(keywordLower) >= 0)\n )\n return (matchNames && matchNames.length > 0);\n });\n cloneLeagueData.Events = matchedEvents;\n leagueDatas.push(cloneLeagueData);\n }\n }\n }\n\n //獲取體育名和排序,因為search的events沒有返回體育名稱,只能自己拿\n let sportInfoMap = {};\n const sportCountData = await this._APIs.getAllSportCount();\n if (sportCountData && sportCountData.SportCount && sportCountData.SportCount.length > 0){\n sportCountData.SportCount.map(scd => {\n const thisId = parseInt(scd.SportId);\n sportInfoMap[thisId] = { name: scd.SportName, order: scd.OrderNumber};\n })\n }\n\n for (const l of leagueDatas) {\n const thisSportId = parseInt(l.SportId);\n let thisSportData = sportDataMap[thisSportId];\n if (!thisSportData) {\n const thisSportInfo = sportInfoMap[thisSportId] ?? { name: 'not set', order: 99999 };\n thisSportData = new SearchSportData(thisSportId, thisSportInfo.name, thisSportInfo.order, []);\n sportDataMap[thisSportId] = thisSportData;\n }\n\n const thisLeagueId = l.CompetitionId;\n let thisLeagueData = leagueDataMap[thisLeagueId];\n if (!thisLeagueData) {\n thisLeagueData = new SearchLeagueData(thisLeagueId, l.CompetitionName, 0,thisSportId, []);\n leagueDataMap[thisLeagueId] = thisLeagueData;\n thisSportData.Leagues.push(thisLeagueData);\n }\n\n if (l.Events && l.Events.length > 0) {\n const eventDatas = l.Events.map(ev => {\n return new SearchEventData(\n ev.EventId, ev.EventDate,\n 0, ev.HomeTeam, 0, ev.AwayTeam,\n thisSportId,thisLeagueId\n )\n })\n\n if (eventDatas && eventDatas.length > 0) {\n thisLeagueData.Events = eventDatas;\n }\n }\n }\n }\n\n //排除下面沒有比賽的聯賽,並把object數據轉為數組\n let sportDatas = [];\n for(let prop in sportDataMap) {\n let thisSportData = sportDataMap[prop];\n thisSportData.Leagues = thisSportData.Leagues.filter(l => l.Events && l.Events.length > 0)\n if (thisSportData.Leagues && thisSportData.Leagues.length > 0) {\n sportDatas.push(thisSportData);\n }\n }\n\n if (sportDatas.length > 0) {\n//排序 by DisplayOrder 小到大\n const compareDisplayOrder = (a,b) => {\n if (a.DisplayOrder < b.DisplayOrder ) {\n return -1; //小于 0 ,那么 a 会被排列到 b 之前\n }\n if (a.DisplayOrder > b.DisplayOrder) {\n return 1; //大于 0 , b 会被排列到 a 之前。\n }\n return 0;\n }\n sportDatas.sort(compareDisplayOrder); //排序體育\n //sportDatas.map(spd => spd.Leagues.sort(compareDisplayOrder)) //排序聯賽 //IM沒提供聯賽排序順序,不排\n\n //排序 by EventDate 近到遠\n const compareEventDate = (a,b) => {\n const mA = a.getEventDateMoment();\n const mB = b.getEventDateMoment();\n\n if (mA.isBefore(mB)) {\n return -1; //小于 0 ,那么 a 会被排列到 b 之前\n }\n if (mA.isAfter(mB)) {\n return 1; //大于 0 , b 会被排列到 a 之前。\n }\n return 0;\n }\n\n sportDatas.map(spd => spd.Leagues.map(l => l.Events.sort(compareEventDate))) //排序比賽\n }\n\n this._cacheSet(cachedResultKey,sportDatas, 3*60); //加速:緩存3分\n\n return sportDatas;\n }\n\n\n //獲取投注前(檢查)信息,返回為PollingResult格式,支持比對數據變化\n async getBetInfo(wagerType = WagerType.SINGLE, Selections = []) {\n //語法糖支持:單注改為數組\n if (wagerType === WagerType.SINGLE && !Array.isArray(Selections)) {\n Selections = [Selections];\n }\n //檢查單注\n if (wagerType === WagerType.SINGLE && Selections.length !== 1 ) {\n throw new VendorError(VendorErrorType.DATA_Error,null, { info: 'single bet but multi selection?'});\n } else {\n //串關檢查\n //一個賽事(Event)只能選一個 投注選項(Selection)\n let eventTmp = [];\n let multiEvents = [];\n Selections.map(item => {\n if (eventTmp.indexOf(item.EventId) === -1) {\n eventTmp.push(item.EventId);\n } else {\n multiEvents.push(item);\n }\n });\n\n if (multiEvents.length > 0) {\n throw new VendorError(VendorErrorType.BET_Selection_Parlay_Error, null, {info: multiEvents})\n }\n }\n\n //後面有過濾,過濾完再取,會不正確 在這裡先存下\n const SelectionIds = Selections.map(item => item.SelectionId);\n\n let notOpenParlySelections = []; //先記錄起來,最後要返回\n let notEUSelections = [];\n if(wagerType === WagerType.COMBO) {\n //IM串關需要過濾未開放串關的投注選項\n notOpenParlySelections = Selections.filter(s => !s.IsOpenParlay);\n const openParlaySelections = Selections.filter(s => s.IsOpenParlay);\n Selections = openParlaySelections;\n\n //IM串關需要全部轉為歐洲盤\n const MemberType = this._getMemberType(); //水位\n const euSelections = Selections.map(sel => SelectionData.clone(sel, IMOddsType.EU, MemberType));\n //過濾掉沒有成功轉為歐洲盤的選項\n notEUSelections = euSelections.filter(s => s.OddsType !== IMOddsType.EU).map(s => {\n const copy = JSON.parse(JSON.stringify(s));\n copy.SelectionStatus = SelectionStatusType.EUODDSONLY; //設置為歐洲盤限定\n return SelectionData.clone(copy) //利用clone重新配置數據\n })\n Selections = euSelections.filter(s => s.OddsType === IMOddsType.EU); //換成歐洲盤\n }\n\n //過濾完之後可能Selections會沒數據\n let newData = null\n if (Selections && Selections.length > 0) {\n //轉成IM格式\n const IMSelectionInfos = Selections.map(item => item.toIMBetInfo());\n newData = await this._APIs.getBetInfo(wagerType, IMSelectionInfos)\n .then(jsonData => {\n let betSettings = jsonData.BetSetting.map(item => {\n return new BetSettingData(\n item.MinStakeAmount,\n item.MaxStakeAmount,\n item.EstimatedPayoutAmount,\n item.ComboSelection,\n item.NoOfCombination,\n 'im',\n )\n });\n\n //過濾掉不認識的玩法(ComboTypeName為undefined)\n if (betSettings && betSettings.length > 0) {\n betSettings = betSettings.filter(bs => bs.ComboTypeName);\n if (wagerType === WagerType.COMBO) { //串關會返回單注的投注法,這邊用不到,去掉\n betSettings = betSettings.filter(item => item.ComboType != 0);\n }\n }\n\n let newSelections = [];\n if (!jsonData.WagerSelectionInfos || (Array.isArray(jsonData.WagerSelectionInfos) && jsonData.WagerSelectionInfos.length <= 0)) {\n //處理已結束比賽WagerSelectionInfos返回為空數組的問題\n //直接使用傳入的Selections參數去返回\n newSelections = Selections.map(item => {\n //設置為不可用\n const copy = JSON.parse(JSON.stringify(item));\n copy.SelectionStatus = SelectionStatusType.NOTAVIILABLE; //設置為不可用\n return SelectionData.clone(copy) //利用clone重新配置數據\n })\n } else {\n newSelections = Selections.map(sourceSelectionData => {\n //注意不能使用WagerSelectionId=SelectionId去判斷,api返回之後有可能會變,只能用EventId去對\n const targetWagerSelectionInfos = jsonData.WagerSelectionInfos.filter(wsi => sourceSelectionData.EventId == wsi.EventId);\n if (targetWagerSelectionInfos && targetWagerSelectionInfos.length > 0) {\n //有對應的返回數據\n let item = targetWagerSelectionInfos[0];\n if (parseInt(item.Market) === 0) {\n item.Market = sourceSelectionData.MarketId;\n }\n\n const MarketName = VendorMarketNames[item.Market];\n\n const oddsDeciaml = Decimal.clone({rounding: 3}) //無條件捨去\n\n return new SelectionData(\n item.WagerSelectionId ? item.WagerSelectionId : sourceSelectionData.SelectionId,\n sourceSelectionData.IsOutRightEvent ? item.OutrightTeamId : item.BetTypeSelectionId,\n sourceSelectionData.SelectionName,\n sourceSelectionData.SelectionGroup,\n sourceSelectionData.Handicap, //展示用\n item.Handicap, //投注用\n item.Specifiers,\n item.SportId,\n item.Market,\n MarketName,\n sourceSelectionData.LeagueId,\n sourceSelectionData.LeagueName,\n sourceSelectionData.HomeTeamId,\n sourceSelectionData.HomeTeamName,\n item.HomeScore,\n sourceSelectionData.AwayTeamId,\n sourceSelectionData.AwayTeamName,\n item.AwayScore,\n item.EventId,\n sourceSelectionData.IsOpenParlay,\n item.MarketlineId,\n sourceSelectionData.BetTypeId,\n sourceSelectionData.BetTypeName,\n sourceSelectionData.PeriodId,\n sourceSelectionData.PeriodName,\n sourceSelectionData.TargetTeamId,\n sourceSelectionData.TargetTeamName,\n sourceSelectionData.IsOutRightEvent,\n sourceSelectionData.OutRightEventName,\n item.Odds,\n item.OddsType,\n sourceSelectionData.OddsList.map(oddsItem => {\n return new OddsData(\n oddsItem.OddsType,\n oddsItem.OddsValues,\n )\n }),\n new oddsDeciaml(item.Odds).toFixed(2),\n item.MarketlineStatusId,\n item.Status === 381 ? 100 : item.Status, //當作賠率沒有變化,反正投注的時候還會檢查\n )\n } else {\n //找不到就直接複製,然後設置為不可用\n const copy = JSON.parse(JSON.stringify(sourceSelectionData));\n copy.SelectionStatus = SelectionStatusType.NOTAVIILABLE; //設置為不可用\n return SelectionData.clone(copy) //利用clone重新配置數據\n }\n })\n }\n\n //IM串關 補回之前過濾掉的投注選項(不支持串關+不是歐洲盤)\n if (wagerType === WagerType.COMBO) {\n if (notOpenParlySelections && notOpenParlySelections.length > 0) {\n newSelections = newSelections.concat(notOpenParlySelections);\n }\n if (notEUSelections && notEUSelections.length > 0) {\n newSelections = newSelections.concat(notEUSelections);\n }\n }\n\n return BetInfoData.createFromIMSource(\n betSettings.length > 0 ? betSettings : null, //考慮statusCode = 350 會返回空的betSetting\n newSelections,\n )\n });\n\n } else {\n //Selections為空 不用查 直接返回\n\n let newSelections = [];\n //IM串關 補回之前過濾掉的投注選項(不支持串關+不是歐洲盤)\n if (wagerType === WagerType.COMBO) {\n if (notOpenParlySelections && notOpenParlySelections.length > 0) {\n newSelections = newSelections.concat(notOpenParlySelections);\n }\n if (notEUSelections && notEUSelections.length > 0) {\n newSelections = newSelections.concat(notEUSelections);\n }\n }\n\n newData = BetInfoData.createFromIMSource(\n null,\n newSelections,\n )\n }\n\n //注意這裡拿到的newData的BetSettings和Selections都是數組型態\n\n //處理 可用投注方式(betSetting) 為空 的問題(只有單注需要如此處理,串關 直接不展示串關方式就行 )\n if(wagerType === WagerType.SINGLE && !newData.BetSettings) {\n newData.Selections = newData.Selections.map(item => {\n //如果有可用的 投注選項,設置為更新中(總之就是不給投注)\n if (item.SelectionStatus === SelectionStatusType.OK) {\n const copy = JSON.parse(JSON.stringify(item));\n copy.SelectionStatus = SelectionStatusType.UPDATING; //設置為更新中\n return SelectionData.clone(copy) //利用clone重新配置數據\n } else {\n return item;\n }\n });\n }\n\n //語法糖支持:單注返回單個Object,串關才返回數組\n if (wagerType === WagerType.SINGLE) {\n newData = new BetInfoData(\n (newData.BetSettings && newData.BetSettings.length >0) ? newData.BetSettings[0] : null,\n null,\n (newData.Selections && newData.Selections.length >0) ? newData.Selections[0] : null,\n )\n }\n\n //比對新舊差異\n const deltaKey = this._getDeltaKey('getBetInfo', {wagerType, SelectionIds});\n const oldData = this._APIDeltas[deltaKey];\n let changes = [];\n if (oldData) {\n //語法糖支持:單注返回單個Object,串關才返回數組\n if (wagerType === WagerType.SINGLE) {\n const oldItem = oldData.Selections;\n const newItem = newData.Selections;\n if (JSON.stringify(oldItem) !== JSON.stringify(newItem)) { //有變化才提交change\n changes.push(new SelectionChangeData(oldItem.SelectionId, oldItem, newItem))\n }\n } else {\n oldData.Selections.map(oldItem => {\n const newSelections = newData.Selections.filter(newItem => newItem.SelectionId === oldItem.SelectionId);\n if (newSelections && newSelections.length > 0) {\n const newItem = newSelections[0];\n if (JSON.stringify(oldItem) !== JSON.stringify(newItem)) { //有變化才提交change\n changes.push(new SelectionChangeData(oldItem.SelectionId, oldItem, newItem))\n }\n }\n })\n }\n }\n\n //保存查詢結果\n this._APIDeltas[deltaKey] = newData;\n\n return new PollingResult(newData, changes);\n }\n\n\n /**\n * 輪詢獲取投注前(檢查)信息 10秒一次\n *\n * 注意\n * 1. 一次只能一個單注/串關,所以 多個單注 需要分開調用這個接口\n * 2. 一個比賽 同時只能選一個投注選項,後面選的要覆蓋之前的\n * 3. EventData.IsOpenParlay === true 才可以加入串關\n *\n * @param onUpdateCallback 輪詢後數據更新回調 (result) => {} result 為 PollingResult格式 {NewData: 單個BetInfoData數據, Changes: SelectionChangeData 數組}\n * @param wagerType 下注方式,1單注 2串關\n * @param Selections 格式,如果下注方式 選擇1單注,直接傳入SelectionData ,如果是2串關,則傳入SelectionData數組\n * @param uniqueName 用來判斷是否使用同一個輪詢,配置不同名字,可以同時開多個輪詢\n * @returns 輪詢key\n */\n getBetInfoPolling(onUpdateCallback, wagerType = WagerType.SINGLE, Selections = [], uniqueName = '') {\n const dataQuery = () => this.getBetInfo(wagerType, Selections);\n //存在多個同時調用,不可以互相覆蓋,需要用下注參數添加 uniqueName\n let array_selections = Selections;\n if (!Array.isArray(Selections)) {\n array_selections = [Selections];\n }\n const selectionIds = array_selections.map(s => s.SelectionId);\n const selectionIdJoins = selectionIds.join('|');\n const betInfo_and_uniqueName = wagerType + '_' + selectionIdJoins + '_' + uniqueName;\n return this._registerPolling('BETINFO', {wagerType, Selections}, dataQuery, onUpdateCallback, 10, betInfo_and_uniqueName);\n }\n\n //輪詢 滾球注單狀態 緩存,目前只拿來記錄重試次數\n _getWagerStatusCache = {}\n\n //輪詢 滾球注單狀態\n async _getWagerStatusPolling(wagerId, testFuncs = [], maxRetryCount = 30, uniqueName = ''){\n const thisCacheKey = wagerId + uniqueName;\n this._getWagerStatusCache[thisCacheKey] = {retryCount:0};\n return new Promise(resolve => {\n const query = () => {\n this._APIs.getPendingWagerStatus([wagerId])\n .then(async jsonData => {\n if (jsonData.StatusCode === 370) { //接口返回找不到注單\n //改查詢未結算注單\n const betListJsonData = await this._APIs.getBetList([IMWagerStatus.PENDING,IMWagerStatus.CONFIRMED,IMWagerStatus.REJECTED,IMWagerStatus.CANCELLED])\n if (betListJsonData.WagerList && betListJsonData.WagerList.length > 0) {\n const targets = betListJsonData.WagerList.filter(w => w.WagerId === wagerId)\n if (targets && targets.length > 0 ) {\n const target = targets[0];\n for(let testf of testFuncs) {\n if (testf.func(target)) {\n delete this._getWagerStatusCache[thisCacheKey]\n console.log('_getWagerStatusPolling', testf.status , jsonData)\n return resolve({status:testf.status, data: target}); //成功\n }\n }\n }\n }\n }\n if (jsonData.PendingWagerStatusList && jsonData.PendingWagerStatusList.length > 0) {\n const targets = jsonData.PendingWagerStatusList.filter(item => item.WagerID === wagerId);\n if (targets && targets.length > 0) {\n const target = targets[0];\n for(let testf of testFuncs) {\n if (testf.func(target)) {\n delete this._getWagerStatusCache[thisCacheKey]\n console.log('_getWagerStatusPolling', testf.status , jsonData)\n return resolve({status:testf.status, data: target}); //成功\n }\n }\n }\n }\n if (this._getWagerStatusCache[thisCacheKey].retryCount < maxRetryCount) {\n this._getWagerStatusCache[thisCacheKey].retryCount = this._getWagerStatusCache[thisCacheKey].retryCount +1;\n console.log('_getWagerStatusPolling', 'RETRY', this._getWagerStatusCache[thisCacheKey] , jsonData)\n setTimeout(query, 1000); //建議一秒一次\n } else {\n delete this._getWagerStatusCache[thisCacheKey]\n console.log('_getWagerStatusCache', 'EXPIRE' , jsonData)\n return resolve({status:'EXPIRE', data: jsonData}); //超時\n }\n })\n };\n\n query();\n });\n }\n\n /**\n * 投注,返回為 BetResultData 格式\n * 注意需要async開頭 不然前面丟出來的VendorError 會需要try...catch去接,更麻煩\n *\n * @param wagerType 下注方式,1單注 2串關\n * @param betInfoData BetInfoData 格式,從getBetInfo獲取的,\n * @param betAmount 下注金額\n * @param comboType 串關類型,選填,默認單注填0,串關需要從BetInfoData裡面的BetSettingData數組 選擇一個\n * @param forceAcceptAnyOdds 強制接受所有賠率變更 默認false\n */\n async placeBet(wagerType = WagerType.SINGLE, betInfoData, betAmount, comboType = 0,forceAcceptAnyOdds = false) {\n //語法糖支持:單注改為數組\n let selections = betInfoData.Selections;\n if (wagerType === WagerType.SINGLE && !Array.isArray(selections)) {\n selections = [selections];\n }\n //檢查單注\n if (wagerType === WagerType.SINGLE && selections.length !== 1) {\n throw new VendorError(VendorErrorType.DATA_Error,null, { info: 'single bet but multi selection?'});\n }\n\n //檢查串關類型(ComboType),必須從BetInfoData裡面的BetSettingData/SystemParlayBetSettings數組 選擇一個\n if(wagerType === WagerType.COMBO) {\n const selectedBetSettings = betInfoData.BetSettings.filter(item => item.ComboType === comboType);\n const selectedSystemBetSettings = betInfoData.SystemParlayBetSettings.filter(item => item.ComboType === comboType);\n if (selectedBetSettings.length <=0 && selectedSystemBetSettings.length <=0) {\n throw new VendorError(VendorErrorType.DATA_Error,null, { info: 'comboType incorrect'});\n }\n\n //selections需要過濾 只留下 支持串關 和 狀態正常的選項\n selections = betInfoData.getSelectionsForCombo();\n }\n\n //轉成IM格式\n const IMWagerSelections = selections.map(item => item.toIMWager());\n const IMComboSelections = [{ComboSelection: comboType, StakeAmount: betAmount}];\n\n const alwaysAcceptBetterOdds = this.getMemberSetting().alwaysAcceptBetterOdds;\n\n //兩種配置 接受全部變化(false) 跟 只接受賠率上升(true)\n let isAcceptAnyOdds = !alwaysAcceptBetterOdds;\n //強制接受賠率變更\n if (forceAcceptAnyOdds) {\n isAcceptAnyOdds = true;\n }\n\n //日志用\n const postJSON = { WagerType:wagerType, WagerSelectionInfos: IMWagerSelections, ComboSelections:IMComboSelections, IsComboAcceptAnyOdds:isAcceptAnyOdds};\n\n return this._APIs.placeBet(wagerType, IMWagerSelections, IMComboSelections, isAcceptAnyOdds)\n .then(async jsonData => {\n //不管是不是串關,都只會有一個WagerSelectionInfos返回\n const wagerSelectionInfo = jsonData.WagerSelectionInfos[0];\n\n // 加速投注:移除pending等待\n // //處理pending,需要等待成單或拒絕\n // if (wagerSelectionInfo && (wagerSelectionInfo.BetConfirmationStatus === 1)) {\n // const betResult = await this._getWagerStatusPolling(wagerSelectionInfo.WagerId,\n // [\n // { status:'OK' ,func: (data) => data.BetConfirmationStatus === 2}, //確認\n // { status:'REJECT', func: (data) => data.BetConfirmationStatus === 3}, //拒絕\n // { status:'CANCEL', func: (data) => data.BetConfirmationStatus === 4}, //取消\n // ],60\n // );\n //\n // if (betResult.status === 'OK') {\n // wagerSelectionInfo.BetConfirmationStatus = 2; //狀態改為確認\n // } else if (betResult.status === 'EXPIRE') { //特別處理超時\n // throw new VendorError(VendorErrorType.BET_Place_Expire, null, {info: betResult})\n // } else {\n // throw new VendorError(VendorErrorType.BET_Place_Error, null, {info: betResult})\n // }\n // }\n\n const isPending = wagerSelectionInfo && (wagerSelectionInfo.BetConfirmationStatus === 1);\n let pendingQueryId = null;\n if (isPending) {\n pendingQueryId = wagerSelectionInfo.WagerId;\n }\n\n return new BetResultData(\n jsonData.AvailableBalance,\n wagerSelectionInfo.WagerId,\n wagerSelectionInfo.BetConfirmationStatus,\n parseInt(wagerSelectionInfo.BetStatusMessage),\n isPending,\n pendingQueryId,\n wagerSelectionInfo.ComboSelectionId,\n wagerSelectionInfo.EstimatedPayoutFullAmount,\n jsonData.AcceptedWagerSelectionList.map(item => {\n return new BetSelectionResultData(\n item.EventId,\n item.StakeOdds,\n item.BetTypeSelectionId,\n )\n }),\n JSON.stringify({ request: postJSON, response:jsonData }),\n )\n });\n }\n\n /**\n * 查詢pending bet 的投注結果\n *\n * @param pendingQueryId\n */\n async queryPendingBetStatus(pendingQueryId) {\n\n const betResult = await this._getWagerStatusPolling(pendingQueryId,\n [\n { status:'OK' ,func: (data) => data.BetConfirmationStatus === 2}, //確認\n { status:'REJECT', func: (data) => data.BetConfirmationStatus === 3}, //拒絕\n { status:'CANCEL', func: (data) => data.BetConfirmationStatus === 4}, //取消\n ],60\n );\n\n if (betResult.status === 'EXPIRE') { //特別處理超時\n return new BetStatusData(\n betResult.status === 'OK',\n pendingQueryId,\n 1, //超時當作待確認\n )\n } else {\n return new BetStatusData(\n betResult.status === 'OK',\n pendingQueryId,\n betResult.data.BetConfirmationStatus,\n )\n }\n }\n\n /**\n * 查詢未結算注單,返回為WagerData數組\n */\n getUnsettleWagers(){\n return this._APIs.getBetList()\n .then(async jsonData => {\n let wagerDatas = jsonData.WagerList.map(item => {\n return WagerData.createFromIMSource(item);\n })\n\n if (wagerDatas && wagerDatas.length > 0) {\n let EventIdMap = {};\n //按sportId: [leagueId] 去分組\n let groupedQueryParams = {};\n wagerDatas.map(item => {\n if (item.WagerItems && item.WagerItems.length > 0) {\n item.WagerItems.map(ii => {\n if (!groupedQueryParams[ii.SportId]) {\n groupedQueryParams[ii.SportId] = [];\n }\n if (groupedQueryParams[ii.SportId].indexOf(ii.LeagueId) === -1) {\n groupedQueryParams[ii.SportId].push(ii.LeagueId);\n }\n if (!EventIdMap[ii.EventId]) {\n EventIdMap[ii.EventId] = true;\n }\n })\n }\n })\n\n let prs = [];\n for(let sid in groupedQueryParams) {\n const lids = groupedQueryParams[sid];\n const pr = this._APIs.getLiveResults(sid,lids) //查詢現場賽果\n prs.push(pr);\n }\n\n await Promise.all(prs).then(resultArray => {\n let matchedResults = {};\n resultArray.map(jsonData => {\n const lresults = jsonData.LiveResults;\n if (lresults && lresults.length>0) {\n lresults.map(item => {\n //只取有用到的比賽數據\n if (EventIdMap[item.EventId]) {\n\n //處理滾球時間(從eventData抄來的)\n let rbMinute = '';\n let rbPeriod = '';\n if (item.RBTime) {\n //有空白 表示為 1H 12:34 這種格式\n const blankIndex = item.RBTime.indexOf(' ');\n if (blankIndex !== -1) {\n const toIndex = item.RBTime.indexOf(':');\n if (toIndex !== -1) {\n const minuteLength = toIndex - blankIndex - 1;\n if (blankIndex >= 0 && minuteLength > 0) {\n rbMinute = item.RBTime.substr(blankIndex + 1, minuteLength);\n }\n } else { //沒有帶秒數的,直接切分鐘\n if (blankIndex >= 0) {\n rbMinute = item.RBTime.substr(blankIndex + 1);\n }\n }\n if (blankIndex >= 0) {\n rbPeriod = item.RBTime.substr(0, blankIndex);\n }\n } else if(item.RBTime.length === 2) {\n rbPeriod = item.RBTime;\n }\n\n if (rbPeriod && rbPeriod.length > 0) {\n const rbname = IMRBPeriodNames[rbPeriod]; //中文名\n if (rbname) {\n rbPeriod = rbname; //有對到才用中文名,沒對到 就直接用原本的字\n }\n }\n }\n\n matchedResults[item.EventId] = {\n RBMinute:rbMinute,\n RBPeriodName:rbPeriod,\n RBHomeScore:item.HomeScore,\n RBAwayScore:item.AwayScore\n };\n }\n })\n }\n })\n\n if (JSON.stringify(matchedResults) != '{}') {\n\n //console.log('====matchedResults',matchedResults);\n\n wagerDatas.map(item => {\n if (item.WagerItems && item.WagerItems.length > 0) {\n item.WagerItems.map(ii => {\n if (matchedResults[ii.EventId]) {\n const thisR = matchedResults[ii.EventId];\n ii.IsRB = true;\n ii.RBMinute = thisR.RBMinute;\n ii.RBPeriodName = thisR.RBPeriodName;\n ii.RBHomeScore = thisR.RBHomeScore;\n ii.RBAwayScore = thisR.RBAwayScore;\n }\n });\n }\n })\n }\n });\n\n }\n return wagerDatas;\n })\n }\n\n /**\n * 輪詢未結算注單 10秒一次\n *\n * @param onUpdateCallback 輪詢後數據更新回調 (result) => {} result 為 PollingResult格式 {NewData:SportData數組, Changes:空數組}\n * @param uniqueName 用來判斷是否使用同一個輪詢,配置不同名字,可以同時開多個輪詢\n */\n getUnsettleWagersPolling(onUpdateCallback, uniqueName = '') {\n const dataQuery = () => this.getUnsettleWagers();\n return this._registerPolling('getUnsettleWagersPolling',{}, dataQuery, onUpdateCallback, 10, uniqueName, true);\n }\n\n /**\n * 提交 提前兌現\n * @param wagerData 要提前兌現的投注,WagerData格式\n */\n async cashOut(wagerData) {\n let cloneWagerData = WagerData.clone(wagerData); //複製一份\n\n //日志用\n const postJSON = { WagerId:wagerData.WagerId, BuyBackPricing:wagerData.CashOutPrice, PricingId:wagerData.CashOutPriceId }\n\n return this._APIs.submitBuyBack(wagerData.WagerId, wagerData.CashOutPrice, wagerData.CashOutPriceId)\n .then(jsonData => {\n //更新結果\n cloneWagerData.CashOutStatus = (jsonData.PricingId && jsonData.BuyBackPricing) ? CashOutStatusType.DONE : CashOutStatusType.FAIL;\n if (cloneWagerData.CashOutStatus == CashOutStatusType.DONE) {\n cloneWagerData.CashOutAmount = jsonData.BuyBackPricing;\n }\n return new CashOutResultData(\n cloneWagerData,\n false, //IM不會有pending\n null,\n JSON.stringify({ request: postJSON, response:jsonData }),\n )\n })\n .catch(async error => {\n if (typeof error === 'object' && error.isVendorError === true) {\n //特別處理新價格 IM是價格過期(error code:367)\n if (error.ErrorType === VendorErrorType.CASHOUT_NEWPRICE) {\n\n //日誌用\n let newPriceJSON = null;\n\n //查詢提前兌現delta 獲取新價格\n const newPriceInfo = await this._APIs.getDeltaBetTrade([cloneWagerData.WagerId])\n .then(jsonData => {\n //日誌用\n newPriceJSON = JSON.parse(JSON.stringify(jsonData));\n //注意這個數據結構和文件寫的不一樣\n //實際Value是在DeltaChanges[]裡面,而且是一個json string,需要額外處理parse\n if (jsonData && jsonData.DeltaChanges && jsonData.DeltaChanges[0] && jsonData.DeltaChanges[0].Value) {\n const srcData = jsonData.DeltaChanges[0].Value\n let thisData = srcData;\n if (typeof thisData === 'string') {\n thisData = JSON.parse(srcData);\n }\n //檢查新價格\n if (\n //新價格狀態 數據要對\n thisData.BetTradeStatus == CashOutStatusType.NOTYET\n && thisData.CanSell\n && thisData.PricingId\n && thisData.BuyBackPricing\n //新價格要有變化,沒變化直接返回空,視為失敗\n && thisData.PricingId != cloneWagerData.CashOutPriceId\n && thisData.BuyBackPricing != cloneWagerData.CashOutPrice\n ) {\n return {\n PricingId: thisData.PricingId,\n BuyBackPricing: thisData.BuyBackPricing,\n }\n } else {\n return null;\n }\n }\n })\n .catch(error => {\n //只是避免往外丟出錯誤\n return null;\n })\n\n if (newPriceInfo) {\n //更新價格\n cloneWagerData.CashOutStatus = CashOutStatusType.NEWPRICE;\n cloneWagerData.CashOutPriceId = newPriceInfo.PricingId;\n cloneWagerData.CashOutPrice = newPriceInfo.BuyBackPricing;\n } else {\n //沒有獲取到新價格 就視為失敗\n cloneWagerData.CashOutStatus = CashOutStatusType.FAIL;\n }\n return new CashOutResultData(\n cloneWagerData,\n false, //IM不會有pending\n null,\n JSON.stringify({ request: postJSON, response: {newPrice: newPriceJSON} }),\n )\n }\n }\n //所有其他錯誤直接視為失敗\n cloneWagerData.CashOutStatus = CashOutStatusType.FAIL;\n return new CashOutResultData(\n cloneWagerData,\n false, //IM不會有pending\n null,\n JSON.stringify({ request: postJSON, response: {error: error} }),\n )\n })\n }\n\n /**\n * 提交 提前兌現 拒絕新價格\n * @param wagerData 要拒絕提前兌現的投注,WagerData格式\n */\n async cashOutDeclineNewOffer(wagerData) {\n return true; //IM不用實現這個\n }\n\n /**\n * 查詢已結算注單,返回為WagerData數組\n * IM用的是投注時間\n *\n * @param StartDate 開始日期 YYYY-MM-DD 格式 默認今天\n * @param EndDate 結束日期 YYYY-MM-DD 格式 默認今天\n * @param WagerSortWay\n */\n getSettledWagers(StartDate = moment().format('YYYY-MM-DD'), EndDate = moment().format('YYYY-MM-DD'), WagerSortWay = IMWagerSortWay.BETDATE){\n //im注單需要轉為-4時間去查詢\n const startDateWithTZ = moment(StartDate + ' 00:00:00').utcOffset(-4);\n const endDateWithTZ = moment(EndDate + ' 23:59:59').utcOffset(-4);\n\n return this._APIs.getStatement(\n startDateWithTZ.format('YYYY-MM-DD'),endDateWithTZ.format('YYYY-MM-DD')\n ,startDateWithTZ.format('HH:mm:ss'),endDateWithTZ.format('HH:mm:ss')\n ,WagerSortWay\n )\n .then(jsonData => {\n return jsonData.WagerList.map(item => {\n return WagerData.createFromIMSource(item);\n })\n })\n }\n\n //獲取用戶配置\n getMemberSetting() {\n let result = super.getMemberSetting();\n\n //把oddsType轉為IM格式\n result.oddsType = IMOddsType[result.oddsType];\n\n //debug\n // result.oddsType = IMOddsType.EU;\n\n return result;\n }\n\n /**\n * 獲取供應商公告\n */\n getAnnouncements() {\n return this._APIs.getAnnouncement()\n .then(jsonData => {\n //考慮沒有數據的情況,返回空數組\n if (!jsonData.Announcement || jsonData.Announcement.length <= 0) {\n return [];\n }\n\n return jsonData.Announcement.map(item=> {\n\n const postingDate = moment(item.PostingDate).utcOffset(VendorConfigs.TIMEZONE).format('YYYY/MM/DD HH:mm');\n\n return new AnnouncementData(\n item.AnnouncementId,\n item.AnnouncementDetail[0].Content,\n postingDate,\n {PostingDate:item.PostingDate, ExpiryDate: item.ExpiryDate, UpdateDate: item.DateUpdated}\n );\n });\n });\n }\n}\n\nconst vendorIMSingleton = new VendorIM();\nif (typeof window !== \"undefined\") {\n window.VendorIMInstance = vendorIMSingleton;\n}\n\nexport default vendorIMSingleton;\n"],"names":["promiseWithTimeout","targetPromise","timeout","timeoutMsg","timeout_fn","timeout_promise","Promise","resolve","reject","timeout_handler","setTimeout","abortable_promise","race","then","result","clearTimeout","VendorIM","_instance","_APIDeltas","MaxParlay","VendorName","VendorPage","EventIdType","HasLeagueIcon","HasTeamIcon","HasCashOut","_APIs","getAllSportCount","IsCombo","_imFetch","getAllCompetitionCount","SportId","IMSports","Market","VendorMarkets","IncludeCloseEvent","getEventInfoMBT","BetTypeIds","IMBetType","MarketlineLevels","EventGroupTypeIds","getDeltaEventInfoMBT","Delta","getMLInfoOBT","getDeltaMLInfoOBT","getEventInfoBYPAGE","Page","PageRecords","OrderBy","getSelectedEventInfo","EventIds","OddsType","IMOddsType","IncludeGroupEvents","getVSEventInfo","Season","MatchDay","getDeltaVSEventInfo","getVSEventDetails","EventId","getOutRightEvents","getDeltaOutRightEventInfo","getLiveResults","ViewingCompetitionIds","search","filter","getLocalizations","LocalizationType","IMLocalizationType","ALL","getDeltaLocalizations","getCompletedResults","EventTypeId","IMEventType","StartDate","EndDate","logOut","getBetInfo","WagerType","SINGLE","Selections","WagerSelectionInfos","placeBet","ComboSelections","IsComboAcceptAnyOdds","CustomerIP","ServerIP","getBetList","BetConfirmationStatus","IMWagerStatus","getStatement","StartTime","EndTime","DateType","IMWagerSortWay","getBalance","getPendingWagerStatus","WagerIds","getAnnouncement","getMemberByToken","getUserPreferences","getDeltaBetTrade","submitBuyBack","WagerId","BuyBackPricing","PricingId","getLiveStreamingInfo","_DeltaAPIMapping","GETEVENTINFOMBT","GETDELTAEVENTINFOMBT","GETMLINFOOBT","GETDELTAMLINFOOBT","GETVSEVENTINFO","GETDELTAVSEVENTINFO","GETOUTRIGHTEVENTS","GETDELTAOUTRIGHTEVENTINFO","GETLOCALIZATIONS","GETDELTALOCALIZATIONS","_supportLoginAPIs","GETEVENTINFOBYPAGE","GETSELECTEDEVENTINFO","LOGOUT","GETBETINFO","PLACEBET","GETBETLIST","GETSTATEMENT","GETBALANCE","GETPENDINGWAGERSTATUS","GETMEMBERBYTOKEN","GETUSERPREFERENCES","UPDATEUSERPREFERENCES","GETFAVOURITEEVENT","ADDFAVOURITEEVENT","REMOVEFAVOURITEEVENT","GETDELTABETTRADE","SUBMITBUYBACK","_getWagerStatusCache","_getUID","thisKey","thisUID","vendorStorage","newUID","uuidv4","_getLoginInfo","token","JSON","parse","memberCode","memberType","_getMemberType","thisMemberType","_queryIMmemberType","loginInfo","this","params","_getTimestamp","fetchParams","method","headers","Accept","body","stringify","url","HostConfig","fetch","response","json","jsonData","SpreadGroup","catch","e","console","log","getTokenFromGateway","getTokenFromGatewayImpl","_checkAndWaitLogin","loginPromise","r","key","md5","currentTimeStamp","moment","utcOffset","format","aes","mode","ecb","padding","pkcs7","iv","ciphertext","toString","base64","_getDeltaKey","name","params4md5","Object","assign","paramsMD5","ClearDeltaCache","apiName","deltaName","thisDeltaKey","vendorSettings","queryPromise","retryCount","originAPIName","originParams","that","thisQueryPromise","delta","full","thisUuid","length","uuid","cachedKey","clonedParams","cachedJsonData","cachedInfo","Date","getTime","expTime","data","StatusCode","IMAPIStatus","isDeltaQuery","deltaKey","cacheObject","thiserror","VendorError","StatusDesc","thisRetryCount","error","errorInfo","parseInt","BetStatusMessage","getSports","favEvents","getFavouriteEvents","SportDatas","SportCount","map","item","targetEventGroup","favEventsForThisSport","favItem","EventGroupTypes","SportData","SportName","Count","MarketData","VendorMarketNames","RBFECount","TodayFECount","EarlyFECount","ORCount","PollingResult","getLeagues","MarketId","CompetitionCount","LeagueData","CompetitionId","CompetitionName","getEvents","sortWay","SortWays","startDate","endDate","MemberType","favEventIdsForThisSport","favEventInfos","getMemberSetting","oddsType","fe","EventInfo","IsOutRightEvent","getEventsDetail","pr","existEventIds","AllEventDatas","notExistEventIds","hasDeletedFavourite","NewData","Lines","l","s","index","BetTypeId","updateLineGroupCount","indexOf","removeFavouriteEvent","window","eventListing_updateSportsCount","configs","_getOutRightEvents","EventDatas","cloneEventDatas","SavedEventDatas","deleteEventIds","EventChanges","DeletedEventIds","Sports","Events","EventData","ed","IsFavourite","DeltaChanges","Action","IMDeltaAction","push","EventChangeData","EventChangeType","existEvents","existItem","newEventSource","Value","newEvent","change","ChangeType","event","targetIndex","NewValue","Changes","filteredEvents","EventDateLocal","filteredChanges","sortLines","eventIds","ForListing","RemoveChanges","InsertUpdateChanges","RemoveEvent","InsertUpdateEvent","concat","ec","getEventsPaged","page","pageRecords","pagedDataOrderBy","eventDatas","getPreCacheEventsFromCacheAPI","events","ev","getEUROCUP202021Events","cahceKey","oldDatas","changes","newEventIds","oldEventMap","eurocup202021","_cacheGet","oev","_cacheSet","getEventDetail","isOutRightEvent","mainEvents","eventData","oldEventData","eventChanges","thisEventData","EventGroupTypeId","IMMergeSideEvents","IMSortLinesAndSelections","isVendorError","ErrorType","VendorErrorType","EventInfos","eventIdsBySportAndOutRight","promiseArr","sportId","outright","outrightPromise","normal","normalPromise","Array","isArray","all","PRsArray","getSportsPollingGlobal","subscriberName","onUpdateCallback","uniqueName","_subscribeGlobalPolling","getSportsPolling","dataQuery","_registerPolling","getEventsPollingGlobal","getEventsPolling","favPromise","isAPIServer","runningPromise","todayPromise","values","prFav","prRunning","prToday","runningEvents","runningChanges","todayEvents","todayChanges","runningAndTodayEvents","runningAndTodayChanges","currentFavEvents","currentFavEventsForThisSport","currentFavEventIdsForThisSport","thisFavEventIds","extraFavEventIds","extraFavEvents","deletedFavEventIds","favChanges","evid","fev","MarketIdForListing","preCacheQuery","APIEventsPollingWithAutoClean","callWithAutoClean","imPollingKey","firstTime","thisPollingKey","deletePolling","getEUROCUP202021EventsPollingGlobal","getEUROCUP202021EventsPolling","getEventDetailPolling","getEventsDetailPollingGlobal","getEventsDetailPolling","keyword","cachedResultKey","cachedResult","searchResult","keywordUpper","keywordLower","sportDataMap","leagueDataMap","leagueDatas","existInLeagueName","cloneLeagueData","matchedEvents","sportInfoMap","sportCountData","sportDatas","prop","thisSportData","compareDisplayOrder","compareEventDate","exec","toUpperCase","toLowerCase","Competitions","matchNames","HomeTeam","AwayTeam","n","scd","thisId","order","OrderNumber","thisSportId","thisSportInfo","SearchSportData","thisLeagueId","thisLeagueData","SearchLeagueData","Leagues","SearchEventData","EventDate","a","b","DisplayOrder","sort","mA","getEventDateMoment","mB","isBefore","isAfter","spd","wagerType","eventTmp","multiEvents","SelectionIds","notOpenParlySelections","notEUSelections","openParlaySelections","euSelections","newData","IMSelectionInfos","newSelections","oldData","oldItem","newItem","info","SelectionId","IsOpenParlay","sel","SelectionData","copy","SelectionStatus","SelectionStatusType","toIMBetInfo","betSettings","BetSetting","BetSettingData","MinStakeAmount","MaxStakeAmount","EstimatedPayoutAmount","ComboSelection","NoOfCombination","bs","ComboTypeName","ComboType","sourceSelectionData","targetWagerSelectionInfos","wsi","MarketName","oddsDeciaml","Decimal","rounding","WagerSelectionId","OutrightTeamId","BetTypeSelectionId","SelectionName","SelectionGroup","Handicap","Specifiers","LeagueId","LeagueName","HomeTeamId","HomeTeamName","HomeScore","AwayTeamId","AwayTeamName","AwayScore","MarketlineId","BetTypeName","PeriodId","PeriodName","TargetTeamId","TargetTeamName","OutRightEventName","Odds","OddsList","oddsItem","OddsData","OddsValues","toFixed","MarketlineStatusId","Status","BetInfoData","BetSettings","SelectionChangeData","getBetInfoPolling","array_selections","selectionIds","selectionIdJoins","join","betInfo_and_uniqueName","_getWagerStatusPolling","wagerId","testFuncs","maxRetryCount","thisCacheKey","query","betListJsonData","targets","target","testf","WagerList","w","func","status","PendingWagerStatusList","WagerID","betInfoData","betAmount","comboType","forceAcceptAnyOdds","selections","selectedBetSettings","selectedSystemBetSettings","IMWagerSelections","IMComboSelections","alwaysAcceptBetterOdds","isAcceptAnyOdds","postJSON","SystemParlayBetSettings","getSelectionsForCombo","toIMWager","StakeAmount","wagerSelectionInfo","isPending","pendingQueryId","BetResultData","AvailableBalance","ComboSelectionId","EstimatedPayoutFullAmount","AcceptedWagerSelectionList","BetSelectionResultData","StakeOdds","request","queryPendingBetStatus","betResult","BetStatusData","getUnsettleWagers","wagerDatas","EventIdMap","groupedQueryParams","prs","sid","lids","WagerData","WagerItems","ii","resultArray","matchedResults","lresults","LiveResults","rbMinute","rbPeriod","RBTime","blankIndex","toIndex","minuteLength","substr","rbname","IMRBPeriodNames","RBMinute","RBPeriodName","RBHomeScore","RBAwayScore","thisR","IsRB","getUnsettleWagersPolling","cashOut","wagerData","cloneWagerData","CashOutPrice","CashOutPriceId","CashOutStatus","CashOutStatusType","CashOutAmount","CashOutResultData","newPriceJSON","newPriceInfo","srcData","thisData","BetTradeStatus","CanSell","newPrice","cashOutDeclineNewOffer","getSettledWagers","WagerSortWay","startDateWithTZ","endDateWithTZ","getAnnouncements","Announcement","postingDate","PostingDate","VendorConfigs","AnnouncementData","AnnouncementId","AnnouncementDetail","Content","ExpiryDate","UpdateDate","DateUpdated","VendorBase","vendorIMSingleton","VendorIMInstance"],"sourceRoot":""}