From ad5cb79d4093e8334de0acac7c3a9133613ee16f Mon Sep 17 00:00:00 2001
From: Meng <381618248@qq.com>
Date: Tue, 20 Jun 2023 12:00:34 +0800
Subject: [PATCH 01/15] =?UTF-8?q?feat(=E4=BB=BB=E5=8A=A1=E5=8F=AF=E8=A7=81?=
=?UTF-8?q?=E6=80=A7=E5=8A=9F=E8=83=BD=E3=80=81=E5=AD=90=E4=BB=BB=E5=8A=A1?=
=?UTF-8?q?=E4=BC=98=E5=8C=96):=E6=96=B0=E5=A2=9E=E4=BB=BB=E5=8A=A1?=
=?UTF-8?q?=E5=8F=AF=E8=A7=81=E6=80=A7=E6=93=8D=E4=BD=9C=E6=A8=A1=E5=9D=97?=
=?UTF-8?q?=E3=80=81=E4=BB=BB=E5=8A=A1=E8=AF=A6=E6=83=85=E5=AD=90=E4=BB=BB?=
=?UTF-8?q?=E5=8A=A1=E6=A0=B7=E5=BC=8F=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Controllers/Api/ProjectController.php | 57 ++++-
app/Models/ProjectTask.php | 174 +++++++++++++-
app/Tasks/PushTask.php | 4 +-
...93619_add_project_tasks_is_all_visible.php | 36 +++
.../js/pages/manage/components/TaskAdd.vue | 24 ++
.../pages/manage/components/TaskAddSimple.vue | 10 +
.../js/pages/manage/components/TaskDetail.vue | 219 ++++++++++++------
resources/assets/js/store/actions.js | 4 +-
.../sass/pages/components/task-detail.scss | 9 +-
9 files changed, 450 insertions(+), 87 deletions(-)
create mode 100644 database/migrations/2023_06_15_093619_add_project_tasks_is_all_visible.php
diff --git a/app/Http/Controllers/Api/ProjectController.php b/app/Http/Controllers/Api/ProjectController.php
index bb4242856..1db3a301a 100755
--- a/app/Http/Controllers/Api/ProjectController.php
+++ b/app/Http/Controllers/Api/ProjectController.php
@@ -16,6 +16,7 @@ use App\Models\ProjectLog;
use App\Models\ProjectTask;
use App\Models\ProjectTaskFile;
use App\Models\ProjectTaskFlowChange;
+use App\Models\ProjectTaskUser;
use App\Models\ProjectUser;
use App\Models\User;
use App\Models\WebSocketDialog;
@@ -880,8 +881,17 @@ class ProjectController extends AbstractController
public function task__lists()
{
$user = User::auth();
- //
+
+ // 任务可见性
+ $project_ids = Project::whereUserid($user->userid)->pluck('id')->toArray(); // 负责人项目ids
+ $main_task_ids = ProjectTask::whereIn('project_id', $project_ids)->pluck('id')->toArray(); // 负责人项目任务ids
+ $other_task_ids = ProjectTaskUser::whereUserid($user->userid)->whereColumn('task_id', '=', 'task_pid')->whereNotIn('project_id', $project_ids)->pluck('task_id')->toArray(); // 非负责人项目任务ids
+ $all_visible_task_ids = ProjectTask::whereIsAllVisible(1)->pluck('id')->toArray(); // 所有人可见项目ids
+ $one_task_ids = array_merge($main_task_ids, $other_task_ids);
+ $visibility_task_ids = array_merge($one_task_ids, $all_visible_task_ids);
+
$builder = ProjectTask::with(['taskUser', 'taskTag']);
+ $builder->whereIn("project_tasks.id", $visibility_task_ids);
//
$parent_id = intval(Request::input('parent_id'));
$project_id = intval(Request::input('project_id'));
@@ -1326,17 +1336,26 @@ class ProjectController extends AbstractController
*/
public function task__one()
{
- User::auth();
+ $user = User::auth();
//
$task_id = intval(Request::input('task_id'));
$archived = Request::input('archived', 'no');
//
$isArchived = str_replace(['all', 'yes', 'no'], [null, false, true], $archived);
$task = ProjectTask::userTask($task_id, $isArchived, true, false, ['taskUser', 'taskTag']);
+ // 项目可见性
+ $project_userid = Project::whereId($task->project_id)->value('userid'); // 项目负责人
+ if ($task->is_all_visible != 1 && $user->userid != $project_userid) {
+ $visibleUserids = ProjectTaskUser::whereTaskId($task_id)->pluck('userid')->toArray();
+ if (!in_array($user->userid, $visibleUserids)) {
+ return Base::retError('无任务权限');
+ }
+ }
//
$data = $task->toArray();
$data['project_name'] = $task->project?->name;
$data['column_name'] = $task->projectColumn?->name;
+ $data['visibility_appointor'] = $task->is_all_visible==1 ? [0] : ProjectTaskUser::whereTaskId($task_id)->whereOwner(2)->pluck('userid');
return Base::retSuccess('success', $data);
}
@@ -1542,7 +1561,7 @@ class ProjectController extends AbstractController
*/
public function task__add()
{
- User::auth();
+ $user = User::auth();
//
$data = Request::input();
$project_id = intval($data['project_id']);
@@ -1587,6 +1606,17 @@ class ProjectController extends AbstractController
$data = $data->toArray();
$data['new_column'] = $newColumn;
}
+
+
+ if ($data['is_all_visible'] == 1) {
+ $data['is_visible'] = 1;
+ } else {
+ $projectOwner = Project::whereId($data['project_id'])->pluck('userid')->toArray(); // 项目负责人
+ $taskOwnerAndAssists = ProjectTaskUser::select(['userid', 'owner'])->whereTaskId($data['id'])->pluck('userid')->toArray();
+ $visibleIds = array_merge($projectOwner, $taskOwnerAndAssists);
+ $data['is_visible'] = in_array($user->userid, $visibleIds) ? 1 : 0;
+ }
+
$task->pushMsg('add', $data);
$task->taskPush(null, 0);
return Base::retSuccess('添加成功', $data);
@@ -1648,6 +1678,7 @@ class ProjectController extends AbstractController
* @apiParam {String} [content] 任务详情(子任务不支持)
* @apiParam {String} [color] 背景色(子任务不支持)
* @apiParam {Array} [assist] 修改协助人员(子任务不支持)
+ * @apiParam {Array} [visibility_appointor] 修改可见性人员
*
* @apiParam {Number} [p_level] 优先级相关(子任务不支持)
* @apiParam {String} [p_name] 优先级相关(子任务不支持)
@@ -1664,17 +1695,31 @@ class ProjectController extends AbstractController
{
User::auth();
//
- $data = Request::input();
- $task_id = intval($data['task_id']);
+ $param = Request::input();
+ $task_id = intval($param['task_id']);
//
$task = ProjectTask::userTask($task_id, true, true, 2);
// 更新任务
$updateMarking = [];
- $task->updateTask($data, $updateMarking);
+ $task->updateTask($param, $updateMarking);
//
$data = ProjectTask::oneTask($task->id)->toArray();
$data['update_marking'] = $updateMarking ?: json_decode('{}');
+ $data['visibility_appointor'] = $data['is_all_visible'] == 1 ? [0] : ProjectTaskUser::whereTaskId($task->id)->whereOwner(2)->pluck('userid');
$task->pushMsg('update', $data);
+ // 可见性推送
+ if (Arr::exists($param, 'visibility_appointor')) {
+ if ($data['is_all_visible'] == 1) {
+ $task->pushMsgVisibleAdd($data);
+ }
+ if ($data['is_all_visible'] == 0) {
+ if ($param['visibility_appointor']) {
+ $task->pushMsgVisibleUpdate($data);
+ } else {
+ $task->pushMsgVisibleRemove();
+ }
+ }
+ }
//
return Base::retSuccess('修改成功', $data);
}
diff --git a/app/Models/ProjectTask.php b/app/Models/ProjectTask.php
index 6b319bfa5..3ac4e0e62 100644
--- a/app/Models/ProjectTask.php
+++ b/app/Models/ProjectTask.php
@@ -370,6 +370,18 @@ class ProjectTask extends AbstractModel
$p_color = $data['p_color'];
$top = intval($data['top']);
$userid = User::userid();
+ $visibility_appoint = $data['visibility_appoint'];
+ $visibility_appointor = $data['visibility_appointor'];
+ // 可见性
+ $visibility_userids = [];
+ $is_all_visible = 0;
+ if ($visibility_appoint) {
+ if (in_array(0, $visibility_appointor)) {
+ $is_all_visible = 1;
+ } else {
+ $visibility_userids = $visibility_appointor;
+ }
+ }
//
if (ProjectTask::whereProjectId($project_id)
->whereNull('project_tasks.complete_at')
@@ -398,6 +410,7 @@ class ProjectTask extends AbstractModel
'p_level' => $p_level,
'p_name' => $p_name,
'p_color' => $p_color,
+ 'is_all_visible' => $is_all_visible
]);
if ($content) {
$task->desc = Base::getHtml($content, 100);
@@ -462,7 +475,7 @@ class ProjectTask extends AbstractModel
}
}
//
- return AbstractModel::transaction(function() use ($assist, $times, $subtasks, $content, $owner, $task) {
+ return AbstractModel::transaction(function() use ($assist, $times, $subtasks, $content, $owner, $task, $visibility_userids) {
$task->save();
$owner = array_values(array_unique($owner));
foreach ($owner as $uid) {
@@ -484,6 +497,17 @@ class ProjectTask extends AbstractModel
'owner' => 0,
])->save();
}
+
+ foreach ($visibility_userids as $uid) {
+ ProjectTaskUser::createInstance([
+ 'project_id' => $task->project_id,
+ 'task_id' => $task->id,
+ 'task_pid' => $task->parent_id ?: $task->id,
+ 'userid' => $uid,
+ 'owner' => 2,
+ ])->save();
+ }
+
if ($content) {
ProjectTaskContent::createInstance([
'project_id' => $task->project_id,
@@ -691,6 +715,26 @@ class ProjectTask extends AbstractModel
$updateMarking['is_update_project'] = true;
$this->syncDialogUser();
}
+ // 可见性
+ if (Arr::exists($data, 'visibility_appointor')) {
+ if (in_array(0, $data['visibility_appointor'])) {
+ ProjectTask::whereId($data['task_id'])->update(['is_all_visible' => 1]);
+ } else {
+ ProjectTask::whereId($data['task_id'])->update(['is_all_visible' => 0]);
+ // 覆盖
+ ProjectTaskUser::whereTaskId($data['task_id'])->whereOwner(2)->delete();
+ foreach ($data['visibility_appointor'] as $uid) {
+ ProjectTaskUser::createInstance([
+ 'project_id' => $this->project_id,
+ 'task_id' => $this->id,
+ 'task_pid' => $this->parent_id ?: $this->id,
+ 'userid' => $uid,
+ 'owner' => 2,
+ ])->save();
+ }
+
+ }
+ }
// 计划时间(原则:子任务时间在主任务时间内)
if (Arr::exists($data, 'times')) {
$oldAt = [Carbon::parse($this->start_at), Carbon::parse($this->end_at)];
@@ -1372,6 +1416,8 @@ class ProjectTask extends AbstractModel
$userids = $this->project->relationUserids();
} elseif (!is_array($userid)) {
$userids = [$userid];
+ } elseif (is_array($userid)) {
+ $userids = $userid;
}
//
$array = [];
@@ -1391,8 +1437,10 @@ class ProjectTask extends AbstractModel
];
}
// 协助人
- $assists = $taskUser->pluck('userid')->toArray();
- $assists = array_intersect($userids, array_diff($assists, $owners));
+// $assists = $taskUser->pluck('userid')->toArray();
+// $assists = array_intersect($userids, array_diff($assists, $owners));
+ $assists = $taskUser->where('owner', 0)->pluck('userid')->toArray();
+ $assists = array_intersect($userids, $assists);
if ($assists) {
$array[] = [
'userid' => array_values($assists),
@@ -1403,13 +1451,21 @@ class ProjectTask extends AbstractModel
];
}
// 项目成员(其他人)
- $userids = array_diff($userids, $owners, $assists);
+ if ($data['is_all_visible'] == 1) {
+ // 全部可见
+ $userids = array_diff($userids, $owners, $assists);
+ } else {
+ // 指定可见
+ $visible = $taskUser->where('owner', 2)->pluck('userid')->toArray();
+ $userids = $visible;
+ }
$data = array_merge($data, [
'owner' => 0,
'assist' => 0,
]);
}
}
+ //
$array[] = [
'userid' => array_values($userids),
'data' => $data
@@ -1430,6 +1486,116 @@ class ProjectTask extends AbstractModel
}
}
+ /**
+ * 添加可见性任务 推送
+ * @param array|self $data 发送内容,默认为[id, parent_id, project_id, column_id, dialog_id]
+ */
+ public function pushMsgVisibleAdd($data = null)
+ {
+ if (!$this->project) {
+ return;
+ }
+ if ($data === null) {
+ $data = [
+ 'id' => $this->id,
+ 'parent_id' => $this->parent_id,
+ 'project_id' => $this->project_id,
+ 'column_id' => $this->column_id,
+ 'dialog_id' => $this->dialog_id,
+ ];
+ } elseif ($data instanceof self) {
+ $data = $data->toArray();
+ }
+ //
+ $array = [];
+ if ($this->is_all_visible == 0) {
+ $userids = ProjectTaskUser::select(['userid', 'owner'])->whereTaskId($this->id)->pluck('userid')->toArray();
+ } else {
+ $userids = ProjectUser::whereProjectId($this->project_id)->pluck('userid')->toArray(); // 项目成员
+ }
+ //
+ $array[] = [
+ 'userid' => array_values($userids),
+ 'data' => $data
+ ];
+ //
+ foreach ($array as $item) {
+ $params = [
+// 'ignoreFd' => Request::header('fd'),
+ 'ignoreFd' => '0',
+ 'userid' => array_values($item),
+ 'msg' => [
+ 'type' => 'projectTask',
+ 'action' => 'add',
+ 'data' => $item['data'],
+ ]
+ ];
+ $task = new PushTask($params, false);
+ Task::deliver($task);
+ }
+ }
+
+ /**
+ * 删除可见性任务 推送
+ * @param string $action
+ * @param array|self $data 发送内容,默认为[id, parent_id, project_id, column_id, dialog_id]
+ */
+ public function pushMsgVisibleRemove($data = null)
+ {
+ if (!$this->project) {
+ return;
+ }
+ if ($data === null) {
+ $data = [
+ 'id' => $this->id,
+ 'parent_id' => $this->parent_id,
+ 'project_id' => $this->project_id,
+ 'column_id' => $this->column_id,
+ 'dialog_id' => $this->dialog_id,
+ ];
+ } elseif ($data instanceof self) {
+ $data = $data->toArray();
+ }
+ //
+ $array = [];
+ // 项目成员 与 项目负责人,任务负责人、协助人的差集
+ $projectUserids = ProjectUser::whereProjectId($this->project_id)->pluck('userid')->toArray(); // 项目成员
+ $projectOwner = Project::whereId($this->project_id)->pluck('userid')->toArray(); // 项目负责人
+ $taskOwnerAndAssists = ProjectTaskUser::select(['userid', 'owner'])->whereIn('owner', [0, 1])->whereTaskId($this->id)->pluck('userid')->toArray();
+ $userids = array_diff($projectUserids, $projectOwner, $taskOwnerAndAssists);
+ //
+ $array[] = [
+ 'userid' => array_values($userids),
+ 'data' => $data
+ ];
+ //
+ foreach ($array as $item) {
+ $params = [
+// 'ignoreFd' => Request::header('fd'),
+ 'ignoreFd' => '0',
+ 'userid' => array_values($item),
+ 'msg' => [
+ 'type' => 'projectTask',
+ 'action' => 'delete',
+ 'data' => $item['data'],
+ ]
+ ];
+ $task = new PushTask($params, false);
+ Task::deliver($task);
+ }
+ }
+
+ /**
+ * 更新可见性任务 推送
+ * @param array|self $data 发送内容,默认为[id, parent_id, project_id, column_id, dialog_id]
+ */
+ public function pushMsgVisibleUpdate($data)
+ {
+ $this->pushMsgVisibleRemove();
+ usleep(300);
+ $this->pushMsgVisibleAdd($data);
+ }
+
/**
* 任务提醒
* @param $userids
diff --git a/app/Tasks/PushTask.php b/app/Tasks/PushTask.php
index 6f506f734..2e02d0acf 100644
--- a/app/Tasks/PushTask.php
+++ b/app/Tasks/PushTask.php
@@ -149,7 +149,7 @@ class PushTask extends AbstractTask
if (!is_array($userid)) {
$userid = [$userid];
}
- foreach ($userid as $uid) {
+ foreach ($userid[0] as $uid) {
$row = WebSocket::select(['fd'])->whereUserid($uid)->pluck('fd');
if ($row->isNotEmpty()) {
$array = array_merge($array, $row->toArray());
@@ -162,6 +162,8 @@ class PushTask extends AbstractTask
$ignoreFd = is_array($ignoreFd) ? $ignoreFd : [$ignoreFd];
}
// 开始发送
+ \Log::info('fd');
+ \Log::info($array);
foreach ($array as $fid) {
if ($ignoreFd) {
if (in_array($fid, $ignoreFd)) continue;
diff --git a/database/migrations/2023_06_15_093619_add_project_tasks_is_all_visible.php b/database/migrations/2023_06_15_093619_add_project_tasks_is_all_visible.php
new file mode 100644
index 000000000..ac95cf314
--- /dev/null
+++ b/database/migrations/2023_06_15_093619_add_project_tasks_is_all_visible.php
@@ -0,0 +1,36 @@
+tinyInteger('is_all_visible')->nullable()->default(1)->after('is_default')->comment('是否所有人可见');
+ }
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ //
+ Schema::table('project_tasks', function (Blueprint $table) {
+ $table->dropColumn("avatar");
+ });
+ }
+}
diff --git a/resources/assets/js/pages/manage/components/TaskAdd.vue b/resources/assets/js/pages/manage/components/TaskAdd.vue
index 8062266e2..0d61dc532 100644
--- a/resources/assets/js/pages/manage/components/TaskAdd.vue
+++ b/resources/assets/js/pages/manage/components/TaskAdd.vue
@@ -92,6 +92,25 @@
+
"+Cn(e[t].content)+`
-`};Xt.fence=function(e,t,n,r,i){var l=e[t],u=l.info?$G(l.info).trim():"",c="",d="",f,g,h,p,m;return u&&(h=u.split(/(\s+)/g),c=h[0],d=h.slice(2).join("")),n.highlight?f=n.highlight(l.content,c,d)||Cn(l.content):f=Cn(l.content),f.indexOf(""+f+`
-`):""+f+`
-`};Xt.image=function(e,t,n,r,i){var l=e[t];return l.attrs[l.attrIndex("alt")][1]=i.renderInlineAsText(l.children,n,r),i.renderToken(e,t,n)};Xt.hardbreak=function(e,t,n){return n.xhtmlOut?`"+Cn(e[t].content)+`
+`};Qt.fence=function(e,t,n,r,a){var l=e[t],u=l.info?$G(l.info).trim():"",c="",d="",f,g,h,p,m;return u&&(h=u.split(/(\s+)/g),c=h[0],d=h.slice(2).join("")),n.highlight?f=n.highlight(l.content,c,d)||Cn(l.content):f=Cn(l.content),f.indexOf(""+f+`
+`):""+f+`
+`};Qt.image=function(e,t,n,r,a){var l=e[t];return l.attrs[l.attrIndex("alt")][1]=a.renderInlineAsText(l.children,n,r),a.renderToken(e,t,n)};Qt.hardbreak=function(e,t,n){return n.xhtmlOut?`=4){i++,l=i;continue}break}return t.line=l,u=t.push("code_block","code",0),u.content=t.getLines(n,l,4+t.blkIndent,!1)+`
-`,u.map=[n,t.line],!0},Eq=function(t,n,r,i){var l,u,c,d,f,g,h,p=!1,m=t.bMarks[n]+t.tShift[n],y=t.eMarks[n];if(t.sCount[n]-t.blkIndent>=4||m+3>y||(l=t.src.charCodeAt(m),l!==126&&l!==96)||(f=m,m=t.skipChars(m,l),u=m-f,u<3)||(h=t.src.slice(f,m),c=t.src.slice(m,y),l===96&&c.indexOf(String.fromCharCode(l))>=0))return!1;if(i)return!0;for(d=n;d++,!(d>=r||(m=f=t.bMarks[d]+t.tShift[d],y=t.eMarks[d],m =4){a++,l=a;continue}break}return t.line=l,u=t.push("code_block","code",0),u.content=t.getLines(n,l,4+t.blkIndent,!1)+`
+`,u.map=[n,t.line],!0},Eq=function(t,n,r,a){var l,u,c,d,f,g,h,p=!1,m=t.bMarks[n]+t.tShift[n],y=t.eMarks[n];if(t.sCount[n]-t.blkIndent>=4||m+3>y||(l=t.src.charCodeAt(m),l!==126&&l!==96)||(f=m,m=t.skipChars(m,l),u=m-f,u<3)||(h=t.src.slice(f,m),c=t.src.slice(m,y),l===96&&c.indexOf(String.fromCharCode(l))>=0))return!1;if(a)return!0;for(d=n;d++,!(d>=r||(m=f=t.bMarks[d]+t.tShift[d],y=t.eMarks[d],m",s},O}(),Da={\u00EE:"\u0131\u0302",\u00EF:"\u0131\u0308",\u00ED:"\u0131\u0301",\u00EC:"\u0131\u0300"},yt=function(){function O(o,s,_,T,I,B,H,K){this.text=void 0,this.height=void 0,this.depth=void 0,this.italic=void 0,this.skew=void 0,this.width=void 0,this.maxFontSize=void 0,this.classes=void 0,this.style=void 0,this.text=o,this.height=s||0,this.depth=_||0,this.italic=T||0,this.skew=I||0,this.width=B||0,this.classes=H||[],this.style=K||{},this.maxFontSize=0;var re=J(this.text.charCodeAt(0));re&&this.classes.push(re+"_fallback"),/[îïíì]/.test(this.text)&&(this.text=Da[this.text])}var a=O.prototype;return a.hasClass=function(s){return E.contains(this.classes,s)},a.toNode=function(){var s=document.createTextNode(this.text),_=null;this.italic>0&&(_=document.createElement("span"),_.style.marginRight=Ne(this.italic)),this.classes.length>0&&(_=_||document.createElement("span"),_.className=Ut(this.classes));for(var T in this.style)this.style.hasOwnProperty(T)&&(_=_||document.createElement("span"),_.style[T]=this.style[T]);return _?(_.appendChild(s),_):s},a.toMarkup=function(){var s=!1,_="0&&(T+="margin-right:"+this.italic+"em;");for(var I in this.style)this.style.hasOwnProperty(I)&&(T+=E.hyphenate(I)+":"+this.style[I]+";");T&&(s=!0,_+=' style="'+E.escape(T)+'"');var B=E.escape(this.text);return s?(_+=">",_+=B,_+="",_):B},O}(),Lt=function(){function O(o,s){this.children=void 0,this.attributes=void 0,this.children=o||[],this.attributes=s||{}}var a=O.prototype;return a.toNode=function(){var s="http://www.w3.org/2000/svg",_=document.createElementNS(s,"svg");for(var T in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,T)&&_.setAttribute(T,this.attributes[T]);for(var I=0;I
",s},O}(),Di={\u00EE:"\u0131\u0302",\u00EF:"\u0131\u0308",\u00ED:"\u0131\u0301",\u00EC:"\u0131\u0300"},yt=function(){function O(o,s,_,T,I,B,H,K){this.text=void 0,this.height=void 0,this.depth=void 0,this.italic=void 0,this.skew=void 0,this.width=void 0,this.maxFontSize=void 0,this.classes=void 0,this.style=void 0,this.text=o,this.height=s||0,this.depth=_||0,this.italic=T||0,this.skew=I||0,this.width=B||0,this.classes=H||[],this.style=K||{},this.maxFontSize=0;var re=J(this.text.charCodeAt(0));re&&this.classes.push(re+"_fallback"),/[îïíì]/.test(this.text)&&(this.text=Di[this.text])}var i=O.prototype;return i.hasClass=function(s){return E.contains(this.classes,s)},i.toNode=function(){var s=document.createTextNode(this.text),_=null;this.italic>0&&(_=document.createElement("span"),_.style.marginRight=Ne(this.italic)),this.classes.length>0&&(_=_||document.createElement("span"),_.className=Ut(this.classes));for(var T in this.style)this.style.hasOwnProperty(T)&&(_=_||document.createElement("span"),_.style[T]=this.style[T]);return _?(_.appendChild(s),_):s},i.toMarkup=function(){var s=!1,_="0&&(T+="margin-right:"+this.italic+"em;");for(var I in this.style)this.style.hasOwnProperty(I)&&(T+=E.hyphenate(I)+":"+this.style[I]+";");T&&(s=!0,_+=' style="'+E.escape(T)+'"');var B=E.escape(this.text);return s?(_+=">",_+=B,_+="",_):B},O}(),Lt=function(){function O(o,s){this.children=void 0,this.attributes=void 0,this.children=o||[],this.attributes=s||{}}var i=O.prototype;return i.toNode=function(){var s="http://www.w3.org/2000/svg",_=document.createElementNS(s,"svg");for(var T in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,T)&&_.setAttribute(T,this.attributes[T]);for(var I=0;I