李勇

新建的项目

# exclude all
/*
# project structure
!/src/
!/etc/
!/docs/
!/test/
# project files
!.gitignore
!README.md
!package.json
!LICENSE
!webpack.config.umd.js
... ...
# DOCS FOLDER
... ...
#CONF FOLDER
... ...
<!DOCTYPE html>
<html>
<head>
<title>学点云课堂</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="stylesheet" href="stylesheets/style.css"/>
</head>
<body style="visibility: hidden ">
<div class="container">
<div class="video_container">
<div class="video_wrapper">
<div id="video_mask"></div>
<div id="video_div"
class="hide">
<video id="video"
autoplay
autostart
poster="./images/waiting.jpg"
controls
playsinline
webkit-playsinline>
该设备不支持HTML5/VIDEO标签播放.
</video>
</div>
<div id="btn_video"
style="display: none;"></div>
<div id="btn_document"
style="display: none;"></div>
<div id="live_document_container"
style="display: none;">
<div>
<div class="document_none">
<div class="text-center document_image"></div>
<p class="text-center">
矮油,还没有文档共享哦~
</p>
</div>
<div class="list_sliders">
<div class="slideWrapper">
<img class="slide">
</div>
<div class="docAnno"></div>
</div>
</div>
<div class="document_pager dn">
<p class="text-center">0/1</p>
</div>
</div>
</div>
</div>
<div class="content_container">
<ul id="tabmenu_list"
style="margin: 0;"
class="nav nav-tabs"
role="tablist">
<li role="chat"
class="active">
<a role="tab" data-toggle="tab-message">聊天</a>
</li>
<li role="doc">
<a role="tab" data-toggle="tab-board">文档</a>
</li>
<li role="detail">
<a role="tab" data-toggle="tab-detail">详情</a>
</li>
</ul>
<div class="tab_container">
<div role="tab-message"
class="tab_body tab_message active">
<div class="tab_body_container">
<div id="panel_message"
data-empty="true"
class="message_container">
<p class="h5 text-center"
style="color: #666;">
暂未收到消息
</p>
</div>
</div>
</div>
<div role="tab-board"
class="tab_body">
<div class="tab_body_container">
<div class="document_none">
<div class="text-center document_image"></div>
<p class="text-center">
矮油,还没有文档共享哦~
</p>
</div>
<div class="list_sliders">
<div class="slideWrapper">
<img class="slide">
</div>
<div class="docAnno"></div>
</div>
</div>
<div id="document_pager"
class="document_pager dn">
<p class="text-center">
0/1
</p>
</div>
</div>
<div role="tab-detail"
class="tab_body">
<div class="tab_body_container">
<div id="detail_wrapper"
class="detail_wrapper"></div>
</div>
</div>
<div class="input_container">
<div class="input_wrapper"
style="overflow: hidden;">
<div class="btn_more"></div>
<div class="btn_face"></div>
<div style="float: right; width: 60px;">
<button id="btn_send"
type="submit"
class="btn btn-primary">
发送
</button>
</div>
<div style="margin:0 84px 0 85px;">
<input id="txt_message"
type="text"
class="form-control"
maxlength="20" onkeyup="this.value=this.value.replace(/^ +| +$/g,'')">
</div>
</div>
</div>
</div>
</div>
<div class="panel_more"
style="display: none;">
<div class="masker"></div>
<div class="panel_inner">
<div class="list_buttons">
<ul>
<li class="btn_layout"
data-layout="live">
<div>
直播布局
</div>
</li>
<li class="btn_night">
<div>
夜间模式
</div>
</li>
</ul>
<div class="btn_close">
<span></span>
</div>
</div>
</div>
</div>
<div class="list_faces"
style="display: none;">
<div class="list_faces_scroller">
<ul>
<li><img data-src="images/face/aimu.gif" data-type="aimu">
</li>
<li><img data-src="images/face/daxiao.gif" data-type="daxiao">
</li>
<li><img data-src="images/face/huaixiao.gif" data-type="huaixiao">
</li>
<li><img data-src="images/face/liuhan.gif" data-type="liuhan">
</li>
<li><img data-src="images/face/shuijiao.gif" data-type="shuijiao">
</li>
<li><img data-src="images/face/yiwen.gif" data-type="yiwen">
</li>
<li><img data-src="images/face/aoman.gif" data-type="aoman">
</li>
<li><img data-src="images/face/jiew.gif" data-type="jiew">
</li>
<li><img data-src="images/face/liulei.gif" data-type="liulei">
</li>
<li><img data-src="images/face/sun.gif" data-type="sun">
</li>
<li><img data-src="images/face/youhh.gif" data-type="youhh">
</li>
<li><img data-src="images/face/baiyan.gif" data-type="baiyan">
</li>
<li><img data-src="images/face/fadai.gif" data-type="fadai">
</li>
<li><img data-src="images/face/jingkong.gif" data-type="jingkong">
</li>
<li><img data-src="images/face/meiyan.gif" data-type="meiyan">
</li>
<li><img data-src="images/face/tiaoxie.gif" data-type="tiaoxie">
</li>
<li><img data-src="images/face/yue.gif" data-type="yue">
</li>
<li><img data-src="images/face/baoquan.gif" data-type="baoquan">
</li>
<li><img data-src="images/face/fanu.gif" data-type="fanu">
</li>
<li><img data-src="images/face/jingya.gif" data-type="jingya">
</li>
<li><img data-src="images/face/mojing.gif" data-type="mojing">
</li>
<li><img data-src="images/face/touxiao.gif" data-type="touxiao">
</li>
<li><img data-src="images/face/yumen.gif" data-type="yumen">
</li>
<li><img data-src="images/face/bishi.gif" data-type="bishi">
</li>
<li><img data-src="images/face/fendou.gif" data-type="fendou">
</li>
<li><img data-src="images/face/kafei.gif" data-type="kafei">
</li>
<li><img data-src="images/face/piezui.gif" data-type="piezui">
</li>
<li><img data-src="images/face/tu.gif" data-type="tu">
</li>
<li><img data-src="images/face/yun.gif" data-type="yun">
</li>
<li><img data-src="images/face/bizui.gif" data-type="bizui">
</li>
<li><img data-src="images/face/ganga.gif" data-type="ganga">
</li>
<li><img data-src="images/face/kelian.gif" data-type="kelian">
</li>
</ul>
<ul>
<li><img data-src="images/face/pijiu.gif" data-type="pijiu">
</li>
<li><img data-src="images/face/weiqu.gif" data-type="weiqu">
</li>
<li><img data-src="images/face/zaijian.gif" data-type="zaijian">
</li>
<li><img data-src="images/face/cahan.gif" data-type="cahan">
</li>
<li><img data-src="images/face/guai.gif" data-type="guai">
</li>
<li><img data-src="images/face/koubi.gif" data-type="koubi">
</li>
<li><img data-src="images/face/qiang.gif" data-type="qiang">
</li>
<li><img data-src="images/face/weixiao.gif" data-type="weixiao">
</li>
<li><img data-src="images/face/zancheng.gif" data-type="zancheng">
</li>
<li><img data-src="images/face/cool.gif" data-type="cool">
</li>
<li><img data-src="images/face/guzhang.gif" data-type="guzhang">
</li>
<li><img data-src="images/face/kuaikl.gif" data-type="kuaikl">
</li>
<li><img data-src="images/face/qinqin.gif" data-type="qinqin">
</li>
<li><img data-src="images/face/woshou.gif" data-type="woshou">
</li>
<li><img data-src="images/face/zhemo.gif" data-type="zhemo">
</li>
<li><img data-src="images/face/dabing.gif" data-type="dabing">
</li>
<li><img data-src="images/face/hanxiao.gif" data-type="hanxiao">
</li>
<li><img data-src="images/face/kulou.gif" data-type="kulou">
</li>
<li><img data-src="images/face/qiu.gif" data-type="qiu">
</li>
<li><img data-src="images/face/xigua.gif" data-type="xigua">
</li>
<li><img data-src="images/face/zhouma.gif" data-type="zhouma">
</li>
<li><img data-src="images/face/daku.gif" data-type="daku">
</li>
<li><img data-src="images/face/haqi.gif" data-type="haqi">
</li>
<li><img data-src="images/face/kun.gif" data-type="kun">
</li>
<li><img data-src="images/face/ruo.gif" data-type="ruo">
</li>
<li><img data-src="images/face/xin.gif" data-type="xin">
</li>
<li><img data-src="images/face/zuohh.gif" data-type="zuohh">
</li>
<li><img data-src="images/face/dangao.gif" data-type="dangao">
</li>
<li><img data-src="images/face/hua.gif" data-type="hua">
</li>
<li><img data-src="images/face/lianhong.gif" data-type="lianhong">
</li>
<li><img data-src="images/face/shuai.gif" data-type="shuai">
</li>
<li><img data-src="images/face/yinxian.gif" data-type="yinxian">
</li>
</ul>
</div>
<div class="list_faces_paginator">
<b class="selected"></b>
<b></b>
</div>
</div>
<div class="dlg_login"
style="display: none;">
<div class="masker"></div>
<div class="dlg_inner">
<div class="dlg_title">
<p style="font-size: 22px; color: #fff;">
Welcome!
</p>
<p style="font-size: 12px; color: #ccc;">
欢迎进入直播互动课堂
</p>
</div>
<div class="dlg_content">
<p class="txt_username">
<input type="text" class="form-control" placeholder="请输入您的姓名" maxlength="20" />
</p>
<p class="txt_password">
<input type="text" class="form-control" placeholder="请输入课堂密码" maxlength="20" />
</p>
<p>
<button id="btn_login" class="btn_login">
进入教室
</button>
</p>
</div>
</div>
</div>
<div class="tip_panel"
style="display: none;">
用户名或者密码错误!
</div>
</div>
<div class="tip_message"
style="display: none;"></div>
<div id="online_users"
style="display: none;">
0人在线
</div>
</body>
</html>
... ...
{
"name": "",
"version": "1.0.1",
"description": "McuClient on H5",
"main": "dist/main.js",
"directories": {
"doc": "docs",
"test": "test"
},
"scripts": {
"test": "test/index.js"
},
"keywords": [
"LiveClass"
],
"author": "www.3mang.com",
"license": "MIT",
"dependencies": {
"base64-js": "^1.2.0",
"es6-promise": "^3.2.1",
"iscroll": "^5.2.0",
"jquery": "^3.1.0",
"jquery-touchswipe": "^1.6.15",
"protobufjs": "^5.0.1",
"string.fromcodepoint": "^0.2.1",
"url-parse": "^1.1.1",
"utf-8": "^1.0.0",
"whatwg-fetch": "^1.0.0",
"zlibjs": "^0.2.0"
},
"wbp": {
"project": "umd",
"entries": {
"main": "./MessageEngine.js"
},
"source": "src/",
"build": "dist/"
}
}
\ No newline at end of file
... ...
export default class Emiter {
constructor() {
this.MAPS = {};
}
on(eid, elistener) {
if (eid && elistener) {
let stub = this.MAPS[eid];
if (!stub) {
return this.MAPS[eid] = [elistener];
}
stub.push(elistener);
}
}
off(eid, elistener) {
if (eid) {
let stub = this.MAPS[eid];
if (stub) {
if (elistener) {
return stub.splice(stub.indexOf(elistener), 1);
}
stub.length = 0;
}
}
}
emit(eid, data) {
if (eid) {
//eid=* broadcast
let asteriskStub = this.MAPS['*'];
if (asteriskStub && asteriskStub.length) {
asteriskStub.forEach(function (elistener) {
elistener(eid, data);
})
}
// eid= normal
let stub = this.MAPS[eid];
if (stub && stub.length) {
stub.forEach(function (elistener) {
elistener(data);
});
}
}
}
}
... ...
// //////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2016-present
// All Rights Reserved.
//
// Author: AlexWang
// Date: 2016-08-27 21:40:49
// Last Modified by: AlexWang
// Last Modified time: 2016-12-05 12:02:48
// QQ Email: 1669499355@qq.com
// Description: 底层Socket管理器,保持一直在线及异常重连.
//
// //////////////////////////////////////////////////////////////////////////////
import Emiter from 'Emiter';
import Loger from 'Loger';
let loger = Loger.getLoger('EverSocket');
class EverSocket extends Emiter {
constructor() {
super();
this._connected = false;
this._lastActiveTime = 0;
this._enableEverSocket = false;
}
begin(ip, port) {
loger.log('开始WebSocket应用.');
this._enableEverSocket = true;
this.wsURL = 'ws://' + ip + ':' + port;
this._newConnection();
}
end() {
loger.log('停止WebSocket应用.');
this._clear();
}
get connected() {
return this._connected;
}
send(data) {
if (this._connected) {
loger.log('SEND MESSAGE---->');
this.websocket.send(data);
} else {
loger.warn('WebSocket未建立连接.消息忽略');
}
}
_setConnected(isConn = true) {
this._connected = isConn;
if (this._connected) {
this.emit(EverSocket.OPEN);
} else {
this.emit(EverSocket.CLOSED);
}
}
_newConnection() {
this.websocket = new WebSocket(this.wsURL);
this.websocket.binaryType = 'arraybuffer';
this.websocket.onopen = this._onOpen.bind(this);
this.websocket.onclose = this._onClose.bind(this);
this.websocket.onerror = this._onError.bind(this);
this.websocket.onmessage = this._onMessage.bind(this);
}
_reConnection() {
this._clear();
this.reConnectionTimeout = window.setTimeout(() => {
loger.log('WebSocket重新建立.');
window.clearTimeout(this.reConnectionTimeout);
this._newConnection();
}, EverSocket.RECONN_INTERVAL);
}
_clear() {
loger.log('WebSocket,Timers销毁');
window.clearInterval(this.pingTimer);
window.clearInterval(this.pongTimer);
this.websocket.onopen = undefined;
this.websocket.onclose = undefined;
this.websocket.onerror = undefined;
this.websocket.onmessage = undefined;
try {
this.websocket.close();
} catch (e) {
loger.log('ignore errors');
}
this.websocket = undefined;
this._enableEverSocket = false;
this._setConnected(false);
}
_onOpen() {
loger.log('WebSocket建立成功', this.wsURL);
//this.pingTimer = window.setInterval(this._sendPingHandler.bind(this), EverSocket.PING_INTERVAL);
//this.pongTimer = window.setInterval(this._checkPongHandler.bind(this), EverSocket.PONG_INTERVAL);
this._setConnected();
}
_onClose(closeEvent) {
loger.log(`WebSocket连接断开 CODE:${closeEvent.code} REASON:${closeEvent.reason} CLEAN: ${closeEvent.wasClean}`, this.wsURL);
this._reConnection();
}
_onError() {
loger.log('WebSocket错误出现');
this._connected = false;
this._reConnection();
}
_onMessage(messageEvent) {
loger.log('<----RECEIVE MESSAGE');
this._lastActiveTime = Date.now();
const bufferData = messageEvent.data;
if (bufferData.byteLength > 0) {
this.emit(EverSocket.MESSAGE, bufferData);
}
}
_sendPingHandler() {
if (this._connected) {
this.websocket.send(new ArrayBuffer);
} else {
this._reConnection();
}
}
_checkPongHandler() {
let pongTime = Date.now();
if (this._lastActiveTime &&
this._lastActiveTime >= pongTime - EverSocket.PONG_INTERVAL &&
this._lastActiveTime <= pongTime
) {} else {
loger.warn('---服务器PINGPONG超时-----');
this._reConnection();
}
}
}
EverSocket.prototype.PONG_INTERVAL = EverSocket.PONG_INTERVAL = 5000;
EverSocket.prototype.PING_INTERVAL = EverSocket.PING_INTERVAL = 3000;
EverSocket.prototype.RECONN_INTERVAL = EverSocket.RECONN_INTERVAL = 2000;
EverSocket.prototype.CONNECTING = EverSocket.CONNECTING = 0;
EverSocket.prototype.OPEN = EverSocket.OPEN = 1;
EverSocket.prototype.CLOSING = EverSocket.CLOSING = 2;
EverSocket.prototype.CLOSED = EverSocket.CLOSED = 3;
EverSocket.prototype.MESSAGE = EverSocket.MESSAGE = 4;
export default new EverSocket();
... ...
// //////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2016-present All Rights Reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// http://www.apache.org/licenses/LICENSE-2.0
//
// Github Home: https://github.com/AlexWang1987
// Author: AlexWang
// Date: 2016-08-27 22:58:47
// QQ Email: 1669499355@qq.com
// Last Modified time: 2016-08-27 23:05:53
// Description: LiveClass-Loger
//
// //////////////////////////////////////////////////////////////////////////////
class Loger {
constructor(info) {
this.info = info || '';
this.id = this.initId();
}
initId() {
const infoType = this.info.constructor.name.toLowerCase();
if (infoType === 'string') {
return this.info;
}
if (infoType === 'object') {
return this.info.mid || '';
}
return '';
}
log(...msg) {
this._log(Loger.LOG, msg);
}
warn(...msg) {
this._log(Loger.WARN, msg);
}
error(...msg) {
this._log(Loger.ERROR, msg);
}
_log(type, msg) {
msg = JSON.stringify(msg);
let logMsg = `${this.id} -> ${msg}`;
if (type >= Loger.logLevel) {
switch (type) {
case Loger.LOG:
console.log(logMsg);
break;
case Loger.WARN:
console.warn(logMsg);
break;
case Loger.ERROR:
console.error(logMsg);
break;
}
}
}
}
Loger.LOG = 0;
Loger.WARN = 1;
Loger.ERROR = 2;
Loger.NO = Infinity;
Loger.logLevel = Loger.LOG;
export default {
getLoger: function getLoger(info) {
return new Loger(info);
},
setLogLevel: function setLogLevel(logLevel) {
Loger.logLevel = logLevel;
},
LOG: Loger.LOG,
WARN: Loger.WARN,
ERROR: Loger.ERROR,
NO: Loger.NO,
};
... ...
import Emiter from './Emiter';
import h5Sass from 'Sass';
import mcu from 'mcu';
import MessageTypes from 'MessageTypes';
import Loger from 'Loger';
import ConferApe from 'apes/ConferApe';
import ChatApe from 'apes/ChatApe';
import VideoChat from 'apes/VideoApe';
import DocApe from 'apes/DocApe';
import WhiteBoardApe from 'apes/WhiteBoardApe';
let loger = Loger.getLoger('MessageEngine');
export default class MessageEngine extends Emiter {
constructor() {
super();
// 应用层会议信息
this.confInfo = null;
// Sass平台层
this.h5Sass = h5Sass;
this.h5Sass.on('*', (type, data) => this.emit(type, data));
this.h5Sass.on(h5Sass.SUCCESS, this._h5SassSuccessHandler.bind(this));
// 底层MCU消息层
this.mcu = mcu;
this.mcu.on('*', (type, data) => this.emit(type, data));
this.mcu.on(MessageTypes.CONFERENCE_JOIN_SUCCESS, this._conferenceJoinSuccessHandler.bind(this));
// 注册所有应用Ape
this.conferApe = new ConferApe();
this.conferApe.on('*', (type, data) => this.emit(type, data));
this.conferApe.on(MessageTypes.DOC_SWITCH, this.docSwitchHandler.bind(this));
this.chat_ape = new ChatApe();
this.chat_ape.on('*', (type, data) => this.emit(type, data));
this.video_ape = new VideoChat();
this.video_ape.on('*', (type, data) => this.emit(type, data));
this.doc_ape = new DocApe();
this.doc_ape.on('*', (type, data) => this.emit(type, data));
this.doc_ape.on(MessageTypes.DOC_UPDATE, this.docUpdateHandler.bind(this));
this.doc_ape.on(MessageTypes.DOC_DEL, this.docDeleteHandler.bind(this));
this.wb_ape = new WhiteBoardApe();
this.wb_ape.on('*', (type, data) => this.emit(type, data));
this.wb_ape.on(MessageTypes.ANNO_UPDATE, this.annoUpdateHandler.bind(this));
this.on(MessageTypes.DOC_SHOW, this.docShowHandler.bind(this));
}
// 白板笔记更新
annoUpdateHandler(annoInfo) {
const activeDocId = this.conferApe.activeDocId;
const docItem = this.doc_ape.docList[activeDocId];
if (docItem && annoInfo.id == docItem.wbid) {
this.emit(MessageTypes.DOC_ANNO, annoInfo);
}
}
// 文档变更-笔记处理
docShowHandler(docItem) {
loger.log('Doc Show ->' + docItem.id + '|' + docItem.curPageNo);
const annoInfo = this.wb_ape.annoInfos[docItem.wbid];
if (annoInfo) {
this.emit(MessageTypes.DOC_ANNO, annoInfo);
} else {
this.emit(MessageTypes.DOC_ANNO);
}
}
// 文档切换
docSwitchHandler() {
const activeDocId = this.conferApe.activeDocId;
loger.log('Switch Doc Active -> ' + activeDocId);
const docItem = this.doc_ape.docList[activeDocId];
if (docItem) {
this.emit(MessageTypes.DOC_SHOW, docItem);
}
}
// 文档变更
docUpdateHandler(docItem) {
loger.log('Doc UpdateId ->' + docItem.id + '| activeDocId ->' + this.conferApe.activeDocId);
if (docItem.id == this.conferApe.activeDocId) {
this.emit(MessageTypes.DOC_SHOW, docItem);
}
}
//文档删除
docDeleteHandler(docItem){
if (docItem.id == this.conferApe.activeDocId) {
this.emit(MessageTypes.DOC_DEL, docItem);
}
}
// MCU 会议成功
_conferenceJoinSuccessHandler() {
this.h5Sass.getClassDetail();
}
// 通过SASS平台验证
_h5SassSuccessHandler() {
loger.log('加入底层MCU会议.');
this.mcu.joinMCU(this.confInfo);
}
// 进入会议
joinClass(_confInfo) {
this.confInfo = _confInfo;
this.h5Sass.sassChecking(_confInfo);
}
// 离开会议
leaveClass() {
this.mcu.leaveMCU();
}
// 参会处理
conferenceHandler(msg_type) {
var msg = {
type: msg_type,
data: null
};
this.emit(msg.type, msg);
}
// 发送聊天消息
sendChatMsg(to, msg) {
if (this.chat_ape) {
this.chat_ape.sendChatMsg(to, msg);
}
}
}
MessageEngine.MESSAGE_DELAY_TIMMER = 100;
... ...
// //////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2016-present All Rights Reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// http://www.apache.org/licenses/LICENSE-2.0
//
// Github Home: https://github.com/AlexWang1987
// Author: AlexWang
// Date: 2016-08-27 23:04:56
// QQ Email: 1669499355@qq.com
// Last Modified time: 2016-09-07 15:58:29
// Description: LiveClass-MessageTypes
//
// //////////////////////////////////////////////////////////////////////////////
function MessageTypes() {}
MessageTypes.CONFERENCE_SHOW_USERNAME = 'show.name.input';
MessageTypes.CONFERENCE_SHOW_ILLEGAL = 'illegal.user';
MessageTypes.CONFERENCE_SHOW_USERNAME_PASSWORD = 'show.name.pasword.input';
MessageTypes.CONFERENCE_SHOW_WRONG_PASSWORD = 'password.wrong';
MessageTypes.CONFERENCE_JOIN_FAILED = 'join.conference.failed';
MessageTypes.CONFERENCE_JOIN_SUCCESS = 'join.conference.success';
MessageTypes.CONFERENCE_JOIN_FULL = 'full.capacity';
MessageTypes.CONFERENCE_EXIT = 'conference.exit';
MessageTypes.CONFERENCE_JOIN_CONFILICT = 'have.been.logged.elsewhere';
MessageTypes.CONFERENCE_SHOW_DETAIL = 'class_detail.message';
MessageTypes.CONFERENCE_SHOW_ROSTER_NUM = 'roster_num.message';
MessageTypes.NET_ERROR = 'net_error';
MessageTypes.PRO_ERROR = 'pro_error';
MessageTypes.VIDEO_SHOW = 'video.message';
MessageTypes.DOC_SHOW = 'document.message';
MessageTypes.DOC_SWITCH = 'document.switch';
MessageTypes.DOC_UPDATE = 'document.update';
MessageTypes.CHAT_RECEIVE = 'chat.message';
MessageTypes.DOC_ANNO = 'document.anno';
MessageTypes.ANNO_UPDATE = 'anno_update';
MessageTypes.DOC_DEL='document.delete';
MessageTypes.AUDIO_SHOW='audio.message';
export default MessageTypes;
... ...
import Emiter from 'Emiter';
import Loger from 'Loger';
import MessageTypes from 'MessageTypes';
// 日志对象
const loger = Loger.getLoger('H5Sass');
let confInfo = {};
class H5Sass extends Emiter {
constructor() {
super();
}
// Sass校验
sassChecking(_confInfo) {
loger.log('发起Sass校验', _confInfo);
this.confInfo = _confInfo;
// 密码校验
if (this.confInfo.nopassword === 'true') {
return this.sendPWDChecking();
}
// MD5校验
this.sendMD5Checking();
}
// 入会校验
sendPWDChecking() {
let url = `http://${this.confInfo.portal}/3m/getCheckMeetinig.do?siteId=${this.confInfo.siteId}&classId=${this.confInfo.confId}&password=${this.confInfo.password}`;
loger.log('会议密码校验', url);
fetch(url, {
timeout: 5000
})
.then(ret => {
if (ret.status === 200) {
return ret.text();
} else {
loger.error(`会议密码校验-网络异常.状态码:${ret.status}`);
this.emit(MessageTypes.NET_ERROR);
throw '';
}
})
.then(ret => {
if (ret === 'false') {
loger.error(`会议密码校验-失败.`);
return this.emit(MessageTypes.CONFERENCE_SHOW_WRONG_PASSWORD);
}
if (ret === 'true') {
loger.log(`会议密码校验-成功.`);
this.sendMD5Checking();
return
}
loger.error(`会议密码校验-协议异常.`);
this.emit(MessageTypes.PRO_ERROR);
})
.catch(err => {
loger.error(`会议密码校验-异常.状态码:${err}`);
this.emit(MessageTypes.NET_ERROR);
});
}
// 发起入会
sendMD5Checking() {
let url = `http://${this.confInfo.portal}/3m/meeting/md5CheckMeeting.do?siteId=${this.confInfo.siteId}&meetingNumber=${this.confInfo.confId}&userId=${this.confInfo.userId}&userName=${this.confInfo.userName}&userType=${this.confInfo.userType}&nopassword=${this.confInfo.nopassword}&md5=${this.confInfo.md5}`;
loger.log('H5SassMD5校验', url);
fetch(url, {
timeout: 5000
})
.then(ret => {
if (ret.status === 200) {
return ret.json();
} else {
loger.error(`H5SassMD5校验-网络异常.状态码:${ret.status}`);
this.emit(MessageTypes.NET_ERROR);
throw '';
}
})
.then(ret => {
if (ret.flag == "true") {
if (ret.h5_mcu_list) {
let server = ret.h5_mcu_list.split(";")[0];
this.confInfo.MCUServerIP = server.split(":")[0];
this.confInfo.MCUServerPort = server.split(":")[1];
}
this.confInfo.maxVideoChannels = ret.maxVideoChannels;
this.confInfo.maxAudioChannels = ret.maxAudioChannels;
this.confInfo.maxMediaChannels = this.confInfo.maxVideoChannels + this.confInfo.maxAudioChannels;
loger.log('H5Sass校验完成');
this.emit(H5Sass.SUCCESS);
} else {
loger.log('H5SassMD5校验-失败.');
this.emit(MessageTypes.CONFERENCE_JOIN_FAILED);
}
})
.catch(err => {
loger.error(`H5SassMD5校验-异常.状态码:${err}`);
this.emit(MessageTypes.NET_ERROR);
});
}
// 获取会议详情
getClassDetail() {
let url = `http://${this.confInfo.portal}/3m/meeting/getClassH5.do?classNumber=${this.confInfo.confId}`;
loger.log('H5Sass获取Class详情.', url);
fetch(url, {
timeout: 5000
})
.then(ret => {
if (ret.ok) {
return ret.json();
} else {
loger.error(`H5Sass获取Class详情-网络异常.状态码:${ret.status}`);
this.emit(MessageTypes.NET_ERROR);
throw '';
}
})
.then(ret => {
if (ret.errorCode === 0) {
loger.log('H5Sass获取Class详情完成');
this.emit(MessageTypes.CONFERENCE_SHOW_DETAIL, ret);
} else {
loger.warn('H5Sass获取Class详情失败.');
this.emit(MessageTypes.NET_ERROR);
}
})
.catch(err => {
loger.error(`H5Sass获取Class详情异常.状态码:${err}`);
this.emit(MessageTypes.NET_ERROR);
});
}
}
H5Sass.prototype.SUCCESS = H5Sass.SUCCESS = 'h5sass.success';
export default new H5Sass;
... ...
// //////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2016-present All Rights Reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// http://www.apache.org/licenses/LICENSE-2.0
//
// Github Home: https://github.com/AlexWang1987
// Author: AlexWang
// Date: 2016-08-26 11:19:56
// QQ Email: 1669499355@qq.com
// Last Modified time: 2017-01-04 14:38:20
// Description: LiveClass-Ape
//
// //////////////////////////////////////////////////////////////////////////////
import pdu from 'pdu';
import Emiter from 'Emiter';
import mcu from 'mcu';
import Loger from 'Loger';
import MessageTypes from 'MessageTypes';
import ApeConsts from './ApeConsts';
import ArrayBufferUtil from 'libs/ArrayBufferUtil';
import PduConsts from 'pdu/PduConsts';
// 日志对象
const loger = Loger.getLoger('Ape');
export default class Ape extends Emiter {
constructor(
session_id,
session_name,
session_tag
) {
super();
this._session_id = session_id;
this._channel_id = session_id; // session_id === channel_id
this._session_name = session_name;
this._session_tag = session_tag;
this._session_channels = {};
this._adapter_pdu = new pdu['RCAdapterPdu'];
this._confInfo = null;
this._rCArrayBufferUtil = ArrayBufferUtil;
this._apeDelayed = false;
this._apeDelayedMsgs = [];
this._apeDelayedTimer = 0;
//Ape 通用消息处理
this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this));
this.on(pdu.RCPDU_CHANNEL_JOIN_RESPONSE, this._joinChannelHandler.bind(this));
this.on(pdu.RCPDU_REG_ADAPTER, this._pduMessageHandler.bind(this));
// 监听底层MCU会议
this.mcu = mcu;
this.mcu.on(MessageTypes.CONFERENCE_JOIN_SUCCESS, this._mcuConferenceJoinSuccessHandler.bind(this));
this.mcu.registerApe(this);
}
regResponsePduHandler() {
}
// 消息处理
_pduMessageHandler(regBuffer) {
if (this._apeDelayed) {
// this._apeDelayedMsgs.push(regBuffer);
// this._apeDelayedStart();
setTimeout(() => {
this._pduRegAdapterHandler(regBuffer);
}, this._confInfo['mcuDelay'] || 12000);
return;
}
this._pduRegAdapterHandler(regBuffer);
}
// _apeDelayedStart() {
// if (this._apeDelayed && !this._apeDelayedTimer) {
// this._apeDelayedTimer = setInterval(this._delayedMsgHandler.bind(this), this._confInfo['mcuDelay'] || 10000);
// }
// }
// _apeDelayedStop() {
// clearInterval(this._apeDelayedTimer);
// this._apeDelayedTimer = 0;
// }
// // 延迟消息处理
// _delayedMsgHandler() {
// if (this._apeDelayedMsgs.length) {
// this._pduRegAdapterHandler(this._apeDelayedMsgs.pop());
// if (!this._apeDelayedMsgs.length) this._apeDelayedStop();
// }
// }
// 数据同步处理
_pduRegAdapterHandler(regBuffer) {
let regPdu = pdu['RCAdapterPdu'].decode(regBuffer);
let regItems = regPdu.item;
let regItemSize = regItems.length;
loger.log(this._session_name + '数据同步消息.同步条数', regItemSize);
for (var i = 0; i < regItemSize; ++i) {
let regItem = regItems[i];
let regItemType = regItem.type;
let regItemData = regItem.itemData;
if (pdu.RCPDU_REG_UPDATE_OBJ !== regItemType) {
if (pdu.RCPDU_REG_RESPONSE_OBJ == regItemType) {
let regResponsePdu = pdu['RCRegistryResponseObjPdu'].decode(regItemData);
this.regResponsePduHandler(regResponsePdu);
}
// 只处理两种类型
continue;
}
let regUpdatedItem = pdu['RCRegistryUpdateObjPdu'].decode(regItemData);
let sub_type = regUpdatedItem.subType;
let object_id = regUpdatedItem.objId;
let user_data = regUpdatedItem.userData;
loger.log('REG OBJECT EVENT ->', pdu.id2type(sub_type));
switch (sub_type) {
case pdu.RCPDU_REG_ROSTER_INSERT_PDU:
let rosterInsertData = pdu['RCRegstryRosterInsertItemPdu'].decode(user_data);
let rosterInsertItems = rosterInsertData.items;
let rosterInsertItemsLen = rosterInsertItems.length;
for (let i = 0; i < rosterInsertItemsLen; ++i) {
let record = rosterInsertItems[i];
let recordId = record.item_id;
let recordData = pdu['RCNodeInfoRecordPdu'].decode(record.item_data);
this.rosterInsertHandler(recordId, recordData);
}
break;
case pdu.RCPDU_REG_ROSTER_DELETE_PDU:
let rosterDelData = pdu['RCRegistryRosterDeleteItemPdu'].decode(user_data);
this.rosterDelHandler(rosterDelData.nodeId);
break;
case pdu.RCPDU_REG_ROSTER_UPDATE_PDU:
let rosterUpdateData = pdu['RCRegistryRosterUpdateItemPdu'].decode(user_data);
let rosterUpdateItems = rosterUpdateData.items;
let rosterUpdateItemsLen = rosterUpdateItems.length;
for (let i = 0; i < rosterUpdateItemsLen; ++i) {
let node = rosterUpdateItems[i];
let nodeId = node.nodeId;
let nodeData = pdu['RCNodeInfoRecordPdu'].decode(node.nodeData);
this.rosterUpdateHandler(nodeId, nodeData);
}
break;
case pdu.RCPDU_REG_TABLE_INSERT_PDU:
let tableInsertData = pdu['RCRegistryTableInsertItemPdu'].decode(user_data);
let tableInsertItems = tableInsertData.items;
let tableInsertItemsLen = tableInsertItems.length;
for (let i = 0; i < tableInsertItemsLen; ++i) {
let insertItem = tableInsertItems[i];
this.tableInsertHandler(insertItem.owner, insertItem.itemIdx, insertItem.itemData);
}
break;
case pdu.RCPDU_REG_TABLE_DELETE_PDU:
let tableDeleteData = pdu['RCRegistryTableDeleteItemPdu'].decode(user_data);
this.tableDeleteHandler(object_id, tableDeleteData);
break;
case pdu.RCPDU_REG_TABLE_UPDATE_PDU:
let tableUpdateData = pdu['RCRegistryTableUpdateItemPdu'].decode(user_data);
let tableUpdateItems = tableUpdateData.items;
let tableUpdateItemsLen = tableUpdateItems.length;
for (let i = 0; i < tableUpdateItemsLen; ++i) {
let tableItem = tableUpdateItems[i];
this.tableUpdateHandler(tableItem.owner, tableItem.itemIdx, tableItem.itemData);
}
break;
case pdu.RCPDU_REG_QUEUE_UPDATE_PDU:
case pdu.RCPDU_REG_QUEUE_DELETE_PDU:
case pdu.RCPDU_REG_QUEUE_INSERT_PDU:
loger.warn('REG QUEUE ARE IGNORED');
break;
}
}
}
rosterInsertHandler(recordId, recordData) {
loger.warn(this._session_name + ' rosterInsertHandler 应有子类具体覆盖处理.');
}
rosterUpdateHandler(nodeId, nodeData) {
loger.warn(this._session_name + ' rosterUpdateHandler 应有子类具体覆盖处理.');
}
rosterDelHandler(recordData) {
loger.warn(this._session_name + ' rosterDelHandler 应有子类具体覆盖处理.');
}
tableInsertHandler(tableId, record) {
loger.warn(this._session_name + ' tableInsertHandler 应有子类具体覆盖处理.');
}
tableUpdateHandler(ownerId, recordId, recordData) {
loger.warn(this._session_name + ' tableUpdateHandler 应有子类具体覆盖处理.');
}
tableDeleteHandler(tableId, record) {
loger.warn(this._session_name + ' tableDelHandler 应有子类具体覆盖处理.');
}
// 加入Session处理
_joinSessionHandler(data) {
loger.log(this._session_name, ' -> 加入Session');
}
// 加入Channel处理
_joinChannelHandler(data) {
let joinedChannel = pdu['RCChannelJoinResponsePdu'].decode(data);
if (joinedChannel.result === pdu.RET_SUCCESS) {
loger.log(this._session_name, ' -> 加入Channel成功. ChannelId', joinedChannel.requestedChannelId);
this._session_channels[joinedChannel.requestedChannelId] = ApeConsts.CJS_JOINNED;
} else {
loger.log(this._session_name, ' -> 加入Channel失败.', joinedChannel);
}
}
// 依赖的会议创建完毕 - 发起Ape加入
_mcuConferenceJoinSuccessHandler(confInfo) {
loger.log('创建Ape->',
'SessionId',
this._session_id,
'SessionName',
this._session_name,
'SessionTag',
this._session_tag);
// 会议依赖底层会议信息
this._confInfo = confInfo;
var joinSessionPdu = new pdu['RCSessionJoinRequestPdu'];
joinSessionPdu.id = this._session_id;
joinSessionPdu.name = this._session_name;
joinSessionPdu.tag = this._session_tag;
joinSessionPdu.sessionData = this._adapter_pdu.toArrayBuffer();
this.sendUniform(joinSessionPdu, true);
var joinChannelPdu = new pdu['RCChannelJoinRequestPdu'];
joinChannelPdu.initiator = this.mcu.confInfo.nodeId;
joinChannelPdu.channelId = this._session_id;
this.send(joinChannelPdu);
}
// 注册Key对象
registerKey(id, name, tag, user_data) {
let adapterItemPdu = new pdu['RCAdapterItemPdu'];
adapterItemPdu.type = pdu.RCPDU_REG_REGISTER_KEY;
// pack register key pdu
let registerKeyPdu = new pdu['RCRegistryRegisterKeyPdu'];
registerKeyPdu.id = id;
registerKeyPdu.name = name;
registerKeyPdu.tag = tag;
if (user_data.length) {
registerKeyPdu.userData = user_data;
}
adapterItemPdu.itemData = registerKeyPdu.toArrayBuffer();
this._adapter_pdu.item.push(adapterItemPdu);
}
// 注册Object对象
registerObj(type, id, name, tag, owner, user_data) {
let adapterItemPdu = new pdu['RCAdapterItemPdu'];
adapterItemPdu.type = pdu.RCPDU_REG_REGISTER_OBJ;
let registerObjPdu = new pdu['RCRegistryRegisterObjPdu'];
registerObjPdu.type = type;
registerObjPdu.objId = id;
registerObjPdu.name = name;
registerObjPdu.tag = tag;
if (owner) {
registerObjPdu.owner = owner;
}
if (user_data.length) {
registerObjPdu.userData = user_data;
}
adapterItemPdu.itemData = registerObjPdu.toArrayBuffer();
this._adapter_pdu.item.push(adapterItemPdu);
}
send(appPdu) {
loger.log('Ape发送数据NORMAL PDU', appPdu);
let normalPdu = pdu.create_normal_pdu(
appPdu.type,
this._confInfo.nodeId,
this._confInfo.confId,
this._session_id,
this._channel_id,
true,
true,
PduConsts.DP_TOP,
this._confInfo.topNodeID,
PduConsts.SEG_ONCE
);
normalPdu.data = appPdu.toArrayBuffer();
// Mcu发送
this.mcu.send(normalPdu);
}
// 发送当前APE(session uniform包)
sendUniform(appPdu, top) {
loger.log('Ape发送数据UNIFORM PDU', appPdu);
let uniformPdu = pdu.create_uniform_pdu(
appPdu.type,
this._confInfo.nodeId,
this._confInfo.confId,
this._session_id,
top ? ApeConsts.BROADCAST_CHANNEL_ID : this._channel_id,
true,
PduConsts.DP_TOP,
top ? this._confInfo.topNodeID : (appPdu.peer || 0),
PduConsts.SEG_ONCE
);
uniformPdu.data = appPdu.toArrayBuffer();
// Mcu发送
this.mcu.send(uniformPdu);
}
}
... ...
export default function ApeConsts(id) {
for (var type_const in ApeConsts) {
if (ApeConsts[type_const] === id) {
return type_const;
}
}
}
ApeConsts.NR_GUEST = 0;
ApeConsts.NR_NORMAL = 1;
ApeConsts.NR_ADMIN = 2;
ApeConsts.NR_MASTER = 4;
ApeConsts.NR_SLAVE = 8;
ApeConsts.NR_ASSISTANT = 16;
ApeConsts.NR_INVISIBLE = 32;
ApeConsts.INVALIDATE_CHANNEL_ID = -1;
ApeConsts.INVALIDATE_NODE_ID = -1;
// doc update status
ApeConsts.DOCUMENT_LOAD = 0;
ApeConsts.DOCUMENT_DEL = 1;
// RCChannelGrabStatus
ApeConsts.CGS_RELEASED = 0;
ApeConsts.CGS_PENDING = 1;
ApeConsts.CGS_OPENNED = 2;
ApeConsts.CGS_GRABBING = 3;
// defs for common session id
ApeConsts.CONFERENCE_SESSION_ID = 11;
ApeConsts.CHAT_SESSION_ID = 12;
ApeConsts.GIFT_SESSION_ID = 13;
ApeConsts.AUDIO_SESSION_ID = 14;
ApeConsts.VIDEO_SESSION_ID = 15;
ApeConsts.WEBSHARING_SESSION_ID = 16;
ApeConsts.DOCSHARING_SESSION_ID = 17;
ApeConsts.WHITEBOARD_SESSION_ID = 18;
ApeConsts.MEDIA_SESSION_ID = 19;
ApeConsts.SCREENSHARING_SESSION_ID = 20;
ApeConsts.POLL_SESSION_ID = 21;
// defs for common channel id
ApeConsts.BROADCAST_CHANNEL_ID = 0;
ApeConsts.CONFERENCE_CHANNEL_ID = ApeConsts.CONFERENCE_SESSION_ID;
ApeConsts.CHAT_CHANNEL_ID = ApeConsts.CHAT_SESSION_ID;
ApeConsts.GIFT_CHANNEL_ID = ApeConsts.GIFT_SESSION_ID;
ApeConsts.WEBSHARING_CHANNEL_ID = ApeConsts.WEBSHARING_SESSION_ID;
ApeConsts.DOCSHARING_CHANNEL_ID = ApeConsts.DOCSHARING_SESSION_ID;
ApeConsts.WHITEBOARD_CHANNEL_ID = ApeConsts.WHITEBOARD_SESSION_ID;
ApeConsts.MEDIA_CHANNEL_ID = ApeConsts.MEDIA_SESSION_ID;
ApeConsts.SCREENSHARING_CHANNEL_ID = ApeConsts.SCREENSHARING_SESSION_ID;
// defs for common session name
ApeConsts.CONFERENCE_SESSION_NAME = "conference app";
ApeConsts.CHAT_SESSION_NAME = "chat app";
ApeConsts.GIFT_SESSION_NAME = "gift app";
ApeConsts.AUDIO_SESSION_NAME = "audio app";
ApeConsts.VIDEO_SESSION_NAME = "video app";
ApeConsts.WEBSHARING_SESSION_NAME = "web sharing app";
ApeConsts.DOCSHARING_SESSION_NAME = "doc sharing app";
ApeConsts.WHITEBOARD_SESSION_NAME = "whiteboard app";
ApeConsts.MEDIA_SESSION_NAME = "media sharing app";
ApeConsts.SCREENSHARING_SESSION_NAME = "screen sharing app";
// def for common session tag
ApeConsts.CONFERENCE_SESSION_TAG = "con-tag";
ApeConsts.CHAT_SESSION_TAG = "cha-tag";
ApeConsts.GIFT_SESSION_TAG = "gif-tag";
ApeConsts.AUDIO_SESSION_TAG = "aud-tag";
ApeConsts.VIDEO_SESSION_TAG = "vid-tag";
ApeConsts.WEBSHARING_SESSION_TAG = "web-tag";
ApeConsts.DOCSHARING_SESSION_TAG = "doc-tag";
ApeConsts.WHITEBOARD_SESSION_TAG = "wbd-tag";
ApeConsts.MEDIA_SESSION_TAG = "med-tag";
ApeConsts.SCREENSHARING_SESSION_TAG = "scr-tag";
ApeConsts.CONFERENCE_OBJ_ROSTER_ID = ((ApeConsts.CONFERENCE_SESSION_ID << 16) + 1);
ApeConsts.CONFERENCE_OBJ_ROSTER_NAME = "node list";
ApeConsts.CONFERENCE_OBJ_ROSTER_TAG = "node list tag";
ApeConsts.CONFERENCE_OBJ_QUEUE_ID = ((ApeConsts.CONFERENCE_SESSION_ID << 16) + 2);
ApeConsts.CONFERENCE_OBJ_QUEUE_NAME = "mic list";
ApeConsts.CONFERENCE_OBJ_QUEUE_TAG = "mic list tag";
// conference tab pages
ApeConsts.CONFERENCE_OBJ_TABLE_ID = ((ApeConsts.CONFERENCE_SESSION_ID << 16) + 3);
ApeConsts.CONFERENCE_OBJ_TABLE_NAME = "tabbar list";
ApeConsts.CONFERENCE_OBJ_TABLE_TAG = "tabbar list tag";
// owned id list is unique in conference
ApeConsts.CONFERENCE_OBJ_COUNTER_ID = ((ApeConsts.CONFERENCE_SESSION_ID << 16) + 4);
ApeConsts.CONFERENCE_OBJ_COUNTER_NAME = "id list";
ApeConsts.CONFERENCE_OBJ_COUNTER_TAG = "id list tag";
// web sharing objects
ApeConsts.WEBSHARING_OBJ_TABLE_ID = ((ApeConsts.WEBSHARING_SESSION_ID << 16) + 1);
ApeConsts.WEBSHARING_OBJ_TABLE_NAME = "web list";
ApeConsts.WEBSHARING_OBJ_TABLE_TAG = "web list tag";
// doc sharing objects
ApeConsts.DOCSHARING_OBJ_TABLE_ID = ((ApeConsts.DOCSHARING_SESSION_ID << 16) + 1);
ApeConsts.DOCSHARING_OBJ_TABLE_NAME = "doc list";
ApeConsts.DOCSHARING_OBJ_TABLE_TAG = "doc list tag";
// doc sharing objects h5
ApeConsts.DOCSHARING_OBJ_TABLE_ID_H5 = ((ApeConsts.DOCSHARING_SESSION_ID << 16) + 2);
ApeConsts.DOCSHARING_OBJ_TABLE_NAME_H5 = "doc list h5";
ApeConsts.DOCSHARING_OBJ_TABLE_TAG_H5 = "doc list tag h5";
// whiteboard objects
ApeConsts.WHITEBOARD_OBJ_TABLE_ID = ((ApeConsts.WHITEBOARD_SESSION_ID << 16) + 1);
ApeConsts.WHITEBOARD_OBJ_TABLE_NAME = "wbd list";
ApeConsts.WHITEBOARD_OBJ_TABLE_TAG = "wbd list tag";
// media sharing objects
ApeConsts.MEDIA_OBJ_TABLE_ID = ((ApeConsts.MEDIA_SESSION_ID << 16) + 1);
ApeConsts.MEDIA_OBJ_TABLE_NAME = "med list";
ApeConsts.MEDIA_OBJ_TABLE_TAG = "med list tag";
// chat sharing objects
ApeConsts.CHAT_OBJ_TABLE_ID = ((ApeConsts.CHAT_SESSION_ID << 16) + 1);
ApeConsts.CHAT_OBJ_TABLE_NAME = "chat list";
ApeConsts.CHAT_OBJ_TABLE_TAG = "chat list tag";
ApeConsts.AUDIO_OBJ_TABLE_ID = ((ApeConsts.AUDIO_SESSION_ID << 16) + 1);
ApeConsts.AUDIO_OBJ_TABLE_NAME = "audio channel list";
ApeConsts.AUDIO_OBJ_TABLE_TAG = "audio channel list tag";
ApeConsts.VIDEO_OBJ_TABLE_ID = ((ApeConsts.VIDEO_SESSION_ID << 16) + 1);
ApeConsts.VIDEO_OBJ_TABLE_NAME = "video channel list";
ApeConsts.VIDEO_OBJ_TABLE_TAG = "video channel list tag";
// screen sharing objects
ApeConsts.SCREENSHARING_OBJ_TABLE_ID = ((ApeConsts.SCREENSHARING_SESSION_ID << 16) + 1);
ApeConsts.SCREEN_OBJ_TABLE_NAME = "scr list";
ApeConsts.SCREEN_OBJ_TABLE_TAG = "scr list tag";
// poll sharing objects
ApeConsts.POLL_OBJ_TABLE_ID = ((ApeConsts.POLL_SESSION_ID << 16) + 1);
ApeConsts.VOTE_OBJ_TABLE_ID = ((ApeConsts.POLL_SESSION_ID << 16) + 2);
ApeConsts.RECORD_OBJ_TABLE_ID = ((ApeConsts.POLL_SESSION_ID << 16) + 3);
ApeConsts.SHAMLIVE_OBJ_TABLE_ID = ((ApeConsts.POLL_SESSION_ID << 16) + 4);
ApeConsts.POLL_OBJ_TABLE_NAME = "poll list";
ApeConsts.POLL_OBJ_TABLE_TAG = "poll list tag";
// registry operation const
ApeConsts.REG_TABLE_INSERT_TAIL = 0xFFFFFF;
ApeConsts.REG_TABLE_DELETE_ALL = 0xFFFFFF;
ApeConsts.CJS_RELEASED = 0;
ApeConsts.CJS_JOINNING = 1;
ApeConsts.CJS_JOINNED = 2;
// 白板动作
ApeConsts.WBA_CLOSE = 1;
ApeConsts.WBA_CHANGE = 2;
ApeConsts.WBA_OPEN = 3;
ApeConsts.WBA_DOC_ANNOTATION = 4;
ApeConsts.WBA_LASER_PEN = 5;
... ...
// //////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2016-present All Rights Reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// http://www.apache.org/licenses/LICENSE-2.0
//
// Github Home: https://github.com/AlexWang1987
// Author: AlexWang
// Date: 2016-08-14 15:55:42
// QQ Email: 1669499355@qq.com
// Last Modified time: 2016-09-06 16:28:14
// Description: LiveClass-ChatApe
//
// //////////////////////////////////////////////////////////////////////////////
import Ape from './Ape';
import ApeConsts from './ApeConsts';
import pdu from 'pdu';
import Loger from 'Loger';
import MessageTypes from 'MessageTypes';
let loger = Loger.getLoger('ChatApe');
class ChatApe extends Ape {
constructor() {
super(
ApeConsts.CHAT_SESSION_ID,
ApeConsts.CHAT_SESSION_NAME,
ApeConsts.CHAT_SESSION_TAG
);
//Ape Models
this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);
this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.CHAT_OBJ_TABLE_ID,
ApeConsts.CHAT_OBJ_TABLE_NAME, ApeConsts.CHAT_OBJ_TABLE_TAG, 0, new ArrayBuffer);
// ape listeners
this.on(pdu.RCPDU_CHAT_SEND_DATA_REQUEST, this.chatMsgIncomingHandler.bind(this));
}
chatMsgIncomingHandler(pdu) {
}
sendChatMsg(to, message) {
loger.log('发送聊天消息.', to, message);
let chatSendPdu = new pdu['RCChatSendDataRequestPdu'];
chatSendPdu.type = pdu.RCPDU_CHAT_SEND_DATA_REQUEST;
chatSendPdu.initiator = this._confInfo.nodeId;
chatSendPdu.peer = to;
chatSendPdu.isPublic = true;
chatSendPdu.userData = this._rCArrayBufferUtil.strToUint8Array("h5" + message);
chatSendPdu.fromName = this._rCArrayBufferUtil.strToUint8Array("h5" + this._confInfo.userName);
chatSendPdu.fromRole = this._confInfo.classRole;
if (!(chatSendPdu.isPublic || 0 === chatSendPdu.peer)) {
this.send(chatSendPdu);
} else {
this.sendUniform(chatSendPdu);
}
}
chatMsgIncomingHandler(chatBuffer) {
var chatReceivePdu = pdu['RCChatSendDataRequestPdu'].decode(chatBuffer);
var chatMsg = {};
chatMsg.fromNodeID = chatReceivePdu.initiator;
chatMsg.toNodeID = chatReceivePdu.peer;
chatMsg.message = this._rCArrayBufferUtil.uint8ArrayToStr(chatReceivePdu.userData, 2);
chatMsg.fromName = this._rCArrayBufferUtil.uint8ArrayToStr(chatReceivePdu.fromName, 2);
chatMsg.fromRole = chatReceivePdu.fromRole;
loger.log('接受聊天消息.', chatMsg);
this.emit(MessageTypes.CHAT_RECEIVE, chatMsg);
}
}
export default ChatApe;
... ...
// //////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2016-present All Rights Reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// http://www.apache.org/licenses/LICENSE-2.0
//
// Github Home: https://github.com/AlexWang1987
// Author: AlexWang
// Date: 2016-08-22 09:57:12
// QQ Email: 1669499355@qq.com
// Last Modified time: 2016-09-07 16:16:35
// Description: LiveClass-ConferApe
//
// //////////////////////////////////////////////////////////////////////////////
import Ape from './Ape';
import ApeConsts from './ApeConsts';
import MessageTypes from 'MessageTypes';
import pdu from 'pdu';
import { Zlib } from 'zlibjs/bin/zlib.min';
import UTF8 from 'utf-8';
import Loger from 'Loger';
let loger = Loger.getLoger('ConferApe');
class ConferApe extends Ape {
constructor() {
super(
ApeConsts.CONFERENCE_SESSION_ID,
ApeConsts.CONFERENCE_SESSION_NAME,
ApeConsts.CONFERENCE_SESSION_TAG
);
// Attribures
this.hostNodeId = -1;
this.hostUserId = '';
this.rosters = {};
this.activeDocId = '';
// Ape Models
this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);
this.registerObj(pdu.RCPDU_REG_REGISTER_ROSTER, ApeConsts.CONFERENCE_OBJ_ROSTER_ID,
ApeConsts.CONFERENCE_OBJ_ROSTER_NAME, ApeConsts.CONFERENCE_OBJ_ROSTER_TAG, 0, new ArrayBuffer);
this.registerObj(pdu.RCPDU_REG_REGISTER_QUEUE, ApeConsts.CONFERENCE_OBJ_QUEUE_ID,
ApeConsts.CONFERENCE_OBJ_QUEUE_NAME, ApeConsts.CONFERENCE_OBJ_QUEUE_TAG, 0, new ArrayBuffer);
this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.CONFERENCE_OBJ_TABLE_ID,
ApeConsts.CONFERENCE_OBJ_TABLE_NAME, ApeConsts.CONFERENCE_OBJ_TABLE_TAG, 0, new ArrayBuffer);
this.registerObj(pdu.RCPDU_REG_REGISTER_COUNTER, ApeConsts.CONFERENCE_OBJ_COUNTER_ID,
ApeConsts.CONFERENCE_OBJ_COUNTER_NAME, ApeConsts.CONFERENCE_OBJ_COUNTER_TAG, 0, new ArrayBuffer);
this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this));
}
_joinSessionHandler(confInfo) {
let nodeInfoRecordPdu = this.mcu.mcuConfInfo.self;
let userDataPdu = new pdu['RCNodeInfoUserDataPdu'];
userDataPdu.qq = '';
userDataPdu.skype = '';
userDataPdu.mobile = '';
nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer();
nodeInfoRecordPdu.deviceType = 3;
let item = new pdu['RCRegistryRosterItemPdu'];
item.nodeId = nodeInfoRecordPdu.nodeId;
item.nodeData = nodeInfoRecordPdu.toArrayBuffer();
let rosterUpdateItem = new pdu['RCRegistryRosterUpdateItemPdu'];
rosterUpdateItem.type = pdu.RCPDU_REG_ROSTER_UPDATE_PDU;
rosterUpdateItem.items.push(item);
let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_ROSTER_ID;
updateObjPdu.subType = rosterUpdateItem.type;
updateObjPdu.userData = rosterUpdateItem.toArrayBuffer();
let adapterItemPdu = new pdu['RCAdapterItemPdu'];
adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();
let adapterPdu = new pdu['RCAdapterPdu'];
adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
adapterPdu.item.push(adapterItemPdu);
this.sendUniform(adapterPdu, true);
}
tableUpdateHandler(owner, recordId, recordData) {
try {
let tabUpdatePdu = pdu.RCTabUpdateDataRequestPdu.decode(recordData);
const uncompressedBytes = new Zlib.Inflate(tabUpdatePdu.action.compact().view).decompress();
let tabInfo = UTF8.getStringFromBytes(uncompressedBytes);
let tabTypeMatches = tabInfo.match(/<TabType>(.+)<\/TabType>/);
if (tabTypeMatches.length > 1 && tabTypeMatches[1] == 'show.docsharing') {
if (tabInfo.match(/<visible>(.+)<\/visible>/)[1] == 'true') {
this.activeDocId = tabInfo.match(/<TabID>(.+)<\/TabID>/)[1];
this.emit(MessageTypes.DOC_SWITCH, this.activeDocId);
}
}
} catch (e) {
loger.warn('ConferApe table update got exception.');
}
}
rosterInsertHandler(nodeId, nodeData) {
this.rosterUpdateHandler(nodeId, nodeData);
}
rosterUpdateHandler(nodeId, nodeData) {
if (nodeData.role === ApeConsts.NR_MASTER ||
nodeData.role === ApeConsts.NR_SLAVE) {
this.hostNodeId = nodeData.nodeId;
this.hostUserId = nodeData.userId;
}
if (nodeData.role === ApeConsts.NR_NORMAL &&
this.hostNodeId === nodeData.nodeId) {
this.hostNodeId = -1;
this.hostUserId = '';
}
let rosterExists = this.rosters[nodeId];
this.rosters[nodeId] = nodeData;
if (!rosterExists) {
this.emitRosterChange();
}
}
rosterDelHandler(nodeId) {
delete this.rosters[nodeId];
this.emitRosterChange();
// 自己退出
if (nodeId == this._confInfo.nodeId) {
this.emit(MessageTypes.CONFERENCE_EXIT);
}
}
emitRosterChange() {
this.emit(MessageTypes.CONFERENCE_SHOW_ROSTER_NUM, Object.keys(this.rosters).length);
}
}
export default ConferApe;
... ...
// //////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2016-present All Rights Reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// http://www.apache.org/licenses/LICENSE-2.0
//
// Github Home: https://github.com/AlexWang1987
// Author: AlexWang
// Date: 2016-08-26 17:30:43
// QQ Email: 1669499355@qq.com
// Last Modified time: 2016-09-21 14:12:25
// Description: LiveClass-DocApe
//
// //////////////////////////////////////////////////////////////////////////////
import Ape from './Ape';
import ApeConsts from './ApeConsts';
import pdu from 'pdu';
import Loger from 'Loger';
import MessageTypes from 'MessageTypes';
let loger = Loger.getLoger('DocApe');
class DocApe extends Ape {
constructor() {
super(
ApeConsts.DOCSHARING_SESSION_ID,
ApeConsts.DOCSHARING_SESSION_NAME,
ApeConsts.DOCSHARING_SESSION_TAG
);
this.docList = {};
// Ape Models
this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);
this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.DOCSHARING_OBJ_TABLE_ID_H5, ApeConsts.DOCSHARING_OBJ_TABLE_NAME_H5, ApeConsts.DOCSHARING_OBJ_TABLE_TAG_H5, 0, new ArrayBuffer);
// 延迟
this._apeDelayed = true;
}
tableInsertHandler(owner, tableId, recordData) {
this.tableUpdateHandler(owner, tableId, recordData);
}
tableDeleteHandler(tableId, record){
const re={};
re.type=ApeConsts.DOCUMENT_DEL;
this.emit(MessageTypes.DOC_DEL, re);
}
tableUpdateHandler(owner, recordId, recordData) {
try {
const recordInfo = pdu['RCDocSendDataRequestPdu'].decode(recordData);
recordInfo.type = ApeConsts.DOCUMENT_LOAD;
recordInfo.ext = recordInfo.name.substr(recordInfo.name.indexOf('.') + 1);
recordInfo.wbid = (recordInfo.id << 10) + recordInfo.curPageNo;
recordInfo.isPicture = ~['bmp', 'png', 'gif', 'jpg', 'jpeg'].indexOf(recordInfo.ext);
if (recordInfo.isPicture) {
recordInfo.namePath = recordInfo.uri.substring(0, recordInfo.uri.lastIndexOf('.'));
recordInfo.loadURL = recordInfo.namePath + '.' + recordInfo.ext;
} else {
recordInfo.namePath = recordInfo.uri.substring(0, recordInfo.uri.lastIndexOf('/'));
recordInfo.loadURL = `${recordInfo.namePath}/${recordInfo.curPageNo}.jpg`;
}
this.docList[recordId] = recordInfo;
this.emit(MessageTypes.DOC_UPDATE, recordInfo);
loger.log('Doc update ->' + recordId);
} catch (e) {
loger.warn('Doc Table Update Decode包异常');
}
}
}
export default DocApe;
... ...
// //////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2016-present All Rights Reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// http://www.apache.org/licenses/LICENSE-2.0
//
// Github Home: https://github.com/AlexWang1987
// Author: AlexWang
// Date: 2016-08-23 18:07:28
// QQ Email: 1669499355@qq.com
// Last Modified time: 2016-09-06 11:13:59
// Description: LiveClass-VideoApe
//
// //////////////////////////////////////////////////////////////////////////////
import Ape from './Ape';
import ApeConsts from './ApeConsts';
import pdu from 'pdu';
import Loger from 'Loger';
import MessageTypes from 'MessageTypes';
let loger = Loger.getLoger('VideoChat');
class VideoChat extends Ape {
constructor() {
super(
ApeConsts.VIDEO_SESSION_ID,
ApeConsts.VIDEO_SESSION_NAME,
ApeConsts.VIDEO_SESSION_TAG
);
//Attributes
this.videoChannels = {};
this.activeChannelId = 0;
this.activeURL = '';
// Ape Models
this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);
this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.VIDEO_OBJ_TABLE_ID, ApeConsts.VIDEO_OBJ_TABLE_NAME, ApeConsts.VIDEO_OBJ_TABLE_TAG, 0, new ArrayBuffer);
// ape listeners
this.on(pdu.RCPDU_VIDEO_SEND_DATA_REQUEST, this.videoIncomingHandler.bind(this));
}
// 视频消息处理
videoIncomingHandler(videoBuffer) {
let videoReceivePdu = pdu['VideoSendDataRequestPdu'].decode(videoBuffer);
let video_data = { };
video_data._initiator = videoReceivePdu.initiator;
video_data._is_key_frame = videoReceivePdu.keyFrame;
video_data._sequence_id = videoReceivePdu.sequenceId;
video_data._slice_id = videoReceivePdu.sliceId;
video_data._data = videoReceivePdu.userData;
// this._notify(RCApeEvent.E_VIDEO_DATA, videoReceivePdu.sessionId, videoReceivePdu.channelId, video_data);
loger.log('接受视频消息.', video_data);
this.emit(MessageTypes.VIDEO_SHOW, video_data);
}
tableUpdateHandler(ownerId, channelId, channelInfo) {
// debugger;
let videoChannelInfo = pdu['RCVideoChannelInfoRecordPdu'].decode(channelInfo);
videoChannelInfo.owner = ownerId;
videoChannelInfo.channelId = channelId;
videoChannelInfo.status = ownerId === 0 ? ApeConsts.CGS_RELEASED : videoChannelInfo.status;
this.videoChannels[channelId] = videoChannelInfo;
switch (videoChannelInfo.status) {
case ApeConsts.CGS_RELEASED:
case ApeConsts.CGS_PENDING:
case ApeConsts.CGS_GRABBING:
// 只能关闭自己的流
if (this.activeChannelId === videoChannelInfo.channelId) {
this.activeChannelId = 0;
this.activeURL = '';
this.emitVideoChange();
}
break;
case ApeConsts.CGS_OPENNED:
this.activeChannelId = videoChannelInfo.channelId;
// AMS
if (this._confInfo.msType === '1') {
this.activeURL = `http://dazhi.3mang.com/live/${this._confInfo.confId}/${this._confInfo.confId}_${videoChannelInfo.channelId}_flash_cam_mic_aac/playlist.m3u8`;
}else {
this.activeURL = `http://hls.3mang.com/live/${this._confInfo.confId}_${videoChannelInfo.channelId}_flash_cam_mic_aac/playlist.m3u8`;
}
// 任何人都可以打开流
this.emitVideoChange();
break;
}
}
emitVideoChange() {
this.emit(MessageTypes.VIDEO_SHOW, {
activeChannelId: this.activeChannelId,
HLSURL: this.activeURL,
});
};
}
export default VideoChat;
... ...
// //////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2016-present All Rights Reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// http://www.apache.org/licenses/LICENSE-2.0
//
// Github Home: https://github.com/AlexWang1987
// Author: AlexWang
// Date: 2016-08-26 17:36:20
// QQ Email: 1669499355@qq.com
// Last Modified time: 2016-09-21 14:06:12
// Description: LiveClass-WhiteBoardApe
//
// //////////////////////////////////////////////////////////////////////////////
import Ape from './Ape';
import ApeConsts from './ApeConsts';
import pdu from 'pdu';
import Loger from 'Loger';
import MessageTypes from 'MessageTypes';
import { Zlib } from 'zlibjs/bin/zlib.min';
import UTF8 from 'utf-8';
let loger = Loger.getLoger('WhiteBoardApe');
class WhiteBoardApe extends Ape {
constructor() {
super(
ApeConsts.WHITEBOARD_SESSION_ID,
ApeConsts.WHITEBOARD_SESSION_NAME,
ApeConsts.WHITEBOARD_SESSION_TAG
);
// properties
this.annoInfos = {};
//Ape Models
this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);
this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.WHITEBOARD_OBJ_TABLE_ID,
ApeConsts.WHITEBOARD_OBJ_TABLE_NAME, ApeConsts.WHITEBOARD_OBJ_TABLE_TAG, 0, new ArrayBuffer);
// ape listeners
this.on(pdu.RCPDU_CONFERENCE_SEND_DATA_REQUEST, this.whiteboardMsgComingHandler.bind(this));
// 白板延迟
this._apeDelayed = true;
}
whiteboardMsgComingHandler(pdu) {
loger.warn('whiteboardMsgComingHandler needs to be handled.');
}
tableInsertHandler(tableId, record) {
this.emitDocChange(ApeConsts.DOCUMENT_DEL);
}
tableUpdateHandler(owner, recordId, recordData) {
const recordInfo = pdu['RCWhiteboardDataRequestPdu'].decode(recordData);
// 目前只处理 文档标注
if (recordInfo.type == ApeConsts.WBA_DOC_ANNOTATION) {
const uncompressedBytes = new Zlib.Inflate(recordInfo.action.compact().view).decompress();
const annoInfo = {
id: recordId,
svg: UTF8.getStringFromBytes(uncompressedBytes)
};
this.annoInfos[recordId] = annoInfo;
this.emit(MessageTypes.ANNO_UPDATE, annoInfo);
} else {
loger.log('白板动作忽略,类型:', ApeConsts(recordInfo.type));
}
}
}
export default WhiteBoardApe;
... ...
# CSS FILE FOLDER
... ...
# FONT FILE FOLDER
... ...
# IMAGE FILE FOLDER
... ...
export default class RCMessageCallback {
constructor() {
this.type;
this.message;
}
create_notify_message(msgType, msgData) {
this.type = msgType;
this.message = msgData;
}
}
RCMessageCallback.MESSAGE_VIDEO = "video.message";
RCMessageCallback.MESSAGE_DOCUMENT = "document.message";
RCMessageCallback.MESSAGE_CHAT = "chat.message";
RCMessageCallback.MESSAGE_Notify = "notify.message";
RCMessageCallback.MESSAGE_ROSTER_NUM = "roster_num.message";
RCMessageCallback.MESSAGE_CLASS_DETAIL = "class_detail.message";
... ...
// //////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2016-present All Rights Reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// http://www.apache.org/licenses/LICENSE-2.0
//
// Github Home: https://github.com/AlexWang1987
// Author: AlexWang
// Date: 2016-08-27 23:06:26
// QQ Email: 1669499355@qq.com
// Last Modified time: 2016-09-04 01:02:29
// Description: LiveClass-undefined
//
// //////////////////////////////////////////////////////////////////////////////
import util from 'util';
import Emiter from 'Emiter';
import MessageTypes from 'MessageTypes';
import mcu from 'mcu';
import mcu from 'mcu.js';
import muc from 'mcu.js';
import dfjsd from 'Loger';
import fdsfds from 'mcu';
import alexwang from 'MessageEngine.js';
... ...
export default class ArrayBufferUtil {
static ab2str(buf) {
return String.fromCharCode.apply(null, new Uint16Array(buf));
}
static str2ab(str) {
let buf = new ArrayBuffer(str.length * 2); // one char use 2 byte
let bufView = new Uint16Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
static strToUint8Array(str) {
let out, i, len, c;
out = "";
len = str.length;
let uintArray = [];
for (i = 0; i < len; i++) {
c = str.charCodeAt(i);
if ((c >= 0x0001) && (c <= 0x007F)) {
uintArray.push(c);
} else if (c > 0x07FF) {
uintArray.push(0xE0 | ((c >> 12) & 0x0F));
uintArray.push(0x80 | ((c >> 6) & 0x3F));
uintArray.push(0x80 | ((c >> 0) & 0x3F));
//out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
//out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
//out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
} else {
uintArray.push(0xC0 | ((c >> 6) & 0x1F));
uintArray.push(0x80 | ((c >> 0) & 0x3F));
//out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
//out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
}
}
return new Uint8Array(uintArray);
}
static uint8ArrayToStr(uint8, index) {
let out, i, len, c;
let char2, char3;
out = "";
len = uint8.buffer.byteLength;
i = uint8.offset + index; //pzm update 前两个字符乱码
while (i < uint8.limit) {
c = uint8.view[i++];
switch (c >> 4) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
// 0xxxxxxx
out += String.fromCharCode(uint8.view[i - 1]);
break;
case 12:
case 13:
// 110x xxxx 10xx xxxx
char2 = uint8.view[i++];
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
break;
case 14:
// 1110 xxxx 10xx xxxx 10xx xxxx
char2 = uint8.view[i++];
char3 = uint8.view[i++];
out += String.fromCharCode(((c & 0x0F) << 12) |
((char2 & 0x3F) << 6) |
((char3 & 0x3F) << 0));
break;
}
}
return out;
}
}
... ...
/*eslint-disable*/
import Emiter from 'Emiter';
import MessageTypes from 'MessageTypes';
import Loger from 'Loger';
import everSocket from 'everSocket';
import pdu from 'pdu/index';
import PduType from 'pdu/PduType';
import PduConsts from 'pdu/PduConsts';
import ApeConsts from 'apes/ApeConsts';
import ConferApe from 'apes/ConferApe';
import ArrayBufferUtil from 'libs/ArrayBufferUtil';
import Base64 from 'base64-js';
let loger = Loger.getLoger('MCU');
class MCU extends Emiter {
constructor() {
super();
this._apes = {};
this._everSocket = everSocket;
this._everSocket.on(everSocket.OPEN, this._everSocketOpenHandler.bind(this));
this._everSocket.on(everSocket.MESSAGE, this._everSocketMsgReceivedHandler.bind(this));
}
// 注册Ape
registerApe(ape) {
this._apes[ape._session_id] = ape;
}
// EverSocket建立通道完毕
_everSocketOpenHandler() {
loger.log('MCU-发送加入会议请求.');
const confInfo = this.confInfo;
// 刷新nodeId
confInfo.nodeId = parseInt(Date.now() / 1000);
var joinRequestPdu = new pdu['RCConferenceJoinRequestPdu'];
joinRequestPdu.type = 2;
joinRequestPdu.initiator = confInfo.nodeId;
joinRequestPdu.nodeType = PduConsts.NT_TERMINAL; //normal
var descriptorPdu = new pdu['RCConferenceDescriptorPdu'];
descriptorPdu.id = confInfo.confId;
descriptorPdu.name = new ArrayBuffer;
descriptorPdu.mode = 0;
descriptorPdu.capacity = 1;
joinRequestPdu.confDesc = descriptorPdu;
let pduMsg = pdu.create_connect_provider_request_pdu(
joinRequestPdu.type,
confInfo.nodeId,
confInfo.confId,
0,
ApeConsts.BROADCAST_CHANNEL_ID,
true,
PduConsts.DP_TOP,
confInfo.topNodeID,
PduConsts.SEG_ONCE
);
pduMsg.set("site", confInfo.siteId);
pduMsg.set("userId", confInfo.userId);
pduMsg.set("userName", Base64.fromByteArray(ArrayBufferUtil.strToUint8Array(confInfo.userName)));
pduMsg.set("userRole", confInfo.userRole);
pduMsg.set("deviceType", "");
pduMsg.set("data", joinRequestPdu.toArrayBuffer());
this._everSocket.send(pduMsg.toArrayBuffer());
}
// EverSocket底层消息处理
_everSocketMsgReceivedHandler(data) {
let pduMsg = pdu.decode_pdu(data);
let pduType = pduMsg.get("type");
let pduData = pduMsg.get("data");
loger.log('MCU-FirstLayer封装消息', 'type', pdu.id2type(pduMsg.type), pduMsg.type, 'sessionId', ApeConsts(pduMsg.sessionId), pduMsg.sessionId);
switch (pduType) {
case PduType.RCPDU_CONNECT_PROVIDER_RESPONSE:
let joinConfPdu = pdu['RCConferenceJoinResponsePdu'].decode(pduData);
let pduResultCode = joinConfPdu.get("result");
switch (pduResultCode) {
case PduConsts.RET_SUCCESS:
this._updateMCUConfInfoDesc(joinConfPdu.get("confDesc"));
this.emit(MessageTypes.CONFERENCE_JOIN_SUCCESS, this.confInfo);
break;
case PduConsts.RET_FULL_CAPACITY:
this.emit(MessageTypes.CONFERENCE_JOIN_FULL);
break;
default:
loger.warn('JoinConfPdu-未知类型-等待处理.', pduResultCode);
}
break;
case PduType.RCPDU_SEND_DATA_REQUEST:
let ape = this._apes[pduMsg.sessionId];
let sessionLabel = ApeConsts(pduMsg.sessionId);
if (ape) {
let subTypeLabel = pdu.id2type(pduMsg.subType);
loger.log('MCU-SecondLayer封装消息', 'sessionId', sessionLabel, pduMsg.sessionId, 'subtype', subTypeLabel, pduMsg.subType);
ape.emit(pduMsg.subType, pduMsg.data);
} else {
loger.warn(sessionLabel + '尚未注册');
}
break;
default:
loger.warn('PDU-未知类型-等待处理.', pduType);
}
}
_updateMCUConfInfoDesc(mcuConfDesc) {
let info = this.mcuConfInfo.info;
info._conference_name = ArrayBufferUtil.uint8ArrayToStr(mcuConfDesc.name, 0);
info._capacity = mcuConfDesc.capacity;
info._mode = mcuConfDesc.mode;
}
// MU服务是否连接
get connected() {
if (this._everSocket && this._everSocket.connected)
return true;
return false;
}
// 会议发送消息 -- 消息同意序列号
send(msg) {
if (this.connected) {
loger.log('MCU-发送会议数据....', msg);
this._everSocket.send(msg.toArrayBuffer());
} else {
loger.log('MCU-发送会议数据失败,MCU底层通道不可用');
}
}
// 主动断开MCU连接
leaveMCU() {
// for (let ape in this._apes) {
// this._apes[ape].stop();
// }
this._everSocket.end();
}
// 主动建立MCU连接
joinMCU(_confInfo) {
loger.log('开始建立EverSocket通道.', _confInfo);
_confInfo.confId = parseInt(_confInfo.confId); // confId 必须整形
this.confInfo = _confInfo;
let nodeInfoRecordPdu = new pdu['RCNodeInfoRecordPdu'];
nodeInfoRecordPdu.name = this.confInfo.userName;
nodeInfoRecordPdu.nodeId = this.confInfo.nodeId;
nodeInfoRecordPdu.userId = this.confInfo.userId;
nodeInfoRecordPdu.role = 1; //NR_NORMAL
nodeInfoRecordPdu.level = 0;
let conferenceRecord = {}; //RCConferenceRecord_T
conferenceRecord._conference_id = this.confInfo.confId;
conferenceRecord._top_node_id = this.confInfo.topNodeID;
this.mcuConfInfo = {}; //RCMeetingInfo_T
this.mcuConfInfo.self = nodeInfoRecordPdu;
this.mcuConfInfo.info = conferenceRecord;
// 内部mcuConfInfo
this.confInfo.mcuConfInfo = this.mcuConfInfo;
//开启EverSocket
this._everSocket.begin(this.confInfo.MCUServerIP, this.confInfo.MCUServerPort);
}
}
export default new MCU;
... ...
export default function PduConsts() {}
PduConsts.NT_TERMINAL = 0;
PduConsts.NT_MULTIPORT_TERMINAL = 1;
PduConsts.NT_MCU = 2;
// PduPriority
PduConsts.DP_TOP = 0;
PduConsts.DP_HIGH = 1;
PduConsts.DP_MEDIUM = 2;
PduConsts.DP_LOW = 3;
// PduSegment
PduConsts.SEG_BEGIN = 0;
PduConsts.SEG_END = 1;
PduConsts.SEG_ONCE = 2;
// PduReturnType
PduConsts.RET_SUCCESS = 0;
PduConsts.RET_USER_REJECTED = 1;
PduConsts.RET_INVALID_CONFERENCE = 2;
PduConsts.RET_INVALID_PASSWORD = 3;
PduConsts.RET_INVALID_CONVENER_PASSWORD = 4;
PduConsts.RET_CHALLENGE_RESPONSE_REQUIRED = 5;
PduConsts.RET_INVALID_CHALLENGE_RESPONSE = 6;
PduConsts.RET_NO_CONNECTION = 7;
PduConsts.RET_FULL_CAPACITY = 8;
... ...
export default function RCPduPackage(targe_type_id) {};
RCPduPackage.RCPDU_CONNECT_PROVIDER_REQUEST = 0;
RCPduPackage.RCPDU_CONNECT_PROVIDER_RESPONSE = 1;
RCPduPackage.RCPDU_CONFERENCE_JOIN_REQUEST = 2;
RCPduPackage.RCPDU_CONFERENCE_JOIN_RESPONSE = 3;
RCPduPackage.RCPDU_CONFERENCE_INVITE_REQUEST = 10;
RCPduPackage.RCPDU_CONFERENCE_INVITE_RESPONSE = 11;
RCPduPackage.RCPDU_CONFERENCE_LOCK_REQUEST = 20;
RCPduPackage.RCPDU_CONFERENCE_LOCK_RESPONSE = 21;
RCPduPackage.RCPDU_CONFERENCE_LOCK_INDICATION = 22;
RCPduPackage.RCPDU_CONFERENCE_UNLOCK_REQUEST = 30;
RCPduPackage.RCPDU_CONFERENCE_UNLOCK_RESPONSE = 31;
RCPduPackage.RCPDU_CONFERENCE_UNLOCK_INDICATION = 32;
RCPduPackage.RCPDU_CONFERENCE_LEAVE_REQUEST = 39;
RCPduPackage.RCPDU_CONFERENCE_TERMINATE_REQUEST = 40;
RCPduPackage.RCPDU_CONFERENCE_TERMINATE_RESPONSE = 41;
RCPduPackage.RCPDU_CONFERENCE_TERMINATE_INDICATION = 42;
RCPduPackage.RCPDU_CONFERENCE_EJECT_USER_REQUEST = 50;
RCPduPackage.RCPDU_CONFERENCE_EJECT_USER_RESPONSE = 51;
RCPduPackage.RCPDU_CONFERENCE_EJECT_USER_INDICATION = 52;
RCPduPackage.RCPDU_ROSTER_UPDATE_INDICATION = 60;
RCPduPackage.RCPDU_REGISTRY_UPDATE_REQUEST = 70;
RCPduPackage.RCPDU_REGISTRY_UPDATE_RESPONSE = 71;
RCPduPackage.RCPDU_REGISTRY_UPDATE_INDICATION = 72;
RCPduPackage.RCPDU_FUNCTION_NOT_SUPPORTED_RESPONSE = 80;
RCPduPackage.RCPDU_SESSION_JOIN_REQUEST = 90;
RCPduPackage.RCPDU_SESSION_JOIN_RESPONSE = 91;
RCPduPackage.RCPDU_CHANNEL_GRAB_REQUEST = 100;
RCPduPackage.RCPDU_CHANNEL_GRAB_RESPONSE = 101;
RCPduPackage.RCPDU_CHANNEL_GRAB_INDICATION = 102;
RCPduPackage.RCPDU_CHANNEL_JOIN_REQUEST = 103;
RCPduPackage.RCPDU_CHANNEL_JOIN_RESPONSE = 104;
RCPduPackage.RCPDU_CHANNEL_LEAVE_REQUEST = 105;
RCPduPackage.RCPDU_CHANNEL_RELEASE_REQUEST = 106;
RCPduPackage.RCPDU_CHANNEL_RELEASE_INDICATION = 107;
RCPduPackage.RCPDU_SEND_DATA_REQUEST = 120;
RCPduPackage.RCPDU_SEND_DATA_REQUEST = 120;
RCPduPackage.RCPDU_SEND_DATA_INDICATION = 121;
RCPduPackage.RCPDU_UNIFORM_SEND_DATA_REQUEST = 125;
RCPduPackage.RCPDU_UNIFORM_SEND_DATA_INDICATION = 126;
RCPduPackage.RCPDU_TOKEN_GRAB_REQUEST = 130;
RCPduPackage.RCPDU_TOKEN_GRAB_CONFIRM = 131;
RCPduPackage.RCPDU_TOKEN_INHIBIT_REQUEST = 132;
RCPduPackage.RCPDU_TOKEN_INHIBIT_CONFIRM = 133;
RCPduPackage.RCPDU_TOKEN_GIVE_REQUEST = 134;
RCPduPackage.RCPDU_TOKEN_GIVE_INDICATION = 135;
RCPduPackage.RCPDU_TOKEN_GIVE_RESPONSE = 136;
RCPduPackage.RCPDU_TOKEN_GIVE_CONFIRM = 137;
RCPduPackage.RCPDU_TOKEN_PLEASE_REQUEST = 138;
RCPduPackage.RCPDU_TOKEN_PLEASE_INDICATION = 139;
RCPduPackage.RCPDU_TOKEN_RELEASE_REQUEST = 140;
RCPduPackage.RCPDU_TOKEN_RELEASE_CONFIRM = 141;
RCPduPackage.RCPDU_TOKEN_TEST_REQUEST = 142;
RCPduPackage.RCPDU_TOKEN_TEST_CONFIRM = 143;
RCPduPackage.RCPDU_REG_REGISTER_KEY = 200;
RCPduPackage.RCPDU_REG_UNREGISTER_KEY = 201;
RCPduPackage.RCPDU_REG_REGISTER_ROSTER = 202;
RCPduPackage.RCPDU_REG_REGISTER_TOKEN = 203;
RCPduPackage.RCPDU_REG_REGISTER_PARAMETER = 204;
RCPduPackage.RCPDU_REG_REGISTER_COUNTER = 205;
RCPduPackage.RCPDU_REG_REGISTER_TABLE = 206;
RCPduPackage.RCPDU_REG_REGISTER_CACHE = 207;
RCPduPackage.RCPDU_REG_REGISTER_OBJ = 208;
RCPduPackage.RCPDU_REG_UNREGISTER_OBJ = 209;
RCPduPackage.RCPDU_REG_UPDATE_OBJ = 210;
RCPduPackage.RCPDU_REG_ADAPTER = 211;
RCPduPackage.RCPDU_REG_CLEANUP_NODE = 212;
RCPduPackage.RCPDU_REG_REGISTER_QUEUE = 213;
RCPduPackage.RCPDU_REG_TABLE_INSERT_PDU = 230;
RCPduPackage.RCPDU_REG_TABLE_DELETE_PDU = 231;
RCPduPackage.RCPDU_REG_TABLE_UPDATE_PDU = 232;
RCPduPackage.RCPDU_REG_ROSTER_INSERT_PDU = 240;
RCPduPackage.RCPDU_REG_ROSTER_DELETE_PDU = 241;
RCPduPackage.RCPDU_REG_ROSTER_UPDATE_PDU = 242;
RCPduPackage.RCPDU_REG_PARAMETER_UPDATE_PDU = 250;
RCPduPackage.RCPDU_REG_QUEUE_INSERT_PDU = 255;
RCPduPackage.RCPDU_REG_QUEUE_DELETE_PDU = 256;
RCPduPackage.RCPDU_REG_QUEUE_UPDATE_PDU = 257;
RCPduPackage.RCPDU_CONFERENCE_SEND_DATA_REQUEST = 259;
RCPduPackage.RCPDU_VIDEO_SEND_DATA_REQUEST = 260;
RCPduPackage.RCPDU_AUDIO_SEND_DATA_REQUEST = 261;
RCPduPackage.RCPDU_GIFT_SEND_DATA_REQUEST = 262;
RCPduPackage.RCPDU_CHAT_SEND_DATA_REQUEST = 263;
RCPduPackage.RCPDU_VOTING_POLL_RECORD = 265;
RCPduPackage.RCPDU_REG_REQUEST_OBJ = 290;
RCPduPackage.RCPDU_REG_RESPONSE_OBJ = 291;
RCPduPackage.RCPDU_REG_COUNTER_REQUEST_PDU = 292;
RCPduPackage.RCPDU_REG_COUNTER_RESPONSE_PDU = 293;
RCPduPackage.RCPDU_INDEX_ADAPTER = 300;
RCPduPackage.RCPDU_INDEX_SERVER_USERS = 301;
RCPduPackage.RCPDU_INDEX_CONFERENCE_USER_JOINED = 302;
RCPduPackage.RCPDU_INDEX_CONFERENCE_USER_EXITED = 303;
RCPduPackage.RCPDU_INDEX_CONFERENCE_USERS = 304;
... ...
此 diff 太大无法显示。
import ProtoBuf from 'protobufjs';
import pro from './pro';
import PduType from './PduType';
import PduConsts from './PduConsts';
let builder = ProtoBuf.newBuilder({ convertFieldsToCamelCase: true });
ProtoBuf.loadProto(pro, builder);
let pdu = builder.build();
// 底层通信层[Firstlayer] - RCSendDataPdu封包
function create_pdu(type, sub_type,
initiator, conference_id, session_id,
channel_id, upward, reliability, priority,
peer, seg) {
var pduMsg = new pdu['RCSendDataPdu']();
pduMsg.set("type", type);
pduMsg.set("subType", sub_type);
pduMsg.set("initiator", initiator);
pduMsg.set("confId", conference_id);
pduMsg.set("sessionId", session_id);
pduMsg.set("channelId", channel_id);
pduMsg.set("upward", upward);
pduMsg.set("reliability", reliability);
pduMsg.set("priority", priority);
pduMsg.set("peer", peer);
pduMsg.set("seg", seg);
return pduMsg;
}
// 底层通信层[Firstlayer] - RCSendDataPdu解包
pdu.decode_pdu = function (buffer) {
return pdu['RCSendDataPdu'].decode(buffer);
};
pdu.create_connect_provider_request_pdu = function (
sub_type,
initiator,
conference_id,
session_id,
channel_id,
reliability,
priority,
peer,
seg
) {
return create_pdu(PduType.RCPDU_CONNECT_PROVIDER_REQUEST,
sub_type, initiator, conference_id, session_id, channel_id, true,
reliability, priority, peer, seg);
};
pdu.create_uniform_pdu = function (
sub_type,
initiator,
conference_id,
session_id,
channel_id,
reliability,
priority,
peer,
seg
) {
return create_pdu(PduType.RCPDU_UNIFORM_SEND_DATA_REQUEST,
sub_type, initiator, conference_id, session_id, channel_id, true,
reliability, priority, peer, seg);
};
pdu.create_normal_pdu = function (
sub_type,
initiator,
conference_id,
session_id,
channel_id,
upward,
reliability,
priority,
peer,
seg
) {
return create_pdu(PduType.RCPDU_SEND_DATA_REQUEST,
sub_type, initiator, conference_id, session_id, channel_id, upward,
reliability, priority, peer, seg);
};
pdu.id2type = function (id) {
for (var type_const in PduType) {
if (PduType[type_const] === id) {
return type_const;
}
}
};
// 合并统一对外
pdu = {...pdu, ...PduType, ...PduConsts };
export default pdu;
... ...
export default `
//start
// pdu_def.proto
// syntax = "proto3";
option optimize_for = LITE_RUNTIME;
enum RCPduPriority_E {
DP_TOP = 0;
DP_HIGH = 1;
DP_MEDIUM = 2;
DP_LOW = 3;
}
enum RCPduSegment_E {
SEG_BEGIN = 0;
SEG_END = 1;
SEG_ONCE = 2;
}
enum RCPduTokenStatus_E {
TS_NOT_IN_USE = 0;
TS_SELF_GRABBED = 1;
TS_OTHER_GRABBED = 2;
TS_SELF_INHIBITED = 3;
TS_OTHER_INHIBITED = 4;
TS_SELF_RECIPIENT = 5;
TS_SELF_GIVING = 6;
TS_OTHER_GIVING = 7;
}
enum RCPduType_E {
// GCC PDU
RCPDU_CONNECT_PROVIDER_REQUEST = 0;
RCPDU_CONNECT_PROVIDER_RESPONSE = 1;
RCPDU_CONFERENCE_JOIN_REQUEST = 2;
RCPDU_CONFERENCE_JOIN_RESPONSE = 3;
RCPDU_CONFERENCE_INVITE_REQUEST = 10;
RCPDU_CONFERENCE_INVITE_RESPONSE = 11;
RCPDU_CONFERENCE_LOCK_REQUEST = 20;
RCPDU_CONFERENCE_LOCK_RESPONSE = 21;
RCPDU_CONFERENCE_LOCK_INDICATION = 22;
RCPDU_CONFERENCE_UNLOCK_REQUEST = 30;
RCPDU_CONFERENCE_UNLOCK_RESPONSE = 31;
RCPDU_CONFERENCE_UNLOCK_INDICATION = 32;
RCPDU_CONFERENCE_LEAVE_REQUEST = 39;
RCPDU_CONFERENCE_TERMINATE_REQUEST = 40;
RCPDU_CONFERENCE_TERMINATE_RESPONSE = 41;
RCPDU_CONFERENCE_TERMINATE_INDICATION = 42;
RCPDU_CONFERENCE_EJECT_USER_REQUEST = 50;
RCPDU_CONFERENCE_EJECT_USER_RESPONSE = 51;
RCPDU_CONFERENCE_EJECT_USER_INDICATION = 52;
RCPDU_ROSTER_UPDATE_INDICATION = 60;
RCPDU_REGISTRY_UPDATE_REQUEST = 70; // INCLUDE ALL OBJS OPERATION
RCPDU_REGISTRY_UPDATE_RESPONSE = 71;
RCPDU_REGISTRY_UPDATE_INDICATION = 72;
RCPDU_FUNCTION_NOT_SUPPORTED_RESPONSE = 80;
// MCS PDU
RCPDU_SESSION_JOIN_REQUEST = 90;
RCPDU_SESSION_JOIN_RESPONSE = 91;
RCPDU_CHANNEL_GRAB_REQUEST = 100;
RCPDU_CHANNEL_GRAB_RESPONSE = 101;
RCPDU_CHANNEL_GRAB_INDICATION = 102;
RCPDU_CHANNEL_JOIN_REQUEST = 103;
RCPDU_CHANNEL_JOIN_RESPONSE = 104;
RCPDU_CHANNEL_LEAVE_REQUEST = 105;
RCPDU_CHANNEL_RELEASE_REQUEST = 106;
RCPDU_CHANNEL_RELEASE_INDICATION = 107;
RCPDU_SEND_DATA_REQUEST = 120;
RCPDU_SEND_DATA_INDICATION = 121;
RCPDU_UNIFORM_SEND_DATA_REQUEST = 125;
RCPDU_UNIFORM_SEND_DATA_INDICATION = 126;
RCPDU_TOKEN_GRAB_REQUEST = 130;
RCPDU_TOKEN_GRAB_CONFIRM = 131;
RCPDU_TOKEN_INHIBIT_REQUEST = 132;
RCPDU_TOKEN_INHIBIT_CONFIRM = 133;
RCPDU_TOKEN_GIVE_REQUEST = 134;
RCPDU_TOKEN_GIVE_INDICATION = 135;
RCPDU_TOKEN_GIVE_RESPONSE = 136;
RCPDU_TOKEN_GIVE_CONFIRM = 137;
RCPDU_TOKEN_PLEASE_REQUEST = 138;
RCPDU_TOKEN_PLEASE_INDICATION = 139;
RCPDU_TOKEN_RELEASE_REQUEST = 140;
RCPDU_TOKEN_RELEASE_CONFIRM = 141;
RCPDU_TOKEN_TEST_REQUEST = 142;
RCPDU_TOKEN_TEST_CONFIRM = 143;
// Registry PDU
RCPDU_REG_REGISTER_KEY = 200;
RCPDU_REG_UNREGISTER_KEY = 201;
RCPDU_REG_REGISTER_ROSTER = 202;
RCPDU_REG_REGISTER_TOKEN = 203;
RCPDU_REG_REGISTER_PARAMETER = 204;
RCPDU_REG_REGISTER_COUNTER = 205;
RCPDU_REG_REGISTER_TABLE = 206;
RCPDU_REG_REGISTER_CACHE = 207;
RCPDU_REG_REGISTER_OBJ = 208;
RCPDU_REG_UNREGISTER_OBJ = 209;
RCPDU_REG_UPDATE_OBJ = 210;
RCPDU_REG_ADAPTER = 211;
RCPDU_REG_CLEANUP_NODE = 212;
RCPDU_REG_REGISTER_QUEUE = 213;
// Registry Obj update PDU
RCPDU_REG_TABLE_INSERT_PDU = 230;
RCPDU_REG_TABLE_DELETE_PDU = 231;
RCPDU_REG_TABLE_UPDATE_PDU = 232;
RCPDU_REG_ROSTER_INSERT_PDU = 240;
RCPDU_REG_ROSTER_DELETE_PDU = 241;
RCPDU_REG_ROSTER_UPDATE_PDU = 242;
RCPDU_REG_PARAMETER_UPDATE_PDU = 250;
RCPDU_REG_QUEUE_INSERT_PDU = 255;
RCPDU_REG_QUEUE_DELETE_PDU = 256;
RCPDU_REG_QUEUE_UPDATE_PDU = 257;
// data
RCPDU_CONFERENCE_SEND_DATA_REQUEST = 259;
RCPDU_VIDEO_SEND_DATA_REQUEST = 260;
RCPDU_AUDIO_SEND_DATA_REQUEST = 261;
RCPDU_GIFT_SEND_DATA_REQUEST = 262;
RCPDU_CHAT_SEND_DATA_REQUEST = 263;
RCPDU_VOTING_POLL_RECORD = 265;
// Registry resource request or response PDU
RCPDU_REG_REQUEST_OBJ = 290;
RCPDU_REG_RESPONSE_OBJ = 291;
RCPDU_REG_COUNTER_REQUEST_PDU = 292;
RCPDU_REG_COUNTER_RESPONSE_PDU = 293;
// Index exchange
RCPDU_INDEX_ADAPTER = 300;
RCPDU_INDEX_SERVER_USERS = 301;
RCPDU_INDEX_CONFERENCE_USER_JOINED = 302;
RCPDU_INDEX_CONFERENCE_USER_EXITED = 303;
RCPDU_INDEX_CONFERENCE_USERS = 304;
}
enum RCPduNodeType_E {
NT_TERMINAL = 0;
NT_MULTIPORT_TERMINAL = 1;
NT_MCU = 2;
}
enum RCPduReason_E {
RSN_USERINITIATED = 0;
RSN_DISCONNECTED = 1;
RSN_SUPER_LEFT = 2;
}
enum RCPduResult_E {
RET_SUCCESS = 0;
RET_USER_REJECTED = 1;
RET_INVALID_CONFERENCE = 2;
RET_INVALID_PASSWORD = 3;
RET_INVALID_CONVENER_PASSWORD = 4;
RET_CHALLENGE_RESPONSE_REQUIRED = 5;
RET_INVALID_CHALLENGE_RESPONSE = 6;
RET_NO_CONNECTION = 7;
RET_FULL_CAPACITY = 8;
}
enum RCPduNodeCategory_E {
NC_CONVENTIONAL = 0;
NC_COUNTED = 1;
NC_ANONYMOUS = 2;
}
message RCConferenceDescriptorPdu {
required uint32 id = 1;
required bytes name = 2;
optional bytes description = 3;
//optional string net_address = 4;
optional uint32 mode = 4;
optional string password = 5;
optional uint32 capacity = 6;
optional bytes user_data = 7;
}
message RCNodeRecordPdu {
required uint32 id = 1;
optional uint32 superior_node = 2;
required RCPduNodeType_E type = 3;
required string name = 4;
required uint32 capability = 5;
optional string net_address = 6;
optional RCPduNodeCategory_E category = 7;
}
message RCApplicationRecordPdu {
required uint32 id = 1; // session id
required string name = 2;
required string tag = 3;
repeated uint32 channel_ids = 4 [packed = true];
optional uint32 capability = 5;
}
//reg.proto
option optimize_for = LITE_RUNTIME;
message RCRegistryRegisterKeyPdu {
required RCPduType_E type = 1 [default = RCPDU_REG_REGISTER_KEY];
required uint32 id = 2;
required string name = 3;
required string tag = 4;
optional bytes user_data = 5;
}
message RCRegistryUnregisterKeyPdu {
optional RCPduType_E type = 1 [default = RCPDU_REG_UNREGISTER_KEY];
required uint32 key_id = 2;
}
message RCRegistryRegisterObjPdu {
optional RCPduType_E type = 1;
required uint32 obj_id = 2;
required string name = 3;
required string tag = 4;
optional uint32 owner = 5;
optional bytes user_data = 6;
}
message RCRegistryUnregisterObjPdu {
optional RCPduType_E type = 1 [default = RCPDU_REG_UNREGISTER_OBJ];
required uint32 obj_id = 2;
}
message RCRegistryUpdateObjPdu {
optional RCPduType_E type = 1 [default = RCPDU_REG_UPDATE_OBJ];
required RCPduType_E sub_type = 2;
required uint32 obj_id = 3;
required bytes user_data = 4;
}
message RCAdapterItemPdu {
required RCPduType_E type = 1;
required bytes item_data = 2;
}
// adapter pdu that used to package a list of pdu.
message RCAdapterPdu {
optional RCPduType_E type = 1 [default = RCPDU_REG_ADAPTER];
repeated RCAdapterItemPdu item = 2;
}
// table operation pdu
message RCRegistryTableItemPdu {
required uint32 item_idx = 1;
required uint32 owner = 2;
required bytes item_data = 3;
}
message RCRegistryTableInsertItemPdu {
optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_INSERT_PDU];
repeated RCRegistryTableItemPdu items = 2;
}
message RCRegistryTableDeleteItemPdu {
optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_DELETE_PDU];
repeated uint32 item_idx = 2;
}
message RCRegistryTableUpdateItemPdu {
optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_UPDATE_PDU];
repeated RCRegistryTableItemPdu items = 2;
}
// roster operation pdu
message RCRegistryRosterItemPdu {
required uint32 node_id = 1;
required bytes node_data = 2;
}
message RCRegistryRosterInsertItemPdu {
optional RCPduType_E type = 1 [default = RCPDU_REG_ROSTER_INSERT_PDU];
repeated RCRegistryRosterItemPdu items = 2;
}
message RCRegistryRosterDeleteItemPdu {
optional RCPduType_E type = 1 [default = RCPDU_REG_ROSTER_DELETE_PDU];
required uint32 node_id = 2;
}
message RCRegistryRosterUpdateItemPdu {
optional RCPduType_E type = 1 [default = RCPDU_REG_ROSTER_UPDATE_PDU];
repeated RCRegistryRosterItemPdu items = 2;
}
//message RCCleanupNodePdu
//{
// optional RCPduType_E type = 1 [default = RCPDU_REG_CLEANUP_NODE];
// required uint32 node_id = 2;
//}
// parameter operation pdu
message RCRegistryParameterUpdatePdu {
optional RCPduType_E type = 1 [default = RCPDU_REG_PARAMETER_UPDATE_PDU];
required uint32 value = 2 [default = 0];
optional uint32 begin_bit = 3 [default = 31];
optional uint32 end_bit = 4;
}
// queue operation pdu
message RCRegistryQueueItemPdu {
required uint32 owner = 1;
required uint32 item_id = 2;
optional bytes item_data = 3;
optional uint32 item_idx = 4;
}
message RCRegstryQueueInsertItemPdu {
optional RCPduType_E type = 1 [default = RCPDU_REG_QUEUE_INSERT_PDU];
repeated RCRegistryQueueItemPdu items = 2;
}
message RCRegistryQueueDeleteItemPdu {
optional RCPduType_E type = 1 [default = RCPDU_REG_QUEUE_DELETE_PDU];
required uint32 item_id = 2;
}
message RCRegistryQueueUpdateItemPdu {
optional RCPduType_E type = 1 [default = RCPDU_REG_QUEUE_UPDATE_PDU];
repeated RCRegistryQueueItemPdu items = 2;
}
message RCRegistryRequestObjPdu {
optional RCPduType_E type = 1 [default = RCPDU_REG_REQUEST_OBJ];
required RCPduType_E sub_type = 2;
required uint32 obj_id = 3;
required bytes user_data = 4;
}
message RCRegistryResponseObjPdu {
optional RCPduType_E type = 1 [default = RCPDU_REG_RESPONSE_OBJ];
required RCPduType_E sub_type = 2;
required uint32 obj_id = 3;
required bytes user_data = 4;
}
message RCRegistryCounterRequestPdu {
optional RCPduType_E type = 1 [default = RCPDU_REG_COUNTER_REQUEST_PDU];
required uint32 count = 2;
}
message RCRegistryCounterResponsePdu {
optional RCPduType_E type = 1 [default = RCPDU_REG_COUNTER_RESPONSE_PDU];
required uint32 start = 2;
required uint32 end = 3;
}
// mcs
option optimize_for = LITE_RUNTIME;
// Session management
message RCSessionJoinRequestPdu {
required RCPduType_E type = 1 [default = RCPDU_SESSION_JOIN_REQUEST];
required uint32 id = 2;
required string name = 3;
required string tag = 4;
optional bytes session_data = 5; //聚合在一起的registry信息
}
message RCSessionJoinResponsePdu {
optional RCPduType_E type = 1 [default = RCPDU_SESSION_JOIN_RESPONSE];
required uint32 id = 2;
optional bytes response_data = 3;
}
// Channel management
message RCChannelGrabRequestPdu {
optional RCPduType_E type = 1 [default = RCPDU_CHANNEL_GRAB_REQUEST];
required uint32 initiator = 2;
required uint32 channel_id = 3;
}
message RCChannelGrabResponsePdu {
optional RCPduType_E type = 1 [default = RCPDU_CHANNEL_GRAB_RESPONSE];
required uint32 initiator = 2;
required uint32 requested_channel_id = 3;
required RCPduResult_E result = 4;
optional uint32 channel_id = 5;
}
message RCChannelGrabIndicationPdu {
optional RCPduType_E type = 1 [default = RCPDU_CHANNEL_GRAB_INDICATION];
required uint32 initiator = 2;
optional uint32 channel_id = 3;
}
message RCChannelJoinRequestPdu {
required RCPduType_E type = 1 [default = RCPDU_CHANNEL_JOIN_REQUEST];
required uint32 initiator = 2;
required uint32 channel_id = 3;
}
message RCChannelJoinResponsePdu {
optional RCPduType_E type = 1 [default = RCPDU_CHANNEL_JOIN_RESPONSE];
required uint32 initiator = 2;
required uint32 requested_channel_id = 3;
required RCPduResult_E result = 4;
}
message RCChannelLeaveRequestPdu {
optional RCPduType_E type = 1 [default = RCPDU_CHANNEL_LEAVE_REQUEST];
required uint32 initiator = 2;
repeated uint32 channel_ids = 3 [packed = true];
}
message RCChannelReleaseRequestPdu {
optional RCPduType_E type = 1 [default = RCPDU_CHANNEL_RELEASE_REQUEST];
required uint32 initiator = 2;
required uint32 channel_id = 3;
}
message RCChannelReleaseIndicationPdu {
optional RCPduType_E type = 1
[default = RCPDU_CHANNEL_RELEASE_INDICATION];
required uint32 initiator = 2;
required uint32 channel_id = 3;
}
// Data transfer
message RCSendDataPdu {
required RCPduType_E type = 1 [default = RCPDU_SEND_DATA_REQUEST];
required RCPduType_E sub_type = 2;
required uint32 initiator = 3;
required uint32 conf_id = 4;
required uint32 session_id = 5;
required uint32 channel_id = 6;
required bool upward = 7;
required bool reliability = 8;
required RCPduPriority_E priority = 9;
required bytes data = 10;
optional uint32 peer = 11;
optional RCPduSegment_E seg = 12;
optional uint32 total_size = 13;
optional uint32 site_id = 14;
optional string user_id = 15;
optional string user_name = 16;
optional string user_role = 17;
optional string device_type = 18;
optional string site = 19;
}
// Token management
message RCTokenGrabRequestPdu {
optional RCPduType_E type = 1 [default = RCPDU_TOKEN_GRAB_REQUEST];
required uint32 initiator = 2;
required uint32 token_id = 3;
}
message RCTokenGrabConfirmPdu {
optional RCPduType_E type = 1 [default = RCPDU_TOKEN_GRAB_CONFIRM];
required uint32 initiator = 2;
required uint32 token_id = 3;
required RCPduResult_E result = 4;
required RCPduTokenStatus_E status = 5;
}
message RCTokenInhibitRequestPdu {
optional RCPduType_E type = 1 [default = RCPDU_TOKEN_INHIBIT_REQUEST];
required uint32 initiator = 2;
required uint32 token_id = 3;
}
message RCTokenInhibitConfirmPdu {
optional RCPduType_E type = 1 [default = RCPDU_TOKEN_INHIBIT_CONFIRM];
required uint32 initiator = 2;
required uint32 token_id = 3;
required RCPduResult_E result = 4;
required RCPduTokenStatus_E status = 5;
}
message RCTokenGiveRequestPdu {
optional RCPduType_E type = 1 [default = RCPDU_TOKEN_GIVE_REQUEST];
required uint32 initiator = 2;
required uint32 token_id = 3;
required uint64 recipient = 4;
}
message RCTokenGiveIndicationPdu {
optional RCPduType_E type = 1 [default = RCPDU_TOKEN_GIVE_INDICATION];
required uint32 initiator = 2;
required uint32 token_id = 3;
required uint64 recipient = 4;
}
message RCTokenGiveResponsePdu {
optional RCPduType_E type = 1 [default = RCPDU_TOKEN_GIVE_RESPONSE];
required uint32 token_id = 2;
required uint64 recipient = 3;
required RCPduResult_E result = 4;
}
message RCTokenGiveConfirmPdu {
optional RCPduType_E type = 1 [default = RCPDU_TOKEN_GIVE_CONFIRM];
required uint32 token_id = 2;
required uint64 recipient = 3;
required RCPduResult_E result = 4;
required RCPduTokenStatus_E status = 5;
}
message RCTokenPleaseRequestPdu {
optional RCPduType_E type = 1 [default = RCPDU_TOKEN_PLEASE_REQUEST];
required uint32 initiator = 2;
required uint32 token_id = 3;
}
message RCTokenPleaseIndicationPdu {
optional RCPduType_E type = 1 [default = RCPDU_TOKEN_PLEASE_INDICATION];
required uint32 initiator = 2;
required uint32 token_id = 3;
}
message RCTokenReleaseRequestPdu {
optional RCPduType_E type = 1 [default = RCPDU_TOKEN_RELEASE_REQUEST];
required uint32 initiator = 2;
required uint32 token_id = 3;
}
message RCTokenReleaseConfirmPdu {
optional RCPduType_E type = 1 [default = RCPDU_TOKEN_TEST_REQUEST];
required uint32 initiator = 2;
required uint32 token_id = 3;
required RCPduResult_E result = 4;
required RCPduTokenStatus_E status = 5;
}
message RCTokenTestRequestPdu {
optional RCPduType_E type = 1 [default = RCPDU_TOKEN_TEST_REQUEST];
required uint32 initiator = 2;
required uint32 token_id = 3;
}
message RCTokenTestConfirmPdu {
optional RCPduType_E type = 1 [default = RCPDU_TOKEN_TEST_CONFIRM];
required uint32 initiator = 2;
required uint32 token_id = 3;
required RCPduTokenStatus_E status = 4;
}
//gcc.proto
option optimize_for = LITE_RUNTIME;
message RCConferenceJoinRequestPdu {
required RCPduType_E type = 1 [default = RCPDU_CONFERENCE_JOIN_REQUEST];
required uint32 initiator = 2;
required RCPduNodeType_E node_type = 3;
required RCConferenceDescriptorPdu conf_desc = 4;
}
message RCConferenceJoinResponsePdu {
optional RCPduType_E type = 1 [default = RCPDU_CONFERENCE_JOIN_RESPONSE];
required uint32 conf_id = 2;
required RCPduResult_E result = 3;
optional RCConferenceDescriptorPdu conf_desc = 4;
}
message RCConferenceInviteRequestPdu {
optional RCPduType_E type = 1 [default = RCPDU_CONFERENCE_INVITE_REQUEST];
required uint32 initiator = 2;
required RCConferenceDescriptorPdu conf_desc = 3;
}
message RCConferenceInviteResponsePdu {
optional RCPduType_E type = 1
[default = RCPDU_CONFERENCE_INVITE_RESPONSE];
required RCPduResult_E result = 2;
optional bytes user_data = 3;
}
message RCConferenceLockRequestPdu {
optional RCPduType_E type = 1 [default = RCPDU_CONFERENCE_LOCK_REQUEST];
}
message RCConferenceLockResponsePdu {
optional RCPduType_E type = 1 [default = RCPDU_CONFERENCE_LOCK_RESPONSE];
required RCPduResult_E result = 2;
}
message RCConferenceLockIndicationPdu {
optional RCPduType_E type = 1
[default = RCPDU_CONFERENCE_LOCK_INDICATION];
}
message RCConferenceUnlockRequestPdu {
optional RCPduType_E type = 1 [default = RCPDU_CONFERENCE_UNLOCK_REQUEST];
}
message RCConferenceUnlockResponsePdu {
optional RCPduType_E type = 1
[default = RCPDU_CONFERENCE_UNLOCK_RESPONSE];
required RCPduResult_E result = 2;
}
message RCConferenceUnlockIndicationPdu {
optional RCPduType_E type = 1
[default = RCPDU_CONFERENCE_UNLOCK_INDICATION];
}
message RCConferenceLeaveRequestPdu {
optional RCPduType_E type = 1 [default = RCPDU_CONFERENCE_LEAVE_REQUEST];
required RCPduReason_E reason = 2;
}
message RCConferenceTerminateRequestPdu {
optional RCPduType_E type = 1
[default = RCPDU_CONFERENCE_TERMINATE_REQUEST];
required RCPduReason_E reason = 2;
}
message RCConferenceTerminateResponsePdu {
optional RCPduType_E type = 1
[default = RCPDU_CONFERENCE_TERMINATE_RESPONSE];
required RCPduResult_E result = 2;
}
message RCConferenceTerminateIndicationPdu { // MCS_Uniform_Send_Data on GCC_Broadcast_Channel
optional RCPduType_E type = 1
[default = RCPDU_CONFERENCE_TERMINATE_INDICATION];
required RCPduReason_E reason = 2;
}
message RCConferenceEjectUserRequestPdu { // MCS_Send_Data on Node ID Channel of Top GCC
optional RCPduType_E type = 1
[default = RCPDU_CONFERENCE_EJECT_USER_REQUEST];
required uint32 ejected_node_id = 2;
required RCPduReason_E reason = 3;
}
message RCConferenceEjectUserResponsePdu { // MCS_Send_Data on Node ID Channel of requester
optional RCPduType_E type = 1
[default = RCPDU_CONFERENCE_EJECT_USER_RESPONSE];
required uint32 ejected_node_id = 2;
required RCPduResult_E result = 3;
}
message RCConferenceEjectUserIndicationPdu { // MCS_Uniform_Send_Data on GCC_Broadcast_Channel
optional RCPduType_E type = 1
[default = RCPDU_CONFERENCE_EJECT_USER_INDICATION];
required uint32 ejected_node_id = 2;
required RCPduReason_E reason = 3;
}
message RCRosterUpdateIndicationPdu { // MCS_Send_Data on Node ID Channel or
// MCS_Uniform_Send_Data on GCC_Broadcast_Channel
optional RCPduType_E type = 1 [default = RCPDU_ROSTER_UPDATE_INDICATION];
required bool full_refresh = 2; // Conference Roster and all
repeated RCNodeRecordPdu node_record = 3;
repeated RCApplicationRecordPdu app_record = 4;
}
message RCRegistryUpdateRequestPdu { // MCS_Send_Data on Node ID Channel of Top GCC
optional RCPduType_E type = 1 [default = RCPDU_REGISTRY_UPDATE_REQUEST];
required uint32 key_id = 2;
required uint32 obj_id = 3;
required bytes user_data = 4;
}
message RCRegistryUpdateIndicationPdu { // MCS_Send_Data on Node ID Channel of Top GCC
optional RCPduType_E type = 1 [default = RCPDU_REGISTRY_UPDATE_RESPONSE];
required uint32 key_id = 2;
required uint32 obj_id = 3;
required bytes user_data = 4;
}
message RCRegistryUpdateResponsePdu { // MCS_Send_Data on Node ID Channel of requester
optional RCPduType_E type = 1 [default = RCPDU_REGISTRY_UPDATE_INDICATION];
required uint32 key_id = 2;
required uint32 obj_id = 3;
required RCPduResult_E result = 4;
}
message RCFunctionNotSupportedResponsePdu {
optional RCPduType_E type = 1
[default = RCPDU_FUNCTION_NOT_SUPPORTED_RESPONSE];
required uint32 request_pdu_id = 2;
}
//ape.proto
option optimize_for = LITE_RUNTIME;
message RCConferenceSendDataRequestPdu {
optional uint32 initiator = 1;
optional uint32 peer = 2;
required bool is_public = 3;
required bytes user_data = 4;
}
message RCChatSendDataRequestPdu {
optional uint32 initiator = 1;
optional uint32 peer = 2;
required bool is_public = 3;
required bytes user_data = 4;
required uint32 from_role = 5;
required bytes from_name = 6;
}
message RCChatSendH5DataRequestPdu {
optional uint32 initiator = 1;
optional uint32 peer = 2;
required bool is_public = 3;
required string user_data = 4;
required string from_role = 5;
required string from_name = 6;
}
message RCDocSendDataRequestPdu {
required int32 id = 1;
required string doc_type = 2;
required string uri = 3;
optional int32 owner = 4;
optional int32 from = 5;
optional string name = 6;
optional int32 cur_page_no = 7;
optional int32 cur_H = 8;
optional int32 cur_V = 9;
optional int32 scale = 10;
optional int32 page_num = 11;
}
message RCGiftSendDataRequestPdu {
optional uint32 initiator = 1;
required uint32 peer = 2;
required uint32 index = 3;
required uint32 num = 4;
optional bytes user_data = 5;
}
message RCAudioSendDataRequestPdu {
optional uint32 initiator = 1;
required bytes user_data = 2;
}
message RCVideoSendDataRequestPdu {
optional uint32 initiator = 1;
required bool key_frame = 2;
required uint32 sequence_id = 3;
required uint32 slice_id = 4;
required bytes user_data = 5;
}
message RCAudioChannelInfoRecordPdu {
required uint32 status = 1;
required uint32 device_id = 2;
required uint32 framerate = 3;
required uint32 bitrate = 4;
required uint32 codec = 5;
}
message RCVideoChannelInfoRecordPdu {
optional uint32 status = 1;
optional uint32 device_id = 2;
optional uint32 width = 3;
optional uint32 height = 4;
optional uint32 framerate = 5;
optional uint32 bitrate = 6;
optional uint32 codec = 7;
optional string peer_id = 8;
optional string url = 9;
optional uint32 type = 10;
optional string shamlive = 11;
optional uint32 livetype = 12;
optional uint32 releaseGrab = 13;
optional string curTime = 14;
}
message RCAudioDeviceInfoRecordPdu {
required uint32 device_id = 1;
required string device_name = 2;
}
message RCVideoDeviceInfoRecordPdu {
required uint32 device_id = 1;
required string device_name = 2;
}
message RCNodeInfoRecordPdu {
required uint32 node_id = 1;
required string name = 2;
required uint32 role = 3;
required uint32 level = 4;
repeated RCAudioDeviceInfoRecordPdu audio_records = 5;
repeated RCVideoDeviceInfoRecordPdu video_records = 6;
optional uint32 status = 7;
optional bytes user_data = 8;
optional string user_id = 9;
optional uint32 handUpTime = 10;
optional uint32 deviceType = 11;
optional uint32 mobileDirection = 12;
}
message RCVotingPollSettingsPdu {
required bool timer = 1;
optional uint32 time_limit = 2;
optional uint32 total_score = 3;
}
message RCVotingPollResultPdu {
required string title = 1;
required string content = 2;
optional uint32 score = 3;
}
message RCVotingPollQuestionPdu {
required uint32 index = 1;
required uint32 type = 2;
required string title = 3;
repeated string options = 4;
optional uint32 score = 5;
optional uint32 time_limit = 6;
optional string restrict_input = 7;
optional uint32 char_limit = 8;
optional string answer = 9;
repeated uint32 selections = 10;
repeated string responses = 11;
}
message RCVotingPollRecordPdu {
required RCVotingPollSettingsPdu settings = 1;
required string title = 2;
repeated RCVotingPollResultPdu results = 3;
repeated RCVotingPollQuestionPdu questions = 4;
}
message RCNodeInfoUserDataPdu {
optional string qq = 1;
optional string skype = 2;
optional string mobile = 3;
}
message RCWhiteboardDataRequestPdu {
required uint32 id = 1;
required uint32 type = 2;
required uint32 initiator = 3;
optional bytes action = 4;
optional uint32 uncomprLen = 5;
}
message RCTabUpdateDataRequestPdu {
optional uint32 id = 1;
optional bytes action = 2;
optional uint32 uncomprLen =3;
}
//end
`;
... ...
import urlParse from 'url-parse';
let url = urlParse(location.href, true);
export default url;
... ...
/** @license zlib.js 2012 - imaya [ https://github.com/imaya/zlib.js ] The MIT License */(function() {'use strict';function l(d){throw d;}var v=void 0,x=!0,aa=this;function D(d,a){var c=d.split("."),e=aa;!(c[0]in e)&&e.execScript&&e.execScript("var "+c[0]);for(var b;c.length&&(b=c.shift());)!c.length&&a!==v?e[b]=a:e=e[b]?e[b]:e[b]={}};var F="undefined"!==typeof Uint8Array&&"undefined"!==typeof Uint16Array&&"undefined"!==typeof Uint32Array&&"undefined"!==typeof DataView;function H(d,a){this.index="number"===typeof a?a:0;this.i=0;this.buffer=d instanceof(F?Uint8Array:Array)?d:new (F?Uint8Array:Array)(32768);2*this.buffer.length<=this.index&&l(Error("invalid index"));this.buffer.length<=this.index&&this.f()}H.prototype.f=function(){var d=this.buffer,a,c=d.length,e=new (F?Uint8Array:Array)(c<<1);if(F)e.set(d);else for(a=0;a<c;++a)e[a]=d[a];return this.buffer=e};
H.prototype.d=function(d,a,c){var e=this.buffer,b=this.index,f=this.i,g=e[b],h;c&&1<a&&(d=8<a?(N[d&255]<<24|N[d>>>8&255]<<16|N[d>>>16&255]<<8|N[d>>>24&255])>>32-a:N[d]>>8-a);if(8>a+f)g=g<<a|d,f+=a;else for(h=0;h<a;++h)g=g<<1|d>>a-h-1&1,8===++f&&(f=0,e[b++]=N[g],g=0,b===e.length&&(e=this.f()));e[b]=g;this.buffer=e;this.i=f;this.index=b};H.prototype.finish=function(){var d=this.buffer,a=this.index,c;0<this.i&&(d[a]<<=8-this.i,d[a]=N[d[a]],a++);F?c=d.subarray(0,a):(d.length=a,c=d);return c};
var fa=new (F?Uint8Array:Array)(256),O;for(O=0;256>O;++O){for(var P=O,Q=P,ga=7,P=P>>>1;P;P>>>=1)Q<<=1,Q|=P&1,--ga;fa[O]=(Q<<ga&255)>>>0}var N=fa;function ha(d){this.buffer=new (F?Uint16Array:Array)(2*d);this.length=0}ha.prototype.getParent=function(d){return 2*((d-2)/4|0)};ha.prototype.push=function(d,a){var c,e,b=this.buffer,f;c=this.length;b[this.length++]=a;for(b[this.length++]=d;0<c;)if(e=this.getParent(c),b[c]>b[e])f=b[c],b[c]=b[e],b[e]=f,f=b[c+1],b[c+1]=b[e+1],b[e+1]=f,c=e;else break;return this.length};
ha.prototype.pop=function(){var d,a,c=this.buffer,e,b,f;a=c[0];d=c[1];this.length-=2;c[0]=c[this.length];c[1]=c[this.length+1];for(f=0;;){b=2*f+2;if(b>=this.length)break;b+2<this.length&&c[b+2]>c[b]&&(b+=2);if(c[b]>c[f])e=c[f],c[f]=c[b],c[b]=e,e=c[f+1],c[f+1]=c[b+1],c[b+1]=e;else break;f=b}return{index:d,value:a,length:this.length}};function R(d){var a=d.length,c=0,e=Number.POSITIVE_INFINITY,b,f,g,h,k,n,q,r,p,m;for(r=0;r<a;++r)d[r]>c&&(c=d[r]),d[r]<e&&(e=d[r]);b=1<<c;f=new (F?Uint32Array:Array)(b);g=1;h=0;for(k=2;g<=c;){for(r=0;r<a;++r)if(d[r]===g){n=0;q=h;for(p=0;p<g;++p)n=n<<1|q&1,q>>=1;m=g<<16|r;for(p=n;p<b;p+=k)f[p]=m;++h}++g;h<<=1;k<<=1}return[f,c,e]};function ia(d,a){this.h=ma;this.w=0;this.input=F&&d instanceof Array?new Uint8Array(d):d;this.b=0;a&&(a.lazy&&(this.w=a.lazy),"number"===typeof a.compressionType&&(this.h=a.compressionType),a.outputBuffer&&(this.a=F&&a.outputBuffer instanceof Array?new Uint8Array(a.outputBuffer):a.outputBuffer),"number"===typeof a.outputIndex&&(this.b=a.outputIndex));this.a||(this.a=new (F?Uint8Array:Array)(32768))}var ma=2,na={NONE:0,r:1,k:ma,O:3},oa=[],S;
for(S=0;288>S;S++)switch(x){case 143>=S:oa.push([S+48,8]);break;case 255>=S:oa.push([S-144+400,9]);break;case 279>=S:oa.push([S-256+0,7]);break;case 287>=S:oa.push([S-280+192,8]);break;default:l("invalid literal: "+S)}
ia.prototype.j=function(){var d,a,c,e,b=this.input;switch(this.h){case 0:c=0;for(e=b.length;c<e;){a=F?b.subarray(c,c+65535):b.slice(c,c+65535);c+=a.length;var f=a,g=c===e,h=v,k=v,n=v,q=v,r=v,p=this.a,m=this.b;if(F){for(p=new Uint8Array(this.a.buffer);p.length<=m+f.length+5;)p=new Uint8Array(p.length<<1);p.set(this.a)}h=g?1:0;p[m++]=h|0;k=f.length;n=~k+65536&65535;p[m++]=k&255;p[m++]=k>>>8&255;p[m++]=n&255;p[m++]=n>>>8&255;if(F)p.set(f,m),m+=f.length,p=p.subarray(0,m);else{q=0;for(r=f.length;q<r;++q)p[m++]=
f[q];p.length=m}this.b=m;this.a=p}break;case 1:var s=new H(F?new Uint8Array(this.a.buffer):this.a,this.b);s.d(1,1,x);s.d(1,2,x);var w=pa(this,b),y,ja,A;y=0;for(ja=w.length;y<ja;y++)if(A=w[y],H.prototype.d.apply(s,oa[A]),256<A)s.d(w[++y],w[++y],x),s.d(w[++y],5),s.d(w[++y],w[++y],x);else if(256===A)break;this.a=s.finish();this.b=this.a.length;break;case ma:var C=new H(F?new Uint8Array(this.a.buffer):this.a,this.b),Ea,M,U,V,W,gb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],ba,Fa,ca,Ga,ka,ra=Array(19),
Ha,X,la,z,Ia;Ea=ma;C.d(1,1,x);C.d(Ea,2,x);M=pa(this,b);ba=qa(this.M,15);Fa=sa(ba);ca=qa(this.L,7);Ga=sa(ca);for(U=286;257<U&&0===ba[U-1];U--);for(V=30;1<V&&0===ca[V-1];V--);var Ja=U,Ka=V,I=new (F?Uint32Array:Array)(Ja+Ka),t,J,u,da,G=new (F?Uint32Array:Array)(316),E,B,K=new (F?Uint8Array:Array)(19);for(t=J=0;t<Ja;t++)I[J++]=ba[t];for(t=0;t<Ka;t++)I[J++]=ca[t];if(!F){t=0;for(da=K.length;t<da;++t)K[t]=0}t=E=0;for(da=I.length;t<da;t+=J){for(J=1;t+J<da&&I[t+J]===I[t];++J);u=J;if(0===I[t])if(3>u)for(;0<
u--;)G[E++]=0,K[0]++;else for(;0<u;)B=138>u?u:138,B>u-3&&B<u&&(B=u-3),10>=B?(G[E++]=17,G[E++]=B-3,K[17]++):(G[E++]=18,G[E++]=B-11,K[18]++),u-=B;else if(G[E++]=I[t],K[I[t]]++,u--,3>u)for(;0<u--;)G[E++]=I[t],K[I[t]]++;else for(;0<u;)B=6>u?u:6,B>u-3&&B<u&&(B=u-3),G[E++]=16,G[E++]=B-3,K[16]++,u-=B}d=F?G.subarray(0,E):G.slice(0,E);ka=qa(K,7);for(z=0;19>z;z++)ra[z]=ka[gb[z]];for(W=19;4<W&&0===ra[W-1];W--);Ha=sa(ka);C.d(U-257,5,x);C.d(V-1,5,x);C.d(W-4,4,x);for(z=0;z<W;z++)C.d(ra[z],3,x);z=0;for(Ia=d.length;z<
Ia;z++)if(X=d[z],C.d(Ha[X],ka[X],x),16<=X){z++;switch(X){case 16:la=2;break;case 17:la=3;break;case 18:la=7;break;default:l("invalid code: "+X)}C.d(d[z],la,x)}var La=[Fa,ba],Ma=[Ga,ca],L,Na,ea,ua,Oa,Pa,Qa,Ra;Oa=La[0];Pa=La[1];Qa=Ma[0];Ra=Ma[1];L=0;for(Na=M.length;L<Na;++L)if(ea=M[L],C.d(Oa[ea],Pa[ea],x),256<ea)C.d(M[++L],M[++L],x),ua=M[++L],C.d(Qa[ua],Ra[ua],x),C.d(M[++L],M[++L],x);else if(256===ea)break;this.a=C.finish();this.b=this.a.length;break;default:l("invalid compression type")}return this.a};
function ta(d,a){this.length=d;this.H=a}
var va=function(){function d(b){switch(x){case 3===b:return[257,b-3,0];case 4===b:return[258,b-4,0];case 5===b:return[259,b-5,0];case 6===b:return[260,b-6,0];case 7===b:return[261,b-7,0];case 8===b:return[262,b-8,0];case 9===b:return[263,b-9,0];case 10===b:return[264,b-10,0];case 12>=b:return[265,b-11,1];case 14>=b:return[266,b-13,1];case 16>=b:return[267,b-15,1];case 18>=b:return[268,b-17,1];case 22>=b:return[269,b-19,2];case 26>=b:return[270,b-23,2];case 30>=b:return[271,b-27,2];case 34>=b:return[272,
b-31,2];case 42>=b:return[273,b-35,3];case 50>=b:return[274,b-43,3];case 58>=b:return[275,b-51,3];case 66>=b:return[276,b-59,3];case 82>=b:return[277,b-67,4];case 98>=b:return[278,b-83,4];case 114>=b:return[279,b-99,4];case 130>=b:return[280,b-115,4];case 162>=b:return[281,b-131,5];case 194>=b:return[282,b-163,5];case 226>=b:return[283,b-195,5];case 257>=b:return[284,b-227,5];case 258===b:return[285,b-258,0];default:l("invalid length: "+b)}}var a=[],c,e;for(c=3;258>=c;c++)e=d(c),a[c]=e[2]<<24|e[1]<<
16|e[0];return a}(),wa=F?new Uint32Array(va):va;
function pa(d,a){function c(b,c){var a=b.H,d=[],e=0,f;f=wa[b.length];d[e++]=f&65535;d[e++]=f>>16&255;d[e++]=f>>24;var g;switch(x){case 1===a:g=[0,a-1,0];break;case 2===a:g=[1,a-2,0];break;case 3===a:g=[2,a-3,0];break;case 4===a:g=[3,a-4,0];break;case 6>=a:g=[4,a-5,1];break;case 8>=a:g=[5,a-7,1];break;case 12>=a:g=[6,a-9,2];break;case 16>=a:g=[7,a-13,2];break;case 24>=a:g=[8,a-17,3];break;case 32>=a:g=[9,a-25,3];break;case 48>=a:g=[10,a-33,4];break;case 64>=a:g=[11,a-49,4];break;case 96>=a:g=[12,a-
65,5];break;case 128>=a:g=[13,a-97,5];break;case 192>=a:g=[14,a-129,6];break;case 256>=a:g=[15,a-193,6];break;case 384>=a:g=[16,a-257,7];break;case 512>=a:g=[17,a-385,7];break;case 768>=a:g=[18,a-513,8];break;case 1024>=a:g=[19,a-769,8];break;case 1536>=a:g=[20,a-1025,9];break;case 2048>=a:g=[21,a-1537,9];break;case 3072>=a:g=[22,a-2049,10];break;case 4096>=a:g=[23,a-3073,10];break;case 6144>=a:g=[24,a-4097,11];break;case 8192>=a:g=[25,a-6145,11];break;case 12288>=a:g=[26,a-8193,12];break;case 16384>=
a:g=[27,a-12289,12];break;case 24576>=a:g=[28,a-16385,13];break;case 32768>=a:g=[29,a-24577,13];break;default:l("invalid distance")}f=g;d[e++]=f[0];d[e++]=f[1];d[e++]=f[2];var h,k;h=0;for(k=d.length;h<k;++h)p[m++]=d[h];w[d[0]]++;y[d[3]]++;s=b.length+c-1;r=null}var e,b,f,g,h,k={},n,q,r,p=F?new Uint16Array(2*a.length):[],m=0,s=0,w=new (F?Uint32Array:Array)(286),y=new (F?Uint32Array:Array)(30),ja=d.w,A;if(!F){for(f=0;285>=f;)w[f++]=0;for(f=0;29>=f;)y[f++]=0}w[256]=1;e=0;for(b=a.length;e<b;++e){f=h=0;
for(g=3;f<g&&e+f!==b;++f)h=h<<8|a[e+f];k[h]===v&&(k[h]=[]);n=k[h];if(!(0<s--)){for(;0<n.length&&32768<e-n[0];)n.shift();if(e+3>=b){r&&c(r,-1);f=0;for(g=b-e;f<g;++f)A=a[e+f],p[m++]=A,++w[A];break}0<n.length?(q=xa(a,e,n),r?r.length<q.length?(A=a[e-1],p[m++]=A,++w[A],c(q,0)):c(r,-1):q.length<ja?r=q:c(q,0)):r?c(r,-1):(A=a[e],p[m++]=A,++w[A])}n.push(e)}p[m++]=256;w[256]++;d.M=w;d.L=y;return F?p.subarray(0,m):p}
function xa(d,a,c){var e,b,f=0,g,h,k,n,q=d.length;h=0;n=c.length;a:for(;h<n;h++){e=c[n-h-1];g=3;if(3<f){for(k=f;3<k;k--)if(d[e+k-1]!==d[a+k-1])continue a;g=f}for(;258>g&&a+g<q&&d[e+g]===d[a+g];)++g;g>f&&(b=e,f=g);if(258===g)break}return new ta(f,a-b)}
function qa(d,a){var c=d.length,e=new ha(572),b=new (F?Uint8Array:Array)(c),f,g,h,k,n;if(!F)for(k=0;k<c;k++)b[k]=0;for(k=0;k<c;++k)0<d[k]&&e.push(k,d[k]);f=Array(e.length/2);g=new (F?Uint32Array:Array)(e.length/2);if(1===f.length)return b[e.pop().index]=1,b;k=0;for(n=e.length/2;k<n;++k)f[k]=e.pop(),g[k]=f[k].value;h=ya(g,g.length,a);k=0;for(n=f.length;k<n;++k)b[f[k].index]=h[k];return b}
function ya(d,a,c){function e(b){var c=k[b][n[b]];c===a?(e(b+1),e(b+1)):--g[c];++n[b]}var b=new (F?Uint16Array:Array)(c),f=new (F?Uint8Array:Array)(c),g=new (F?Uint8Array:Array)(a),h=Array(c),k=Array(c),n=Array(c),q=(1<<c)-a,r=1<<c-1,p,m,s,w,y;b[c-1]=a;for(m=0;m<c;++m)q<r?f[m]=0:(f[m]=1,q-=r),q<<=1,b[c-2-m]=(b[c-1-m]/2|0)+a;b[0]=f[0];h[0]=Array(b[0]);k[0]=Array(b[0]);for(m=1;m<c;++m)b[m]>2*b[m-1]+f[m]&&(b[m]=2*b[m-1]+f[m]),h[m]=Array(b[m]),k[m]=Array(b[m]);for(p=0;p<a;++p)g[p]=c;for(s=0;s<b[c-1];++s)h[c-
1][s]=d[s],k[c-1][s]=s;for(p=0;p<c;++p)n[p]=0;1===f[c-1]&&(--g[0],++n[c-1]);for(m=c-2;0<=m;--m){w=p=0;y=n[m+1];for(s=0;s<b[m];s++)w=h[m+1][y]+h[m+1][y+1],w>d[p]?(h[m][s]=w,k[m][s]=a,y+=2):(h[m][s]=d[p],k[m][s]=p,++p);n[m]=0;1===f[m]&&e(m)}return g}
function sa(d){var a=new (F?Uint16Array:Array)(d.length),c=[],e=[],b=0,f,g,h,k;f=0;for(g=d.length;f<g;f++)c[d[f]]=(c[d[f]]|0)+1;f=1;for(g=16;f<=g;f++)e[f]=b,b+=c[f]|0,b<<=1;f=0;for(g=d.length;f<g;f++){b=e[d[f]];e[d[f]]+=1;h=a[f]=0;for(k=d[f];h<k;h++)a[f]=a[f]<<1|b&1,b>>>=1}return a};function T(d,a){this.l=[];this.m=32768;this.e=this.g=this.c=this.q=0;this.input=F?new Uint8Array(d):d;this.s=!1;this.n=za;this.C=!1;if(a||!(a={}))a.index&&(this.c=a.index),a.bufferSize&&(this.m=a.bufferSize),a.bufferType&&(this.n=a.bufferType),a.resize&&(this.C=a.resize);switch(this.n){case Aa:this.b=32768;this.a=new (F?Uint8Array:Array)(32768+this.m+258);break;case za:this.b=0;this.a=new (F?Uint8Array:Array)(this.m);this.f=this.K;this.t=this.I;this.o=this.J;break;default:l(Error("invalid inflate mode"))}}
var Aa=0,za=1,Ba={F:Aa,D:za};
T.prototype.p=function(){for(;!this.s;){var d=Y(this,3);d&1&&(this.s=x);d>>>=1;switch(d){case 0:var a=this.input,c=this.c,e=this.a,b=this.b,f=a.length,g=v,h=v,k=e.length,n=v;this.e=this.g=0;c+1>=f&&l(Error("invalid uncompressed block header: LEN"));g=a[c++]|a[c++]<<8;c+1>=f&&l(Error("invalid uncompressed block header: NLEN"));h=a[c++]|a[c++]<<8;g===~h&&l(Error("invalid uncompressed block header: length verify"));c+g>a.length&&l(Error("input buffer is broken"));switch(this.n){case Aa:for(;b+g>e.length;){n=
k-b;g-=n;if(F)e.set(a.subarray(c,c+n),b),b+=n,c+=n;else for(;n--;)e[b++]=a[c++];this.b=b;e=this.f();b=this.b}break;case za:for(;b+g>e.length;)e=this.f({v:2});break;default:l(Error("invalid inflate mode"))}if(F)e.set(a.subarray(c,c+g),b),b+=g,c+=g;else for(;g--;)e[b++]=a[c++];this.c=c;this.b=b;this.a=e;break;case 1:this.o(Ca,Da);break;case 2:Sa(this);break;default:l(Error("unknown BTYPE: "+d))}}return this.t()};
var Ta=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],Ua=F?new Uint16Array(Ta):Ta,Va=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,258,258],Wa=F?new Uint16Array(Va):Va,Xa=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0],Ya=F?new Uint8Array(Xa):Xa,Za=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],$a=F?new Uint16Array(Za):Za,ab=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,
10,11,11,12,12,13,13],bb=F?new Uint8Array(ab):ab,cb=new (F?Uint8Array:Array)(288),Z,db;Z=0;for(db=cb.length;Z<db;++Z)cb[Z]=143>=Z?8:255>=Z?9:279>=Z?7:8;var Ca=R(cb),eb=new (F?Uint8Array:Array)(30),fb,hb;fb=0;for(hb=eb.length;fb<hb;++fb)eb[fb]=5;var Da=R(eb);function Y(d,a){for(var c=d.g,e=d.e,b=d.input,f=d.c,g=b.length,h;e<a;)f>=g&&l(Error("input buffer is broken")),c|=b[f++]<<e,e+=8;h=c&(1<<a)-1;d.g=c>>>a;d.e=e-a;d.c=f;return h}
function ib(d,a){for(var c=d.g,e=d.e,b=d.input,f=d.c,g=b.length,h=a[0],k=a[1],n,q;e<k&&!(f>=g);)c|=b[f++]<<e,e+=8;n=h[c&(1<<k)-1];q=n>>>16;d.g=c>>q;d.e=e-q;d.c=f;return n&65535}
function Sa(d){function a(a,b,c){var d,e=this.z,f,g;for(g=0;g<a;)switch(d=ib(this,b),d){case 16:for(f=3+Y(this,2);f--;)c[g++]=e;break;case 17:for(f=3+Y(this,3);f--;)c[g++]=0;e=0;break;case 18:for(f=11+Y(this,7);f--;)c[g++]=0;e=0;break;default:e=c[g++]=d}this.z=e;return c}var c=Y(d,5)+257,e=Y(d,5)+1,b=Y(d,4)+4,f=new (F?Uint8Array:Array)(Ua.length),g,h,k,n;for(n=0;n<b;++n)f[Ua[n]]=Y(d,3);if(!F){n=b;for(b=f.length;n<b;++n)f[Ua[n]]=0}g=R(f);h=new (F?Uint8Array:Array)(c);k=new (F?Uint8Array:Array)(e);
d.z=0;d.o(R(a.call(d,c,g,h)),R(a.call(d,e,g,k)))}T.prototype.o=function(d,a){var c=this.a,e=this.b;this.u=d;for(var b=c.length-258,f,g,h,k;256!==(f=ib(this,d));)if(256>f)e>=b&&(this.b=e,c=this.f(),e=this.b),c[e++]=f;else{g=f-257;k=Wa[g];0<Ya[g]&&(k+=Y(this,Ya[g]));f=ib(this,a);h=$a[f];0<bb[f]&&(h+=Y(this,bb[f]));e>=b&&(this.b=e,c=this.f(),e=this.b);for(;k--;)c[e]=c[e++-h]}for(;8<=this.e;)this.e-=8,this.c--;this.b=e};
T.prototype.J=function(d,a){var c=this.a,e=this.b;this.u=d;for(var b=c.length,f,g,h,k;256!==(f=ib(this,d));)if(256>f)e>=b&&(c=this.f(),b=c.length),c[e++]=f;else{g=f-257;k=Wa[g];0<Ya[g]&&(k+=Y(this,Ya[g]));f=ib(this,a);h=$a[f];0<bb[f]&&(h+=Y(this,bb[f]));e+k>b&&(c=this.f(),b=c.length);for(;k--;)c[e]=c[e++-h]}for(;8<=this.e;)this.e-=8,this.c--;this.b=e};
T.prototype.f=function(){var d=new (F?Uint8Array:Array)(this.b-32768),a=this.b-32768,c,e,b=this.a;if(F)d.set(b.subarray(32768,d.length));else{c=0;for(e=d.length;c<e;++c)d[c]=b[c+32768]}this.l.push(d);this.q+=d.length;if(F)b.set(b.subarray(a,a+32768));else for(c=0;32768>c;++c)b[c]=b[a+c];this.b=32768;return b};
T.prototype.K=function(d){var a,c=this.input.length/this.c+1|0,e,b,f,g=this.input,h=this.a;d&&("number"===typeof d.v&&(c=d.v),"number"===typeof d.G&&(c+=d.G));2>c?(e=(g.length-this.c)/this.u[2],f=258*(e/2)|0,b=f<h.length?h.length+f:h.length<<1):b=h.length*c;F?(a=new Uint8Array(b),a.set(h)):a=h;return this.a=a};
T.prototype.t=function(){var d=0,a=this.a,c=this.l,e,b=new (F?Uint8Array:Array)(this.q+(this.b-32768)),f,g,h,k;if(0===c.length)return F?this.a.subarray(32768,this.b):this.a.slice(32768,this.b);f=0;for(g=c.length;f<g;++f){e=c[f];h=0;for(k=e.length;h<k;++h)b[d++]=e[h]}f=32768;for(g=this.b;f<g;++f)b[d++]=a[f];this.l=[];return this.buffer=b};
T.prototype.I=function(){var d,a=this.b;F?this.C?(d=new Uint8Array(a),d.set(this.a.subarray(0,a))):d=this.a.subarray(0,a):(this.a.length>a&&(this.a.length=a),d=this.a);return this.buffer=d};function jb(d){if("string"===typeof d){var a=d.split(""),c,e;c=0;for(e=a.length;c<e;c++)a[c]=(a[c].charCodeAt(0)&255)>>>0;d=a}for(var b=1,f=0,g=d.length,h,k=0;0<g;){h=1024<g?1024:g;g-=h;do b+=d[k++],f+=b;while(--h);b%=65521;f%=65521}return(f<<16|b)>>>0};function kb(d,a){var c,e;this.input=d;this.c=0;if(a||!(a={}))a.index&&(this.c=a.index),a.verify&&(this.N=a.verify);c=d[this.c++];e=d[this.c++];switch(c&15){case lb:this.method=lb;break;default:l(Error("unsupported compression method"))}0!==((c<<8)+e)%31&&l(Error("invalid fcheck flag:"+((c<<8)+e)%31));e&32&&l(Error("fdict flag is not supported"));this.B=new T(d,{index:this.c,bufferSize:a.bufferSize,bufferType:a.bufferType,resize:a.resize})}
kb.prototype.p=function(){var d=this.input,a,c;a=this.B.p();this.c=this.B.c;this.N&&(c=(d[this.c++]<<24|d[this.c++]<<16|d[this.c++]<<8|d[this.c++])>>>0,c!==jb(a)&&l(Error("invalid adler-32 checksum")));return a};var lb=8;function mb(d,a){this.input=d;this.a=new (F?Uint8Array:Array)(32768);this.h=$.k;var c={},e;if((a||!(a={}))&&"number"===typeof a.compressionType)this.h=a.compressionType;for(e in a)c[e]=a[e];c.outputBuffer=this.a;this.A=new ia(this.input,c)}var $=na;
mb.prototype.j=function(){var d,a,c,e,b,f,g,h=0;g=this.a;d=lb;switch(d){case lb:a=Math.LOG2E*Math.log(32768)-8;break;default:l(Error("invalid compression method"))}c=a<<4|d;g[h++]=c;switch(d){case lb:switch(this.h){case $.NONE:b=0;break;case $.r:b=1;break;case $.k:b=2;break;default:l(Error("unsupported compression type"))}break;default:l(Error("invalid compression method"))}e=b<<6|0;g[h++]=e|31-(256*c+e)%31;f=jb(this.input);this.A.b=h;g=this.A.j();h=g.length;F&&(g=new Uint8Array(g.buffer),g.length<=
h+4&&(this.a=new Uint8Array(g.length+4),this.a.set(g),g=this.a),g=g.subarray(0,h+4));g[h++]=f>>24&255;g[h++]=f>>16&255;g[h++]=f>>8&255;g[h++]=f&255;return g};function nb(d,a){var c,e,b,f;if(Object.keys)c=Object.keys(a);else for(e in c=[],b=0,a)c[b++]=e;b=0;for(f=c.length;b<f;++b)e=c[b],D(d+"."+e,a[e])};D("Zlib.Inflate",kb);D("Zlib.Inflate.prototype.decompress",kb.prototype.p);nb("Zlib.Inflate.BufferType",{ADAPTIVE:Ba.D,BLOCK:Ba.F});D("Zlib.Deflate",mb);D("Zlib.Deflate.compress",function(d,a){return(new mb(d,a)).j()});D("Zlib.Deflate.prototype.compress",mb.prototype.j);nb("Zlib.Deflate.CompressionType",{NONE:$.NONE,FIXED:$.r,DYNAMIC:$.k});}).call(this); //@ sourceMappingURL=zlib.min.js.map
... ...
# TEST FOLDER
... ...
console.log('test cases have not been finished.');
... ...
module.exports = function (umdConf) {
umdConf.devServer.host = '0.0.0.0';
//umdConf.webpackFeatures.enableEntryHTML();//生成
umdConf.output.publicPath = '';
umdConf.output.library = 'MessageEngine';
//console.dir(umdConf);
if (umdConf.devMode) {
umdConf.webpackFeatures.enableEntryHot();
} else {
umdConf.webpackFeatures.enableUglifyJs({
comments: false
});
}
};
... ...