| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790 |
- <?php
- namespace App\Services;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Http\Request;
- use App\Http\Requests\PostRequest;
- use App\Http\Traits\CommonTrait;
- use App\Http\Traits\BoardTrait;
- use App\Models\Board;
- use App\Models\BoardMeta;
- use App\Models\Post;
- use App\Models\PostMeta;
- use App\Models\PostLike;
- use App\Models\PostTag;
- use App\Models\PostLink;
- use App\Models\PostFile;
- use App\Models\PostHistory;
- use App\Models\PostDeleted;
- use App\Models\User;
- use App\Models\FileLib;
- use App\Models\PostBlame;
- use App\Models\PostBookmark;
- use App\Models\PostFileDownLog;
- use App\Models\PostLinkClickLog;
- use App\Models\EditorImage;
- use App\Models\EmailLib;
- use App\Models\Exp;
- use App\Models\DTO\ResponseData;
- use Exception;
- class PostService
- {
- use CommonTrait;
- use BoardTrait;
- public Board $boardModel;
- public BoardMeta $boardMetaModel;
- public User $userModel;
- public Post $postModel;
- public PostMeta $postMetaModel;
- public PostHistory $postHistoryModel;
- public PostBookmark $postBookmarkModel;
- public PostLike $postLikeModel;
- public PostTag $postTagModel;
- public PostFile $postFileModel;
- public PostFileDownLog $postFileDownLogModel;
- public PostBlame $postBlameModel;
- public PostLink $postLinkModel;
- public PostLinkClickLog $postLinkClickLogModel;
- public PostDeleted $postDeletedModel;
- public FileLib $fileLib;
- public EditorImage $editorImageModel;
- public function __construct()
- {
- $this->boardModel = new Board();
- $this->boardMetaModel = new BoardMeta();
- $this->postModel = new Post();
- $this->postMetaModel = new PostMeta();
- $this->postHistoryModel = new PostHistory();
- $this->postBookmarkModel = new PostBookmark();
- $this->postLikeModel = new PostLike();
- $this->postTagModel = new PostTag();
- $this->postFileModel = new PostFile();
- $this->postFileDownLogModel = new PostFileDownLog();
- $this->postBlameModel = new PostBlame();
- $this->postLinkModel = new PostLink();
- $this->postLinkClickLogModel = new PostLinkClickLog();
- $this->postDeletedModel = new PostDeleted();
- $this->userModel = new User();
- $this->fileLib = new FileLib();
- $this->editorImageModel = new EditorImage();
- }
- public function meta(int $postID): ?PostMeta
- {
- return $this->postMetaModel->getAllMeta($postID);
- }
- /**
- * 게시글 정보 조회
- */
- public function find(int $postID): Post
- {
- $post = $this->postModel->get($postID);
- if(!$post->exists) {
- return $post;
- }
- $code = $post->board->code;
- $boardMeta = $this->boardMetaModel->getAllMeta($post->board_id);
- // 게시글 정보
- $post->viewURL = route('board.post.view', [$code, $postID]);
- $post->beforeViewURL = ($post->beforePostID ? route('board.post.view', [$code, $post->beforePostID]) : null);
- $post->nextViewURL = ($post->nextPostID ? route('board.post.view', [$code, $post->nextPostID]) : null);
- $post->createdAt = $post->created_at->format('Y.m.d H:i:s');
- $post->ipAddress = null;
- $post->isBookmark = false;
- $post->isLike = false;
- $post->isDislike = false;
- // 본문 URL 링크 자동 생성
- if ($boardMeta->item('use_auto_url', 0)) {
- $post->content = $this->urlAutoLink($post->content, $boardMeta->item('content_target_blank', 0)); // Link 새창 여부
- }
- // 익명 게시판일 경우
- if(
- $boardMeta->item('use_anonymous', 0)
- && (!$post->user->is_admin || !$boardMeta->item('anonymous_except_admin', 0))
- && $post->user->id
- ) {
- $post->username = $this->createAnonymousName(
- $boardMeta->item('anonymous_name'), $post->user_id, $post->id
- );
- }
- if($post->user->exists) {
- $post->user->thumb = $this->profileThumbSrc($post->user->thumb);
- $post->user->createdAt = $post->user->created_at->format('Y.m.d');
- }
- // IP 형식 처리
- $showPostIP = $boardMeta->item('show_post_ip'); // 노출 방법
- if ($showPostIP) {
- $ipDisplayStyle = ($showPostIP == 2 || IS_ADMIN ? '1111' : config('ip_display_style')); // IP 형식
- $post->ipAddress = $this->ipAddrMasking($post->ip_address, $ipDisplayStyle);
- }
- // 즐겨찾기
- if ($boardMeta->item('use_bookmark', 0)) {
- $post->isBookmark = $this->postBookmarkModel->isAlready($post, UID);
- }
- // 좋아요
- if ($boardMeta->item('use_post_like', 0)) {
- $post->isLike = $this->postLikeModel->isAlready($post, UID, LIKE);
- }
- // 싫어요
- if ($boardMeta->item('use_post_dislike', 0)) {
- $post->isDislike = $this->postLikeModel->isAlready($post, UID, DISLIKE);
- }
- // 태그
- $post->tags = $post->postTag;
- // 첨부파일
- $post->files = $post->postFile;
- // 링크 첨부
- $post->links = $post->postLink;
- return $post;
- }
- /**
- * 게시글 등록 처리
- */
- public function register(PostRequest $request, ResponseData $response): ResponseData
- {
- DB::beginTransaction();
- try {
- $user = $request->user();
- $boardID = intval($request->post('bid'));
- $boardMeta = $request->boardMeta;
- // 게시글 첨부 사진 저장
- $content = $this->getContent($request);
- $thumbnail = $this->getThumbnail($content,
- ($boardMeta->item('board_layout_type') == BOARD_LAYOUT_TYPE_1 ? NO_IMAGE_NORMAL_SRC : null)
- );
- $imageRows = $this->getImageRows($content);
- $videoRows = $this->getVideoRows($content);
- // 게시글 정보 저장
- $post = $this->postModel->register([
- 'board_id' => $boardID,
- 'board_category_id' => $request->post('category'),
- 'user_id' => $user?->id,
- 'thumbnail' => $thumbnail,
- 'subject' => trim($request->post('subject')),
- 'content' => $content,
- 'sid' => $user?->sid,
- 'username' => $request->post('username', $user?->name),
- 'email' => $user?->email,
- 'password' => $request->post('password'),
- 'comment_rows' => 0,
- 'comment_updated_at' => null,
- 'is_reply' => 0,
- 'is_personal' => $boardMeta->item('use_personal', 0),
- 'is_secret' => ($boardMeta->item('use_post_secret', 0) == '2' ? 1 : $request->post('is_secret', 0)),
- 'is_notice' => $request->post('is_notice', 0),
- 'is_speaker' => $request->post('is_speaker', 0),
- 'is_html' => $boardMeta->item('use_post_dhtml', 0),
- 'use_comment' => $boardMeta->item('use_comment', 0),
- 'receive_email' => 0,
- 'hit' => 0,
- 'like' => 0,
- 'dislike' => 0,
- 'blame' => 0,
- 'device_type' => DEVICE_TYPE,
- 'file_rows' => 0,
- 'image_rows' => $imageRows,
- 'video_rows' => $videoRows,
- 'link_rows' => 0,
- 'tag_rows' => 0,
- 'is_delete' => 0,
- 'ip_address' => IP_ADDRESS,
- 'user_agent' => USER_AGENT,
- 'deleted_at' => null,
- 'updated_at' => null,
- 'created_at' => now()
- ]);
- // 게시글 Tag 저장
- $this->postTagModel->register($post, $request->post('tags'));
- // 게시글 Link 저장
- $this->postLinkModel->register($post, $request->post('links'));
- // 게시글 File 저장
- $this->postFileModel->register($post, $request->file('files'));
- // 게시글 기록 저장
- if ($boardMeta->use_post_history) {
- $this->postHistoryModel->register($post,'게시글 등록');
- }
- // 게시판 게시글 수 갱신
- $this->boardModel->updatePostRows($boardID);
- $response->post = $post;
- DB::commit();
- } catch (Exception $e) {
- $response = $response::fromException($e);
- DB::rollBack();
- }
- return $response;
- }
- /**
- * 게시글 수정 처리
- */
- public function updater(PostRequest $request, ResponseData $response): ResponseData
- {
- DB::beginTransaction();
- try {
- $user = $request->user();
- $boardMeta = $request->boardMeta;
- $boardID = intval($request->post('bid'));
- $postID = intval($request->post('pid'));
- // 게시글 첨부 사진 저장
- $content = $this->getContent($request);
- $thumbnail = $this->getThumbnail($content,
- ($boardMeta->item('board_layout_type') == BOARD_LAYOUT_TYPE_1 ? NO_IMAGE_NORMAL_SRC : null)
- );
- $imageRows = $this->getImageRows($content);
- $videoRows = $this->getVideoRows($content);
- // 게시글 기록 저장
- if ($boardMeta->item('use_post_history', 0)) {
- $this->postHistoryModel->updater($request->post, '게시글 수정');
- }
- // 게시글 정보 저장
- $post = $this->postModel->updater($postID, [
- 'board_id' => $boardID,
- 'board_category_id' => $request->post('category'),
- 'user_id' => $user?->id,
- 'thumbnail' => $thumbnail,
- 'subject' => trim($request->post('subject')),
- 'content' => $content,
- 'sid' => $user?->sid,
- 'username' => $request->post('username', $user?->name),
- 'email' => $user?->email,
- 'password' => $request->post('password'),
- 'is_personal' => $boardMeta->item('use_personal', 0),
- 'is_secret' => ($boardMeta->item('use_post_secret', 0) == '2' ? 1 : $request->post('is_secret', 0)),
- 'is_notice' => $request->post('is_notice', 0),
- 'is_speaker' => $request->post('is_speaker', 0),
- 'is_html' => $boardMeta->item('use_post_dhtml', 0),
- 'use_comment' => $boardMeta->item('use_comment', 0),
- 'receive_email' => 0,
- 'device_type' => DEVICE_TYPE,
- 'file_rows' => 0,
- 'image_rows' => $imageRows,
- 'video_rows' => $videoRows,
- 'link_rows' => 0,
- 'tag_rows' => 0,
- 'ip_address' => IP_ADDRESS,
- 'user_agent' => USER_AGENT,
- 'updated_at' => now()
- ]);
- // 게시글 Tag 저장
- $this->postTagModel->updater($post, $request->post('tags'));
- // 게시글 Link 저장
- $this->postLinkModel->updater($post, $request->post('links'));
- // 게시글 File 저장
- $this->postFileModel->updater($post, $request->post('file_is_delete', []), $request->file('files'));
- DB::commit();
- } catch (Exception $e) {
- $response = $response::fromException($e);
- DB::rollBack();
- }
- return $response;
- }
- /**
- * 게시글 삭제
- */
- public function delete(Request $request, ResponseData $response): ResponseData
- {
- DB::beginTransaction();
- try {
- $post = $request->post;
- // 게시글 존재 확인
- if (!$post->exists) {
- throw new Exception('게시글이 존재 하지 않습니다.');
- }
- $user = $request->user();
- // 게시글 삭제 여부 승인
- $this->postModel->remove($post, $user);
- DB::commit();
- } catch (Exception $e) {
- $response = $response::fromException($e);
- DB::rollBack();
- }
- return $response;
- }
- /**
- * 게시글 즐겨찾기
- */
- public function bookmark(Request $request, ResponseData $response): ResponseData
- {
- DB::beginTransaction();
- try {
- $post = $this->postModel->findOrNew(
- $request->input('pid')
- );
- // 게시글 존재 확인
- if (!$post->exists) {
- throw new Exception('게시글이 존재 하지 않습니다.');
- }
- $boardMeta = $this->boardMetaModel->getAllMeta($post->board_id);
- if (!$boardMeta->item('use_bookmark', 0)) {
- throw new Exception('즐겨찾기 기능은 사용하지 않습니다.');
- }
- $userID = $request->user()->id;
- if ($this->postBookmarkModel->isAlready($post, $userID)) {
- $this->postBookmarkModel->remove($post, $userID);
- } else {
- $this->postBookmarkModel->register([
- 'board_id' => $post->board_id,
- 'post_id' => $post->id,
- 'user_id' => $userID,
- 'ip_address' => IP_ADDRESS,
- 'user_agent' => USER_AGENT,
- 'created_at' => now()
- ]);
- }
- // 즐겨찾기 수 저장
- $this->postMetaModel->save($post->id, [
- 'bookmark_rows' => $this->postBookmarkModel->rows($post)
- ]);
- $response->post = $post;
- DB::commit();
- } catch (Exception $e) {
- $response = $response::fromException($e);
- DB::rollBack();
- }
- return $response;
- }
- /**
- * 게시글 신고
- */
- public function blame(Request $request, ResponseData $response): ResponseData
- {
- DB::beginTransaction();
- try {
- $post = $this->postModel->findOrNew(
- $request->input('pid')
- );
- // 게시글 존재 확인
- if(!$post->exists) {
- throw new Exception('게시글이 존재 하지 않습니다.');
- }
- $boardMeta = $this->boardMetaModel->getAllMeta($post->board_id);
- if (!$boardMeta->item('use_blame', 0)) {
- throw new Exception('신고 기능은 사용하지 않습니다.');
- }
- $userID = $request->user()->id;
- // 이미 신고했는지 확인
- if ($this->postBlameModel->isAlready($post, $userID)) {
- throw new Exception('이미 신고하셨습니다.');
- }
- $this->postBlameModel->register([
- 'board_id' => $post->board_id,
- 'post_id' => $post->id,
- 'user_id' => $userID,
- 'type' => $request->post('type'),
- 'reason' => $request->post('reason'),
- 'status' => 0,
- 'memo' => null,
- 'ip_address' => IP_ADDRESS,
- 'user_agent' => USER_AGENT,
- 'created_at' => now()
- ]);
- // 게시글 신고 수 증가
- $this->postModel->increaseBlame($post->id);
- $response->post = $post;
- DB::commit();
- } catch (Exception $e) {
- $response = $response::fromException($e);
- DB::rollBack();
- }
- return $response;
- }
- /**
- * 게시글 좋아요
- */
- public function like(Request $request, ResponseData $response): ResponseData
- {
- DB::beginTransaction();
- try {
- $post = $this->postModel->findOrNew(
- $request->input('pid')
- );
- // 게시글 존재 확인
- if(!$post->exists) {
- throw new Exception('게시글이 존재 하지 않습니다.');
- }
- $boardMeta = $this->boardMetaModel->getAllMeta($post->board_id);
- if (!$boardMeta->item('use_post_like', 0)) {
- throw new Exception('추천 기능은 사용하지 않습니다.');
- }
- $userID = $request->user()->id;
- $saveData = [
- 'board_id' => $post->board_id,
- 'post_id' => $post->id,
- 'user_id' => $userID,
- 'type' => LIKE,
- 'ip_address' => IP_ADDRESS,
- 'user_agent' => USER_AGENT,
- 'created_at' => now()
- ];
- $likeInfo = $this->postLikeModel->info($post, $userID);
- if ($likeInfo->exists) { // 이미 추천함
- $this->postLikeModel->remove($post, $userID);
- if ($likeInfo->type == LIKE) {
- $this->postModel->decreaseLike($post->id);
- } else if ($likeInfo->type == DISLIKE) {
- $this->postLikeModel->register($saveData);
- $this->postModel->increaseLike($post->id);
- $this->postModel->decreaseDisLike($post->id);
- }
- } else { // 추천
- $this->postLikeModel->register($saveData);
- $this->postModel->increaseLike($post->id);
- }
- $response->post = $post;
- DB::commit();
- } catch (Exception $e) {
- $response = $response::fromException($e);
- DB::rollBack();
- }
- return $response;
- }
- /**
- * 게시글 싫어요
- */
- public function dislike(Request $request, ResponseData $response): ResponseData
- {
- DB::beginTransaction();
- try {
- $post = $this->postModel->findOrNew(
- $request->input('pid')
- );
- // 게시글 존재 확인
- if(!$post->exists) {
- throw new Exception('게시글이 존재 하지 않습니다.');
- }
- $boardMeta = $this->boardMetaModel->getAllMeta($post->board_id);
- if (!$boardMeta->item('use_post_dislike', 0)) {
- throw new Exception('비추천 기능은 사용하지 않습니다.');
- }
- $userID = $request->user()->id;
- $saveData = [
- 'board_id' => $post->board_id,
- 'post_id' => $post->id,
- 'user_id' => $userID,
- 'type' => DISLIKE,
- 'ip_address' => IP_ADDRESS,
- 'user_agent' => USER_AGENT,
- 'created_at' => now()
- ];
- $likeInfo = $this->postLikeModel->info($post, $userID);
- if ($likeInfo->exists) { // 이미 추천함
- $this->postLikeModel->remove($post, $userID);
- if ($likeInfo->type == DISLIKE) {
- $this->postModel->decreaseDisLike($post->id);
- } else if ($likeInfo->type == LIKE) {
- $this->postLikeModel->register($saveData);
- $this->postModel->increaseDisLike($post->id);
- $this->postModel->decreaseLike($post->id);
- }
- } else {
- $this->postLikeModel->register($saveData);
- $this->postModel->increaseDisLike($post->id);
- }
- $response->post = $post;
- DB::commit();
- } catch (Exception $e) {
- $response = $response::fromException($e);
- DB::rollBack();
- }
- return $response;
- }
- /**
- * 게시글 첨부파일 다운로드
- */
- public function download(Request $request): object
- {
- $ret = (object)[
- 'path' => null,
- 'name' => null
- ];
- $file = $this->postFileModel->info(
- $request->post('fid')
- );
- if (!$file->exists) {
- return $ret;
- }
- // 다운로드 횟수 증가
- $file->increaseDownload($file->id);
- // 다운로드 기록
- $boardMeta = $this->boardMetaModel->getAllMeta($file->board_id);
- if ($boardMeta->item('use_download_log', 0)) {
- $this->postFileDownLogModel->register([
- 'post_file_id' => $file->id,
- 'board_id' => $file->board_id,
- 'post_id' => $file->post_id,
- 'user_id' => $file->user_id,
- 'ip_address' => IP_ADDRESS,
- 'user_agent' => USER_AGENT,
- 'created_at' => now()
- ]);
- }
- $ret->path = $file->file_path;
- $ret->name = $file->origin_name;
- return $ret;
- }
- /**
- * 게시글 Link 클릭
- */
- public function linked(Request $request): string|null
- {
- $link = $this->postLinkModel->info(
- $request->post('lid')
- );
- if (!$link->exists) {
- return null;
- }
- // Link 클릭 횟수 증가
- $link->increaseHit($link->id);
- // Link 클릭 기록
- $boardMeta = $this->boardMetaModel->getAllMeta($link->board_id);
- if ($boardMeta->item('use_link_click_log', 0)) {
- $this->postLinkClickLogModel->register([
- 'post_link_id' => $link->id,
- 'board_id' => $link->board_id,
- 'post_id' => $link->post_id,
- 'user_id' => $link->user_id,
- 'ip_address' => IP_ADDRESS,
- 'user_agent' => USER_AGENT,
- 'created_at' => now()
- ]);
- }
- return ($link->url ?? null);
- }
- /**
- * 게시글 보기 조회 수 증가
- */
- public function addHit(Post $post): void
- {
- if($this->postModel->addHit($post)) {
- $this->postModel->increaseHit($post->id);
- }
- }
- /**
- * 게시글 작성 개수
- */
- public function userPostRows(Board $board, ?User $user): int
- {
- return $this->postModel->where([
- ['board_id', $board->id],
- ['user_id', $user?->id],
- ['ip_address', IP_ADDRESS]
- ])->whereRaw('DATE(created_at) = CURDATE()')->count();
- }
- /**
- * 게시글 추천 여부
- */
- public function userPostIsLike(Post $post, User $user): int
- {
- return $this->postLikeModel->where([
- ['board_id', $post->board_id],
- ['post_id', $post->id],
- ['user_id', $user->id]
- ])->orWhere('ip_address', IP_ADDRESS)->exists();
- }
- /**
- * 첨부 사진 저장
- */
- private function getContent(PostRequest $request): string
- {
- // 게시글 이미지 저장
- $boardMeta = $request->boardMeta;
- $postID = $this->postModel->lastedKey();
- $content = trim($request->post('content'));
- if ($boardMeta->item('save_external_image', 0)) {
- // link
- $content = $this->fileLib->saveImageFromUrl($content, UPLOAD_PATH_POST, $postID);
- }
- // blob
- $content = $this->fileLib->saveImageFromBlob($content, UPLOAD_PATH_POST, $postID);
- // 이미지 DB 기록
- $images = $this->fileLib->getImageFromContent($content);
- if(count($images) > 0) {
- foreach($images as $img) {
- $this->editorImageModel->register([
- 'target_type' => EDITOR_IMG_TYPE_1,
- 'target_id' => $postID,
- 'user_id' => UID,
- 'origin_name' => $img->origin,
- 'file_name' => $img->name,
- 'file_path' => $img->path,
- 'file_url' => $img->url,
- 'file_size' => $img->size,
- 'file_type' => $img->type,
- 'width' => $img->width,
- 'height' => $img->height,
- 'ip_address' => IP_ADDRESS,
- 'user_agent' => USER_AGENT
- ]);
- }
- }
- return $content;
- }
- /**
- * 게시글 경험치 지급
- */
- public function setUserExp(Post $post, User $user, int $type): bool
- {
- if(!$post->exists) {
- return false;
- }
- $boardMeta = $this->boardMetaModel->getAllMeta($post->board_id);
- if (!$boardMeta->item('use_exp', 0)) {
- return false;
- }
- $column = MAP_EXP_TYPE[$type];
- $content = MAP_EXP_CONTENT[$type];
- $value = intval($boardMeta->{$column});
- $relatedID = sprintf("%d-%d", $post->board_id, $post->id);
- // 경험치 지급 구분
- return (new Exp)->register([
- 'user_id' => $user->id,
- 'content' => $content,
- 'value' => $value,
- 'type' => $type,
- 'related_id' => $relatedID,
- 'method' => request()->getMethod(),
- 'created_at' => now()
- ]);
- }
- /**
- * 게시글 관련 메일 발송
- */
- public function sendEmailNotify(Post $post, string $sendMailFormType): bool
- {
- if (!in_array($sendMailFormType, MAP_SEND_MAIL_TYPE)) {
- return false;
- }
- $boardMeta = $this->boardMetaModel->getAllMeta($post->board_id);
- $sendMailType = str_replace('_form', '', $sendMailFormType);
- // 최고 관리자에게 발송
- $admin = ($boardMeta->item($sendMailType . '_super_admin', 0) ? $this->userModel->getMaster() : null);
- // 게시글 작성자에게 발송
- $postWriter = ($boardMeta->item($sendMailType . '_post_writer', 0) ? $post->user : null);
- if (!$admin && !$postWriter) {
- return false;
- }
- return (new EmailLib)->send($sendMailFormType, $admin, $postWriter);
- }
- }
|