From bb42d5f31984c891bd1019d6c3734c79fcaa9918 Mon Sep 17 00:00:00 2001 From: zouap Date: Mon, 1 Aug 2022 11:15:13 +0800 Subject: [PATCH 01/30] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=EF=BC=8C=E8=A7=A3=E5=86=B3=E7=9B=B8=E5=85=B3Bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zouap --- modules/storage/minio_ext.go | 62 ++++++++++++++++++++++++++++++++++++++++---- modules/storage/obs.go | 23 ---------------- routers/search.go | 7 +++-- 3 files changed, 62 insertions(+), 30 deletions(-) diff --git a/modules/storage/minio_ext.go b/modules/storage/minio_ext.go index 4c0cbac55..05b692335 100755 --- a/modules/storage/minio_ext.go +++ b/modules/storage/minio_ext.go @@ -179,30 +179,82 @@ func GetOneLevelAllObjectUnderDirMinio(bucket string, prefixRootPath string, rel output, err := core.ListObjects(bucket, Prefix, "", "", 1000) fileInfos := make([]FileInfo, 0) prefixLen := len(Prefix) + fileMap := make(map[string]bool, 0) if err == nil { for _, val := range output.Contents { + log.Info("val key=" + val.Key) var isDir bool var fileName string if val.Key == Prefix { continue } - if strings.HasSuffix(val.Key, "/") { + fileName = val.Key[prefixLen:] + log.Info("fileName =" + fileName) + files := strings.Split(fileName, "/") + if fileMap[files[0]] { + continue + } else { + fileMap[files[0]] = true + } + ParenDir := relativePath + fileName = files[0] + if len(files) > 1 { isDir = true - fileName = val.Key[prefixLen : len(val.Key)-1] - relativePath += val.Key[prefixLen:] + ParenDir += fileName + "/" } else { isDir = false - fileName = val.Key[prefixLen:] } + fileInfo := FileInfo{ ModTime: val.LastModified.Local().Format("2006-01-02 15:04:05"), FileName: fileName, Size: val.Size, IsDir: isDir, - ParenDir: relativePath, + ParenDir: ParenDir, } fileInfos = append(fileInfos, fileInfo) + + // log.Info("val key=" + val.Key) + // var isDir bool + // var fileName string + // if val.Key == Prefix { + // continue + // } + + // fileName = val.Key[prefixLen:] + // log.Info("fileName =" + fileName) + // files := strings.Split(fileName, "/") + // if fileMap[files[0]] { + // continue + // } else { + // fileMap[files[0]] = true + // } + // ParenDir := relativePath + // fileName = files[0] + // if len(files) > 1 { + // isDir = true + // ParenDir += fileName + "/" + // } else { + // isDir = false + // } + + // // if strings.HasSuffix(val.Key, "/") { + // // isDir = true + // // fileName = val.Key[prefixLen : len(val.Key)-1] + // // relativePath += val.Key[prefixLen:] + // // } else { + // // isDir = false + // // fileName = val.Key[prefixLen:] + // // } + // fileInfo := FileInfo{ + // ModTime: val.LastModified.Local().Format("2006-01-02 15:04:05"), + // FileName: fileName, + // Size: val.Size, + // IsDir: isDir, + // ParenDir: relativePath, + // } + // fileInfos = append(fileInfos, fileInfo) } return fileInfos, err } else { diff --git a/modules/storage/obs.go b/modules/storage/obs.go index 29b7998f7..2cb3af927 100755 --- a/modules/storage/obs.go +++ b/modules/storage/obs.go @@ -395,29 +395,6 @@ func GetOneLevelAllObjectUnderDir(bucket string, prefixRootPath string, relative } else { isDir = false } - - // if strings.Contains(val.Key[prefixLen:len(val.Key)-1], "/") { - - // files := strings.Split(fileName, "/") - // fileName = files[0] - // isDir = true - // if fileMap[files[0]] { - // continue - // } else { - // fileMap[files[0]] = true - // } - // } else { - // if strings.HasSuffix(val.Key, "/") { - // isDir = true - // fileName = val.Key[prefixLen : len(val.Key)-1] - // relativePath += val.Key[prefixLen:] - // } else { - // isDir = false - // fileName = val.Key[prefixLen:] - // } - // fileMap[fileName] = true - // } - fileInfo := FileInfo{ ModTime: val.LastModified.Local().Format("2006-01-02 15:04:05"), FileName: fileName, diff --git a/routers/search.go b/routers/search.go index 628350424..72bf97bf4 100644 --- a/routers/search.go +++ b/routers/search.go @@ -314,7 +314,7 @@ func searchRepo(ctx *context.Context, TableName string, Key string, Page int, Pa res, err := client.Search(TableName).Query(boolQ).SortBy(getSort(SortBy, ascending, "num_stars", false)...).From(from).Size(Size).Highlight(queryHighlight("alias", "description", "topics")).Do(ctx.Req.Context()) if err == nil { esresult := makeRepoResult(res, Key, OnlyReturnNum, language) - setForkRepoOrder(esresult) + setForkRepoOrder(esresult, SortBy) resultObj.Total = resultObj.PrivateTotal + esresult.Total isNeedSort := false if len(resultObj.Result) > 0 { @@ -347,7 +347,10 @@ func searchRepo(ctx *context.Context, TableName string, Key string, Page int, Pa } } -func setForkRepoOrder(esresult *SearchRes) { +func setForkRepoOrder(esresult *SearchRes, SortBy string) { + if SortBy == "default" || SortBy == "" { + return + } forkidMap := make(map[string]int, 0) for index, re := range esresult.Result { if re["fork_id"] != nil { From faaf5ebdf23a8afa7ec12cd5e849d748186160c1 Mon Sep 17 00:00:00 2001 From: zouap Date: Mon, 1 Aug 2022 16:29:11 +0800 Subject: [PATCH 02/30] =?UTF-8?q?=E6=90=9C=E7=B4=A2=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=97=B6=E6=8E=92=E5=BA=8F=E9=97=AE=E9=A2=98=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zouap --- models/user.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/models/user.go b/models/user.go index a423a843b..6cf3fadb3 100755 --- a/models/user.go +++ b/models/user.go @@ -1768,7 +1768,6 @@ func (opts *SearchUserOptions) toConds() builder.Cond { if !opts.IsActive.IsNone() { cond = cond.And(builder.Eq{"is_active": opts.IsActive.IsTrue()}) } - return cond } @@ -1780,12 +1779,15 @@ func SearchUsers(opts *SearchUserOptions) (users []*User, _ int64, _ error) { if err != nil { return nil, 0, fmt.Errorf("Count: %v", err) } - + orderby := opts.OrderBy.String() if len(opts.OrderBy) == 0 { - opts.OrderBy = SearchOrderByAlphabetically + orderby = SearchOrderByAlphabetically.String() + lowerKeyword := strings.ToLower(opts.Keyword) + if len(opts.Keyword) > 0 { + orderby = " CASE when lower_name='" + lowerKeyword + "' then 0 when charindex('" + lowerKeyword + "',lower_name)>0 then 1 else 2 END ASC" + } } - - sess := x.Where(cond).OrderBy(opts.OrderBy.String()) + sess := x.Where(cond).OrderBy(orderby) if opts.Page != 0 { sess = opts.setSessionPagination(sess) } From d2c9eb1c803dcc017eb820db6377eeb6a2e0a91e Mon Sep 17 00:00:00 2001 From: zouap Date: Mon, 1 Aug 2022 16:39:52 +0800 Subject: [PATCH 03/30] =?UTF-8?q?=E6=90=9C=E7=B4=A2=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=97=B6=E6=8E=92=E5=BA=8F=E9=97=AE=E9=A2=98=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zouap --- models/user.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/user.go b/models/user.go index 6cf3fadb3..dcbb9be3d 100755 --- a/models/user.go +++ b/models/user.go @@ -1784,7 +1784,7 @@ func SearchUsers(opts *SearchUserOptions) (users []*User, _ int64, _ error) { orderby = SearchOrderByAlphabetically.String() lowerKeyword := strings.ToLower(opts.Keyword) if len(opts.Keyword) > 0 { - orderby = " CASE when lower_name='" + lowerKeyword + "' then 0 when charindex('" + lowerKeyword + "',lower_name)>0 then 1 else 2 END ASC" + orderby = " CASE when lower_name='" + lowerKeyword + "' then 0 when strpos(lower_name,'" + lowerKeyword + "')>0 then 1 else 2 END ASC" } } sess := x.Where(cond).OrderBy(orderby) From 7de4942280d6c845f89cecc5146099f27b80062b Mon Sep 17 00:00:00 2001 From: zouap Date: Mon, 1 Aug 2022 17:05:12 +0800 Subject: [PATCH 04/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E9=A2=84=E8=A7=88=E7=95=8C=E9=9D=A2=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zouap --- public/self/dataset_preview.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/public/self/dataset_preview.js b/public/self/dataset_preview.js index e6b79dd7d..81620e1a0 100644 --- a/public/self/dataset_preview.js +++ b/public/self/dataset_preview.js @@ -123,13 +123,13 @@ function loadimg(uuid,filename){ function loadimg(){ var length = labeltastresult[fileindex].pic_image_field.length; -  if(labeltastresult[fileindex].pic_image_field.substring(length - 5) == ".json"  -     || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".xml" -     || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".txt" -     || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".csv" -     || labeltastresult[fileindex].pic_image_field.substring(length - 3) == ".md" -     || labeltastresult[fileindex].pic_image_field.substring(length - 3) == ".py" -     || labeltastresult[fileindex].pic_image_field.substring(length - 3) == ".sh"){ +  if(labeltastresult[fileindex].pic_image_field.substring(length - 5).toLowerCase() == ".json"  +     || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".xml" +     || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".txt" +     || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".csv" +     || labeltastresult[fileindex].pic_image_field.substring(length - 3).toLowerCase() == ".md" +     || labeltastresult[fileindex].pic_image_field.substring(length - 3).toLowerCase() == ".py" +     || labeltastresult[fileindex].pic_image_field.substring(length - 3).toLowerCase() == ".sh"){ //文本 canvas.style.display="none"; @@ -138,11 +138,11 @@ function loadimg(){ $('#textcontent').height(canvas.height-40) $("#textcontent").text(textContent); }else{ - if(labeltastresult[fileindex].pic_image_field.substring(length - 5) == ".jpeg"  -    || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".jpg" -    || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".bmp" -    || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".gif" -    || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".png"){ + if(labeltastresult[fileindex].pic_image_field.substring(length - 5).toLowerCase() == ".jpeg"  +    || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".jpg" +    || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".bmp" +    || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".gif" +    || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".png"){ canvas.style.display="block"; document.getElementById("textcontent").style.display="none"; img.src = ip + "/getgiteaimage?uuid=" + dataset_id + "&filename=" + labeltastresult[fileindex].pic_image_field; From 252995b0eb164df3b23210815ed301af1fbaabaa Mon Sep 17 00:00:00 2001 From: zouap Date: Mon, 1 Aug 2022 17:08:14 +0800 Subject: [PATCH 05/30] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E9=A2=84=E8=A7=88=E7=95=8C=E9=9D=A2=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zouap --- public/self/dataset_preview.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/public/self/dataset_preview.js b/public/self/dataset_preview.js index e6b79dd7d..81620e1a0 100644 --- a/public/self/dataset_preview.js +++ b/public/self/dataset_preview.js @@ -123,13 +123,13 @@ function loadimg(uuid,filename){ function loadimg(){ var length = labeltastresult[fileindex].pic_image_field.length; -  if(labeltastresult[fileindex].pic_image_field.substring(length - 5) == ".json"  -     || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".xml" -     || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".txt" -     || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".csv" -     || labeltastresult[fileindex].pic_image_field.substring(length - 3) == ".md" -     || labeltastresult[fileindex].pic_image_field.substring(length - 3) == ".py" -     || labeltastresult[fileindex].pic_image_field.substring(length - 3) == ".sh"){ +  if(labeltastresult[fileindex].pic_image_field.substring(length - 5).toLowerCase() == ".json"  +     || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".xml" +     || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".txt" +     || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".csv" +     || labeltastresult[fileindex].pic_image_field.substring(length - 3).toLowerCase() == ".md" +     || labeltastresult[fileindex].pic_image_field.substring(length - 3).toLowerCase() == ".py" +     || labeltastresult[fileindex].pic_image_field.substring(length - 3).toLowerCase() == ".sh"){ //文本 canvas.style.display="none"; @@ -138,11 +138,11 @@ function loadimg(){ $('#textcontent').height(canvas.height-40) $("#textcontent").text(textContent); }else{ - if(labeltastresult[fileindex].pic_image_field.substring(length - 5) == ".jpeg"  -    || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".jpg" -    || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".bmp" -    || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".gif" -    || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".png"){ + if(labeltastresult[fileindex].pic_image_field.substring(length - 5).toLowerCase() == ".jpeg"  +    || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".jpg" +    || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".bmp" +    || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".gif" +    || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".png"){ canvas.style.display="block"; document.getElementById("textcontent").style.display="none"; img.src = ip + "/getgiteaimage?uuid=" + dataset_id + "&filename=" + labeltastresult[fileindex].pic_image_field; From d645b39956f2a3b98e9abeaedf00280b949e7f19 Mon Sep 17 00:00:00 2001 From: liuzx Date: Tue, 2 Aug 2022 10:39:20 +0800 Subject: [PATCH 06/30] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=86=97=E4=BD=99?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=EF=BC=8Cfix-2650?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- models/cloudbrain.go | 15 ----- models/cloudbrain_static.go | 143 +++++--------------------------------------- 2 files changed, 16 insertions(+), 142 deletions(-) diff --git a/models/cloudbrain.go b/models/cloudbrain.go index 5091a8762..f9897b91d 100755 --- a/models/cloudbrain.go +++ b/models/cloudbrain.go @@ -1680,21 +1680,6 @@ func GetCloudbrainsNeededStopByUserID(userID int64) ([]*Cloudbrain, error) { return cloudBrains, err } -func GetWaittingTop() ([]*CloudbrainInfo, error) { - sess := x.NewSession() - defer sess.Close() - var cond = builder.NewCond() - cond = cond.And( - builder.Eq{"cloudbrain.status": string(JobWaiting)}, - ) - sess.OrderBy("cloudbrain.created_unix ASC limit 1") - cloudbrains := make([]*CloudbrainInfo, 0, 1) - if err := sess.Table(&Cloudbrain{}).Where(cond). - Find(&cloudbrains); err != nil { - log.Info("find error.") - } - return cloudbrains, nil -} func GetModelartsReDebugTaskByJobId(jobID string) ([]*Cloudbrain, error) { sess := x.NewSession() defer sess.Close() diff --git a/models/cloudbrain_static.go b/models/cloudbrain_static.go index e3ac5e963..371b30f66 100644 --- a/models/cloudbrain_static.go +++ b/models/cloudbrain_static.go @@ -36,133 +36,6 @@ type TaskDetail struct { FlavorName string `json:"FlavorName"` } -func GetDebugOnePeriodCount(beginTime time.Time, endTime time.Time) (int64, error) { - countSql := "SELECT count(*) FROM " + - "public.cloudbrain where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + - " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + - " and job_type ='" + string(JobTypeDebug) + "'" + - " and type='" + strconv.Itoa(TypeCloudBrainOne) + "'" - - return x.SQL(countSql).Count() -} -func GetDebugOnePeriodDuration(beginTime time.Time, endTime time.Time) (int64, error) { - total, err := x.Where("created_unix >= ? And created_unix < ? And job_type = ? And type = ? ", strconv.FormatInt(beginTime.Unix(), 10), strconv.FormatInt(endTime.Unix(), 10), JobTypeDebug, TypeCloudBrainOne).SumInt(&Cloudbrain{}, "duration") - if err != nil { - return 0, err - } - - return total, nil -} - -func GetTrainOnePeriodCount(beginTime time.Time, endTime time.Time) (int64, error) { - countSql := "SELECT count(*) FROM " + - "public.cloudbrain where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + - " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + - " and job_type ='" + string(JobTypeTrain) + "'" + - " and type='" + strconv.Itoa(TypeCloudBrainOne) + "'" - - return x.SQL(countSql).Count() -} -func GetTrainOnePeriodDuration(beginTime time.Time, endTime time.Time) (int64, error) { - total, err := x.Where("created_unix >= ? And created_unix < ? And job_type = ? And type = ? ", strconv.FormatInt(beginTime.Unix(), 10), strconv.FormatInt(endTime.Unix(), 10), JobTypeTrain, TypeCloudBrainOne).SumInt(&Cloudbrain{}, "duration") - if err != nil { - return 0, err - } - - return total, nil -} - -func GetBenchmarkOnePeriodCount(beginTime time.Time, endTime time.Time) (int64, error) { - countSql := "SELECT count(*) FROM " + - "public.cloudbrain where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + - " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + - " and job_type ='" + string(JobTypeBenchmark) + "'" + - " and type='" + strconv.Itoa(TypeCloudBrainOne) + "'" - return x.SQL(countSql).Count() -} -func GetBenchmarkOnePeriodDuration(beginTime time.Time, endTime time.Time) (int64, error) { - total, err := x.Where("created_unix >= ? And created_unix < ? And job_type = ? And type = ? ", strconv.FormatInt(beginTime.Unix(), 10), strconv.FormatInt(endTime.Unix(), 10), JobTypeBenchmark, TypeCloudBrainOne).SumInt(&Cloudbrain{}, "duration") - if err != nil { - return 0, err - } - - return total, nil -} -func GetDebugTwoPeriodCount(beginTime time.Time, endTime time.Time) (int64, error) { - countSql := "SELECT count(*) FROM " + - "public.cloudbrain where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + - " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + - " and job_type ='" + string(JobTypeDebug) + "'" + - " and type='" + strconv.Itoa(TypeCloudBrainTwo) + "'" - return x.SQL(countSql).Count() -} -func GetDebugTwoPeriodDuration(beginTime time.Time, endTime time.Time) (int64, error) { - total, err := x.Where("created_unix >= ? And created_unix < ? And job_type = ? And type = ? ", strconv.FormatInt(beginTime.Unix(), 10), strconv.FormatInt(endTime.Unix(), 10), JobTypeDebug, TypeCloudBrainTwo).SumInt(&Cloudbrain{}, "duration") - if err != nil { - return 0, err - } - return total, nil -} -func GetTrainTwoPeriodCount(beginTime time.Time, endTime time.Time) (int64, error) { - countSql := "SELECT count(*) FROM " + - "public.cloudbrain where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + - " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + - " and job_type ='" + string(JobTypeTrain) + "'" + - " and type='" + strconv.Itoa(TypeCloudBrainTwo) + "'" - return x.SQL(countSql).Count() -} -func GetTrainTwoPeriodDuration(beginTime time.Time, endTime time.Time) (int64, error) { - total, err := x.Where("created_unix >= ? And created_unix < ? And job_type = ? And type = ? ", strconv.FormatInt(beginTime.Unix(), 10), strconv.FormatInt(endTime.Unix(), 10), JobTypeTrain, TypeCloudBrainTwo).SumInt(&Cloudbrain{}, "duration") - if err != nil { - return 0, err - } - return total, nil -} -func GetInferenceTwoPeriodCount(beginTime time.Time, endTime time.Time) (int64, error) { - countSql := "SELECT count(*) FROM " + - "public.cloudbrain where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + - " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + - " and job_type ='" + string(JobTypeInference) + "'" + - " and type='" + strconv.Itoa(TypeCloudBrainTwo) + "'" - return x.SQL(countSql).Count() -} -func GetInferenceTwoPeriodDuration(beginTime time.Time, endTime time.Time) (int64, error) { - total, err := x.Where("created_unix >= ? And created_unix < ? And job_type = ? And type = ? ", strconv.FormatInt(beginTime.Unix(), 10), strconv.FormatInt(endTime.Unix(), 10), JobTypeInference, TypeCloudBrainTwo).SumInt(&Cloudbrain{}, "duration") - if err != nil { - return 0, err - } - return total, nil -} - -func GetCloudBrainOnePeriodCount(beginTime time.Time, endTime time.Time) (int64, error) { - countSql := "SELECT count(*) FROM " + - "public.cloudbrain where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + - " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + - " and type='" + strconv.Itoa(TypeCloudBrainOne) + "'" - return x.SQL(countSql).Count() -} -func GetCloudBrainOnePeriodDuration(beginTime time.Time, endTime time.Time) (int64, error) { - total, err := x.Where("created_unix >= ? And created_unix < ? And type = ? ", strconv.FormatInt(beginTime.Unix(), 10), strconv.FormatInt(endTime.Unix(), 10), TypeCloudBrainOne).SumInt(&Cloudbrain{}, "duration") - if err != nil { - return 0, err - } - return total, nil -} -func GetCloudBrainTwoPeriodCount(beginTime time.Time, endTime time.Time) (int64, error) { - countSql := "SELECT count(*) FROM " + - "public.cloudbrain where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + - " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + - " and type='" + strconv.Itoa(TypeCloudBrainTwo) + "'" - return x.SQL(countSql).Count() -} -func GetCloudBrainTwoPeriodDuration(beginTime time.Time, endTime time.Time) (int64, error) { - total, err := x.Where("created_unix >= ? And created_unix < ? And type = ? ", strconv.FormatInt(beginTime.Unix(), 10), strconv.FormatInt(endTime.Unix(), 10), TypeCloudBrainTwo).SumInt(&Cloudbrain{}, "duration") - if err != nil { - return 0, err - } - return total, nil -} - func GetTodayCreatorCount(beginTime time.Time, endTime time.Time) (int64, error) { countSql := "SELECT count(distinct user_id) FROM " + "public.cloudbrain where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) + @@ -211,6 +84,22 @@ func GetAllStatusCloudBrain() map[string]int { return cloudBrainStatusResult } +func GetWaittingTop() ([]*CloudbrainInfo, error) { + sess := x.NewSession() + defer sess.Close() + var cond = builder.NewCond() + cond = cond.And( + builder.Eq{"cloudbrain.status": string(JobWaiting)}, + ) + sess.OrderBy("cloudbrain.created_unix ASC limit 10") + cloudbrains := make([]*CloudbrainInfo, 0, 10) + if err := sess.Table(&Cloudbrain{}).Where(cond). + Find(&cloudbrains); err != nil { + log.Info("find error.") + } + return cloudbrains, nil +} + func GetRunningTop() ([]*CloudbrainInfo, error) { sess := x.NewSession() defer sess.Close() From 60682c67e05d32f18f0de6d2b5c7c8f460665ac8 Mon Sep 17 00:00:00 2001 From: ychao_1983 Date: Tue, 2 Aug 2022 14:10:08 +0800 Subject: [PATCH 07/30] fix-2591 --- go.mod | 2 +- go.sum | 2 + vendor/github.com/yuin/goldmark/Makefile | 2 +- vendor/github.com/yuin/goldmark/README.md | 135 +- vendor/github.com/yuin/goldmark/ast/ast.go | 28 +- vendor/github.com/yuin/goldmark/ast/block.go | 40 +- vendor/github.com/yuin/goldmark/ast/inline.go | 4 +- .../yuin/goldmark/extension/ast/footnote.go | 41 +- .../yuin/goldmark/extension/definition_list.go | 2 +- .../github.com/yuin/goldmark/extension/footnote.go | 421 ++- .../github.com/yuin/goldmark/extension/linkify.go | 39 +- vendor/github.com/yuin/goldmark/extension/table.go | 313 +- .../yuin/goldmark/extension/typographer.go | 96 +- vendor/github.com/yuin/goldmark/go.mod | 2 +- .../github.com/yuin/goldmark/parser/attribute.go | 11 +- .../github.com/yuin/goldmark/parser/atx_heading.go | 6 +- .../github.com/yuin/goldmark/parser/code_block.go | 21 + .../github.com/yuin/goldmark/parser/code_span.go | 13 +- .../github.com/yuin/goldmark/parser/delimiter.go | 26 +- .../github.com/yuin/goldmark/parser/fcode_block.go | 15 +- .../github.com/yuin/goldmark/parser/html_block.go | 12 +- vendor/github.com/yuin/goldmark/parser/link.go | 108 +- vendor/github.com/yuin/goldmark/parser/link_ref.go | 73 +- vendor/github.com/yuin/goldmark/parser/list.go | 56 +- .../github.com/yuin/goldmark/parser/list_item.go | 21 +- vendor/github.com/yuin/goldmark/parser/parser.go | 57 +- vendor/github.com/yuin/goldmark/parser/raw_html.go | 107 +- .../github.com/yuin/goldmark/renderer/html/html.go | 60 +- vendor/github.com/yuin/goldmark/text/reader.go | 110 + .../yuin/goldmark/util/unicode_case_folding.go | 3019 ++++++++++---------- vendor/github.com/yuin/goldmark/util/util.go | 171 +- .../github.com/yuin/goldmark/util/util_unsafe.go | 9 +- vendor/modules.txt | 2 +- 33 files changed, 3133 insertions(+), 1891 deletions(-) diff --git a/go.mod b/go.mod index 387a34520..e07defe79 100755 --- a/go.mod +++ b/go.mod @@ -120,7 +120,7 @@ require ( github.com/urfave/cli v1.22.1 github.com/xanzy/go-gitlab v0.31.0 github.com/yohcop/openid-go v1.0.0 - github.com/yuin/goldmark v1.1.30 + github.com/yuin/goldmark v1.4.13 github.com/yuin/goldmark-meta v0.0.0-20191126180153-f0638e958b60 golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 golang.org/x/mod v0.3.0 // indirect diff --git a/go.sum b/go.sum index d55d7af48..bd231b321 100755 --- a/go.sum +++ b/go.sum @@ -804,6 +804,8 @@ github.com/yuin/goldmark v1.1.27 h1:nqDD4MMMQA0lmWq03Z2/myGPYLQoXtmi0rGVs95ntbo= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.30 h1:j4d4Lw3zqZelDhBksEo3BnWg9xhXRQGJPPSL6OApZjI= github.com/yuin/goldmark v1.1.30/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark-meta v0.0.0-20191126180153-f0638e958b60 h1:gZucqLjL1eDzVWrXj4uiWeMbAopJlBR2mKQAsTGdPwo= github.com/yuin/goldmark-meta v0.0.0-20191126180153-f0638e958b60/go.mod h1:i9VhcIHN2PxXMbQrKqXNueok6QNONoPjNMoj9MygVL0= github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= diff --git a/vendor/github.com/yuin/goldmark/Makefile b/vendor/github.com/yuin/goldmark/Makefile index 667a19a47..d0b99cff2 100644 --- a/vendor/github.com/yuin/goldmark/Makefile +++ b/vendor/github.com/yuin/goldmark/Makefile @@ -12,5 +12,5 @@ fuzz: rm -rf ./fuzz/crashers rm -rf ./fuzz/suppressions rm -f ./fuzz/fuzz-fuzz.zip - cd ./fuzz && go-fuzz-build + cd ./fuzz && GO111MODULE=off go-fuzz-build cd ./fuzz && go-fuzz diff --git a/vendor/github.com/yuin/goldmark/README.md b/vendor/github.com/yuin/goldmark/README.md index b0923c930..e3d6918e6 100644 --- a/vendor/github.com/yuin/goldmark/README.md +++ b/vendor/github.com/yuin/goldmark/README.md @@ -1,14 +1,14 @@ goldmark ========================================== -[![http://godoc.org/github.com/yuin/goldmark](https://godoc.org/github.com/yuin/goldmark?status.svg)](http://godoc.org/github.com/yuin/goldmark) +[![https://pkg.go.dev/github.com/yuin/goldmark](https://pkg.go.dev/badge/github.com/yuin/goldmark.svg)](https://pkg.go.dev/github.com/yuin/goldmark) [![https://github.com/yuin/goldmark/actions?query=workflow:test](https://github.com/yuin/goldmark/workflows/test/badge.svg?branch=master&event=push)](https://github.com/yuin/goldmark/actions?query=workflow:test) [![https://coveralls.io/github/yuin/goldmark](https://coveralls.io/repos/github/yuin/goldmark/badge.svg?branch=master)](https://coveralls.io/github/yuin/goldmark) [![https://goreportcard.com/report/github.com/yuin/goldmark](https://goreportcard.com/badge/github.com/yuin/goldmark)](https://goreportcard.com/report/github.com/yuin/goldmark) > A Markdown parser written in Go. Easy to extend, standards-compliant, well-structured. -goldmark is compliant with CommonMark 0.29. +goldmark is compliant with CommonMark 0.30. Motivation ---------------------- @@ -173,6 +173,7 @@ Parser and Renderer options - This extension enables Table, Strikethrough, Linkify and TaskList. - This extension does not filter tags defined in [6.11: Disallowed Raw HTML (extension)](https://github.github.com/gfm/#disallowed-raw-html-extension-). If you need to filter HTML tags, see [Security](#security). + - If you need to parse github emojis, you can use [goldmark-emoji](https://github.com/yuin/goldmark-emoji) extension. - `extension.DefinitionList` - [PHP Markdown Extra: Definition lists](https://michelf.ca/projects/php-markdown/extra/#def-list) - `extension.Footnote` @@ -203,6 +204,18 @@ heading {#id .className attrName=attrValue} ============ ``` +### Table extension +The Table extension implements [Table(extension)](https://github.github.com/gfm/#tables-extension-), as +defined in [GitHub Flavored Markdown Spec](https://github.github.com/gfm/). + +Specs are defined for XHTML, so specs use some deprecated attributes for HTML5. + +You can override alignment rendering method via options. + +| Functional option | Type | Description | +| ----------------- | ---- | ----------- | +| `extension.WithTableCellAlignMethod` | `extension.TableCellAlignMethod` | Option indicates how are table cells aligned. | + ### Typographer extension The Typographer extension translates plain ASCII punctuation characters into typographic-punctuation HTML entities. @@ -219,7 +232,7 @@ Default substitutions are: | `<<` | `«` | | `>>` | `»` | -You can override the defualt substitutions via `extensions.WithTypographicSubstitutions`: +You can override the default substitutions via `extensions.WithTypographicSubstitutions`: ```go markdown := goldmark.New( @@ -267,13 +280,96 @@ markdown := goldmark.New( []byte("https:"), }), extension.WithLinkifyURLRegexp( - xurls.Strict(), + xurls.Strict, ), ), ), ) ``` +### Footnotes extension + +The Footnote extension implements [PHP Markdown Extra: Footnotes](https://michelf.ca/projects/php-markdown/extra/#footnotes). + +This extension has some options: + +| Functional option | Type | Description | +| ----------------- | ---- | ----------- | +| `extension.WithFootnoteIDPrefix` | `[]byte` | a prefix for the id attributes.| +| `extension.WithFootnoteIDPrefixFunction` | `func(gast.Node) []byte` | a function that determines the id attribute for given Node.| +| `extension.WithFootnoteLinkTitle` | `[]byte` | an optional title attribute for footnote links.| +| `extension.WithFootnoteBacklinkTitle` | `[]byte` | an optional title attribute for footnote backlinks. | +| `extension.WithFootnoteLinkClass` | `[]byte` | a class for footnote links. This defaults to `footnote-ref`. | +| `extension.WithFootnoteBacklinkClass` | `[]byte` | a class for footnote backlinks. This defaults to `footnote-backref`. | +| `extension.WithFootnoteBacklinkHTML` | `[]byte` | a class for footnote backlinks. This defaults to `↩︎`. | + +Some options can have special substitutions. Occurrences of “^^” in the string will be replaced by the corresponding footnote number in the HTML output. Occurrences of “%%” will be replaced by a number for the reference (footnotes can have multiple references). + +`extension.WithFootnoteIDPrefix` and `extension.WithFootnoteIDPrefixFunction` are useful if you have multiple Markdown documents displayed inside one HTML document to avoid footnote ids to clash each other. + +`extension.WithFootnoteIDPrefix` sets fixed id prefix, so you may write codes like the following: + +```go +for _, path := range files { + source := readAll(path) + prefix := getPrefix(path) + + markdown := goldmark.New( + goldmark.WithExtensions( + NewFootnote( + WithFootnoteIDPrefix([]byte(path)), + ), + ), + ) + var b bytes.Buffer + err := markdown.Convert(source, &b) + if err != nil { + t.Error(err.Error()) + } +} +``` + +`extension.WithFootnoteIDPrefixFunction` determines an id prefix by calling given function, so you may write codes like the following: + +```go +markdown := goldmark.New( + goldmark.WithExtensions( + NewFootnote( + WithFootnoteIDPrefixFunction(func(n gast.Node) []byte { + v, ok := n.OwnerDocument().Meta()["footnote-prefix"] + if ok { + return util.StringToReadOnlyBytes(v.(string)) + } + return nil + }), + ), + ), +) + +for _, path := range files { + source := readAll(path) + var b bytes.Buffer + + doc := markdown.Parser().Parse(text.NewReader(source)) + doc.Meta()["footnote-prefix"] = getPrefix(path) + err := markdown.Renderer().Render(&b, source, doc) +} +``` + +You can use [goldmark-meta](https://github.com/yuin/goldmark-meta) to define a id prefix in the markdown document: + + +```markdown +--- +title: document title +slug: article1 +footnote-prefix: article1 +--- + +# My article + +``` + Security -------------------- By default, goldmark does not render raw HTML or potentially-dangerous URLs. @@ -291,28 +387,29 @@ blackfriday v2 seems to be the fastest, but as it is not CommonMark compliant, i goldmark, meanwhile, builds a clean, extensible AST structure, achieves full compliance with CommonMark, and consumes less memory, all while being reasonably fast. +- MBP 2019 13″(i5, 16GB), Go1.17 + ``` -goos: darwin -goarch: amd64 -BenchmarkMarkdown/Blackfriday-v2-12 326 3465240 ns/op 3298861 B/op 20047 allocs/op -BenchmarkMarkdown/GoldMark-12 303 3927494 ns/op 2574809 B/op 13853 allocs/op -BenchmarkMarkdown/CommonMark-12 244 4900853 ns/op 2753851 B/op 20527 allocs/op -BenchmarkMarkdown/Lute-12 130 9195245 ns/op 9175030 B/op 123534 allocs/op -BenchmarkMarkdown/GoMarkdown-12 9 113541994 ns/op 2187472 B/op 22173 allocs/op +BenchmarkMarkdown/Blackfriday-v2-8 302 3743747 ns/op 3290445 B/op 20050 allocs/op +BenchmarkMarkdown/GoldMark-8 280 4200974 ns/op 2559738 B/op 13435 allocs/op +BenchmarkMarkdown/CommonMark-8 226 5283686 ns/op 2702490 B/op 20792 allocs/op +BenchmarkMarkdown/Lute-8 12 92652857 ns/op 10602649 B/op 40555 allocs/op +BenchmarkMarkdown/GoMarkdown-8 13 81380167 ns/op 2245002 B/op 22889 allocs/op ``` ### against cmark (CommonMark reference implementation written in C) +- MBP 2019 13″(i5, 16GB), Go1.17 + ``` ----------- cmark ----------- file: _data.md iteration: 50 -average: 0.0037760639 sec -go run ./goldmark_benchmark.go +average: 0.0044073057 sec ------- goldmark ------- file: _data.md iteration: 50 -average: 0.0040964230 sec +average: 0.0041611990 sec ``` As you can see, goldmark's performance is on par with cmark's. @@ -324,7 +421,17 @@ Extensions extension for the goldmark Markdown parser. - [goldmark-highlighting](https://github.com/yuin/goldmark-highlighting): A syntax-highlighting extension for the goldmark markdown parser. +- [goldmark-emoji](https://github.com/yuin/goldmark-emoji): An emoji + extension for the goldmark Markdown parser. - [goldmark-mathjax](https://github.com/litao91/goldmark-mathjax): Mathjax support for the goldmark markdown parser +- [goldmark-pdf](https://github.com/stephenafamo/goldmark-pdf): A PDF renderer that can be passed to `goldmark.WithRenderer()`. +- [goldmark-hashtag](https://github.com/abhinav/goldmark-hashtag): Adds support for `#hashtag`-based tagging to goldmark. +- [goldmark-wikilink](https://github.com/abhinav/goldmark-wikilink): Adds support for `[[wiki]]`-style links to goldmark. +- [goldmark-toc](https://github.com/abhinav/goldmark-toc): Adds support for generating tables-of-contents for goldmark documents. +- [goldmark-mermaid](https://github.com/abhinav/goldmark-mermaid): Adds support for rendering [Mermaid](https://mermaid-js.github.io/mermaid/) diagrams in goldmark documents. +- [goldmark-pikchr](https://github.com/jchenry/goldmark-pikchr): Adds support for rendering [Pikchr](https://pikchr.org/home/doc/trunk/homepage.md) diagrams in goldmark documents. +- [goldmark-embed](https://github.com/13rac1/goldmark-embed): Adds support for rendering embeds from YouTube links. + goldmark internal(for extension developers) ---------------------------------------------- diff --git a/vendor/github.com/yuin/goldmark/ast/ast.go b/vendor/github.com/yuin/goldmark/ast/ast.go index 66059e94c..3719ebbd8 100644 --- a/vendor/github.com/yuin/goldmark/ast/ast.go +++ b/vendor/github.com/yuin/goldmark/ast/ast.go @@ -45,11 +45,6 @@ type Attribute struct { Value interface{} } -var attrNameIDS = []byte("#") -var attrNameID = []byte("id") -var attrNameClassS = []byte(".") -var attrNameClass = []byte("class") - // A Node interface defines basic AST node functionalities. type Node interface { // Type returns a type of this node. @@ -116,6 +111,11 @@ type Node interface { // tail of the children. InsertAfter(self, v1, insertee Node) + // OwnerDocument returns this node's owner document. + // If this node is not a child of the Document node, OwnerDocument + // returns nil. + OwnerDocument() *Document + // Dump dumps an AST tree structure to stdout. // This function completely aimed for debugging. // level is a indent level. Implementer should indent informations with @@ -169,7 +169,7 @@ type Node interface { RemoveAttributes() } -// A BaseNode struct implements the Node interface. +// A BaseNode struct implements the Node interface partialliy. type BaseNode struct { firstChild Node lastChild Node @@ -358,6 +358,22 @@ func (n *BaseNode) InsertBefore(self, v1, insertee Node) { } } +// OwnerDocument implements Node.OwnerDocument +func (n *BaseNode) OwnerDocument() *Document { + d := n.Parent() + for { + p := d.Parent() + if p == nil { + if v, ok := d.(*Document); ok { + return v + } + break + } + d = p + } + return nil +} + // Text implements Node.Text . func (n *BaseNode) Text(source []byte) []byte { var buf bytes.Buffer diff --git a/vendor/github.com/yuin/goldmark/ast/block.go b/vendor/github.com/yuin/goldmark/ast/block.go index f5bca33fe..02e9d5190 100644 --- a/vendor/github.com/yuin/goldmark/ast/block.go +++ b/vendor/github.com/yuin/goldmark/ast/block.go @@ -7,7 +7,7 @@ import ( textm "github.com/yuin/goldmark/text" ) -// A BaseBlock struct implements the Node interface. +// A BaseBlock struct implements the Node interface partialliy. type BaseBlock struct { BaseNode blankPreviousLines bool @@ -50,6 +50,8 @@ func (b *BaseBlock) SetLines(v *textm.Segments) { // A Document struct is a root node of Markdown text. type Document struct { BaseBlock + + meta map[string]interface{} } // KindDocument is a NodeKind of the Document node. @@ -70,10 +72,42 @@ func (n *Document) Kind() NodeKind { return KindDocument } +// OwnerDocument implements Node.OwnerDocument +func (n *Document) OwnerDocument() *Document { + return n +} + +// Meta returns metadata of this document. +func (n *Document) Meta() map[string]interface{} { + if n.meta == nil { + n.meta = map[string]interface{}{} + } + return n.meta +} + +// SetMeta sets given metadata to this document. +func (n *Document) SetMeta(meta map[string]interface{}) { + if n.meta == nil { + n.meta = map[string]interface{}{} + } + for k, v := range meta { + n.meta[k] = v + } +} + +// AddMeta adds given metadata to this document. +func (n *Document) AddMeta(key string, value interface{}) { + if n.meta == nil { + n.meta = map[string]interface{}{} + } + n.meta[key] = value +} + // NewDocument returns a new Document node. func NewDocument() *Document { return &Document{ BaseBlock: BaseBlock{}, + meta: nil, } } @@ -311,7 +345,7 @@ type List struct { Marker byte // IsTight is a true if this list is a 'tight' list. - // See https://spec.commonmark.org/0.29/#loose for details. + // See https://spec.commonmark.org/0.30/#loose for details. IsTight bool // Start is an initial number of this ordered list. @@ -393,7 +427,7 @@ func NewListItem(offset int) *ListItem { } // HTMLBlockType represents kinds of an html blocks. -// See https://spec.commonmark.org/0.29/#html-blocks +// See https://spec.commonmark.org/0.30/#html-blocks type HTMLBlockType int const ( diff --git a/vendor/github.com/yuin/goldmark/ast/inline.go b/vendor/github.com/yuin/goldmark/ast/inline.go index 23dcad4bc..fa6fc34f9 100644 --- a/vendor/github.com/yuin/goldmark/ast/inline.go +++ b/vendor/github.com/yuin/goldmark/ast/inline.go @@ -8,7 +8,7 @@ import ( "github.com/yuin/goldmark/util" ) -// A BaseInline struct implements the Node interface. +// A BaseInline struct implements the Node interface partialliy. type BaseInline struct { BaseNode } @@ -111,7 +111,7 @@ func (n *Text) SetRaw(v bool) { } // HardLineBreak returns true if this node ends with a hard line break. -// See https://spec.commonmark.org/0.29/#hard-line-breaks for details. +// See https://spec.commonmark.org/0.30/#hard-line-breaks for details. func (n *Text) HardLineBreak() bool { return n.flags&textHardLineBreak != 0 } diff --git a/vendor/github.com/yuin/goldmark/extension/ast/footnote.go b/vendor/github.com/yuin/goldmark/extension/ast/footnote.go index 835f8478b..97fea4403 100644 --- a/vendor/github.com/yuin/goldmark/extension/ast/footnote.go +++ b/vendor/github.com/yuin/goldmark/extension/ast/footnote.go @@ -2,6 +2,7 @@ package ast import ( "fmt" + gast "github.com/yuin/goldmark/ast" ) @@ -9,13 +10,17 @@ import ( // (PHP Markdown Extra) text. type FootnoteLink struct { gast.BaseInline - Index int + Index int + RefCount int + RefIndex int } // Dump implements Node.Dump. func (n *FootnoteLink) Dump(source []byte, level int) { m := map[string]string{} m["Index"] = fmt.Sprintf("%v", n.Index) + m["RefCount"] = fmt.Sprintf("%v", n.RefCount) + m["RefIndex"] = fmt.Sprintf("%v", n.RefIndex) gast.DumpHelper(n, source, level, m, nil) } @@ -30,36 +35,44 @@ func (n *FootnoteLink) Kind() gast.NodeKind { // NewFootnoteLink returns a new FootnoteLink node. func NewFootnoteLink(index int) *FootnoteLink { return &FootnoteLink{ - Index: index, + Index: index, + RefCount: 0, + RefIndex: 0, } } -// A FootnoteBackLink struct represents a link to a footnote of Markdown +// A FootnoteBacklink struct represents a link to a footnote of Markdown // (PHP Markdown Extra) text. -type FootnoteBackLink struct { +type FootnoteBacklink struct { gast.BaseInline - Index int + Index int + RefCount int + RefIndex int } // Dump implements Node.Dump. -func (n *FootnoteBackLink) Dump(source []byte, level int) { +func (n *FootnoteBacklink) Dump(source []byte, level int) { m := map[string]string{} m["Index"] = fmt.Sprintf("%v", n.Index) + m["RefCount"] = fmt.Sprintf("%v", n.RefCount) + m["RefIndex"] = fmt.Sprintf("%v", n.RefIndex) gast.DumpHelper(n, source, level, m, nil) } -// KindFootnoteBackLink is a NodeKind of the FootnoteBackLink node. -var KindFootnoteBackLink = gast.NewNodeKind("FootnoteBackLink") +// KindFootnoteBacklink is a NodeKind of the FootnoteBacklink node. +var KindFootnoteBacklink = gast.NewNodeKind("FootnoteBacklink") // Kind implements Node.Kind. -func (n *FootnoteBackLink) Kind() gast.NodeKind { - return KindFootnoteBackLink +func (n *FootnoteBacklink) Kind() gast.NodeKind { + return KindFootnoteBacklink } -// NewFootnoteBackLink returns a new FootnoteBackLink node. -func NewFootnoteBackLink(index int) *FootnoteBackLink { - return &FootnoteBackLink{ - Index: index, +// NewFootnoteBacklink returns a new FootnoteBacklink node. +func NewFootnoteBacklink(index int) *FootnoteBacklink { + return &FootnoteBacklink{ + Index: index, + RefCount: 0, + RefIndex: 0, } } diff --git a/vendor/github.com/yuin/goldmark/extension/definition_list.go b/vendor/github.com/yuin/goldmark/extension/definition_list.go index eb16dd03f..d2f5fecbe 100644 --- a/vendor/github.com/yuin/goldmark/extension/definition_list.go +++ b/vendor/github.com/yuin/goldmark/extension/definition_list.go @@ -138,7 +138,7 @@ func (b *definitionDescriptionParser) Open(parent gast.Node, reader text.Reader, para.Parent().RemoveChild(para.Parent(), para) } cpos, padding := util.IndentPosition(line[pos+1:], pos+1, list.Offset-pos-1) - reader.AdvanceAndSetPadding(cpos, padding) + reader.AdvanceAndSetPadding(cpos+1, padding) return ast.NewDefinitionDescription(), parser.HasChildren } diff --git a/vendor/github.com/yuin/goldmark/extension/footnote.go b/vendor/github.com/yuin/goldmark/extension/footnote.go index ede72db87..09b6fa8b0 100644 --- a/vendor/github.com/yuin/goldmark/extension/footnote.go +++ b/vendor/github.com/yuin/goldmark/extension/footnote.go @@ -2,6 +2,9 @@ package extension import ( "bytes" + "fmt" + "strconv" + "github.com/yuin/goldmark" gast "github.com/yuin/goldmark/ast" "github.com/yuin/goldmark/extension/ast" @@ -10,10 +13,10 @@ import ( "github.com/yuin/goldmark/renderer/html" "github.com/yuin/goldmark/text" "github.com/yuin/goldmark/util" - "strconv" ) var footnoteListKey = parser.NewContextKey() +var footnoteLinkListKey = parser.NewContextKey() type footnoteBlockParser struct { } @@ -164,7 +167,20 @@ func (s *footnoteParser) Parse(parent gast.Node, block text.Reader, pc parser.Co return nil } - return ast.NewFootnoteLink(index) + fnlink := ast.NewFootnoteLink(index) + var fnlist []*ast.FootnoteLink + if tmp := pc.Get(footnoteLinkListKey); tmp != nil { + fnlist = tmp.([]*ast.FootnoteLink) + } else { + fnlist = []*ast.FootnoteLink{} + pc.Set(footnoteLinkListKey, fnlist) + } + pc.Set(footnoteLinkListKey, append(fnlist, fnlink)) + if line[0] == '!' { + parent.AppendChild(parent, gast.NewTextSegment(text.NewSegment(segment.Start, segment.Start+1))) + } + + return fnlink } type footnoteASTTransformer struct { @@ -180,23 +196,62 @@ func NewFootnoteASTTransformer() parser.ASTTransformer { func (a *footnoteASTTransformer) Transform(node *gast.Document, reader text.Reader, pc parser.Context) { var list *ast.FootnoteList - if tlist := pc.Get(footnoteListKey); tlist != nil { - list = tlist.(*ast.FootnoteList) - } else { - return + var fnlist []*ast.FootnoteLink + if tmp := pc.Get(footnoteListKey); tmp != nil { + list = tmp.(*ast.FootnoteList) + } + if tmp := pc.Get(footnoteLinkListKey); tmp != nil { + fnlist = tmp.([]*ast.FootnoteLink) } + pc.Set(footnoteListKey, nil) + pc.Set(footnoteLinkListKey, nil) + + if list == nil { + return + } + + counter := map[int]int{} + if fnlist != nil { + for _, fnlink := range fnlist { + if fnlink.Index >= 0 { + counter[fnlink.Index]++ + } + } + refCounter := map[int]int{} + for _, fnlink := range fnlist { + fnlink.RefCount = counter[fnlink.Index] + if _, ok := refCounter[fnlink.Index]; !ok { + refCounter[fnlink.Index] = 0 + } + fnlink.RefIndex = refCounter[fnlink.Index] + refCounter[fnlink.Index]++ + } + } for footnote := list.FirstChild(); footnote != nil; { var container gast.Node = footnote next := footnote.NextSibling() if fc := container.LastChild(); fc != nil && gast.IsParagraph(fc) { container = fc } - index := footnote.(*ast.Footnote).Index + fn := footnote.(*ast.Footnote) + index := fn.Index if index < 0 { list.RemoveChild(list, footnote) } else { - container.AppendChild(container, ast.NewFootnoteBackLink(index)) + refCount := counter[index] + backLink := ast.NewFootnoteBacklink(index) + backLink.RefCount = refCount + backLink.RefIndex = 0 + container.AppendChild(container, backLink) + if refCount > 1 { + for i := 1; i < refCount; i++ { + backLink := ast.NewFootnoteBacklink(index) + backLink.RefCount = refCount + backLink.RefIndex = i + container.AppendChild(container, backLink) + } + } } footnote = next } @@ -214,19 +269,250 @@ func (a *footnoteASTTransformer) Transform(node *gast.Document, reader text.Read node.AppendChild(node, list) } +// FootnoteConfig holds configuration values for the footnote extension. +// +// Link* and Backlink* configurations have some variables: +// Occurrances of “^^” in the string will be replaced by the +// corresponding footnote number in the HTML output. +// Occurrances of “%%” will be replaced by a number for the +// reference (footnotes can have multiple references). +type FootnoteConfig struct { + html.Config + + // IDPrefix is a prefix for the id attributes generated by footnotes. + IDPrefix []byte + + // IDPrefix is a function that determines the id attribute for given Node. + IDPrefixFunction func(gast.Node) []byte + + // LinkTitle is an optional title attribute for footnote links. + LinkTitle []byte + + // BacklinkTitle is an optional title attribute for footnote backlinks. + BacklinkTitle []byte + + // LinkClass is a class for footnote links. + LinkClass []byte + + // BacklinkClass is a class for footnote backlinks. + BacklinkClass []byte + + // BacklinkHTML is an HTML content for footnote backlinks. + BacklinkHTML []byte +} + +// FootnoteOption interface is a functional option interface for the extension. +type FootnoteOption interface { + renderer.Option + // SetFootnoteOption sets given option to the extension. + SetFootnoteOption(*FootnoteConfig) +} + +// NewFootnoteConfig returns a new Config with defaults. +func NewFootnoteConfig() FootnoteConfig { + return FootnoteConfig{ + Config: html.NewConfig(), + LinkTitle: []byte(""), + BacklinkTitle: []byte(""), + LinkClass: []byte("footnote-ref"), + BacklinkClass: []byte("footnote-backref"), + BacklinkHTML: []byte("↩︎"), + } +} + +// SetOption implements renderer.SetOptioner. +func (c *FootnoteConfig) SetOption(name renderer.OptionName, value interface{}) { + switch name { + case optFootnoteIDPrefixFunction: + c.IDPrefixFunction = value.(func(gast.Node) []byte) + case optFootnoteIDPrefix: + c.IDPrefix = value.([]byte) + case optFootnoteLinkTitle: + c.LinkTitle = value.([]byte) + case optFootnoteBacklinkTitle: + c.BacklinkTitle = value.([]byte) + case optFootnoteLinkClass: + c.LinkClass = value.([]byte) + case optFootnoteBacklinkClass: + c.BacklinkClass = value.([]byte) + case optFootnoteBacklinkHTML: + c.BacklinkHTML = value.([]byte) + default: + c.Config.SetOption(name, value) + } +} + +type withFootnoteHTMLOptions struct { + value []html.Option +} + +func (o *withFootnoteHTMLOptions) SetConfig(c *renderer.Config) { + if o.value != nil { + for _, v := range o.value { + v.(renderer.Option).SetConfig(c) + } + } +} + +func (o *withFootnoteHTMLOptions) SetFootnoteOption(c *FootnoteConfig) { + if o.value != nil { + for _, v := range o.value { + v.SetHTMLOption(&c.Config) + } + } +} + +// WithFootnoteHTMLOptions is functional option that wraps goldmark HTMLRenderer options. +func WithFootnoteHTMLOptions(opts ...html.Option) FootnoteOption { + return &withFootnoteHTMLOptions{opts} +} + +const optFootnoteIDPrefix renderer.OptionName = "FootnoteIDPrefix" + +type withFootnoteIDPrefix struct { + value []byte +} + +func (o *withFootnoteIDPrefix) SetConfig(c *renderer.Config) { + c.Options[optFootnoteIDPrefix] = o.value +} + +func (o *withFootnoteIDPrefix) SetFootnoteOption(c *FootnoteConfig) { + c.IDPrefix = o.value +} + +// WithFootnoteIDPrefix is a functional option that is a prefix for the id attributes generated by footnotes. +func WithFootnoteIDPrefix(a []byte) FootnoteOption { + return &withFootnoteIDPrefix{a} +} + +const optFootnoteIDPrefixFunction renderer.OptionName = "FootnoteIDPrefixFunction" + +type withFootnoteIDPrefixFunction struct { + value func(gast.Node) []byte +} + +func (o *withFootnoteIDPrefixFunction) SetConfig(c *renderer.Config) { + c.Options[optFootnoteIDPrefixFunction] = o.value +} + +func (o *withFootnoteIDPrefixFunction) SetFootnoteOption(c *FootnoteConfig) { + c.IDPrefixFunction = o.value +} + +// WithFootnoteIDPrefixFunction is a functional option that is a prefix for the id attributes generated by footnotes. +func WithFootnoteIDPrefixFunction(a func(gast.Node) []byte) FootnoteOption { + return &withFootnoteIDPrefixFunction{a} +} + +const optFootnoteLinkTitle renderer.OptionName = "FootnoteLinkTitle" + +type withFootnoteLinkTitle struct { + value []byte +} + +func (o *withFootnoteLinkTitle) SetConfig(c *renderer.Config) { + c.Options[optFootnoteLinkTitle] = o.value +} + +func (o *withFootnoteLinkTitle) SetFootnoteOption(c *FootnoteConfig) { + c.LinkTitle = o.value +} + +// WithFootnoteLinkTitle is a functional option that is an optional title attribute for footnote links. +func WithFootnoteLinkTitle(a []byte) FootnoteOption { + return &withFootnoteLinkTitle{a} +} + +const optFootnoteBacklinkTitle renderer.OptionName = "FootnoteBacklinkTitle" + +type withFootnoteBacklinkTitle struct { + value []byte +} + +func (o *withFootnoteBacklinkTitle) SetConfig(c *renderer.Config) { + c.Options[optFootnoteBacklinkTitle] = o.value +} + +func (o *withFootnoteBacklinkTitle) SetFootnoteOption(c *FootnoteConfig) { + c.BacklinkTitle = o.value +} + +// WithFootnoteBacklinkTitle is a functional option that is an optional title attribute for footnote backlinks. +func WithFootnoteBacklinkTitle(a []byte) FootnoteOption { + return &withFootnoteBacklinkTitle{a} +} + +const optFootnoteLinkClass renderer.OptionName = "FootnoteLinkClass" + +type withFootnoteLinkClass struct { + value []byte +} + +func (o *withFootnoteLinkClass) SetConfig(c *renderer.Config) { + c.Options[optFootnoteLinkClass] = o.value +} + +func (o *withFootnoteLinkClass) SetFootnoteOption(c *FootnoteConfig) { + c.LinkClass = o.value +} + +// WithFootnoteLinkClass is a functional option that is a class for footnote links. +func WithFootnoteLinkClass(a []byte) FootnoteOption { + return &withFootnoteLinkClass{a} +} + +const optFootnoteBacklinkClass renderer.OptionName = "FootnoteBacklinkClass" + +type withFootnoteBacklinkClass struct { + value []byte +} + +func (o *withFootnoteBacklinkClass) SetConfig(c *renderer.Config) { + c.Options[optFootnoteBacklinkClass] = o.value +} + +func (o *withFootnoteBacklinkClass) SetFootnoteOption(c *FootnoteConfig) { + c.BacklinkClass = o.value +} + +// WithFootnoteBacklinkClass is a functional option that is a class for footnote backlinks. +func WithFootnoteBacklinkClass(a []byte) FootnoteOption { + return &withFootnoteBacklinkClass{a} +} + +const optFootnoteBacklinkHTML renderer.OptionName = "FootnoteBacklinkHTML" + +type withFootnoteBacklinkHTML struct { + value []byte +} + +func (o *withFootnoteBacklinkHTML) SetConfig(c *renderer.Config) { + c.Options[optFootnoteBacklinkHTML] = o.value +} + +func (o *withFootnoteBacklinkHTML) SetFootnoteOption(c *FootnoteConfig) { + c.BacklinkHTML = o.value +} + +// WithFootnoteBacklinkHTML is an HTML content for footnote backlinks. +func WithFootnoteBacklinkHTML(a []byte) FootnoteOption { + return &withFootnoteBacklinkHTML{a} +} + // FootnoteHTMLRenderer is a renderer.NodeRenderer implementation that // renders FootnoteLink nodes. type FootnoteHTMLRenderer struct { - html.Config + FootnoteConfig } // NewFootnoteHTMLRenderer returns a new FootnoteHTMLRenderer. -func NewFootnoteHTMLRenderer(opts ...html.Option) renderer.NodeRenderer { +func NewFootnoteHTMLRenderer(opts ...FootnoteOption) renderer.NodeRenderer { r := &FootnoteHTMLRenderer{ - Config: html.NewConfig(), + FootnoteConfig: NewFootnoteConfig(), } for _, opt := range opts { - opt.SetHTMLOption(&r.Config) + opt.SetFootnoteOption(&r.FootnoteConfig) } return r } @@ -234,7 +520,7 @@ func NewFootnoteHTMLRenderer(opts ...html.Option) renderer.NodeRenderer { // RegisterFuncs implements renderer.NodeRenderer.RegisterFuncs. func (r *FootnoteHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) { reg.Register(ast.KindFootnoteLink, r.renderFootnoteLink) - reg.Register(ast.KindFootnoteBackLink, r.renderFootnoteBackLink) + reg.Register(ast.KindFootnoteBacklink, r.renderFootnoteBacklink) reg.Register(ast.KindFootnote, r.renderFootnote) reg.Register(ast.KindFootnoteList, r.renderFootnoteList) } @@ -243,25 +529,53 @@ func (r *FootnoteHTMLRenderer) renderFootnoteLink(w util.BufWriter, source []byt if entering { n := node.(*ast.FootnoteLink) is := strconv.Itoa(n.Index) - _, _ = w.WriteString(` 0 { + _, _ = w.WriteString(fmt.Sprintf("%v", n.RefIndex)) + } + _ = w.WriteByte(':') _, _ = w.WriteString(is) - _, _ = w.WriteString(`">`) + _, _ = w.WriteString(`" class="`) + _, _ = w.Write(applyFootnoteTemplate(r.FootnoteConfig.LinkClass, + n.Index, n.RefCount)) + if len(r.FootnoteConfig.LinkTitle) > 0 { + _, _ = w.WriteString(`" title="`) + _, _ = w.Write(util.EscapeHTML(applyFootnoteTemplate(r.FootnoteConfig.LinkTitle, n.Index, n.RefCount))) + } + _, _ = w.WriteString(`" role="doc-noteref">`) + _, _ = w.WriteString(is) _, _ = w.WriteString(``) } return gast.WalkContinue, nil } -func (r *FootnoteHTMLRenderer) renderFootnoteBackLink(w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) { +func (r *FootnoteHTMLRenderer) renderFootnoteBacklink(w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) { if entering { - n := node.(*ast.FootnoteBackLink) + n := node.(*ast.FootnoteBacklink) is := strconv.Itoa(n.Index) - _, _ = w.WriteString(` 0 { + _, _ = w.WriteString(fmt.Sprintf("%v", n.RefIndex)) + } + _ = w.WriteByte(':') _, _ = w.WriteString(is) - _, _ = w.WriteString(`" class="footnote-backref" role="doc-backlink">`) - _, _ = w.WriteString("↩︎") + _, _ = w.WriteString(`" class="`) + _, _ = w.Write(applyFootnoteTemplate(r.FootnoteConfig.BacklinkClass, n.Index, n.RefCount)) + if len(r.FootnoteConfig.BacklinkTitle) > 0 { + _, _ = w.WriteString(`" title="`) + _, _ = w.Write(util.EscapeHTML(applyFootnoteTemplate(r.FootnoteConfig.BacklinkTitle, n.Index, n.RefCount))) + } + _, _ = w.WriteString(`" role="doc-backlink">`) + _, _ = w.Write(applyFootnoteTemplate(r.FootnoteConfig.BacklinkHTML, n.Index, n.RefCount)) _, _ = w.WriteString(``) } return gast.WalkContinue, nil @@ -271,9 +585,11 @@ func (r *FootnoteHTMLRenderer) renderFootnote(w util.BufWriter, source []byte, n n := node.(*ast.Footnote) is := strconv.Itoa(n.Index) if entering { - _, _ = w.WriteString(`
  • \n") } else { _, _ = w.WriteString("\n") - _, _ = w.WriteString("\n") + _, _ = w.WriteString("\n") } return gast.WalkContinue, nil } +func (r *FootnoteHTMLRenderer) idPrefix(node gast.Node) []byte { + if r.FootnoteConfig.IDPrefix != nil { + return r.FootnoteConfig.IDPrefix + } + if r.FootnoteConfig.IDPrefixFunction != nil { + return r.FootnoteConfig.IDPrefixFunction(node) + } + return []byte("") +} + +func applyFootnoteTemplate(b []byte, index, refCount int) []byte { + fast := true + for i, c := range b { + if i != 0 { + if b[i-1] == '^' && c == '^' { + fast = false + break + } + if b[i-1] == '%' && c == '%' { + fast = false + break + } + } + } + if fast { + return b + } + is := []byte(strconv.Itoa(index)) + rs := []byte(strconv.Itoa(refCount)) + ret := bytes.Replace(b, []byte("^^"), is, -1) + return bytes.Replace(ret, []byte("%%"), rs, -1) +} + type footnote struct { + options []FootnoteOption } // Footnote is an extension that allow you to use PHP Markdown Extra Footnotes. -var Footnote = &footnote{} +var Footnote = &footnote{ + options: []FootnoteOption{}, +} + +// NewFootnote returns a new extension with given options. +func NewFootnote(opts ...FootnoteOption) goldmark.Extender { + return &footnote{ + options: opts, + } +} func (e *footnote) Extend(m goldmark.Markdown) { m.Parser().AddOptions( @@ -331,6 +682,6 @@ func (e *footnote) Extend(m goldmark.Markdown) { ), ) m.Renderer().AddOptions(renderer.WithNodeRenderers( - util.Prioritized(NewFootnoteHTMLRenderer(), 500), + util.Prioritized(NewFootnoteHTMLRenderer(e.options...), 500), )) } diff --git a/vendor/github.com/yuin/goldmark/extension/linkify.go b/vendor/github.com/yuin/goldmark/extension/linkify.go index 9e68fa534..2f046eb54 100644 --- a/vendor/github.com/yuin/goldmark/extension/linkify.go +++ b/vendor/github.com/yuin/goldmark/extension/linkify.go @@ -11,9 +11,9 @@ import ( "github.com/yuin/goldmark/util" ) -var wwwURLRegxp = regexp.MustCompile(`^www\.[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]+(?:(?:/|[#?])[-a-zA-Z0-9@:%_\+.~#!?&//=\(\);,'">\^{}\[\]` + "`" + `]*)?`) +var wwwURLRegxp = regexp.MustCompile(`^www\.[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-z]+(?:[/#?][-a-zA-Z0-9@:%_\+.~#!?&/=\(\);,'">\^{}\[\]` + "`" + `]*)?`) -var urlRegexp = regexp.MustCompile(`^(?:http|https|ftp):\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]+(?:(?:/|[#?])[-a-zA-Z0-9@:%_+.~#$!?&//=\(\);,'">\^{}\[\]` + "`" + `]*)?`) +var urlRegexp = regexp.MustCompile(`^(?:http|https|ftp)://[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-z]+(?::\d+)?(?:[/#?][-a-zA-Z0-9@:%_+.~#$!?&/=\(\);,'">\^{}\[\]` + "`" + `]*)?`) // An LinkifyConfig struct is a data structure that holds configuration of the // Linkify extension. @@ -24,10 +24,12 @@ type LinkifyConfig struct { EmailRegexp *regexp.Regexp } -const optLinkifyAllowedProtocols parser.OptionName = "LinkifyAllowedProtocols" -const optLinkifyURLRegexp parser.OptionName = "LinkifyURLRegexp" -const optLinkifyWWWRegexp parser.OptionName = "LinkifyWWWRegexp" -const optLinkifyEmailRegexp parser.OptionName = "LinkifyEmailRegexp" +const ( + optLinkifyAllowedProtocols parser.OptionName = "LinkifyAllowedProtocols" + optLinkifyURLRegexp parser.OptionName = "LinkifyURLRegexp" + optLinkifyWWWRegexp parser.OptionName = "LinkifyWWWRegexp" + optLinkifyEmailRegexp parser.OptionName = "LinkifyEmailRegexp" +) // SetOption implements SetOptioner. func (c *LinkifyConfig) SetOption(name parser.OptionName, value interface{}) { @@ -156,10 +158,12 @@ func (s *linkifyParser) Trigger() []byte { return []byte{' ', '*', '_', '~', '('} } -var protoHTTP = []byte("http:") -var protoHTTPS = []byte("https:") -var protoFTP = []byte("ftp:") -var domainWWW = []byte("www.") +var ( + protoHTTP = []byte("http:") + protoHTTPS = []byte("https:") + protoFTP = []byte("ftp:") + domainWWW = []byte("www.") +) func (s *linkifyParser) Parse(parent ast.Node, block text.Reader, pc parser.Context) ast.Node { if pc.IsInLinkLabel() { @@ -269,9 +273,20 @@ func (s *linkifyParser) Parse(parent ast.Node, block text.Reader, pc parser.Cont s := segment.WithStop(segment.Start + 1) ast.MergeOrAppendTextSegment(parent, s) } - consumes += m[1] + i := m[1] - 1 + for ; i > 0; i-- { + c := line[i] + switch c { + case '?', '!', '.', ',', ':', '*', '_', '~': + default: + goto endfor + } + } +endfor: + i++ + consumes += i block.Advance(consumes) - n := ast.NewTextSegment(text.NewSegment(start, start+m[1])) + n := ast.NewTextSegment(text.NewSegment(start, start+i)) link := ast.NewAutoLink(typ, n) link.Protocol = protocol return link diff --git a/vendor/github.com/yuin/goldmark/extension/table.go b/vendor/github.com/yuin/goldmark/extension/table.go index 91ba33199..c637b99f0 100644 --- a/vendor/github.com/yuin/goldmark/extension/table.go +++ b/vendor/github.com/yuin/goldmark/extension/table.go @@ -15,7 +15,121 @@ import ( "github.com/yuin/goldmark/util" ) -var tableDelimRegexp = regexp.MustCompile(`^[\s\-\|\:]+$`) +var escapedPipeCellListKey = parser.NewContextKey() + +type escapedPipeCell struct { + Cell *ast.TableCell + Pos []int + Transformed bool +} + +// TableCellAlignMethod indicates how are table cells aligned in HTML format.indicates how are table cells aligned in HTML format. +type TableCellAlignMethod int + +const ( + // TableCellAlignDefault renders alignments by default method. + // With XHTML, alignments are rendered as an align attribute. + // With HTML5, alignments are rendered as a style attribute. + TableCellAlignDefault TableCellAlignMethod = iota + + // TableCellAlignAttribute renders alignments as an align attribute. + TableCellAlignAttribute + + // TableCellAlignStyle renders alignments as a style attribute. + TableCellAlignStyle + + // TableCellAlignNone does not care about alignments. + // If you using classes or other styles, you can add these attributes + // in an ASTTransformer. + TableCellAlignNone +) + +// TableConfig struct holds options for the extension. +type TableConfig struct { + html.Config + + // TableCellAlignMethod indicates how are table celss aligned. + TableCellAlignMethod TableCellAlignMethod +} + +// TableOption interface is a functional option interface for the extension. +type TableOption interface { + renderer.Option + // SetTableOption sets given option to the extension. + SetTableOption(*TableConfig) +} + +// NewTableConfig returns a new Config with defaults. +func NewTableConfig() TableConfig { + return TableConfig{ + Config: html.NewConfig(), + TableCellAlignMethod: TableCellAlignDefault, + } +} + +// SetOption implements renderer.SetOptioner. +func (c *TableConfig) SetOption(name renderer.OptionName, value interface{}) { + switch name { + case optTableCellAlignMethod: + c.TableCellAlignMethod = value.(TableCellAlignMethod) + default: + c.Config.SetOption(name, value) + } +} + +type withTableHTMLOptions struct { + value []html.Option +} + +func (o *withTableHTMLOptions) SetConfig(c *renderer.Config) { + if o.value != nil { + for _, v := range o.value { + v.(renderer.Option).SetConfig(c) + } + } +} + +func (o *withTableHTMLOptions) SetTableOption(c *TableConfig) { + if o.value != nil { + for _, v := range o.value { + v.SetHTMLOption(&c.Config) + } + } +} + +// WithTableHTMLOptions is functional option that wraps goldmark HTMLRenderer options. +func WithTableHTMLOptions(opts ...html.Option) TableOption { + return &withTableHTMLOptions{opts} +} + +const optTableCellAlignMethod renderer.OptionName = "TableTableCellAlignMethod" + +type withTableCellAlignMethod struct { + value TableCellAlignMethod +} + +func (o *withTableCellAlignMethod) SetConfig(c *renderer.Config) { + c.Options[optTableCellAlignMethod] = o.value +} + +func (o *withTableCellAlignMethod) SetTableOption(c *TableConfig) { + c.TableCellAlignMethod = o.value +} + +// WithTableCellAlignMethod is a functional option that indicates how are table cells aligned in HTML format. +func WithTableCellAlignMethod(a TableCellAlignMethod) TableOption { + return &withTableCellAlignMethod{a} +} + +func isTableDelim(bs []byte) bool { + for _, b := range bs { + if !(util.IsSpace(b) || b == '-' || b == '|' || b == ':') { + return false + } + } + return true +} + var tableDelimLeft = regexp.MustCompile(`^\s*\:\-+\s*$`) var tableDelimRight = regexp.MustCompile(`^\s*\-+\:\s*$`) var tableDelimCenter = regexp.MustCompile(`^\s*\:\-+\:\s*$`) @@ -37,25 +151,34 @@ func (b *tableParagraphTransformer) Transform(node *gast.Paragraph, reader text. if lines.Len() < 2 { return } - alignments := b.parseDelimiter(lines.At(1), reader) - if alignments == nil { - return - } - header := b.parseRow(lines.At(0), alignments, true, reader) - if header == nil || len(alignments) != header.ChildCount() { - return - } - table := ast.NewTable() - table.Alignments = alignments - table.AppendChild(table, ast.NewTableHeader(header)) - for i := 2; i < lines.Len(); i++ { - table.AppendChild(table, b.parseRow(lines.At(i), alignments, false, reader)) + for i := 1; i < lines.Len(); i++ { + alignments := b.parseDelimiter(lines.At(i), reader) + if alignments == nil { + continue + } + header := b.parseRow(lines.At(i-1), alignments, true, reader, pc) + if header == nil || len(alignments) != header.ChildCount() { + return + } + table := ast.NewTable() + table.Alignments = alignments + table.AppendChild(table, ast.NewTableHeader(header)) + for j := i + 1; j < lines.Len(); j++ { + table.AppendChild(table, b.parseRow(lines.At(j), alignments, false, reader, pc)) + } + node.Lines().SetSliced(0, i-1) + node.Parent().InsertAfter(node.Parent(), node, table) + if node.Lines().Len() == 0 { + node.Parent().RemoveChild(node.Parent(), node) + } else { + last := node.Lines().At(i - 2) + last.Stop = last.Stop - 1 // trim last newline(\n) + node.Lines().Set(i-2, last) + } } - node.Parent().InsertBefore(node.Parent(), node, table) - node.Parent().RemoveChild(node.Parent(), node) } -func (b *tableParagraphTransformer) parseRow(segment text.Segment, alignments []ast.Alignment, isHeader bool, reader text.Reader) *ast.TableRow { +func (b *tableParagraphTransformer) parseRow(segment text.Segment, alignments []ast.Alignment, isHeader bool, reader text.Reader, pc parser.Context) *ast.TableRow { source := reader.Source() line := segment.Value(source) pos := 0 @@ -79,18 +202,39 @@ func (b *tableParagraphTransformer) parseRow(segment text.Segment, alignments [] } else { alignment = alignments[i] } - closure := util.FindClosure(line[pos:], byte(0), '|', true, false) - if closure < 0 { - closure = len(line[pos:]) - } + + var escapedCell *escapedPipeCell node := ast.NewTableCell() - seg := text.NewSegment(segment.Start+pos, segment.Start+pos+closure) + node.Alignment = alignment + hasBacktick := false + closure := pos + for ; closure < limit; closure++ { + if line[closure] == '`' { + hasBacktick = true + } + if line[closure] == '|' { + if closure == 0 || line[closure-1] != '\\' { + break + } else if hasBacktick { + if escapedCell == nil { + escapedCell = &escapedPipeCell{node, []int{}, false} + escapedList := pc.ComputeIfAbsent(escapedPipeCellListKey, + func() interface{} { + return []*escapedPipeCell{} + }).([]*escapedPipeCell) + escapedList = append(escapedList, escapedCell) + pc.Set(escapedPipeCellListKey, escapedList) + } + escapedCell.Pos = append(escapedCell.Pos, segment.Start+closure-1) + } + } + } + seg := text.NewSegment(segment.Start+pos, segment.Start+closure) seg = seg.TrimLeftSpace(source) seg = seg.TrimRightSpace(source) node.Lines().Append(seg) - node.Alignment = alignment row.AppendChild(row, node) - pos += closure + 1 + pos = closure + 1 } for ; i < len(alignments); i++ { row.AppendChild(row, ast.NewTableCell()) @@ -100,7 +244,7 @@ func (b *tableParagraphTransformer) parseRow(segment text.Segment, alignments [] func (b *tableParagraphTransformer) parseDelimiter(segment text.Segment, reader text.Reader) []ast.Alignment { line := segment.Value(reader.Source()) - if !tableDelimRegexp.Match(line) { + if !isTableDelim(line) { return nil } cols := bytes.Split(line, []byte{'|'}) @@ -128,19 +272,74 @@ func (b *tableParagraphTransformer) parseDelimiter(segment text.Segment, reader return alignments } +type tableASTTransformer struct { +} + +var defaultTableASTTransformer = &tableASTTransformer{} + +// NewTableASTTransformer returns a parser.ASTTransformer for tables. +func NewTableASTTransformer() parser.ASTTransformer { + return defaultTableASTTransformer +} + +func (a *tableASTTransformer) Transform(node *gast.Document, reader text.Reader, pc parser.Context) { + lst := pc.Get(escapedPipeCellListKey) + if lst == nil { + return + } + pc.Set(escapedPipeCellListKey, nil) + for _, v := range lst.([]*escapedPipeCell) { + if v.Transformed { + continue + } + _ = gast.Walk(v.Cell, func(n gast.Node, entering bool) (gast.WalkStatus, error) { + if !entering || n.Kind() != gast.KindCodeSpan { + return gast.WalkContinue, nil + } + + for c := n.FirstChild(); c != nil; { + next := c.NextSibling() + if c.Kind() != gast.KindText { + c = next + continue + } + parent := c.Parent() + ts := &c.(*gast.Text).Segment + n := c + for _, v := range lst.([]*escapedPipeCell) { + for _, pos := range v.Pos { + if ts.Start <= pos && pos < ts.Stop { + segment := n.(*gast.Text).Segment + n1 := gast.NewRawTextSegment(segment.WithStop(pos)) + n2 := gast.NewRawTextSegment(segment.WithStart(pos + 1)) + parent.InsertAfter(parent, n, n1) + parent.InsertAfter(parent, n1, n2) + parent.RemoveChild(parent, n) + n = n2 + v.Transformed = true + } + } + } + c = next + } + return gast.WalkContinue, nil + }) + } +} + // TableHTMLRenderer is a renderer.NodeRenderer implementation that // renders Table nodes. type TableHTMLRenderer struct { - html.Config + TableConfig } // NewTableHTMLRenderer returns a new TableHTMLRenderer. -func NewTableHTMLRenderer(opts ...html.Option) renderer.NodeRenderer { +func NewTableHTMLRenderer(opts ...TableOption) renderer.NodeRenderer { r := &TableHTMLRenderer{ - Config: html.NewConfig(), + TableConfig: NewTableConfig(), } for _, opt := range opts { - opt.SetHTMLOption(&r.Config) + opt.SetTableOption(&r.TableConfig) } return r } @@ -281,14 +480,33 @@ func (r *TableHTMLRenderer) renderTableCell(w util.BufWriter, source []byte, nod tag = "th" } if entering { - align := "" + fmt.Fprintf(w, "<%s", tag) if n.Alignment != ast.AlignNone { - if _, ok := n.AttributeString("align"); !ok { // Skip align render if overridden - // TODO: "align" is deprecated. style="text-align:%s" instead? - align = fmt.Sprintf(` align="%s"`, n.Alignment.String()) + amethod := r.TableConfig.TableCellAlignMethod + if amethod == TableCellAlignDefault { + if r.Config.XHTML { + amethod = TableCellAlignAttribute + } else { + amethod = TableCellAlignStyle + } + } + switch amethod { + case TableCellAlignAttribute: + if _, ok := n.AttributeString("align"); !ok { // Skip align render if overridden + fmt.Fprintf(w, ` align="%s"`, n.Alignment.String()) + } + case TableCellAlignStyle: + v, ok := n.AttributeString("style") + var cob util.CopyOnWriteBuffer + if ok { + cob = util.NewCopyOnWriteBuffer(v.([]byte)) + cob.AppendByte(';') + } + style := fmt.Sprintf("text-align:%s", n.Alignment.String()) + cob.AppendString(style) + n.SetAttributeString("style", cob.Bytes()) } } - fmt.Fprintf(w, "<%s", tag) if n.Attributes() != nil { if tag == "td" { html.RenderAttributes(w, n, TableTdCellAttributeFilter) // @@ -296,7 +514,7 @@ func (r *TableHTMLRenderer) renderTableCell(w util.BufWriter, source []byte, nod html.RenderAttributes(w, n, TableThCellAttributeFilter) // } } - fmt.Fprintf(w, "%s>", align) + _ = w.WriteByte('>') } else { fmt.Fprintf(w, "\n", tag) } @@ -304,16 +522,31 @@ func (r *TableHTMLRenderer) renderTableCell(w util.BufWriter, source []byte, nod } type table struct { + options []TableOption } // Table is an extension that allow you to use GFM tables . -var Table = &table{} +var Table = &table{ + options: []TableOption{}, +} + +// NewTable returns a new extension with given options. +func NewTable(opts ...TableOption) goldmark.Extender { + return &table{ + options: opts, + } +} func (e *table) Extend(m goldmark.Markdown) { - m.Parser().AddOptions(parser.WithParagraphTransformers( - util.Prioritized(NewTableParagraphTransformer(), 200), - )) + m.Parser().AddOptions( + parser.WithParagraphTransformers( + util.Prioritized(NewTableParagraphTransformer(), 200), + ), + parser.WithASTTransformers( + util.Prioritized(defaultTableASTTransformer, 0), + ), + ) m.Renderer().AddOptions(renderer.WithNodeRenderers( - util.Prioritized(NewTableHTMLRenderer(), 500), + util.Prioritized(NewTableHTMLRenderer(e.options...), 500), )) } diff --git a/vendor/github.com/yuin/goldmark/extension/typographer.go b/vendor/github.com/yuin/goldmark/extension/typographer.go index c3b975109..f56c06f74 100644 --- a/vendor/github.com/yuin/goldmark/extension/typographer.go +++ b/vendor/github.com/yuin/goldmark/extension/typographer.go @@ -10,6 +10,27 @@ import ( "github.com/yuin/goldmark/util" ) +var uncloseCounterKey = parser.NewContextKey() + +type unclosedCounter struct { + Single int + Double int +} + +func (u *unclosedCounter) Reset() { + u.Single = 0 + u.Double = 0 +} + +func getUnclosedCounter(pc parser.Context) *unclosedCounter { + v := pc.Get(uncloseCounterKey) + if v == nil { + v = &unclosedCounter{} + pc.Set(uncloseCounterKey, v) + } + return v.(*unclosedCounter) +} + // TypographicPunctuation is a key of the punctuations that can be replaced with // typographic entities. type TypographicPunctuation int @@ -139,11 +160,10 @@ func NewTypographerParser(opts ...TypographerOption) parser.InlineParser { } func (s *typographerParser) Trigger() []byte { - return []byte{'\'', '"', '-', '.', '<', '>'} + return []byte{'\'', '"', '-', '.', ',', '<', '>', '*', '['} } func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser.Context) gast.Node { - before := block.PrecendingCharacter() line, _ := block.PeekLine() c := line[0] if len(line) > 2 { @@ -189,10 +209,12 @@ func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser } } if c == '\'' || c == '"' { + before := block.PrecendingCharacter() d := parser.ScanDelimiter(line, before, 1, defaultTypographerDelimiterProcessor) if d == nil { return nil } + counter := getUnclosedCounter(pc) if c == '\'' { if s.Substitutions[Apostrophe] != nil { // Handle decade abbrevations such as '90s @@ -201,13 +223,20 @@ func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser if len(line) > 4 { after = util.ToRune(line, 4) } - if len(line) == 3 || unicode.IsSpace(after) || unicode.IsPunct(after) { + if len(line) == 3 || util.IsSpaceRune(after) || util.IsPunctRune(after) { node := gast.NewString(s.Substitutions[Apostrophe]) node.SetCode(true) block.Advance(1) return node } } + // special cases: 'twas, 'em, 'net + if len(line) > 1 && (unicode.IsPunct(before) || unicode.IsSpace(before)) && (line[1] == 't' || line[1] == 'e' || line[1] == 'n' || line[1] == 'l') { + node := gast.NewString(s.Substitutions[Apostrophe]) + node.SetCode(true) + block.Advance(1) + return node + } // Convert normal apostrophes. This is probably more flexible than necessary but // converts any apostrophe in between two alphanumerics. if len(line) > 1 && (unicode.IsDigit(before) || unicode.IsLetter(before)) && (unicode.IsLetter(util.ToRune(line, 1))) { @@ -218,16 +247,43 @@ func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser } } if s.Substitutions[LeftSingleQuote] != nil && d.CanOpen && !d.CanClose { - node := gast.NewString(s.Substitutions[LeftSingleQuote]) + nt := LeftSingleQuote + // special cases: Alice's, I'm, Don't, You'd + if len(line) > 1 && (line[1] == 's' || line[1] == 'm' || line[1] == 't' || line[1] == 'd') && (len(line) < 3 || util.IsPunct(line[2]) || util.IsSpace(line[2])) { + nt = RightSingleQuote + } + // special cases: I've, I'll, You're + if len(line) > 2 && ((line[1] == 'v' && line[2] == 'e') || (line[1] == 'l' && line[2] == 'l') || (line[1] == 'r' && line[2] == 'e')) && (len(line) < 4 || util.IsPunct(line[3]) || util.IsSpace(line[3])) { + nt = RightSingleQuote + } + if nt == LeftSingleQuote { + counter.Single++ + } + + node := gast.NewString(s.Substitutions[nt]) node.SetCode(true) block.Advance(1) return node } - if s.Substitutions[RightSingleQuote] != nil && d.CanClose && !d.CanOpen { - node := gast.NewString(s.Substitutions[RightSingleQuote]) - node.SetCode(true) - block.Advance(1) - return node + if s.Substitutions[RightSingleQuote] != nil { + // plural possesives and abbreviations: Smiths', doin' + if len(line) > 1 && unicode.IsSpace(util.ToRune(line, 0)) || unicode.IsPunct(util.ToRune(line, 0)) && (len(line) > 2 && !unicode.IsDigit(util.ToRune(line, 1))) { + node := gast.NewString(s.Substitutions[RightSingleQuote]) + node.SetCode(true) + block.Advance(1) + return node + } + } + if s.Substitutions[RightSingleQuote] != nil && counter.Single > 0 { + isClose := d.CanClose && !d.CanOpen + maybeClose := d.CanClose && d.CanOpen && len(line) > 1 && unicode.IsPunct(util.ToRune(line, 1)) && (len(line) == 2 || (len(line) > 2 && util.IsPunct(line[2]) || util.IsSpace(line[2]))) + if isClose || maybeClose { + node := gast.NewString(s.Substitutions[RightSingleQuote]) + node.SetCode(true) + block.Advance(1) + counter.Single-- + return node + } } } if c == '"' { @@ -235,13 +291,23 @@ func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser node := gast.NewString(s.Substitutions[LeftDoubleQuote]) node.SetCode(true) block.Advance(1) + counter.Double++ return node } - if s.Substitutions[RightDoubleQuote] != nil && d.CanClose && !d.CanOpen { - node := gast.NewString(s.Substitutions[RightDoubleQuote]) - node.SetCode(true) - block.Advance(1) - return node + if s.Substitutions[RightDoubleQuote] != nil && counter.Double > 0 { + isClose := d.CanClose && !d.CanOpen + maybeClose := d.CanClose && d.CanOpen && len(line) > 1 && (unicode.IsPunct(util.ToRune(line, 1))) && (len(line) == 2 || (len(line) > 2 && util.IsPunct(line[2]) || util.IsSpace(line[2]))) + if isClose || maybeClose { + // special case: "Monitor 21"" + if len(line) > 1 && line[1] == '"' && unicode.IsDigit(before) { + return nil + } + node := gast.NewString(s.Substitutions[RightDoubleQuote]) + node.SetCode(true) + block.Advance(1) + counter.Double-- + return node + } } } } @@ -249,7 +315,7 @@ func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser } func (s *typographerParser) CloseBlock(parent gast.Node, pc parser.Context) { - // nothing to do + getUnclosedCounter(pc).Reset() } type typographer struct { diff --git a/vendor/github.com/yuin/goldmark/go.mod b/vendor/github.com/yuin/goldmark/go.mod index a10efcad5..3a2e0db9e 100644 --- a/vendor/github.com/yuin/goldmark/go.mod +++ b/vendor/github.com/yuin/goldmark/go.mod @@ -1,3 +1,3 @@ module github.com/yuin/goldmark -go 1.13 +go 1.18 diff --git a/vendor/github.com/yuin/goldmark/parser/attribute.go b/vendor/github.com/yuin/goldmark/parser/attribute.go index ea8c0645d..f86c83610 100644 --- a/vendor/github.com/yuin/goldmark/parser/attribute.go +++ b/vendor/github.com/yuin/goldmark/parser/attribute.go @@ -89,7 +89,11 @@ func parseAttribute(reader text.Reader) (Attribute, bool) { reader.Advance(1) line, _ := reader.PeekLine() i := 0 - for ; i < len(line) && !util.IsSpace(line[i]) && (!util.IsPunct(line[i]) || line[i] == '_' || line[i] == '-'); i++ { + // HTML5 allows any kind of characters as id, but XHTML restricts characters for id. + // CommonMark is basically defined for XHTML(even though it is legacy). + // So we restrict id characters. + for ; i < len(line) && !util.IsSpace(line[i]) && + (!util.IsPunct(line[i]) || line[i] == '_' || line[i] == '-' || line[i] == ':' || line[i] == '.'); i++ { } name := attrNameClass if c == '#' { @@ -129,6 +133,11 @@ func parseAttribute(reader text.Reader) (Attribute, bool) { if !ok { return Attribute{}, false } + if bytes.Equal(name, attrNameClass) { + if _, ok = value.([]byte); !ok { + return Attribute{}, false + } + } return Attribute{Name: name, Value: value}, true } diff --git a/vendor/github.com/yuin/goldmark/parser/atx_heading.go b/vendor/github.com/yuin/goldmark/parser/atx_heading.go index a631e0b1f..13a198b52 100644 --- a/vendor/github.com/yuin/goldmark/parser/atx_heading.go +++ b/vendor/github.com/yuin/goldmark/parser/atx_heading.go @@ -91,6 +91,9 @@ func (b *atxHeadingParser) Open(parent ast.Node, reader text.Reader, pc Context) if i == pos || level > 6 { return nil, NoChildren } + if i == len(line) { // alone '#' (without a new line character) + return ast.NewHeading(level), NoChildren + } l := util.TrimLeftSpaceLength(line[i:]) if l == 0 { return nil, NoChildren @@ -126,7 +129,8 @@ func (b *atxHeadingParser) Open(parent ast.Node, reader text.Reader, pc Context) if closureClose > 0 { reader.Advance(closureClose) attrs, ok := ParseAttributes(reader) - parsed = ok + rest, _ := reader.PeekLine() + parsed = ok && util.IsBlank(rest) if parsed { for _, attr := range attrs { node.SetAttribute(attr.Name, attr.Value) diff --git a/vendor/github.com/yuin/goldmark/parser/code_block.go b/vendor/github.com/yuin/goldmark/parser/code_block.go index d02c21fc7..732f18c65 100644 --- a/vendor/github.com/yuin/goldmark/parser/code_block.go +++ b/vendor/github.com/yuin/goldmark/parser/code_block.go @@ -31,6 +31,10 @@ func (b *codeBlockParser) Open(parent ast.Node, reader text.Reader, pc Context) node := ast.NewCodeBlock() reader.AdvanceAndSetPadding(pos, padding) _, segment = reader.PeekLine() + // if code block line starts with a tab, keep a tab as it is. + if segment.Padding != 0 { + preserveLeadingTabInCodeBlock(&segment, reader, 0) + } node.Lines().Append(segment) reader.Advance(segment.Len() - 1) return node, NoChildren @@ -49,6 +53,12 @@ func (b *codeBlockParser) Continue(node ast.Node, reader text.Reader, pc Context } reader.AdvanceAndSetPadding(pos, padding) _, segment = reader.PeekLine() + + // if code block line starts with a tab, keep a tab as it is. + if segment.Padding != 0 { + preserveLeadingTabInCodeBlock(&segment, reader, 0) + } + node.Lines().Append(segment) reader.Advance(segment.Len() - 1) return Continue | NoChildren @@ -77,3 +87,14 @@ func (b *codeBlockParser) CanInterruptParagraph() bool { func (b *codeBlockParser) CanAcceptIndentedLine() bool { return true } + +func preserveLeadingTabInCodeBlock(segment *text.Segment, reader text.Reader, indent int) { + offsetWithPadding := reader.LineOffset() + indent + sl, ss := reader.Position() + reader.SetPosition(sl, text.NewSegment(ss.Start-1, ss.Stop)) + if offsetWithPadding == reader.LineOffset() { + segment.Padding = 0 + segment.Start-- + } + reader.SetPosition(sl, ss) +} diff --git a/vendor/github.com/yuin/goldmark/parser/code_span.go b/vendor/github.com/yuin/goldmark/parser/code_span.go index 13652367f..a74b09bc4 100644 --- a/vendor/github.com/yuin/goldmark/parser/code_span.go +++ b/vendor/github.com/yuin/goldmark/parser/code_span.go @@ -3,7 +3,6 @@ package parser import ( "github.com/yuin/goldmark/ast" "github.com/yuin/goldmark/text" - "github.com/yuin/goldmark/util" ) type codeSpanParser struct { @@ -52,9 +51,7 @@ func (s *codeSpanParser) Parse(parent ast.Node, block text.Reader, pc Context) a } } } - if !util.IsBlank(line) { - node.AppendChild(node, ast.NewRawTextSegment(segment)) - } + node.AppendChild(node, ast.NewRawTextSegment(segment)) block.AdvanceLine() } end: @@ -62,11 +59,11 @@ end: // trim first halfspace and last halfspace segment := node.FirstChild().(*ast.Text).Segment shouldTrimmed := true - if !(!segment.IsEmpty() && block.Source()[segment.Start] == ' ') { + if !(!segment.IsEmpty() && isSpaceOrNewline(block.Source()[segment.Start])) { shouldTrimmed = false } segment = node.LastChild().(*ast.Text).Segment - if !(!segment.IsEmpty() && block.Source()[segment.Stop-1] == ' ') { + if !(!segment.IsEmpty() && isSpaceOrNewline(block.Source()[segment.Stop-1])) { shouldTrimmed = false } if shouldTrimmed { @@ -81,3 +78,7 @@ end: } return node } + +func isSpaceOrNewline(c byte) bool { + return c == ' ' || c == '\n' +} diff --git a/vendor/github.com/yuin/goldmark/parser/delimiter.go b/vendor/github.com/yuin/goldmark/parser/delimiter.go index 612d7b737..eb843af44 100644 --- a/vendor/github.com/yuin/goldmark/parser/delimiter.go +++ b/vendor/github.com/yuin/goldmark/parser/delimiter.go @@ -3,7 +3,6 @@ package parser import ( "fmt" "strings" - "unicode" "github.com/yuin/goldmark/ast" "github.com/yuin/goldmark/text" @@ -31,11 +30,11 @@ type Delimiter struct { Segment text.Segment // CanOpen is set true if this delimiter can open a span for a new node. - // See https://spec.commonmark.org/0.29/#can-open-emphasis for details. + // See https://spec.commonmark.org/0.30/#can-open-emphasis for details. CanOpen bool // CanClose is set true if this delimiter can close a span for a new node. - // See https://spec.commonmark.org/0.29/#can-open-emphasis for details. + // See https://spec.commonmark.org/0.30/#can-open-emphasis for details. CanClose bool // Length is a remaining length of this delimiter. @@ -128,10 +127,10 @@ func ScanDelimiter(line []byte, before rune, min int, processor DelimiterProcess } canOpen, canClose := false, false - beforeIsPunctuation := unicode.IsPunct(before) - beforeIsWhitespace := unicode.IsSpace(before) - afterIsPunctuation := unicode.IsPunct(after) - afterIsWhitespace := unicode.IsSpace(after) + beforeIsPunctuation := util.IsPunctRune(before) + beforeIsWhitespace := util.IsSpaceRune(before) + afterIsPunctuation := util.IsPunctRune(after) + afterIsWhitespace := util.IsSpaceRune(after) isLeft := !afterIsWhitespace && (!afterIsPunctuation || beforeIsWhitespace || beforeIsPunctuation) @@ -163,15 +162,11 @@ func ProcessDelimiters(bottom ast.Node, pc Context) { var closer *Delimiter if bottom != nil { if bottom != lastDelimiter { - for c := lastDelimiter.PreviousSibling(); c != nil; { + for c := lastDelimiter.PreviousSibling(); c != nil && c != bottom; { if d, ok := c.(*Delimiter); ok { closer = d } - prev := c.PreviousSibling() - if prev == bottom { - break - } - c = prev + c = c.PreviousSibling() } } } else { @@ -190,7 +185,7 @@ func ProcessDelimiters(bottom ast.Node, pc Context) { found := false maybeOpener := false var opener *Delimiter - for opener = closer.PreviousDelimiter; opener != nil; opener = opener.PreviousDelimiter { + for opener = closer.PreviousDelimiter; opener != nil && opener != bottom; opener = opener.PreviousDelimiter { if opener.CanOpen && opener.Processor.CanOpenCloser(opener, closer) { maybeOpener = true consume = opener.CalcComsumption(closer) @@ -201,10 +196,11 @@ func ProcessDelimiters(bottom ast.Node, pc Context) { } } if !found { + next := closer.NextDelimiter if !maybeOpener && !closer.CanOpen { pc.RemoveDelimiter(closer) } - closer = closer.NextDelimiter + closer = next continue } opener.ConsumeCharacters(consume) diff --git a/vendor/github.com/yuin/goldmark/parser/fcode_block.go b/vendor/github.com/yuin/goldmark/parser/fcode_block.go index f5b83eef7..5914138d3 100644 --- a/vendor/github.com/yuin/goldmark/parser/fcode_block.go +++ b/vendor/github.com/yuin/goldmark/parser/fcode_block.go @@ -71,6 +71,7 @@ func (b *fencedCodeBlockParser) Open(parent ast.Node, reader text.Reader, pc Con func (b *fencedCodeBlockParser) Continue(node ast.Node, reader text.Reader, pc Context) State { line, segment := reader.PeekLine() fdata := pc.Get(fencedCodeBlockInfoKey).(*fenceData) + w, pos := util.IndentWidth(line, reader.LineOffset()) if w < 4 { i := pos @@ -86,9 +87,19 @@ func (b *fencedCodeBlockParser) Continue(node ast.Node, reader text.Reader, pc C return Close } } - pos, padding := util.DedentPositionPadding(line, reader.LineOffset(), segment.Padding, fdata.indent) - + pos, padding := util.IndentPositionPadding(line, reader.LineOffset(), segment.Padding, fdata.indent) + if pos < 0 { + pos = util.FirstNonSpacePosition(line) + if pos < 0 { + pos = 0 + } + padding = 0 + } seg := text.NewSegmentPadding(segment.Start+pos, segment.Stop, padding) + // if code block line starts with a tab, keep a tab as it is. + if padding != 0 { + preserveLeadingTabInCodeBlock(&seg, reader, fdata.indent) + } node.Lines().Append(seg) reader.AdvanceAndSetPadding(segment.Stop-segment.Start-pos-1, padding) return Continue | NoChildren diff --git a/vendor/github.com/yuin/goldmark/parser/html_block.go b/vendor/github.com/yuin/goldmark/parser/html_block.go index 95b6918cd..380e723f2 100644 --- a/vendor/github.com/yuin/goldmark/parser/html_block.go +++ b/vendor/github.com/yuin/goldmark/parser/html_block.go @@ -76,8 +76,8 @@ var allowedBlockTags = map[string]bool{ "ul": true, } -var htmlBlockType1OpenRegexp = regexp.MustCompile(`(?i)^[ ]{0,3}<(script|pre|style)(?:\s.*|>.*|/>.*|)\n?$`) -var htmlBlockType1CloseRegexp = regexp.MustCompile(`(?i)^.*.*`) +var htmlBlockType1OpenRegexp = regexp.MustCompile(`(?i)^[ ]{0,3}<(script|pre|style|textarea)(?:\s.*|>.*|/>.*|)(?:\r\n|\n)?$`) +var htmlBlockType1CloseRegexp = regexp.MustCompile(`(?i)^.*.*`) var htmlBlockType2OpenRegexp = regexp.MustCompile(`^[ ]{0,3}'} @@ -85,15 +85,15 @@ var htmlBlockType2Close = []byte{'-', '-', '>'} var htmlBlockType3OpenRegexp = regexp.MustCompile(`^[ ]{0,3}<\?`) var htmlBlockType3Close = []byte{'?', '>'} -var htmlBlockType4OpenRegexp = regexp.MustCompile(`^[ ]{0,3}'} var htmlBlockType5OpenRegexp = regexp.MustCompile(`^[ ]{0,3}<\!\[CDATA\[`) var htmlBlockType5Close = []byte{']', ']', '>'} -var htmlBlockType6Regexp = regexp.MustCompile(`^[ ]{0,3}.*|/>.*|)\n?$`) +var htmlBlockType6Regexp = regexp.MustCompile(`^[ ]{0,3}<(?:/[ ]*)?([a-zA-Z]+[a-zA-Z0-9\-]*)(?:[ ].*|>.*|/>.*|)(?:\r\n|\n)?$`) -var htmlBlockType7Regexp = regexp.MustCompile(`^[ ]{0,3}<(/)?([a-zA-Z0-9]+)(` + attributePattern + `*)(:?>|/>)\s*\n?$`) +var htmlBlockType7Regexp = regexp.MustCompile(`^[ ]{0,3}<(/[ ]*)?([a-zA-Z]+[a-zA-Z0-9\-]*)(` + attributePattern + `*)[ ]*(?:>|/>)[ ]*(?:\r\n|\n)?$`) type htmlBlockParser struct { } @@ -201,7 +201,7 @@ func (b *htmlBlockParser) Continue(node ast.Node, reader text.Reader, pc Context } if bytes.Contains(line, closurePattern) { htmlBlock.ClosureLine = segment - reader.Advance(segment.Len() - 1) + reader.Advance(segment.Len()) return Close } diff --git a/vendor/github.com/yuin/goldmark/parser/link.go b/vendor/github.com/yuin/goldmark/parser/link.go index e7c6966f3..99583ac2a 100644 --- a/vendor/github.com/yuin/goldmark/parser/link.go +++ b/vendor/github.com/yuin/goldmark/parser/link.go @@ -2,7 +2,6 @@ package parser import ( "fmt" - "regexp" "strings" "github.com/yuin/goldmark/ast" @@ -49,6 +48,13 @@ func (s *linkLabelState) Kind() ast.NodeKind { return kindLinkLabelState } +func linkLabelStateLength(v *linkLabelState) int { + if v == nil || v.Last == nil || v.First == nil { + return 0 + } + return v.Last.Segment.Stop - v.First.Segment.Start +} + func pushLinkLabelState(pc Context, v *linkLabelState) { tlist := pc.Get(linkLabelStateKey) var list *linkLabelState @@ -113,8 +119,6 @@ func (s *linkParser) Trigger() []byte { return []byte{'!', '[', ']'} } -var linkDestinationRegexp = regexp.MustCompile(`\s*([^\s].+)`) -var linkTitleRegexp = regexp.MustCompile(`\s+(\)|["'\(].+)`) var linkBottom = NewContextKey() func (s *linkParser) Parse(parent ast.Node, block text.Reader, pc Context) ast.Node { @@ -143,7 +147,14 @@ func (s *linkParser) Parse(parent ast.Node, block text.Reader, pc Context) ast.N } block.Advance(1) removeLinkLabelState(pc, last) - if s.containsLink(last) { // a link in a link text is not allowed + // CommonMark spec says: + // > A link label can have at most 999 characters inside the square brackets. + if linkLabelStateLength(tlist.(*linkLabelState)) > 998 { + ast.MergeOrReplaceTextSegment(last.Parent(), last, last.Segment) + return nil + } + + if !last.IsImage && s.containsLink(last) { // a link in a link text is not allowed ast.MergeOrReplaceTextSegment(last.Parent(), last, last.Segment) return nil } @@ -167,6 +178,13 @@ func (s *linkParser) Parse(parent ast.Node, block text.Reader, pc Context) ast.N block.SetPosition(l, pos) ssegment := text.NewSegment(last.Segment.Stop, segment.Start) maybeReference := block.Value(ssegment) + // CommonMark spec says: + // > A link label can have at most 999 characters inside the square brackets. + if len(maybeReference) > 999 { + ast.MergeOrReplaceTextSegment(last.Parent(), last, last.Segment) + return nil + } + ref, ok := pc.Reference(util.ToLinkReference(maybeReference)) if !ok { ast.MergeOrReplaceTextSegment(last.Parent(), last, last.Segment) @@ -185,15 +203,17 @@ func (s *linkParser) Parse(parent ast.Node, block text.Reader, pc Context) ast.N return link } -func (s *linkParser) containsLink(last *linkLabelState) bool { - if last.IsImage { +func (s *linkParser) containsLink(n ast.Node) bool { + if n == nil { return false } - var c ast.Node - for c = last; c != nil; c = c.NextSibling() { + for c := n; c != nil; c = c.NextSibling() { if _, ok := c.(*ast.Link); ok { return true } + if s.containsLink(c.FirstChild()) { + return true + } } return false } @@ -224,21 +244,38 @@ func (s *linkParser) processLinkLabel(parent ast.Node, link *ast.Link, last *lin } } +var linkFindClosureOptions text.FindClosureOptions = text.FindClosureOptions{ + Nesting: false, + Newline: true, + Advance: true, +} + func (s *linkParser) parseReferenceLink(parent ast.Node, last *linkLabelState, block text.Reader, pc Context) (*ast.Link, bool) { _, orgpos := block.Position() block.Advance(1) // skip '[' - line, segment := block.PeekLine() - endIndex := util.FindClosure(line, '[', ']', false, true) - if endIndex < 0 { + segments, found := block.FindClosure('[', ']', linkFindClosureOptions) + if !found { return nil, false } - block.Advance(endIndex + 1) - ssegment := segment.WithStop(segment.Start + endIndex) - maybeReference := block.Value(ssegment) + var maybeReference []byte + if segments.Len() == 1 { // avoid allocate a new byte slice + maybeReference = block.Value(segments.At(0)) + } else { + maybeReference = []byte{} + for i := 0; i < segments.Len(); i++ { + s := segments.At(i) + maybeReference = append(maybeReference, block.Value(s)...) + } + } if util.IsBlank(maybeReference) { // collapsed reference link - ssegment = text.NewSegment(last.Segment.Stop, orgpos.Start-1) - maybeReference = block.Value(ssegment) + s := text.NewSegment(last.Segment.Stop, orgpos.Start-1) + maybeReference = block.Value(s) + } + // CommonMark spec says: + // > A link label can have at most 999 characters inside the square brackets. + if len(maybeReference) > 999 { + return nil, true } ref, ok := pc.Reference(util.ToLinkReference(maybeReference)) @@ -293,20 +330,17 @@ func (s *linkParser) parseLink(parent ast.Node, last *linkLabelState, block text func parseLinkDestination(block text.Reader) ([]byte, bool) { block.SkipSpaces() line, _ := block.PeekLine() - buf := []byte{} if block.Peek() == '<' { i := 1 for i < len(line) { c := line[i] if c == '\\' && i < len(line)-1 && util.IsPunct(line[i+1]) { - buf = append(buf, '\\', line[i+1]) i += 2 continue } else if c == '>' { block.Advance(i + 1) return line[1:i], true } - buf = append(buf, c) i++ } return nil, false @@ -316,7 +350,6 @@ func parseLinkDestination(block text.Reader) ([]byte, bool) { for i < len(line) { c := line[i] if c == '\\' && i < len(line)-1 && util.IsPunct(line[i+1]) { - buf = append(buf, '\\', line[i+1]) i += 2 continue } else if c == '(' { @@ -329,7 +362,6 @@ func parseLinkDestination(block text.Reader) ([]byte, bool) { } else if util.IsSpace(c) { break } - buf = append(buf, c) i++ } block.Advance(i) @@ -346,34 +378,24 @@ func parseLinkTitle(block text.Reader) ([]byte, bool) { if opener == '(' { closer = ')' } - savedLine, savedPosition := block.Position() - var title []byte - for i := 0; ; i++ { - line, _ := block.PeekLine() - if line == nil { - block.SetPosition(savedLine, savedPosition) - return nil, false - } - offset := 0 - if i == 0 { - offset = 1 - } - pos := util.FindClosure(line[offset:], opener, closer, false, true) - if pos < 0 { - title = append(title, line[offset:]...) - block.AdvanceLine() - continue + block.Advance(1) + segments, found := block.FindClosure(opener, closer, linkFindClosureOptions) + if found { + if segments.Len() == 1 { + return block.Value(segments.At(0)), true } - pos += offset + 1 // 1: closer - block.Advance(pos) - if i == 0 { // avoid allocating new slice - return line[offset : pos-1], true + var title []byte + for i := 0; i < segments.Len(); i++ { + s := segments.At(i) + title = append(title, block.Value(s)...) } - return append(title, line[offset:pos-1]...), true + return title, true } + return nil, false } func (s *linkParser) CloseBlock(parent ast.Node, block text.Reader, pc Context) { + pc.Set(linkBottom, nil) tlist := pc.Get(linkLabelStateKey) if tlist == nil { return diff --git a/vendor/github.com/yuin/goldmark/parser/link_ref.go b/vendor/github.com/yuin/goldmark/parser/link_ref.go index 3fa1ecf6f..ea3f6544a 100644 --- a/vendor/github.com/yuin/goldmark/parser/link_ref.go +++ b/vendor/github.com/yuin/goldmark/parser/link_ref.go @@ -52,7 +52,7 @@ func (p *linkReferenceParagraphTransformer) Transform(node *ast.Paragraph, reade func parseLinkReferenceDefinition(block text.Reader, pc Context) (int, int) { block.SkipSpaces() - line, segment := block.PeekLine() + line, _ := block.PeekLine() if line == nil { return -1, -1 } @@ -67,39 +67,33 @@ func parseLinkReferenceDefinition(block text.Reader, pc Context) (int, int) { if line[pos] != '[' { return -1, -1 } - open := segment.Start + pos + 1 - closes := -1 block.Advance(pos + 1) - for { - line, segment = block.PeekLine() - if line == nil { - return -1, -1 - } - closure := util.FindClosure(line, '[', ']', false, false) - if closure > -1 { - closes = segment.Start + closure - next := closure + 1 - if next >= len(line) || line[next] != ':' { - return -1, -1 - } - block.Advance(next + 1) - break + segments, found := block.FindClosure('[', ']', linkFindClosureOptions) + if !found { + return -1, -1 + } + var label []byte + if segments.Len() == 1 { + label = block.Value(segments.At(0)) + } else { + for i := 0; i < segments.Len(); i++ { + s := segments.At(i) + label = append(label, block.Value(s)...) } - block.AdvanceLine() } - if closes < 0 { + if util.IsBlank(label) { return -1, -1 } - label := block.Value(text.NewSegment(open, closes)) - if util.IsBlank(label) { + if block.Peek() != ':' { return -1, -1 } + block.Advance(1) block.SkipSpaces() destination, ok := parseLinkDestination(block) if !ok { return -1, -1 } - line, segment = block.PeekLine() + line, _ = block.PeekLine() isNewLine := line == nil || util.IsBlank(line) endLine, _ := block.Position() @@ -117,45 +111,40 @@ func parseLinkReferenceDefinition(block text.Reader, pc Context) (int, int) { return -1, -1 } block.Advance(1) - open = -1 - closes = -1 closer := opener if opener == '(' { closer = ')' } - for { - line, segment = block.PeekLine() - if line == nil { + segments, found = block.FindClosure(opener, closer, linkFindClosureOptions) + if !found { + if !isNewLine { return -1, -1 } - if open < 0 { - open = segment.Start - } - closure := util.FindClosure(line, opener, closer, false, true) - if closure > -1 { - closes = segment.Start + closure - block.Advance(closure + 1) - break - } + ref := NewReference(label, destination, nil) + pc.AddReference(ref) block.AdvanceLine() + return startLine, endLine + 1 } - if closes < 0 { - return -1, -1 + var title []byte + if segments.Len() == 1 { + title = block.Value(segments.At(0)) + } else { + for i := 0; i < segments.Len(); i++ { + s := segments.At(i) + title = append(title, block.Value(s)...) + } } - line, segment = block.PeekLine() + line, _ = block.PeekLine() if line != nil && !util.IsBlank(line) { if !isNewLine { return -1, -1 } - title := block.Value(text.NewSegment(open, closes)) ref := NewReference(label, destination, title) pc.AddReference(ref) return startLine, endLine } - title := block.Value(text.NewSegment(open, closes)) - endLine, _ = block.Position() ref := NewReference(label, destination, title) pc.AddReference(ref) diff --git a/vendor/github.com/yuin/goldmark/parser/list.go b/vendor/github.com/yuin/goldmark/parser/list.go index 9183a6da3..e5cad1173 100644 --- a/vendor/github.com/yuin/goldmark/parser/list.go +++ b/vendor/github.com/yuin/goldmark/parser/list.go @@ -1,10 +1,11 @@ package parser import ( + "strconv" + "github.com/yuin/goldmark/ast" "github.com/yuin/goldmark/text" "github.com/yuin/goldmark/util" - "strconv" ) type listItemType int @@ -15,6 +16,10 @@ const ( orderedList ) +var skipListParserKey = NewContextKey() +var emptyListItemWithBlankLines = NewContextKey() +var listItemFlagValue interface{} = true + // Same as // `^(([ ]*)([\-\*\+]))(\s+.*)?\n?$`.FindSubmatchIndex or // `^(([ ]*)(\d{1,9}[\.\)]))(\s+.*)?\n?$`.FindSubmatchIndex @@ -122,8 +127,8 @@ func (b *listParser) Trigger() []byte { func (b *listParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State) { last := pc.LastOpenedBlock().Node - if _, lok := last.(*ast.List); lok || pc.Get(skipListParser) != nil { - pc.Set(skipListParser, nil) + if _, lok := last.(*ast.List); lok || pc.Get(skipListParserKey) != nil { + pc.Set(skipListParserKey, nil) return nil, NoChildren } line, _ := reader.PeekLine() @@ -143,7 +148,7 @@ func (b *listParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast. return nil, NoChildren } //an empty list item cannot interrupt a paragraph: - if match[5]-match[4] == 1 { + if match[4] < 0 || util.IsBlank(line[match[4]:match[5]]) { return nil, NoChildren } } @@ -153,6 +158,7 @@ func (b *listParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast. if start > -1 { node.Start = start } + pc.Set(emptyListItemWithBlankLines, nil) return node, HasChildren } @@ -160,9 +166,8 @@ func (b *listParser) Continue(node ast.Node, reader text.Reader, pc Context) Sta list := node.(*ast.List) line, _ := reader.PeekLine() if util.IsBlank(line) { - // A list item can begin with at most one blank line - if node.ChildCount() == 1 && node.LastChild().ChildCount() == 0 { - return Close + if node.LastChild().ChildCount() == 0 { + pc.Set(emptyListItemWithBlankLines, listItemFlagValue) } return Continue | HasChildren } @@ -175,10 +180,23 @@ func (b *listParser) Continue(node ast.Node, reader text.Reader, pc Context) Sta // - a // - b <--- current line // it maybe a new child of the list. + // + // Empty list items can have multiple blanklines + // + // - <--- 1st item is an empty thus "offset" is unknown + // + // + // - <--- current line + // + // -> 1 list with 2 blank items + // + // So if the last item is an empty, it maybe a new child of the list. + // offset := lastOffset(node) + lastIsEmpty := node.LastChild().ChildCount() == 0 indent, _ := util.IndentWidth(line, reader.LineOffset()) - if indent < offset { + if indent < offset || lastIsEmpty { if indent < 4 { match, typ := matchesListItem(line, false) // may have a leading spaces more than 3 if typ != notList && match[1]-offset < 4 { @@ -200,10 +218,27 @@ func (b *listParser) Continue(node ast.Node, reader text.Reader, pc Context) Sta return Close } } - return Continue | HasChildren } } + if !lastIsEmpty { + return Close + } + } + + if lastIsEmpty && indent < offset { + return Close + } + + // Non empty items can not exist next to an empty list item + // with blank lines. So we need to close the current list + // + // - + // + // foo + // + // -> 1 list with 1 blank items and 1 paragraph + if pc.Get(emptyListItemWithBlankLines) != nil { return Close } return Continue | HasChildren @@ -230,8 +265,9 @@ func (b *listParser) Close(node ast.Node, reader text.Reader, pc Context) { if list.IsTight { for child := node.FirstChild(); child != nil; child = child.NextSibling() { - for gc := child.FirstChild(); gc != nil; gc = gc.NextSibling() { + for gc := child.FirstChild(); gc != nil; { paragraph, ok := gc.(*ast.Paragraph) + gc = gc.NextSibling() if ok { textBlock := ast.NewTextBlock() textBlock.SetLines(paragraph.Lines()) diff --git a/vendor/github.com/yuin/goldmark/parser/list_item.go b/vendor/github.com/yuin/goldmark/parser/list_item.go index 4a698d838..81357a9ad 100644 --- a/vendor/github.com/yuin/goldmark/parser/list_item.go +++ b/vendor/github.com/yuin/goldmark/parser/list_item.go @@ -17,9 +17,6 @@ func NewListItemParser() BlockParser { return defaultListItemParser } -var skipListParser = NewContextKey() -var skipListParserValue interface{} = true - func (b *listItemParser) Trigger() []byte { return []byte{'-', '+', '*', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'} } @@ -38,9 +35,12 @@ func (b *listItemParser) Open(parent ast.Node, reader text.Reader, pc Context) ( if match[1]-offset > 3 { return nil, NoChildren } + + pc.Set(emptyListItemWithBlankLines, nil) + itemOffset := calcListOffset(line, match) node := ast.NewListItem(match[3] + itemOffset) - if match[4] < 0 || match[5]-match[4] == 1 { + if match[4] < 0 || util.IsBlank(line[match[4]:match[5]]) { return node, NoChildren } @@ -53,18 +53,23 @@ func (b *listItemParser) Open(parent ast.Node, reader text.Reader, pc Context) ( func (b *listItemParser) Continue(node ast.Node, reader text.Reader, pc Context) State { line, _ := reader.PeekLine() if util.IsBlank(line) { + reader.Advance(len(line) - 1) return Continue | HasChildren } - indent, _ := util.IndentWidth(line, reader.LineOffset()) offset := lastOffset(node.Parent()) - if indent < offset && indent < 4 { + isEmpty := node.ChildCount() == 0 + indent, _ := util.IndentWidth(line, reader.LineOffset()) + if (isEmpty || indent < offset) && indent < 4 { _, typ := matchesListItem(line, true) // new list item found if typ != notList { - pc.Set(skipListParser, skipListParserValue) + pc.Set(skipListParserKey, listItemFlagValue) + return Close + } + if !isEmpty { + return Close } - return Close } pos, padding := util.IndentPosition(line, reader.LineOffset(), offset) reader.AdvanceAndSetPadding(pos, padding) diff --git a/vendor/github.com/yuin/goldmark/parser/parser.go b/vendor/github.com/yuin/goldmark/parser/parser.go index def13db66..bac070452 100644 --- a/vendor/github.com/yuin/goldmark/parser/parser.go +++ b/vendor/github.com/yuin/goldmark/parser/parser.go @@ -138,6 +138,9 @@ type Context interface { // Get returns a value associated with the given key. Get(ContextKey) interface{} + // ComputeIfAbsent computes a value if a value associated with the given key is absent and returns the value. + ComputeIfAbsent(ContextKey, func() interface{}) interface{} + // Set sets the given value to the context. Set(ContextKey, interface{}) @@ -252,6 +255,15 @@ func (p *parseContext) Get(key ContextKey) interface{} { return p.store[key] } +func (p *parseContext) ComputeIfAbsent(key ContextKey, f func() interface{}) interface{} { + v := p.store[key] + if v == nil { + v = f() + p.store[key] = v + } + return v +} + func (p *parseContext) Set(key ContextKey, value interface{}) { p.store[key] = value } @@ -1103,6 +1115,12 @@ func (p *parser) walkBlock(block ast.Node, cb func(node ast.Node)) { cb(block) } +const ( + lineBreakHard uint8 = 1 << iota + lineBreakSoft + lineBreakVisible +) + func (p *parser) parseBlock(block text.BlockReader, parent ast.Node, pc Context) { if parent.IsRaw() { return @@ -1117,21 +1135,25 @@ func (p *parser) parseBlock(block text.BlockReader, parent ast.Node, pc Context) break } lineLength := len(line) - hardlineBreak := false - softLinebreak := line[lineLength-1] == '\n' - if lineLength >= 2 && line[lineLength-2] == '\\' && softLinebreak { // ends with \\n + var lineBreakFlags uint8 = 0 + hasNewLine := line[lineLength-1] == '\n' + if ((lineLength >= 3 && line[lineLength-2] == '\\' && line[lineLength-3] != '\\') || (lineLength == 2 && line[lineLength-2] == '\\')) && hasNewLine { // ends with \\n lineLength -= 2 - hardlineBreak = true - - } else if lineLength >= 3 && line[lineLength-3] == '\\' && line[lineLength-2] == '\r' && softLinebreak { // ends with \\r\n + lineBreakFlags |= lineBreakHard | lineBreakVisible + } else if ((lineLength >= 4 && line[lineLength-3] == '\\' && line[lineLength-2] == '\r' && line[lineLength-4] != '\\') || (lineLength == 3 && line[lineLength-3] == '\\' && line[lineLength-2] == '\r')) && hasNewLine { // ends with \\r\n lineLength -= 3 - hardlineBreak = true - } else if lineLength >= 3 && line[lineLength-3] == ' ' && line[lineLength-2] == ' ' && softLinebreak { // ends with [space][space]\n + lineBreakFlags |= lineBreakHard | lineBreakVisible + } else if lineLength >= 3 && line[lineLength-3] == ' ' && line[lineLength-2] == ' ' && hasNewLine { // ends with [space][space]\n lineLength -= 3 - hardlineBreak = true - } else if lineLength >= 4 && line[lineLength-4] == ' ' && line[lineLength-3] == ' ' && line[lineLength-2] == '\r' && softLinebreak { // ends with [space][space]\r\n + lineBreakFlags |= lineBreakHard + } else if lineLength >= 4 && line[lineLength-4] == ' ' && line[lineLength-3] == ' ' && line[lineLength-2] == '\r' && hasNewLine { // ends with [space][space]\r\n lineLength -= 4 - hardlineBreak = true + lineBreakFlags |= lineBreakHard + } else if hasNewLine { + // If the line ends with a newline character, but it is not a hardlineBreak, then it is a softLinebreak + // If the line ends with a hardlineBreak, then it cannot end with a softLinebreak + // See https://spec.commonmark.org/0.30/#soft-line-breaks + lineBreakFlags |= lineBreakSoft } l, startPosition := block.Position() @@ -1195,11 +1217,14 @@ func (p *parser) parseBlock(block text.BlockReader, parent ast.Node, pc Context) continue } diff := startPosition.Between(currentPosition) - stop := diff.Stop - rest := diff.WithStop(stop) - text := ast.NewTextSegment(rest.TrimRightSpace(source)) - text.SetSoftLineBreak(softLinebreak) - text.SetHardLineBreak(hardlineBreak) + var text *ast.Text + if lineBreakFlags&(lineBreakHard|lineBreakVisible) == lineBreakHard|lineBreakVisible { + text = ast.NewTextSegment(diff) + } else { + text = ast.NewTextSegment(diff.TrimRightSpace(source)) + } + text.SetSoftLineBreak(lineBreakFlags&lineBreakSoft != 0) + text.SetHardLineBreak(lineBreakFlags&lineBreakHard != 0) parent.AppendChild(parent, text) block.AdvanceLine() } diff --git a/vendor/github.com/yuin/goldmark/parser/raw_html.go b/vendor/github.com/yuin/goldmark/parser/raw_html.go index d7ba414ff..55b9a9967 100644 --- a/vendor/github.com/yuin/goldmark/parser/raw_html.go +++ b/vendor/github.com/yuin/goldmark/parser/raw_html.go @@ -2,10 +2,11 @@ package parser import ( "bytes" + "regexp" + "github.com/yuin/goldmark/ast" "github.com/yuin/goldmark/text" "github.com/yuin/goldmark/util" - "regexp" ) type rawHTMLParser struct { @@ -31,43 +32,101 @@ func (s *rawHTMLParser) Parse(parent ast.Node, block text.Reader, pc Context) as if len(line) > 2 && line[1] == '/' && util.IsAlphaNumeric(line[2]) { return s.parseMultiLineRegexp(closeTagRegexp, block, pc) } - if bytes.HasPrefix(line, []byte("|`) -var processingInstructionRegexp = regexp.MustCompile(`^(?:<\?).*?(?:\?>)`) -var declRegexp = regexp.MustCompile(`^]*>`) -var cdataRegexp = regexp.MustCompile(``) -func (s *rawHTMLParser) parseSingleLineRegexp(reg *regexp.Regexp, block text.Reader, pc Context) ast.Node { +var openProcessingInstruction = []byte("") +var openCDATA = []byte("") +var closeDecl = []byte(">") +var emptyComment = []byte("") +var invalidComment1 = []byte("") +var invalidComment2 = []byte("") +var openComment = []byte("") +var doubleHyphen = []byte("--") + +func (s *rawHTMLParser) parseComment(block text.Reader, pc Context) ast.Node { + savedLine, savedSegment := block.Position() + node := ast.NewRawHTML() line, segment := block.PeekLine() - match := reg.FindSubmatchIndex(line) - if match == nil { + if bytes.HasPrefix(line, emptyComment) { + node.Segments.Append(segment.WithStop(segment.Start + len(emptyComment))) + block.Advance(len(emptyComment)) + return node + } + if bytes.HasPrefix(line, invalidComment1) || bytes.HasPrefix(line, invalidComment2) { return nil } - node := ast.NewRawHTML() - node.Segments.Append(segment.WithStop(segment.Start + match[1])) - block.Advance(match[1]) - return node + offset := len(openComment) + line = line[offset:] + for { + hindex := bytes.Index(line, doubleHyphen) + if hindex > -1 { + hindex += offset + } + index := bytes.Index(line, closeComment) + offset + if index > -1 && hindex == index { + if index == 0 || len(line) < 2 || line[index-offset-1] != '-' { + node.Segments.Append(segment.WithStop(segment.Start + index + len(closeComment))) + block.Advance(index + len(closeComment)) + return node + } + } + if hindex > 0 { + break + } + node.Segments.Append(segment) + block.AdvanceLine() + line, segment = block.PeekLine() + offset = 0 + if line == nil { + break + } + } + block.SetPosition(savedLine, savedSegment) + return nil } -var dummyMatch = [][]byte{} +func (s *rawHTMLParser) parseUntil(block text.Reader, closer []byte, pc Context) ast.Node { + savedLine, savedSegment := block.Position() + node := ast.NewRawHTML() + for { + line, segment := block.PeekLine() + if line == nil { + break + } + index := bytes.Index(line, closer) + if index > -1 { + node.Segments.Append(segment.WithStop(segment.Start + index + len(closer))) + block.Advance(index + len(closer)) + return node + } + node.Segments.Append(segment) + block.AdvanceLine() + } + block.SetPosition(savedLine, savedSegment) + return nil +} func (s *rawHTMLParser) parseMultiLineRegexp(reg *regexp.Regexp, block text.Reader, pc Context) ast.Node { sline, ssegment := block.Position() @@ -102,7 +161,3 @@ func (s *rawHTMLParser) parseMultiLineRegexp(reg *regexp.Regexp, block text.Read } return nil } - -func (s *rawHTMLParser) CloseBlock(parent ast.Node, pc Context) { - // nothing to do -} diff --git a/vendor/github.com/yuin/goldmark/renderer/html/html.go b/vendor/github.com/yuin/goldmark/renderer/html/html.go index 537a256fe..12fa7ce2c 100644 --- a/vendor/github.com/yuin/goldmark/renderer/html/html.go +++ b/vendor/github.com/yuin/goldmark/renderer/html/html.go @@ -198,16 +198,24 @@ func (r *Renderer) writeLines(w util.BufWriter, source []byte, n ast.Node) { var GlobalAttributeFilter = util.NewBytesFilter( []byte("accesskey"), []byte("autocapitalize"), + []byte("autofocus"), []byte("class"), []byte("contenteditable"), - []byte("contextmenu"), []byte("dir"), []byte("draggable"), - []byte("dropzone"), + []byte("enterkeyhint"), []byte("hidden"), []byte("id"), + []byte("inert"), + []byte("inputmode"), + []byte("is"), + []byte("itemid"), []byte("itemprop"), + []byte("itemref"), + []byte("itemscope"), + []byte("itemtype"), []byte("lang"), + []byte("part"), []byte("slot"), []byte("spellcheck"), []byte("style"), @@ -296,7 +304,7 @@ func (r *Renderer) renderHTMLBlock(w util.BufWriter, source []byte, node ast.Nod l := n.Lines().Len() for i := 0; i < l; i++ { line := n.Lines().At(i) - _, _ = w.Write(line.Value(source)) + r.Writer.SecureWrite(w, line.Value(source)) } } else { _, _ = w.WriteString("\n") @@ -305,7 +313,7 @@ func (r *Renderer) renderHTMLBlock(w util.BufWriter, source []byte, node ast.Nod if n.HasClosure() { if r.Unsafe { closure := n.ClosureLine - _, _ = w.Write(closure.Value(source)) + r.Writer.SecureWrite(w, closure.Value(source)) } else { _, _ = w.WriteString("\n") } @@ -318,6 +326,7 @@ func (r *Renderer) renderHTMLBlock(w util.BufWriter, source []byte, node ast.Nod var ListAttributeFilter = GlobalAttributeFilter.Extend( []byte("start"), []byte("reversed"), + []byte("type"), ) func (r *Renderer) renderList(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { @@ -476,9 +485,7 @@ func (r *Renderer) renderCodeSpan(w util.BufWriter, source []byte, n ast.Node, e value := segment.Value(source) if bytes.HasSuffix(value, []byte("\n")) { r.Writer.RawWrite(w, value[:len(value)-1]) - if c != n.LastChild() { - r.Writer.RawWrite(w, []byte(" ")) - } + r.Writer.RawWrite(w, []byte(" ")) } else { r.Writer.RawWrite(w, value) } @@ -564,7 +571,7 @@ func (r *Renderer) renderImage(w util.BufWriter, source []byte, node ast.Node, e _, _ = w.Write(util.EscapeHTML(util.URLEscape(n.Destination, true))) } _, _ = w.WriteString(`" alt="`) - _, _ = w.Write(n.Text(source)) + _, _ = w.Write(util.EscapeHTML(n.Text(source))) _ = w.WriteByte('"') if n.Title != nil { _, _ = w.WriteString(` title="`) @@ -669,8 +676,13 @@ type Writer interface { // RawWrite writes the given source to writer without resolving references and // unescaping backslash escaped characters. RawWrite(writer util.BufWriter, source []byte) + + // SecureWrite writes the given source to writer with replacing insecure characters. + SecureWrite(writer util.BufWriter, source []byte) } +var replacementCharacter = []byte("\ufffd") + type defaultWriter struct { } @@ -685,6 +697,23 @@ func escapeRune(writer util.BufWriter, r rune) { _, _ = writer.WriteRune(util.ToValidRune(r)) } +func (d *defaultWriter) SecureWrite(writer util.BufWriter, source []byte) { + n := 0 + l := len(source) + for i := 0; i < l; i++ { + if source[i] == '\u0000' { + _, _ = writer.Write(source[i-n : i]) + n = 0 + _, _ = writer.Write(replacementCharacter) + continue + } + n++ + } + if n != 0 { + _, _ = writer.Write(source[l-n:]) + } +} + func (d *defaultWriter) RawWrite(writer util.BufWriter, source []byte) { n := 0 l := len(source) @@ -718,6 +747,13 @@ func (d *defaultWriter) Write(writer util.BufWriter, source []byte) { continue } } + if c == '\x00' { + d.RawWrite(writer, source[n:i]) + d.RawWrite(writer, replacementCharacter) + n = i + 1 + escaped = false + continue + } if c == '&' { pos := i next := i + 1 @@ -729,7 +765,7 @@ func (d *defaultWriter) Write(writer util.BufWriter, source []byte) { if nnext < limit && nc == 'x' || nc == 'X' { start := nnext + 1 i, ok = util.ReadWhile(source, [2]int{start, limit}, util.IsHexDecimal) - if ok && i < limit && source[i] == ';' { + if ok && i < limit && source[i] == ';' && i-start < 7 { v, _ := strconv.ParseUint(util.BytesToReadOnlyString(source[start:i]), 16, 32) d.RawWrite(writer, source[n:pos]) n = i + 1 @@ -741,7 +777,7 @@ func (d *defaultWriter) Write(writer util.BufWriter, source []byte) { start := nnext i, ok = util.ReadWhile(source, [2]int{start, limit}, util.IsNumeric) if ok && i < limit && i-start < 8 && source[i] == ';' { - v, _ := strconv.ParseUint(util.BytesToReadOnlyString(source[start:i]), 0, 32) + v, _ := strconv.ParseUint(util.BytesToReadOnlyString(source[start:i]), 10, 32) d.RawWrite(writer, source[n:pos]) n = i + 1 escapeRune(writer, rune(v)) @@ -783,6 +819,7 @@ var bPng = []byte("png;") var bGif = []byte("gif;") var bJpeg = []byte("jpeg;") var bWebp = []byte("webp;") +var bSvg = []byte("svg;") var bJs = []byte("javascript:") var bVb = []byte("vbscript:") var bFile = []byte("file:") @@ -794,7 +831,8 @@ func IsDangerousURL(url []byte) bool { if bytes.HasPrefix(url, bDataImage) && len(url) >= 11 { v := url[11:] if bytes.HasPrefix(v, bPng) || bytes.HasPrefix(v, bGif) || - bytes.HasPrefix(v, bJpeg) || bytes.HasPrefix(v, bWebp) { + bytes.HasPrefix(v, bJpeg) || bytes.HasPrefix(v, bWebp) || + bytes.HasPrefix(v, bSvg) { return false } return true diff --git a/vendor/github.com/yuin/goldmark/text/reader.go b/vendor/github.com/yuin/goldmark/text/reader.go index df25e5457..319f1c8b8 100644 --- a/vendor/github.com/yuin/goldmark/text/reader.go +++ b/vendor/github.com/yuin/goldmark/text/reader.go @@ -70,6 +70,28 @@ type Reader interface { // Match performs regular expression searching to current line. FindSubMatch(reg *regexp.Regexp) [][]byte + + // FindClosure finds corresponding closure. + FindClosure(opener, closer byte, options FindClosureOptions) (*Segments, bool) +} + +// FindClosureOptions is options for Reader.FindClosure +type FindClosureOptions struct { + // CodeSpan is a flag for the FindClosure. If this is set to true, + // FindClosure ignores closers in codespans. + CodeSpan bool + + // Nesting is a flag for the FindClosure. If this is set to true, + // FindClosure allows nesting. + Nesting bool + + // Newline is a flag for the FindClosure. If this is set to true, + // FindClosure searches for a closer over multiple lines. + Newline bool + + // Advance is a flag for the FindClosure. If this is set to true, + // FindClosure advances pointers when closer is found. + Advance bool } type reader struct { @@ -92,6 +114,10 @@ func NewReader(source []byte) Reader { return r } +func (r *reader) FindClosure(opener, closer byte, options FindClosureOptions) (*Segments, bool) { + return findClosureReader(r, opener, closer, options) +} + func (r *reader) ResetPosition() { r.line = -1 r.head = 0 @@ -272,6 +298,10 @@ func NewBlockReader(source []byte, segments *Segments) BlockReader { return r } +func (r *blockReader) FindClosure(opener, closer byte, options FindClosureOptions) (*Segments, bool) { + return findClosureReader(r, opener, closer, options) +} + func (r *blockReader) ResetPosition() { r.line = -1 r.head = 0 @@ -541,3 +571,83 @@ func readRuneReader(r Reader) (rune, int, error) { r.Advance(size) return rn, size, nil } + +func findClosureReader(r Reader, opener, closer byte, opts FindClosureOptions) (*Segments, bool) { + opened := 1 + codeSpanOpener := 0 + closed := false + orgline, orgpos := r.Position() + var ret *Segments + + for { + bs, seg := r.PeekLine() + if bs == nil { + goto end + } + i := 0 + for i < len(bs) { + c := bs[i] + if opts.CodeSpan && codeSpanOpener != 0 && c == '`' { + codeSpanCloser := 0 + for ; i < len(bs); i++ { + if bs[i] == '`' { + codeSpanCloser++ + } else { + i-- + break + } + } + if codeSpanCloser == codeSpanOpener { + codeSpanOpener = 0 + } + } else if codeSpanOpener == 0 && c == '\\' && i < len(bs)-1 && util.IsPunct(bs[i+1]) { + i += 2 + continue + } else if opts.CodeSpan && codeSpanOpener == 0 && c == '`' { + for ; i < len(bs); i++ { + if bs[i] == '`' { + codeSpanOpener++ + } else { + i-- + break + } + } + } else if (opts.CodeSpan && codeSpanOpener == 0) || !opts.CodeSpan { + if c == closer { + opened-- + if opened == 0 { + if ret == nil { + ret = NewSegments() + } + ret.Append(seg.WithStop(seg.Start + i)) + r.Advance(i + 1) + closed = true + goto end + } + } else if c == opener { + if !opts.Nesting { + goto end + } + opened++ + } + } + i++ + } + if !opts.Newline { + goto end + } + r.AdvanceLine() + if ret == nil { + ret = NewSegments() + } + ret.Append(seg) + } +end: + if !opts.Advance { + r.SetPosition(orgline, orgpos) + } + if closed { + return ret, true + } + return nil, false +} diff --git a/vendor/github.com/yuin/goldmark/util/unicode_case_folding.go b/vendor/github.com/yuin/goldmark/util/unicode_case_folding.go index f66ee7c43..f0e6aa4b8 100644 --- a/vendor/github.com/yuin/goldmark/util/unicode_case_folding.go +++ b/vendor/github.com/yuin/goldmark/util/unicode_case_folding.go @@ -1,1491 +1,1534 @@ package util -var unicodeCaseFoldings = map[rune][]rune{ - 0x41: []int32{97}, - 0x42: []int32{98}, - 0x43: []int32{99}, - 0x44: []int32{100}, - 0x45: []int32{101}, - 0x46: []int32{102}, - 0x47: []int32{103}, - 0x48: []int32{104}, - 0x49: []int32{105}, - 0x4a: []int32{106}, - 0x4b: []int32{107}, - 0x4c: []int32{108}, - 0x4d: []int32{109}, - 0x4e: []int32{110}, - 0x4f: []int32{111}, - 0x50: []int32{112}, - 0x51: []int32{113}, - 0x52: []int32{114}, - 0x53: []int32{115}, - 0x54: []int32{116}, - 0x55: []int32{117}, - 0x56: []int32{118}, - 0x57: []int32{119}, - 0x58: []int32{120}, - 0x59: []int32{121}, - 0x5a: []int32{122}, - 0xb5: []int32{956}, - 0xc0: []int32{224}, - 0xc1: []int32{225}, - 0xc2: []int32{226}, - 0xc3: []int32{227}, - 0xc4: []int32{228}, - 0xc5: []int32{229}, - 0xc6: []int32{230}, - 0xc7: []int32{231}, - 0xc8: []int32{232}, - 0xc9: []int32{233}, - 0xca: []int32{234}, - 0xcb: []int32{235}, - 0xcc: []int32{236}, - 0xcd: []int32{237}, - 0xce: []int32{238}, - 0xcf: []int32{239}, - 0xd0: []int32{240}, - 0xd1: []int32{241}, - 0xd2: []int32{242}, - 0xd3: []int32{243}, - 0xd4: []int32{244}, - 0xd5: []int32{245}, - 0xd6: []int32{246}, - 0xd8: []int32{248}, - 0xd9: []int32{249}, - 0xda: []int32{250}, - 0xdb: []int32{251}, - 0xdc: []int32{252}, - 0xdd: []int32{253}, - 0xde: []int32{254}, - 0xdf: []int32{115, 115}, - 0x100: []int32{257}, - 0x102: []int32{259}, - 0x104: []int32{261}, - 0x106: []int32{263}, - 0x108: []int32{265}, - 0x10a: []int32{267}, - 0x10c: []int32{269}, - 0x10e: []int32{271}, - 0x110: []int32{273}, - 0x112: []int32{275}, - 0x114: []int32{277}, - 0x116: []int32{279}, - 0x118: []int32{281}, - 0x11a: []int32{283}, - 0x11c: []int32{285}, - 0x11e: []int32{287}, - 0x120: []int32{289}, - 0x122: []int32{291}, - 0x124: []int32{293}, - 0x126: []int32{295}, - 0x128: []int32{297}, - 0x12a: []int32{299}, - 0x12c: []int32{301}, - 0x12e: []int32{303}, - 0x130: []int32{105, 775}, - 0x132: []int32{307}, - 0x134: []int32{309}, - 0x136: []int32{311}, - 0x139: []int32{314}, - 0x13b: []int32{316}, - 0x13d: []int32{318}, - 0x13f: []int32{320}, - 0x141: []int32{322}, - 0x143: []int32{324}, - 0x145: []int32{326}, - 0x147: []int32{328}, - 0x149: []int32{700, 110}, - 0x14a: []int32{331}, - 0x14c: []int32{333}, - 0x14e: []int32{335}, - 0x150: []int32{337}, - 0x152: []int32{339}, - 0x154: []int32{341}, - 0x156: []int32{343}, - 0x158: []int32{345}, - 0x15a: []int32{347}, - 0x15c: []int32{349}, - 0x15e: []int32{351}, - 0x160: []int32{353}, - 0x162: []int32{355}, - 0x164: []int32{357}, - 0x166: []int32{359}, - 0x168: []int32{361}, - 0x16a: []int32{363}, - 0x16c: []int32{365}, - 0x16e: []int32{367}, - 0x170: []int32{369}, - 0x172: []int32{371}, - 0x174: []int32{373}, - 0x176: []int32{375}, - 0x178: []int32{255}, - 0x179: []int32{378}, - 0x17b: []int32{380}, - 0x17d: []int32{382}, - 0x17f: []int32{115}, - 0x181: []int32{595}, - 0x182: []int32{387}, - 0x184: []int32{389}, - 0x186: []int32{596}, - 0x187: []int32{392}, - 0x189: []int32{598}, - 0x18a: []int32{599}, - 0x18b: []int32{396}, - 0x18e: []int32{477}, - 0x18f: []int32{601}, - 0x190: []int32{603}, - 0x191: []int32{402}, - 0x193: []int32{608}, - 0x194: []int32{611}, - 0x196: []int32{617}, - 0x197: []int32{616}, - 0x198: []int32{409}, - 0x19c: []int32{623}, - 0x19d: []int32{626}, - 0x19f: []int32{629}, - 0x1a0: []int32{417}, - 0x1a2: []int32{419}, - 0x1a4: []int32{421}, - 0x1a6: []int32{640}, - 0x1a7: []int32{424}, - 0x1a9: []int32{643}, - 0x1ac: []int32{429}, - 0x1ae: []int32{648}, - 0x1af: []int32{432}, - 0x1b1: []int32{650}, - 0x1b2: []int32{651}, - 0x1b3: []int32{436}, - 0x1b5: []int32{438}, - 0x1b7: []int32{658}, - 0x1b8: []int32{441}, - 0x1bc: []int32{445}, - 0x1c4: []int32{454}, - 0x1c5: []int32{454}, - 0x1c7: []int32{457}, - 0x1c8: []int32{457}, - 0x1ca: []int32{460}, - 0x1cb: []int32{460}, - 0x1cd: []int32{462}, - 0x1cf: []int32{464}, - 0x1d1: []int32{466}, - 0x1d3: []int32{468}, - 0x1d5: []int32{470}, - 0x1d7: []int32{472}, - 0x1d9: []int32{474}, - 0x1db: []int32{476}, - 0x1de: []int32{479}, - 0x1e0: []int32{481}, - 0x1e2: []int32{483}, - 0x1e4: []int32{485}, - 0x1e6: []int32{487}, - 0x1e8: []int32{489}, - 0x1ea: []int32{491}, - 0x1ec: []int32{493}, - 0x1ee: []int32{495}, - 0x1f0: []int32{106, 780}, - 0x1f1: []int32{499}, - 0x1f2: []int32{499}, - 0x1f4: []int32{501}, - 0x1f6: []int32{405}, - 0x1f7: []int32{447}, - 0x1f8: []int32{505}, - 0x1fa: []int32{507}, - 0x1fc: []int32{509}, - 0x1fe: []int32{511}, - 0x200: []int32{513}, - 0x202: []int32{515}, - 0x204: []int32{517}, - 0x206: []int32{519}, - 0x208: []int32{521}, - 0x20a: []int32{523}, - 0x20c: []int32{525}, - 0x20e: []int32{527}, - 0x210: []int32{529}, - 0x212: []int32{531}, - 0x214: []int32{533}, - 0x216: []int32{535}, - 0x218: []int32{537}, - 0x21a: []int32{539}, - 0x21c: []int32{541}, - 0x21e: []int32{543}, - 0x220: []int32{414}, - 0x222: []int32{547}, - 0x224: []int32{549}, - 0x226: []int32{551}, - 0x228: []int32{553}, - 0x22a: []int32{555}, - 0x22c: []int32{557}, - 0x22e: []int32{559}, - 0x230: []int32{561}, - 0x232: []int32{563}, - 0x23a: []int32{11365}, - 0x23b: []int32{572}, - 0x23d: []int32{410}, - 0x23e: []int32{11366}, - 0x241: []int32{578}, - 0x243: []int32{384}, - 0x244: []int32{649}, - 0x245: []int32{652}, - 0x246: []int32{583}, - 0x248: []int32{585}, - 0x24a: []int32{587}, - 0x24c: []int32{589}, - 0x24e: []int32{591}, - 0x345: []int32{953}, - 0x370: []int32{881}, - 0x372: []int32{883}, - 0x376: []int32{887}, - 0x37f: []int32{1011}, - 0x386: []int32{940}, - 0x388: []int32{941}, - 0x389: []int32{942}, - 0x38a: []int32{943}, - 0x38c: []int32{972}, - 0x38e: []int32{973}, - 0x38f: []int32{974}, - 0x390: []int32{953, 776, 769}, - 0x391: []int32{945}, - 0x392: []int32{946}, - 0x393: []int32{947}, - 0x394: []int32{948}, - 0x395: []int32{949}, - 0x396: []int32{950}, - 0x397: []int32{951}, - 0x398: []int32{952}, - 0x399: []int32{953}, - 0x39a: []int32{954}, - 0x39b: []int32{955}, - 0x39c: []int32{956}, - 0x39d: []int32{957}, - 0x39e: []int32{958}, - 0x39f: []int32{959}, - 0x3a0: []int32{960}, - 0x3a1: []int32{961}, - 0x3a3: []int32{963}, - 0x3a4: []int32{964}, - 0x3a5: []int32{965}, - 0x3a6: []int32{966}, - 0x3a7: []int32{967}, - 0x3a8: []int32{968}, - 0x3a9: []int32{969}, - 0x3aa: []int32{970}, - 0x3ab: []int32{971}, - 0x3b0: []int32{965, 776, 769}, - 0x3c2: []int32{963}, - 0x3cf: []int32{983}, - 0x3d0: []int32{946}, - 0x3d1: []int32{952}, - 0x3d5: []int32{966}, - 0x3d6: []int32{960}, - 0x3d8: []int32{985}, - 0x3da: []int32{987}, - 0x3dc: []int32{989}, - 0x3de: []int32{991}, - 0x3e0: []int32{993}, - 0x3e2: []int32{995}, - 0x3e4: []int32{997}, - 0x3e6: []int32{999}, - 0x3e8: []int32{1001}, - 0x3ea: []int32{1003}, - 0x3ec: []int32{1005}, - 0x3ee: []int32{1007}, - 0x3f0: []int32{954}, - 0x3f1: []int32{961}, - 0x3f4: []int32{952}, - 0x3f5: []int32{949}, - 0x3f7: []int32{1016}, - 0x3f9: []int32{1010}, - 0x3fa: []int32{1019}, - 0x3fd: []int32{891}, - 0x3fe: []int32{892}, - 0x3ff: []int32{893}, - 0x400: []int32{1104}, - 0x401: []int32{1105}, - 0x402: []int32{1106}, - 0x403: []int32{1107}, - 0x404: []int32{1108}, - 0x405: []int32{1109}, - 0x406: []int32{1110}, - 0x407: []int32{1111}, - 0x408: []int32{1112}, - 0x409: []int32{1113}, - 0x40a: []int32{1114}, - 0x40b: []int32{1115}, - 0x40c: []int32{1116}, - 0x40d: []int32{1117}, - 0x40e: []int32{1118}, - 0x40f: []int32{1119}, - 0x410: []int32{1072}, - 0x411: []int32{1073}, - 0x412: []int32{1074}, - 0x413: []int32{1075}, - 0x414: []int32{1076}, - 0x415: []int32{1077}, - 0x416: []int32{1078}, - 0x417: []int32{1079}, - 0x418: []int32{1080}, - 0x419: []int32{1081}, - 0x41a: []int32{1082}, - 0x41b: []int32{1083}, - 0x41c: []int32{1084}, - 0x41d: []int32{1085}, - 0x41e: []int32{1086}, - 0x41f: []int32{1087}, - 0x420: []int32{1088}, - 0x421: []int32{1089}, - 0x422: []int32{1090}, - 0x423: []int32{1091}, - 0x424: []int32{1092}, - 0x425: []int32{1093}, - 0x426: []int32{1094}, - 0x427: []int32{1095}, - 0x428: []int32{1096}, - 0x429: []int32{1097}, - 0x42a: []int32{1098}, - 0x42b: []int32{1099}, - 0x42c: []int32{1100}, - 0x42d: []int32{1101}, - 0x42e: []int32{1102}, - 0x42f: []int32{1103}, - 0x460: []int32{1121}, - 0x462: []int32{1123}, - 0x464: []int32{1125}, - 0x466: []int32{1127}, - 0x468: []int32{1129}, - 0x46a: []int32{1131}, - 0x46c: []int32{1133}, - 0x46e: []int32{1135}, - 0x470: []int32{1137}, - 0x472: []int32{1139}, - 0x474: []int32{1141}, - 0x476: []int32{1143}, - 0x478: []int32{1145}, - 0x47a: []int32{1147}, - 0x47c: []int32{1149}, - 0x47e: []int32{1151}, - 0x480: []int32{1153}, - 0x48a: []int32{1163}, - 0x48c: []int32{1165}, - 0x48e: []int32{1167}, - 0x490: []int32{1169}, - 0x492: []int32{1171}, - 0x494: []int32{1173}, - 0x496: []int32{1175}, - 0x498: []int32{1177}, - 0x49a: []int32{1179}, - 0x49c: []int32{1181}, - 0x49e: []int32{1183}, - 0x4a0: []int32{1185}, - 0x4a2: []int32{1187}, - 0x4a4: []int32{1189}, - 0x4a6: []int32{1191}, - 0x4a8: []int32{1193}, - 0x4aa: []int32{1195}, - 0x4ac: []int32{1197}, - 0x4ae: []int32{1199}, - 0x4b0: []int32{1201}, - 0x4b2: []int32{1203}, - 0x4b4: []int32{1205}, - 0x4b6: []int32{1207}, - 0x4b8: []int32{1209}, - 0x4ba: []int32{1211}, - 0x4bc: []int32{1213}, - 0x4be: []int32{1215}, - 0x4c0: []int32{1231}, - 0x4c1: []int32{1218}, - 0x4c3: []int32{1220}, - 0x4c5: []int32{1222}, - 0x4c7: []int32{1224}, - 0x4c9: []int32{1226}, - 0x4cb: []int32{1228}, - 0x4cd: []int32{1230}, - 0x4d0: []int32{1233}, - 0x4d2: []int32{1235}, - 0x4d4: []int32{1237}, - 0x4d6: []int32{1239}, - 0x4d8: []int32{1241}, - 0x4da: []int32{1243}, - 0x4dc: []int32{1245}, - 0x4de: []int32{1247}, - 0x4e0: []int32{1249}, - 0x4e2: []int32{1251}, - 0x4e4: []int32{1253}, - 0x4e6: []int32{1255}, - 0x4e8: []int32{1257}, - 0x4ea: []int32{1259}, - 0x4ec: []int32{1261}, - 0x4ee: []int32{1263}, - 0x4f0: []int32{1265}, - 0x4f2: []int32{1267}, - 0x4f4: []int32{1269}, - 0x4f6: []int32{1271}, - 0x4f8: []int32{1273}, - 0x4fa: []int32{1275}, - 0x4fc: []int32{1277}, - 0x4fe: []int32{1279}, - 0x500: []int32{1281}, - 0x502: []int32{1283}, - 0x504: []int32{1285}, - 0x506: []int32{1287}, - 0x508: []int32{1289}, - 0x50a: []int32{1291}, - 0x50c: []int32{1293}, - 0x50e: []int32{1295}, - 0x510: []int32{1297}, - 0x512: []int32{1299}, - 0x514: []int32{1301}, - 0x516: []int32{1303}, - 0x518: []int32{1305}, - 0x51a: []int32{1307}, - 0x51c: []int32{1309}, - 0x51e: []int32{1311}, - 0x520: []int32{1313}, - 0x522: []int32{1315}, - 0x524: []int32{1317}, - 0x526: []int32{1319}, - 0x528: []int32{1321}, - 0x52a: []int32{1323}, - 0x52c: []int32{1325}, - 0x52e: []int32{1327}, - 0x531: []int32{1377}, - 0x532: []int32{1378}, - 0x533: []int32{1379}, - 0x534: []int32{1380}, - 0x535: []int32{1381}, - 0x536: []int32{1382}, - 0x537: []int32{1383}, - 0x538: []int32{1384}, - 0x539: []int32{1385}, - 0x53a: []int32{1386}, - 0x53b: []int32{1387}, - 0x53c: []int32{1388}, - 0x53d: []int32{1389}, - 0x53e: []int32{1390}, - 0x53f: []int32{1391}, - 0x540: []int32{1392}, - 0x541: []int32{1393}, - 0x542: []int32{1394}, - 0x543: []int32{1395}, - 0x544: []int32{1396}, - 0x545: []int32{1397}, - 0x546: []int32{1398}, - 0x547: []int32{1399}, - 0x548: []int32{1400}, - 0x549: []int32{1401}, - 0x54a: []int32{1402}, - 0x54b: []int32{1403}, - 0x54c: []int32{1404}, - 0x54d: []int32{1405}, - 0x54e: []int32{1406}, - 0x54f: []int32{1407}, - 0x550: []int32{1408}, - 0x551: []int32{1409}, - 0x552: []int32{1410}, - 0x553: []int32{1411}, - 0x554: []int32{1412}, - 0x555: []int32{1413}, - 0x556: []int32{1414}, - 0x587: []int32{1381, 1410}, - 0x10a0: []int32{11520}, - 0x10a1: []int32{11521}, - 0x10a2: []int32{11522}, - 0x10a3: []int32{11523}, - 0x10a4: []int32{11524}, - 0x10a5: []int32{11525}, - 0x10a6: []int32{11526}, - 0x10a7: []int32{11527}, - 0x10a8: []int32{11528}, - 0x10a9: []int32{11529}, - 0x10aa: []int32{11530}, - 0x10ab: []int32{11531}, - 0x10ac: []int32{11532}, - 0x10ad: []int32{11533}, - 0x10ae: []int32{11534}, - 0x10af: []int32{11535}, - 0x10b0: []int32{11536}, - 0x10b1: []int32{11537}, - 0x10b2: []int32{11538}, - 0x10b3: []int32{11539}, - 0x10b4: []int32{11540}, - 0x10b5: []int32{11541}, - 0x10b6: []int32{11542}, - 0x10b7: []int32{11543}, - 0x10b8: []int32{11544}, - 0x10b9: []int32{11545}, - 0x10ba: []int32{11546}, - 0x10bb: []int32{11547}, - 0x10bc: []int32{11548}, - 0x10bd: []int32{11549}, - 0x10be: []int32{11550}, - 0x10bf: []int32{11551}, - 0x10c0: []int32{11552}, - 0x10c1: []int32{11553}, - 0x10c2: []int32{11554}, - 0x10c3: []int32{11555}, - 0x10c4: []int32{11556}, - 0x10c5: []int32{11557}, - 0x10c7: []int32{11559}, - 0x10cd: []int32{11565}, - 0x13f8: []int32{5104}, - 0x13f9: []int32{5105}, - 0x13fa: []int32{5106}, - 0x13fb: []int32{5107}, - 0x13fc: []int32{5108}, - 0x13fd: []int32{5109}, - 0x1c80: []int32{1074}, - 0x1c81: []int32{1076}, - 0x1c82: []int32{1086}, - 0x1c83: []int32{1089}, - 0x1c84: []int32{1090}, - 0x1c85: []int32{1090}, - 0x1c86: []int32{1098}, - 0x1c87: []int32{1123}, - 0x1c88: []int32{42571}, - 0x1c90: []int32{4304}, - 0x1c91: []int32{4305}, - 0x1c92: []int32{4306}, - 0x1c93: []int32{4307}, - 0x1c94: []int32{4308}, - 0x1c95: []int32{4309}, - 0x1c96: []int32{4310}, - 0x1c97: []int32{4311}, - 0x1c98: []int32{4312}, - 0x1c99: []int32{4313}, - 0x1c9a: []int32{4314}, - 0x1c9b: []int32{4315}, - 0x1c9c: []int32{4316}, - 0x1c9d: []int32{4317}, - 0x1c9e: []int32{4318}, - 0x1c9f: []int32{4319}, - 0x1ca0: []int32{4320}, - 0x1ca1: []int32{4321}, - 0x1ca2: []int32{4322}, - 0x1ca3: []int32{4323}, - 0x1ca4: []int32{4324}, - 0x1ca5: []int32{4325}, - 0x1ca6: []int32{4326}, - 0x1ca7: []int32{4327}, - 0x1ca8: []int32{4328}, - 0x1ca9: []int32{4329}, - 0x1caa: []int32{4330}, - 0x1cab: []int32{4331}, - 0x1cac: []int32{4332}, - 0x1cad: []int32{4333}, - 0x1cae: []int32{4334}, - 0x1caf: []int32{4335}, - 0x1cb0: []int32{4336}, - 0x1cb1: []int32{4337}, - 0x1cb2: []int32{4338}, - 0x1cb3: []int32{4339}, - 0x1cb4: []int32{4340}, - 0x1cb5: []int32{4341}, - 0x1cb6: []int32{4342}, - 0x1cb7: []int32{4343}, - 0x1cb8: []int32{4344}, - 0x1cb9: []int32{4345}, - 0x1cba: []int32{4346}, - 0x1cbd: []int32{4349}, - 0x1cbe: []int32{4350}, - 0x1cbf: []int32{4351}, - 0x1e00: []int32{7681}, - 0x1e02: []int32{7683}, - 0x1e04: []int32{7685}, - 0x1e06: []int32{7687}, - 0x1e08: []int32{7689}, - 0x1e0a: []int32{7691}, - 0x1e0c: []int32{7693}, - 0x1e0e: []int32{7695}, - 0x1e10: []int32{7697}, - 0x1e12: []int32{7699}, - 0x1e14: []int32{7701}, - 0x1e16: []int32{7703}, - 0x1e18: []int32{7705}, - 0x1e1a: []int32{7707}, - 0x1e1c: []int32{7709}, - 0x1e1e: []int32{7711}, - 0x1e20: []int32{7713}, - 0x1e22: []int32{7715}, - 0x1e24: []int32{7717}, - 0x1e26: []int32{7719}, - 0x1e28: []int32{7721}, - 0x1e2a: []int32{7723}, - 0x1e2c: []int32{7725}, - 0x1e2e: []int32{7727}, - 0x1e30: []int32{7729}, - 0x1e32: []int32{7731}, - 0x1e34: []int32{7733}, - 0x1e36: []int32{7735}, - 0x1e38: []int32{7737}, - 0x1e3a: []int32{7739}, - 0x1e3c: []int32{7741}, - 0x1e3e: []int32{7743}, - 0x1e40: []int32{7745}, - 0x1e42: []int32{7747}, - 0x1e44: []int32{7749}, - 0x1e46: []int32{7751}, - 0x1e48: []int32{7753}, - 0x1e4a: []int32{7755}, - 0x1e4c: []int32{7757}, - 0x1e4e: []int32{7759}, - 0x1e50: []int32{7761}, - 0x1e52: []int32{7763}, - 0x1e54: []int32{7765}, - 0x1e56: []int32{7767}, - 0x1e58: []int32{7769}, - 0x1e5a: []int32{7771}, - 0x1e5c: []int32{7773}, - 0x1e5e: []int32{7775}, - 0x1e60: []int32{7777}, - 0x1e62: []int32{7779}, - 0x1e64: []int32{7781}, - 0x1e66: []int32{7783}, - 0x1e68: []int32{7785}, - 0x1e6a: []int32{7787}, - 0x1e6c: []int32{7789}, - 0x1e6e: []int32{7791}, - 0x1e70: []int32{7793}, - 0x1e72: []int32{7795}, - 0x1e74: []int32{7797}, - 0x1e76: []int32{7799}, - 0x1e78: []int32{7801}, - 0x1e7a: []int32{7803}, - 0x1e7c: []int32{7805}, - 0x1e7e: []int32{7807}, - 0x1e80: []int32{7809}, - 0x1e82: []int32{7811}, - 0x1e84: []int32{7813}, - 0x1e86: []int32{7815}, - 0x1e88: []int32{7817}, - 0x1e8a: []int32{7819}, - 0x1e8c: []int32{7821}, - 0x1e8e: []int32{7823}, - 0x1e90: []int32{7825}, - 0x1e92: []int32{7827}, - 0x1e94: []int32{7829}, - 0x1e96: []int32{104, 817}, - 0x1e97: []int32{116, 776}, - 0x1e98: []int32{119, 778}, - 0x1e99: []int32{121, 778}, - 0x1e9a: []int32{97, 702}, - 0x1e9b: []int32{7777}, - 0x1e9e: []int32{115, 115}, - 0x1ea0: []int32{7841}, - 0x1ea2: []int32{7843}, - 0x1ea4: []int32{7845}, - 0x1ea6: []int32{7847}, - 0x1ea8: []int32{7849}, - 0x1eaa: []int32{7851}, - 0x1eac: []int32{7853}, - 0x1eae: []int32{7855}, - 0x1eb0: []int32{7857}, - 0x1eb2: []int32{7859}, - 0x1eb4: []int32{7861}, - 0x1eb6: []int32{7863}, - 0x1eb8: []int32{7865}, - 0x1eba: []int32{7867}, - 0x1ebc: []int32{7869}, - 0x1ebe: []int32{7871}, - 0x1ec0: []int32{7873}, - 0x1ec2: []int32{7875}, - 0x1ec4: []int32{7877}, - 0x1ec6: []int32{7879}, - 0x1ec8: []int32{7881}, - 0x1eca: []int32{7883}, - 0x1ecc: []int32{7885}, - 0x1ece: []int32{7887}, - 0x1ed0: []int32{7889}, - 0x1ed2: []int32{7891}, - 0x1ed4: []int32{7893}, - 0x1ed6: []int32{7895}, - 0x1ed8: []int32{7897}, - 0x1eda: []int32{7899}, - 0x1edc: []int32{7901}, - 0x1ede: []int32{7903}, - 0x1ee0: []int32{7905}, - 0x1ee2: []int32{7907}, - 0x1ee4: []int32{7909}, - 0x1ee6: []int32{7911}, - 0x1ee8: []int32{7913}, - 0x1eea: []int32{7915}, - 0x1eec: []int32{7917}, - 0x1eee: []int32{7919}, - 0x1ef0: []int32{7921}, - 0x1ef2: []int32{7923}, - 0x1ef4: []int32{7925}, - 0x1ef6: []int32{7927}, - 0x1ef8: []int32{7929}, - 0x1efa: []int32{7931}, - 0x1efc: []int32{7933}, - 0x1efe: []int32{7935}, - 0x1f08: []int32{7936}, - 0x1f09: []int32{7937}, - 0x1f0a: []int32{7938}, - 0x1f0b: []int32{7939}, - 0x1f0c: []int32{7940}, - 0x1f0d: []int32{7941}, - 0x1f0e: []int32{7942}, - 0x1f0f: []int32{7943}, - 0x1f18: []int32{7952}, - 0x1f19: []int32{7953}, - 0x1f1a: []int32{7954}, - 0x1f1b: []int32{7955}, - 0x1f1c: []int32{7956}, - 0x1f1d: []int32{7957}, - 0x1f28: []int32{7968}, - 0x1f29: []int32{7969}, - 0x1f2a: []int32{7970}, - 0x1f2b: []int32{7971}, - 0x1f2c: []int32{7972}, - 0x1f2d: []int32{7973}, - 0x1f2e: []int32{7974}, - 0x1f2f: []int32{7975}, - 0x1f38: []int32{7984}, - 0x1f39: []int32{7985}, - 0x1f3a: []int32{7986}, - 0x1f3b: []int32{7987}, - 0x1f3c: []int32{7988}, - 0x1f3d: []int32{7989}, - 0x1f3e: []int32{7990}, - 0x1f3f: []int32{7991}, - 0x1f48: []int32{8000}, - 0x1f49: []int32{8001}, - 0x1f4a: []int32{8002}, - 0x1f4b: []int32{8003}, - 0x1f4c: []int32{8004}, - 0x1f4d: []int32{8005}, - 0x1f50: []int32{965, 787}, - 0x1f52: []int32{965, 787, 768}, - 0x1f54: []int32{965, 787, 769}, - 0x1f56: []int32{965, 787, 834}, - 0x1f59: []int32{8017}, - 0x1f5b: []int32{8019}, - 0x1f5d: []int32{8021}, - 0x1f5f: []int32{8023}, - 0x1f68: []int32{8032}, - 0x1f69: []int32{8033}, - 0x1f6a: []int32{8034}, - 0x1f6b: []int32{8035}, - 0x1f6c: []int32{8036}, - 0x1f6d: []int32{8037}, - 0x1f6e: []int32{8038}, - 0x1f6f: []int32{8039}, - 0x1f80: []int32{7936, 953}, - 0x1f81: []int32{7937, 953}, - 0x1f82: []int32{7938, 953}, - 0x1f83: []int32{7939, 953}, - 0x1f84: []int32{7940, 953}, - 0x1f85: []int32{7941, 953}, - 0x1f86: []int32{7942, 953}, - 0x1f87: []int32{7943, 953}, - 0x1f88: []int32{7936, 953}, - 0x1f89: []int32{7937, 953}, - 0x1f8a: []int32{7938, 953}, - 0x1f8b: []int32{7939, 953}, - 0x1f8c: []int32{7940, 953}, - 0x1f8d: []int32{7941, 953}, - 0x1f8e: []int32{7942, 953}, - 0x1f8f: []int32{7943, 953}, - 0x1f90: []int32{7968, 953}, - 0x1f91: []int32{7969, 953}, - 0x1f92: []int32{7970, 953}, - 0x1f93: []int32{7971, 953}, - 0x1f94: []int32{7972, 953}, - 0x1f95: []int32{7973, 953}, - 0x1f96: []int32{7974, 953}, - 0x1f97: []int32{7975, 953}, - 0x1f98: []int32{7968, 953}, - 0x1f99: []int32{7969, 953}, - 0x1f9a: []int32{7970, 953}, - 0x1f9b: []int32{7971, 953}, - 0x1f9c: []int32{7972, 953}, - 0x1f9d: []int32{7973, 953}, - 0x1f9e: []int32{7974, 953}, - 0x1f9f: []int32{7975, 953}, - 0x1fa0: []int32{8032, 953}, - 0x1fa1: []int32{8033, 953}, - 0x1fa2: []int32{8034, 953}, - 0x1fa3: []int32{8035, 953}, - 0x1fa4: []int32{8036, 953}, - 0x1fa5: []int32{8037, 953}, - 0x1fa6: []int32{8038, 953}, - 0x1fa7: []int32{8039, 953}, - 0x1fa8: []int32{8032, 953}, - 0x1fa9: []int32{8033, 953}, - 0x1faa: []int32{8034, 953}, - 0x1fab: []int32{8035, 953}, - 0x1fac: []int32{8036, 953}, - 0x1fad: []int32{8037, 953}, - 0x1fae: []int32{8038, 953}, - 0x1faf: []int32{8039, 953}, - 0x1fb2: []int32{8048, 953}, - 0x1fb3: []int32{945, 953}, - 0x1fb4: []int32{940, 953}, - 0x1fb6: []int32{945, 834}, - 0x1fb7: []int32{945, 834, 953}, - 0x1fb8: []int32{8112}, - 0x1fb9: []int32{8113}, - 0x1fba: []int32{8048}, - 0x1fbb: []int32{8049}, - 0x1fbc: []int32{945, 953}, - 0x1fbe: []int32{953}, - 0x1fc2: []int32{8052, 953}, - 0x1fc3: []int32{951, 953}, - 0x1fc4: []int32{942, 953}, - 0x1fc6: []int32{951, 834}, - 0x1fc7: []int32{951, 834, 953}, - 0x1fc8: []int32{8050}, - 0x1fc9: []int32{8051}, - 0x1fca: []int32{8052}, - 0x1fcb: []int32{8053}, - 0x1fcc: []int32{951, 953}, - 0x1fd2: []int32{953, 776, 768}, - 0x1fd3: []int32{953, 776, 769}, - 0x1fd6: []int32{953, 834}, - 0x1fd7: []int32{953, 776, 834}, - 0x1fd8: []int32{8144}, - 0x1fd9: []int32{8145}, - 0x1fda: []int32{8054}, - 0x1fdb: []int32{8055}, - 0x1fe2: []int32{965, 776, 768}, - 0x1fe3: []int32{965, 776, 769}, - 0x1fe4: []int32{961, 787}, - 0x1fe6: []int32{965, 834}, - 0x1fe7: []int32{965, 776, 834}, - 0x1fe8: []int32{8160}, - 0x1fe9: []int32{8161}, - 0x1fea: []int32{8058}, - 0x1feb: []int32{8059}, - 0x1fec: []int32{8165}, - 0x1ff2: []int32{8060, 953}, - 0x1ff3: []int32{969, 953}, - 0x1ff4: []int32{974, 953}, - 0x1ff6: []int32{969, 834}, - 0x1ff7: []int32{969, 834, 953}, - 0x1ff8: []int32{8056}, - 0x1ff9: []int32{8057}, - 0x1ffa: []int32{8060}, - 0x1ffb: []int32{8061}, - 0x1ffc: []int32{969, 953}, - 0x2126: []int32{969}, - 0x212a: []int32{107}, - 0x212b: []int32{229}, - 0x2132: []int32{8526}, - 0x2160: []int32{8560}, - 0x2161: []int32{8561}, - 0x2162: []int32{8562}, - 0x2163: []int32{8563}, - 0x2164: []int32{8564}, - 0x2165: []int32{8565}, - 0x2166: []int32{8566}, - 0x2167: []int32{8567}, - 0x2168: []int32{8568}, - 0x2169: []int32{8569}, - 0x216a: []int32{8570}, - 0x216b: []int32{8571}, - 0x216c: []int32{8572}, - 0x216d: []int32{8573}, - 0x216e: []int32{8574}, - 0x216f: []int32{8575}, - 0x2183: []int32{8580}, - 0x24b6: []int32{9424}, - 0x24b7: []int32{9425}, - 0x24b8: []int32{9426}, - 0x24b9: []int32{9427}, - 0x24ba: []int32{9428}, - 0x24bb: []int32{9429}, - 0x24bc: []int32{9430}, - 0x24bd: []int32{9431}, - 0x24be: []int32{9432}, - 0x24bf: []int32{9433}, - 0x24c0: []int32{9434}, - 0x24c1: []int32{9435}, - 0x24c2: []int32{9436}, - 0x24c3: []int32{9437}, - 0x24c4: []int32{9438}, - 0x24c5: []int32{9439}, - 0x24c6: []int32{9440}, - 0x24c7: []int32{9441}, - 0x24c8: []int32{9442}, - 0x24c9: []int32{9443}, - 0x24ca: []int32{9444}, - 0x24cb: []int32{9445}, - 0x24cc: []int32{9446}, - 0x24cd: []int32{9447}, - 0x24ce: []int32{9448}, - 0x24cf: []int32{9449}, - 0x2c00: []int32{11312}, - 0x2c01: []int32{11313}, - 0x2c02: []int32{11314}, - 0x2c03: []int32{11315}, - 0x2c04: []int32{11316}, - 0x2c05: []int32{11317}, - 0x2c06: []int32{11318}, - 0x2c07: []int32{11319}, - 0x2c08: []int32{11320}, - 0x2c09: []int32{11321}, - 0x2c0a: []int32{11322}, - 0x2c0b: []int32{11323}, - 0x2c0c: []int32{11324}, - 0x2c0d: []int32{11325}, - 0x2c0e: []int32{11326}, - 0x2c0f: []int32{11327}, - 0x2c10: []int32{11328}, - 0x2c11: []int32{11329}, - 0x2c12: []int32{11330}, - 0x2c13: []int32{11331}, - 0x2c14: []int32{11332}, - 0x2c15: []int32{11333}, - 0x2c16: []int32{11334}, - 0x2c17: []int32{11335}, - 0x2c18: []int32{11336}, - 0x2c19: []int32{11337}, - 0x2c1a: []int32{11338}, - 0x2c1b: []int32{11339}, - 0x2c1c: []int32{11340}, - 0x2c1d: []int32{11341}, - 0x2c1e: []int32{11342}, - 0x2c1f: []int32{11343}, - 0x2c20: []int32{11344}, - 0x2c21: []int32{11345}, - 0x2c22: []int32{11346}, - 0x2c23: []int32{11347}, - 0x2c24: []int32{11348}, - 0x2c25: []int32{11349}, - 0x2c26: []int32{11350}, - 0x2c27: []int32{11351}, - 0x2c28: []int32{11352}, - 0x2c29: []int32{11353}, - 0x2c2a: []int32{11354}, - 0x2c2b: []int32{11355}, - 0x2c2c: []int32{11356}, - 0x2c2d: []int32{11357}, - 0x2c2e: []int32{11358}, - 0x2c60: []int32{11361}, - 0x2c62: []int32{619}, - 0x2c63: []int32{7549}, - 0x2c64: []int32{637}, - 0x2c67: []int32{11368}, - 0x2c69: []int32{11370}, - 0x2c6b: []int32{11372}, - 0x2c6d: []int32{593}, - 0x2c6e: []int32{625}, - 0x2c6f: []int32{592}, - 0x2c70: []int32{594}, - 0x2c72: []int32{11379}, - 0x2c75: []int32{11382}, - 0x2c7e: []int32{575}, - 0x2c7f: []int32{576}, - 0x2c80: []int32{11393}, - 0x2c82: []int32{11395}, - 0x2c84: []int32{11397}, - 0x2c86: []int32{11399}, - 0x2c88: []int32{11401}, - 0x2c8a: []int32{11403}, - 0x2c8c: []int32{11405}, - 0x2c8e: []int32{11407}, - 0x2c90: []int32{11409}, - 0x2c92: []int32{11411}, - 0x2c94: []int32{11413}, - 0x2c96: []int32{11415}, - 0x2c98: []int32{11417}, - 0x2c9a: []int32{11419}, - 0x2c9c: []int32{11421}, - 0x2c9e: []int32{11423}, - 0x2ca0: []int32{11425}, - 0x2ca2: []int32{11427}, - 0x2ca4: []int32{11429}, - 0x2ca6: []int32{11431}, - 0x2ca8: []int32{11433}, - 0x2caa: []int32{11435}, - 0x2cac: []int32{11437}, - 0x2cae: []int32{11439}, - 0x2cb0: []int32{11441}, - 0x2cb2: []int32{11443}, - 0x2cb4: []int32{11445}, - 0x2cb6: []int32{11447}, - 0x2cb8: []int32{11449}, - 0x2cba: []int32{11451}, - 0x2cbc: []int32{11453}, - 0x2cbe: []int32{11455}, - 0x2cc0: []int32{11457}, - 0x2cc2: []int32{11459}, - 0x2cc4: []int32{11461}, - 0x2cc6: []int32{11463}, - 0x2cc8: []int32{11465}, - 0x2cca: []int32{11467}, - 0x2ccc: []int32{11469}, - 0x2cce: []int32{11471}, - 0x2cd0: []int32{11473}, - 0x2cd2: []int32{11475}, - 0x2cd4: []int32{11477}, - 0x2cd6: []int32{11479}, - 0x2cd8: []int32{11481}, - 0x2cda: []int32{11483}, - 0x2cdc: []int32{11485}, - 0x2cde: []int32{11487}, - 0x2ce0: []int32{11489}, - 0x2ce2: []int32{11491}, - 0x2ceb: []int32{11500}, - 0x2ced: []int32{11502}, - 0x2cf2: []int32{11507}, - 0xa640: []int32{42561}, - 0xa642: []int32{42563}, - 0xa644: []int32{42565}, - 0xa646: []int32{42567}, - 0xa648: []int32{42569}, - 0xa64a: []int32{42571}, - 0xa64c: []int32{42573}, - 0xa64e: []int32{42575}, - 0xa650: []int32{42577}, - 0xa652: []int32{42579}, - 0xa654: []int32{42581}, - 0xa656: []int32{42583}, - 0xa658: []int32{42585}, - 0xa65a: []int32{42587}, - 0xa65c: []int32{42589}, - 0xa65e: []int32{42591}, - 0xa660: []int32{42593}, - 0xa662: []int32{42595}, - 0xa664: []int32{42597}, - 0xa666: []int32{42599}, - 0xa668: []int32{42601}, - 0xa66a: []int32{42603}, - 0xa66c: []int32{42605}, - 0xa680: []int32{42625}, - 0xa682: []int32{42627}, - 0xa684: []int32{42629}, - 0xa686: []int32{42631}, - 0xa688: []int32{42633}, - 0xa68a: []int32{42635}, - 0xa68c: []int32{42637}, - 0xa68e: []int32{42639}, - 0xa690: []int32{42641}, - 0xa692: []int32{42643}, - 0xa694: []int32{42645}, - 0xa696: []int32{42647}, - 0xa698: []int32{42649}, - 0xa69a: []int32{42651}, - 0xa722: []int32{42787}, - 0xa724: []int32{42789}, - 0xa726: []int32{42791}, - 0xa728: []int32{42793}, - 0xa72a: []int32{42795}, - 0xa72c: []int32{42797}, - 0xa72e: []int32{42799}, - 0xa732: []int32{42803}, - 0xa734: []int32{42805}, - 0xa736: []int32{42807}, - 0xa738: []int32{42809}, - 0xa73a: []int32{42811}, - 0xa73c: []int32{42813}, - 0xa73e: []int32{42815}, - 0xa740: []int32{42817}, - 0xa742: []int32{42819}, - 0xa744: []int32{42821}, - 0xa746: []int32{42823}, - 0xa748: []int32{42825}, - 0xa74a: []int32{42827}, - 0xa74c: []int32{42829}, - 0xa74e: []int32{42831}, - 0xa750: []int32{42833}, - 0xa752: []int32{42835}, - 0xa754: []int32{42837}, - 0xa756: []int32{42839}, - 0xa758: []int32{42841}, - 0xa75a: []int32{42843}, - 0xa75c: []int32{42845}, - 0xa75e: []int32{42847}, - 0xa760: []int32{42849}, - 0xa762: []int32{42851}, - 0xa764: []int32{42853}, - 0xa766: []int32{42855}, - 0xa768: []int32{42857}, - 0xa76a: []int32{42859}, - 0xa76c: []int32{42861}, - 0xa76e: []int32{42863}, - 0xa779: []int32{42874}, - 0xa77b: []int32{42876}, - 0xa77d: []int32{7545}, - 0xa77e: []int32{42879}, - 0xa780: []int32{42881}, - 0xa782: []int32{42883}, - 0xa784: []int32{42885}, - 0xa786: []int32{42887}, - 0xa78b: []int32{42892}, - 0xa78d: []int32{613}, - 0xa790: []int32{42897}, - 0xa792: []int32{42899}, - 0xa796: []int32{42903}, - 0xa798: []int32{42905}, - 0xa79a: []int32{42907}, - 0xa79c: []int32{42909}, - 0xa79e: []int32{42911}, - 0xa7a0: []int32{42913}, - 0xa7a2: []int32{42915}, - 0xa7a4: []int32{42917}, - 0xa7a6: []int32{42919}, - 0xa7a8: []int32{42921}, - 0xa7aa: []int32{614}, - 0xa7ab: []int32{604}, - 0xa7ac: []int32{609}, - 0xa7ad: []int32{620}, - 0xa7ae: []int32{618}, - 0xa7b0: []int32{670}, - 0xa7b1: []int32{647}, - 0xa7b2: []int32{669}, - 0xa7b3: []int32{43859}, - 0xa7b4: []int32{42933}, - 0xa7b6: []int32{42935}, - 0xa7b8: []int32{42937}, - 0xa7ba: []int32{42939}, - 0xa7bc: []int32{42941}, - 0xa7be: []int32{42943}, - 0xa7c2: []int32{42947}, - 0xa7c4: []int32{42900}, - 0xa7c5: []int32{642}, - 0xa7c6: []int32{7566}, - 0xab70: []int32{5024}, - 0xab71: []int32{5025}, - 0xab72: []int32{5026}, - 0xab73: []int32{5027}, - 0xab74: []int32{5028}, - 0xab75: []int32{5029}, - 0xab76: []int32{5030}, - 0xab77: []int32{5031}, - 0xab78: []int32{5032}, - 0xab79: []int32{5033}, - 0xab7a: []int32{5034}, - 0xab7b: []int32{5035}, - 0xab7c: []int32{5036}, - 0xab7d: []int32{5037}, - 0xab7e: []int32{5038}, - 0xab7f: []int32{5039}, - 0xab80: []int32{5040}, - 0xab81: []int32{5041}, - 0xab82: []int32{5042}, - 0xab83: []int32{5043}, - 0xab84: []int32{5044}, - 0xab85: []int32{5045}, - 0xab86: []int32{5046}, - 0xab87: []int32{5047}, - 0xab88: []int32{5048}, - 0xab89: []int32{5049}, - 0xab8a: []int32{5050}, - 0xab8b: []int32{5051}, - 0xab8c: []int32{5052}, - 0xab8d: []int32{5053}, - 0xab8e: []int32{5054}, - 0xab8f: []int32{5055}, - 0xab90: []int32{5056}, - 0xab91: []int32{5057}, - 0xab92: []int32{5058}, - 0xab93: []int32{5059}, - 0xab94: []int32{5060}, - 0xab95: []int32{5061}, - 0xab96: []int32{5062}, - 0xab97: []int32{5063}, - 0xab98: []int32{5064}, - 0xab99: []int32{5065}, - 0xab9a: []int32{5066}, - 0xab9b: []int32{5067}, - 0xab9c: []int32{5068}, - 0xab9d: []int32{5069}, - 0xab9e: []int32{5070}, - 0xab9f: []int32{5071}, - 0xaba0: []int32{5072}, - 0xaba1: []int32{5073}, - 0xaba2: []int32{5074}, - 0xaba3: []int32{5075}, - 0xaba4: []int32{5076}, - 0xaba5: []int32{5077}, - 0xaba6: []int32{5078}, - 0xaba7: []int32{5079}, - 0xaba8: []int32{5080}, - 0xaba9: []int32{5081}, - 0xabaa: []int32{5082}, - 0xabab: []int32{5083}, - 0xabac: []int32{5084}, - 0xabad: []int32{5085}, - 0xabae: []int32{5086}, - 0xabaf: []int32{5087}, - 0xabb0: []int32{5088}, - 0xabb1: []int32{5089}, - 0xabb2: []int32{5090}, - 0xabb3: []int32{5091}, - 0xabb4: []int32{5092}, - 0xabb5: []int32{5093}, - 0xabb6: []int32{5094}, - 0xabb7: []int32{5095}, - 0xabb8: []int32{5096}, - 0xabb9: []int32{5097}, - 0xabba: []int32{5098}, - 0xabbb: []int32{5099}, - 0xabbc: []int32{5100}, - 0xabbd: []int32{5101}, - 0xabbe: []int32{5102}, - 0xabbf: []int32{5103}, - 0xfb00: []int32{102, 102}, - 0xfb01: []int32{102, 105}, - 0xfb02: []int32{102, 108}, - 0xfb03: []int32{102, 102, 105}, - 0xfb04: []int32{102, 102, 108}, - 0xfb05: []int32{115, 116}, - 0xfb06: []int32{115, 116}, - 0xfb13: []int32{1396, 1398}, - 0xfb14: []int32{1396, 1381}, - 0xfb15: []int32{1396, 1387}, - 0xfb16: []int32{1406, 1398}, - 0xfb17: []int32{1396, 1389}, - 0xff21: []int32{65345}, - 0xff22: []int32{65346}, - 0xff23: []int32{65347}, - 0xff24: []int32{65348}, - 0xff25: []int32{65349}, - 0xff26: []int32{65350}, - 0xff27: []int32{65351}, - 0xff28: []int32{65352}, - 0xff29: []int32{65353}, - 0xff2a: []int32{65354}, - 0xff2b: []int32{65355}, - 0xff2c: []int32{65356}, - 0xff2d: []int32{65357}, - 0xff2e: []int32{65358}, - 0xff2f: []int32{65359}, - 0xff30: []int32{65360}, - 0xff31: []int32{65361}, - 0xff32: []int32{65362}, - 0xff33: []int32{65363}, - 0xff34: []int32{65364}, - 0xff35: []int32{65365}, - 0xff36: []int32{65366}, - 0xff37: []int32{65367}, - 0xff38: []int32{65368}, - 0xff39: []int32{65369}, - 0xff3a: []int32{65370}, - 0x10400: []int32{66600}, - 0x10401: []int32{66601}, - 0x10402: []int32{66602}, - 0x10403: []int32{66603}, - 0x10404: []int32{66604}, - 0x10405: []int32{66605}, - 0x10406: []int32{66606}, - 0x10407: []int32{66607}, - 0x10408: []int32{66608}, - 0x10409: []int32{66609}, - 0x1040a: []int32{66610}, - 0x1040b: []int32{66611}, - 0x1040c: []int32{66612}, - 0x1040d: []int32{66613}, - 0x1040e: []int32{66614}, - 0x1040f: []int32{66615}, - 0x10410: []int32{66616}, - 0x10411: []int32{66617}, - 0x10412: []int32{66618}, - 0x10413: []int32{66619}, - 0x10414: []int32{66620}, - 0x10415: []int32{66621}, - 0x10416: []int32{66622}, - 0x10417: []int32{66623}, - 0x10418: []int32{66624}, - 0x10419: []int32{66625}, - 0x1041a: []int32{66626}, - 0x1041b: []int32{66627}, - 0x1041c: []int32{66628}, - 0x1041d: []int32{66629}, - 0x1041e: []int32{66630}, - 0x1041f: []int32{66631}, - 0x10420: []int32{66632}, - 0x10421: []int32{66633}, - 0x10422: []int32{66634}, - 0x10423: []int32{66635}, - 0x10424: []int32{66636}, - 0x10425: []int32{66637}, - 0x10426: []int32{66638}, - 0x10427: []int32{66639}, - 0x104b0: []int32{66776}, - 0x104b1: []int32{66777}, - 0x104b2: []int32{66778}, - 0x104b3: []int32{66779}, - 0x104b4: []int32{66780}, - 0x104b5: []int32{66781}, - 0x104b6: []int32{66782}, - 0x104b7: []int32{66783}, - 0x104b8: []int32{66784}, - 0x104b9: []int32{66785}, - 0x104ba: []int32{66786}, - 0x104bb: []int32{66787}, - 0x104bc: []int32{66788}, - 0x104bd: []int32{66789}, - 0x104be: []int32{66790}, - 0x104bf: []int32{66791}, - 0x104c0: []int32{66792}, - 0x104c1: []int32{66793}, - 0x104c2: []int32{66794}, - 0x104c3: []int32{66795}, - 0x104c4: []int32{66796}, - 0x104c5: []int32{66797}, - 0x104c6: []int32{66798}, - 0x104c7: []int32{66799}, - 0x104c8: []int32{66800}, - 0x104c9: []int32{66801}, - 0x104ca: []int32{66802}, - 0x104cb: []int32{66803}, - 0x104cc: []int32{66804}, - 0x104cd: []int32{66805}, - 0x104ce: []int32{66806}, - 0x104cf: []int32{66807}, - 0x104d0: []int32{66808}, - 0x104d1: []int32{66809}, - 0x104d2: []int32{66810}, - 0x104d3: []int32{66811}, - 0x10c80: []int32{68800}, - 0x10c81: []int32{68801}, - 0x10c82: []int32{68802}, - 0x10c83: []int32{68803}, - 0x10c84: []int32{68804}, - 0x10c85: []int32{68805}, - 0x10c86: []int32{68806}, - 0x10c87: []int32{68807}, - 0x10c88: []int32{68808}, - 0x10c89: []int32{68809}, - 0x10c8a: []int32{68810}, - 0x10c8b: []int32{68811}, - 0x10c8c: []int32{68812}, - 0x10c8d: []int32{68813}, - 0x10c8e: []int32{68814}, - 0x10c8f: []int32{68815}, - 0x10c90: []int32{68816}, - 0x10c91: []int32{68817}, - 0x10c92: []int32{68818}, - 0x10c93: []int32{68819}, - 0x10c94: []int32{68820}, - 0x10c95: []int32{68821}, - 0x10c96: []int32{68822}, - 0x10c97: []int32{68823}, - 0x10c98: []int32{68824}, - 0x10c99: []int32{68825}, - 0x10c9a: []int32{68826}, - 0x10c9b: []int32{68827}, - 0x10c9c: []int32{68828}, - 0x10c9d: []int32{68829}, - 0x10c9e: []int32{68830}, - 0x10c9f: []int32{68831}, - 0x10ca0: []int32{68832}, - 0x10ca1: []int32{68833}, - 0x10ca2: []int32{68834}, - 0x10ca3: []int32{68835}, - 0x10ca4: []int32{68836}, - 0x10ca5: []int32{68837}, - 0x10ca6: []int32{68838}, - 0x10ca7: []int32{68839}, - 0x10ca8: []int32{68840}, - 0x10ca9: []int32{68841}, - 0x10caa: []int32{68842}, - 0x10cab: []int32{68843}, - 0x10cac: []int32{68844}, - 0x10cad: []int32{68845}, - 0x10cae: []int32{68846}, - 0x10caf: []int32{68847}, - 0x10cb0: []int32{68848}, - 0x10cb1: []int32{68849}, - 0x10cb2: []int32{68850}, - 0x118a0: []int32{71872}, - 0x118a1: []int32{71873}, - 0x118a2: []int32{71874}, - 0x118a3: []int32{71875}, - 0x118a4: []int32{71876}, - 0x118a5: []int32{71877}, - 0x118a6: []int32{71878}, - 0x118a7: []int32{71879}, - 0x118a8: []int32{71880}, - 0x118a9: []int32{71881}, - 0x118aa: []int32{71882}, - 0x118ab: []int32{71883}, - 0x118ac: []int32{71884}, - 0x118ad: []int32{71885}, - 0x118ae: []int32{71886}, - 0x118af: []int32{71887}, - 0x118b0: []int32{71888}, - 0x118b1: []int32{71889}, - 0x118b2: []int32{71890}, - 0x118b3: []int32{71891}, - 0x118b4: []int32{71892}, - 0x118b5: []int32{71893}, - 0x118b6: []int32{71894}, - 0x118b7: []int32{71895}, - 0x118b8: []int32{71896}, - 0x118b9: []int32{71897}, - 0x118ba: []int32{71898}, - 0x118bb: []int32{71899}, - 0x118bc: []int32{71900}, - 0x118bd: []int32{71901}, - 0x118be: []int32{71902}, - 0x118bf: []int32{71903}, - 0x16e40: []int32{93792}, - 0x16e41: []int32{93793}, - 0x16e42: []int32{93794}, - 0x16e43: []int32{93795}, - 0x16e44: []int32{93796}, - 0x16e45: []int32{93797}, - 0x16e46: []int32{93798}, - 0x16e47: []int32{93799}, - 0x16e48: []int32{93800}, - 0x16e49: []int32{93801}, - 0x16e4a: []int32{93802}, - 0x16e4b: []int32{93803}, - 0x16e4c: []int32{93804}, - 0x16e4d: []int32{93805}, - 0x16e4e: []int32{93806}, - 0x16e4f: []int32{93807}, - 0x16e50: []int32{93808}, - 0x16e51: []int32{93809}, - 0x16e52: []int32{93810}, - 0x16e53: []int32{93811}, - 0x16e54: []int32{93812}, - 0x16e55: []int32{93813}, - 0x16e56: []int32{93814}, - 0x16e57: []int32{93815}, - 0x16e58: []int32{93816}, - 0x16e59: []int32{93817}, - 0x16e5a: []int32{93818}, - 0x16e5b: []int32{93819}, - 0x16e5c: []int32{93820}, - 0x16e5d: []int32{93821}, - 0x16e5e: []int32{93822}, - 0x16e5f: []int32{93823}, - 0x1e900: []int32{125218}, - 0x1e901: []int32{125219}, - 0x1e902: []int32{125220}, - 0x1e903: []int32{125221}, - 0x1e904: []int32{125222}, - 0x1e905: []int32{125223}, - 0x1e906: []int32{125224}, - 0x1e907: []int32{125225}, - 0x1e908: []int32{125226}, - 0x1e909: []int32{125227}, - 0x1e90a: []int32{125228}, - 0x1e90b: []int32{125229}, - 0x1e90c: []int32{125230}, - 0x1e90d: []int32{125231}, - 0x1e90e: []int32{125232}, - 0x1e90f: []int32{125233}, - 0x1e910: []int32{125234}, - 0x1e911: []int32{125235}, - 0x1e912: []int32{125236}, - 0x1e913: []int32{125237}, - 0x1e914: []int32{125238}, - 0x1e915: []int32{125239}, - 0x1e916: []int32{125240}, - 0x1e917: []int32{125241}, - 0x1e918: []int32{125242}, - 0x1e919: []int32{125243}, - 0x1e91a: []int32{125244}, - 0x1e91b: []int32{125245}, - 0x1e91c: []int32{125246}, - 0x1e91d: []int32{125247}, - 0x1e91e: []int32{125248}, - 0x1e91f: []int32{125249}, - 0x1e920: []int32{125250}, - 0x1e921: []int32{125251}, +var unicodeCaseFoldings = map[rune][]rune { + 0x41 : []int32{97}, + 0x42 : []int32{98}, + 0x43 : []int32{99}, + 0x44 : []int32{100}, + 0x45 : []int32{101}, + 0x46 : []int32{102}, + 0x47 : []int32{103}, + 0x48 : []int32{104}, + 0x49 : []int32{105}, + 0x4a : []int32{106}, + 0x4b : []int32{107}, + 0x4c : []int32{108}, + 0x4d : []int32{109}, + 0x4e : []int32{110}, + 0x4f : []int32{111}, + 0x50 : []int32{112}, + 0x51 : []int32{113}, + 0x52 : []int32{114}, + 0x53 : []int32{115}, + 0x54 : []int32{116}, + 0x55 : []int32{117}, + 0x56 : []int32{118}, + 0x57 : []int32{119}, + 0x58 : []int32{120}, + 0x59 : []int32{121}, + 0x5a : []int32{122}, + 0xb5 : []int32{956}, + 0xc0 : []int32{224}, + 0xc1 : []int32{225}, + 0xc2 : []int32{226}, + 0xc3 : []int32{227}, + 0xc4 : []int32{228}, + 0xc5 : []int32{229}, + 0xc6 : []int32{230}, + 0xc7 : []int32{231}, + 0xc8 : []int32{232}, + 0xc9 : []int32{233}, + 0xca : []int32{234}, + 0xcb : []int32{235}, + 0xcc : []int32{236}, + 0xcd : []int32{237}, + 0xce : []int32{238}, + 0xcf : []int32{239}, + 0xd0 : []int32{240}, + 0xd1 : []int32{241}, + 0xd2 : []int32{242}, + 0xd3 : []int32{243}, + 0xd4 : []int32{244}, + 0xd5 : []int32{245}, + 0xd6 : []int32{246}, + 0xd8 : []int32{248}, + 0xd9 : []int32{249}, + 0xda : []int32{250}, + 0xdb : []int32{251}, + 0xdc : []int32{252}, + 0xdd : []int32{253}, + 0xde : []int32{254}, + 0xdf : []int32{115, 115}, + 0x100 : []int32{257}, + 0x102 : []int32{259}, + 0x104 : []int32{261}, + 0x106 : []int32{263}, + 0x108 : []int32{265}, + 0x10a : []int32{267}, + 0x10c : []int32{269}, + 0x10e : []int32{271}, + 0x110 : []int32{273}, + 0x112 : []int32{275}, + 0x114 : []int32{277}, + 0x116 : []int32{279}, + 0x118 : []int32{281}, + 0x11a : []int32{283}, + 0x11c : []int32{285}, + 0x11e : []int32{287}, + 0x120 : []int32{289}, + 0x122 : []int32{291}, + 0x124 : []int32{293}, + 0x126 : []int32{295}, + 0x128 : []int32{297}, + 0x12a : []int32{299}, + 0x12c : []int32{301}, + 0x12e : []int32{303}, + 0x130 : []int32{105, 775}, + 0x132 : []int32{307}, + 0x134 : []int32{309}, + 0x136 : []int32{311}, + 0x139 : []int32{314}, + 0x13b : []int32{316}, + 0x13d : []int32{318}, + 0x13f : []int32{320}, + 0x141 : []int32{322}, + 0x143 : []int32{324}, + 0x145 : []int32{326}, + 0x147 : []int32{328}, + 0x149 : []int32{700, 110}, + 0x14a : []int32{331}, + 0x14c : []int32{333}, + 0x14e : []int32{335}, + 0x150 : []int32{337}, + 0x152 : []int32{339}, + 0x154 : []int32{341}, + 0x156 : []int32{343}, + 0x158 : []int32{345}, + 0x15a : []int32{347}, + 0x15c : []int32{349}, + 0x15e : []int32{351}, + 0x160 : []int32{353}, + 0x162 : []int32{355}, + 0x164 : []int32{357}, + 0x166 : []int32{359}, + 0x168 : []int32{361}, + 0x16a : []int32{363}, + 0x16c : []int32{365}, + 0x16e : []int32{367}, + 0x170 : []int32{369}, + 0x172 : []int32{371}, + 0x174 : []int32{373}, + 0x176 : []int32{375}, + 0x178 : []int32{255}, + 0x179 : []int32{378}, + 0x17b : []int32{380}, + 0x17d : []int32{382}, + 0x17f : []int32{115}, + 0x181 : []int32{595}, + 0x182 : []int32{387}, + 0x184 : []int32{389}, + 0x186 : []int32{596}, + 0x187 : []int32{392}, + 0x189 : []int32{598}, + 0x18a : []int32{599}, + 0x18b : []int32{396}, + 0x18e : []int32{477}, + 0x18f : []int32{601}, + 0x190 : []int32{603}, + 0x191 : []int32{402}, + 0x193 : []int32{608}, + 0x194 : []int32{611}, + 0x196 : []int32{617}, + 0x197 : []int32{616}, + 0x198 : []int32{409}, + 0x19c : []int32{623}, + 0x19d : []int32{626}, + 0x19f : []int32{629}, + 0x1a0 : []int32{417}, + 0x1a2 : []int32{419}, + 0x1a4 : []int32{421}, + 0x1a6 : []int32{640}, + 0x1a7 : []int32{424}, + 0x1a9 : []int32{643}, + 0x1ac : []int32{429}, + 0x1ae : []int32{648}, + 0x1af : []int32{432}, + 0x1b1 : []int32{650}, + 0x1b2 : []int32{651}, + 0x1b3 : []int32{436}, + 0x1b5 : []int32{438}, + 0x1b7 : []int32{658}, + 0x1b8 : []int32{441}, + 0x1bc : []int32{445}, + 0x1c4 : []int32{454}, + 0x1c5 : []int32{454}, + 0x1c7 : []int32{457}, + 0x1c8 : []int32{457}, + 0x1ca : []int32{460}, + 0x1cb : []int32{460}, + 0x1cd : []int32{462}, + 0x1cf : []int32{464}, + 0x1d1 : []int32{466}, + 0x1d3 : []int32{468}, + 0x1d5 : []int32{470}, + 0x1d7 : []int32{472}, + 0x1d9 : []int32{474}, + 0x1db : []int32{476}, + 0x1de : []int32{479}, + 0x1e0 : []int32{481}, + 0x1e2 : []int32{483}, + 0x1e4 : []int32{485}, + 0x1e6 : []int32{487}, + 0x1e8 : []int32{489}, + 0x1ea : []int32{491}, + 0x1ec : []int32{493}, + 0x1ee : []int32{495}, + 0x1f0 : []int32{106, 780}, + 0x1f1 : []int32{499}, + 0x1f2 : []int32{499}, + 0x1f4 : []int32{501}, + 0x1f6 : []int32{405}, + 0x1f7 : []int32{447}, + 0x1f8 : []int32{505}, + 0x1fa : []int32{507}, + 0x1fc : []int32{509}, + 0x1fe : []int32{511}, + 0x200 : []int32{513}, + 0x202 : []int32{515}, + 0x204 : []int32{517}, + 0x206 : []int32{519}, + 0x208 : []int32{521}, + 0x20a : []int32{523}, + 0x20c : []int32{525}, + 0x20e : []int32{527}, + 0x210 : []int32{529}, + 0x212 : []int32{531}, + 0x214 : []int32{533}, + 0x216 : []int32{535}, + 0x218 : []int32{537}, + 0x21a : []int32{539}, + 0x21c : []int32{541}, + 0x21e : []int32{543}, + 0x220 : []int32{414}, + 0x222 : []int32{547}, + 0x224 : []int32{549}, + 0x226 : []int32{551}, + 0x228 : []int32{553}, + 0x22a : []int32{555}, + 0x22c : []int32{557}, + 0x22e : []int32{559}, + 0x230 : []int32{561}, + 0x232 : []int32{563}, + 0x23a : []int32{11365}, + 0x23b : []int32{572}, + 0x23d : []int32{410}, + 0x23e : []int32{11366}, + 0x241 : []int32{578}, + 0x243 : []int32{384}, + 0x244 : []int32{649}, + 0x245 : []int32{652}, + 0x246 : []int32{583}, + 0x248 : []int32{585}, + 0x24a : []int32{587}, + 0x24c : []int32{589}, + 0x24e : []int32{591}, + 0x345 : []int32{953}, + 0x370 : []int32{881}, + 0x372 : []int32{883}, + 0x376 : []int32{887}, + 0x37f : []int32{1011}, + 0x386 : []int32{940}, + 0x388 : []int32{941}, + 0x389 : []int32{942}, + 0x38a : []int32{943}, + 0x38c : []int32{972}, + 0x38e : []int32{973}, + 0x38f : []int32{974}, + 0x390 : []int32{953, 776, 769}, + 0x391 : []int32{945}, + 0x392 : []int32{946}, + 0x393 : []int32{947}, + 0x394 : []int32{948}, + 0x395 : []int32{949}, + 0x396 : []int32{950}, + 0x397 : []int32{951}, + 0x398 : []int32{952}, + 0x399 : []int32{953}, + 0x39a : []int32{954}, + 0x39b : []int32{955}, + 0x39c : []int32{956}, + 0x39d : []int32{957}, + 0x39e : []int32{958}, + 0x39f : []int32{959}, + 0x3a0 : []int32{960}, + 0x3a1 : []int32{961}, + 0x3a3 : []int32{963}, + 0x3a4 : []int32{964}, + 0x3a5 : []int32{965}, + 0x3a6 : []int32{966}, + 0x3a7 : []int32{967}, + 0x3a8 : []int32{968}, + 0x3a9 : []int32{969}, + 0x3aa : []int32{970}, + 0x3ab : []int32{971}, + 0x3b0 : []int32{965, 776, 769}, + 0x3c2 : []int32{963}, + 0x3cf : []int32{983}, + 0x3d0 : []int32{946}, + 0x3d1 : []int32{952}, + 0x3d5 : []int32{966}, + 0x3d6 : []int32{960}, + 0x3d8 : []int32{985}, + 0x3da : []int32{987}, + 0x3dc : []int32{989}, + 0x3de : []int32{991}, + 0x3e0 : []int32{993}, + 0x3e2 : []int32{995}, + 0x3e4 : []int32{997}, + 0x3e6 : []int32{999}, + 0x3e8 : []int32{1001}, + 0x3ea : []int32{1003}, + 0x3ec : []int32{1005}, + 0x3ee : []int32{1007}, + 0x3f0 : []int32{954}, + 0x3f1 : []int32{961}, + 0x3f4 : []int32{952}, + 0x3f5 : []int32{949}, + 0x3f7 : []int32{1016}, + 0x3f9 : []int32{1010}, + 0x3fa : []int32{1019}, + 0x3fd : []int32{891}, + 0x3fe : []int32{892}, + 0x3ff : []int32{893}, + 0x400 : []int32{1104}, + 0x401 : []int32{1105}, + 0x402 : []int32{1106}, + 0x403 : []int32{1107}, + 0x404 : []int32{1108}, + 0x405 : []int32{1109}, + 0x406 : []int32{1110}, + 0x407 : []int32{1111}, + 0x408 : []int32{1112}, + 0x409 : []int32{1113}, + 0x40a : []int32{1114}, + 0x40b : []int32{1115}, + 0x40c : []int32{1116}, + 0x40d : []int32{1117}, + 0x40e : []int32{1118}, + 0x40f : []int32{1119}, + 0x410 : []int32{1072}, + 0x411 : []int32{1073}, + 0x412 : []int32{1074}, + 0x413 : []int32{1075}, + 0x414 : []int32{1076}, + 0x415 : []int32{1077}, + 0x416 : []int32{1078}, + 0x417 : []int32{1079}, + 0x418 : []int32{1080}, + 0x419 : []int32{1081}, + 0x41a : []int32{1082}, + 0x41b : []int32{1083}, + 0x41c : []int32{1084}, + 0x41d : []int32{1085}, + 0x41e : []int32{1086}, + 0x41f : []int32{1087}, + 0x420 : []int32{1088}, + 0x421 : []int32{1089}, + 0x422 : []int32{1090}, + 0x423 : []int32{1091}, + 0x424 : []int32{1092}, + 0x425 : []int32{1093}, + 0x426 : []int32{1094}, + 0x427 : []int32{1095}, + 0x428 : []int32{1096}, + 0x429 : []int32{1097}, + 0x42a : []int32{1098}, + 0x42b : []int32{1099}, + 0x42c : []int32{1100}, + 0x42d : []int32{1101}, + 0x42e : []int32{1102}, + 0x42f : []int32{1103}, + 0x460 : []int32{1121}, + 0x462 : []int32{1123}, + 0x464 : []int32{1125}, + 0x466 : []int32{1127}, + 0x468 : []int32{1129}, + 0x46a : []int32{1131}, + 0x46c : []int32{1133}, + 0x46e : []int32{1135}, + 0x470 : []int32{1137}, + 0x472 : []int32{1139}, + 0x474 : []int32{1141}, + 0x476 : []int32{1143}, + 0x478 : []int32{1145}, + 0x47a : []int32{1147}, + 0x47c : []int32{1149}, + 0x47e : []int32{1151}, + 0x480 : []int32{1153}, + 0x48a : []int32{1163}, + 0x48c : []int32{1165}, + 0x48e : []int32{1167}, + 0x490 : []int32{1169}, + 0x492 : []int32{1171}, + 0x494 : []int32{1173}, + 0x496 : []int32{1175}, + 0x498 : []int32{1177}, + 0x49a : []int32{1179}, + 0x49c : []int32{1181}, + 0x49e : []int32{1183}, + 0x4a0 : []int32{1185}, + 0x4a2 : []int32{1187}, + 0x4a4 : []int32{1189}, + 0x4a6 : []int32{1191}, + 0x4a8 : []int32{1193}, + 0x4aa : []int32{1195}, + 0x4ac : []int32{1197}, + 0x4ae : []int32{1199}, + 0x4b0 : []int32{1201}, + 0x4b2 : []int32{1203}, + 0x4b4 : []int32{1205}, + 0x4b6 : []int32{1207}, + 0x4b8 : []int32{1209}, + 0x4ba : []int32{1211}, + 0x4bc : []int32{1213}, + 0x4be : []int32{1215}, + 0x4c0 : []int32{1231}, + 0x4c1 : []int32{1218}, + 0x4c3 : []int32{1220}, + 0x4c5 : []int32{1222}, + 0x4c7 : []int32{1224}, + 0x4c9 : []int32{1226}, + 0x4cb : []int32{1228}, + 0x4cd : []int32{1230}, + 0x4d0 : []int32{1233}, + 0x4d2 : []int32{1235}, + 0x4d4 : []int32{1237}, + 0x4d6 : []int32{1239}, + 0x4d8 : []int32{1241}, + 0x4da : []int32{1243}, + 0x4dc : []int32{1245}, + 0x4de : []int32{1247}, + 0x4e0 : []int32{1249}, + 0x4e2 : []int32{1251}, + 0x4e4 : []int32{1253}, + 0x4e6 : []int32{1255}, + 0x4e8 : []int32{1257}, + 0x4ea : []int32{1259}, + 0x4ec : []int32{1261}, + 0x4ee : []int32{1263}, + 0x4f0 : []int32{1265}, + 0x4f2 : []int32{1267}, + 0x4f4 : []int32{1269}, + 0x4f6 : []int32{1271}, + 0x4f8 : []int32{1273}, + 0x4fa : []int32{1275}, + 0x4fc : []int32{1277}, + 0x4fe : []int32{1279}, + 0x500 : []int32{1281}, + 0x502 : []int32{1283}, + 0x504 : []int32{1285}, + 0x506 : []int32{1287}, + 0x508 : []int32{1289}, + 0x50a : []int32{1291}, + 0x50c : []int32{1293}, + 0x50e : []int32{1295}, + 0x510 : []int32{1297}, + 0x512 : []int32{1299}, + 0x514 : []int32{1301}, + 0x516 : []int32{1303}, + 0x518 : []int32{1305}, + 0x51a : []int32{1307}, + 0x51c : []int32{1309}, + 0x51e : []int32{1311}, + 0x520 : []int32{1313}, + 0x522 : []int32{1315}, + 0x524 : []int32{1317}, + 0x526 : []int32{1319}, + 0x528 : []int32{1321}, + 0x52a : []int32{1323}, + 0x52c : []int32{1325}, + 0x52e : []int32{1327}, + 0x531 : []int32{1377}, + 0x532 : []int32{1378}, + 0x533 : []int32{1379}, + 0x534 : []int32{1380}, + 0x535 : []int32{1381}, + 0x536 : []int32{1382}, + 0x537 : []int32{1383}, + 0x538 : []int32{1384}, + 0x539 : []int32{1385}, + 0x53a : []int32{1386}, + 0x53b : []int32{1387}, + 0x53c : []int32{1388}, + 0x53d : []int32{1389}, + 0x53e : []int32{1390}, + 0x53f : []int32{1391}, + 0x540 : []int32{1392}, + 0x541 : []int32{1393}, + 0x542 : []int32{1394}, + 0x543 : []int32{1395}, + 0x544 : []int32{1396}, + 0x545 : []int32{1397}, + 0x546 : []int32{1398}, + 0x547 : []int32{1399}, + 0x548 : []int32{1400}, + 0x549 : []int32{1401}, + 0x54a : []int32{1402}, + 0x54b : []int32{1403}, + 0x54c : []int32{1404}, + 0x54d : []int32{1405}, + 0x54e : []int32{1406}, + 0x54f : []int32{1407}, + 0x550 : []int32{1408}, + 0x551 : []int32{1409}, + 0x552 : []int32{1410}, + 0x553 : []int32{1411}, + 0x554 : []int32{1412}, + 0x555 : []int32{1413}, + 0x556 : []int32{1414}, + 0x587 : []int32{1381, 1410}, + 0x10a0 : []int32{11520}, + 0x10a1 : []int32{11521}, + 0x10a2 : []int32{11522}, + 0x10a3 : []int32{11523}, + 0x10a4 : []int32{11524}, + 0x10a5 : []int32{11525}, + 0x10a6 : []int32{11526}, + 0x10a7 : []int32{11527}, + 0x10a8 : []int32{11528}, + 0x10a9 : []int32{11529}, + 0x10aa : []int32{11530}, + 0x10ab : []int32{11531}, + 0x10ac : []int32{11532}, + 0x10ad : []int32{11533}, + 0x10ae : []int32{11534}, + 0x10af : []int32{11535}, + 0x10b0 : []int32{11536}, + 0x10b1 : []int32{11537}, + 0x10b2 : []int32{11538}, + 0x10b3 : []int32{11539}, + 0x10b4 : []int32{11540}, + 0x10b5 : []int32{11541}, + 0x10b6 : []int32{11542}, + 0x10b7 : []int32{11543}, + 0x10b8 : []int32{11544}, + 0x10b9 : []int32{11545}, + 0x10ba : []int32{11546}, + 0x10bb : []int32{11547}, + 0x10bc : []int32{11548}, + 0x10bd : []int32{11549}, + 0x10be : []int32{11550}, + 0x10bf : []int32{11551}, + 0x10c0 : []int32{11552}, + 0x10c1 : []int32{11553}, + 0x10c2 : []int32{11554}, + 0x10c3 : []int32{11555}, + 0x10c4 : []int32{11556}, + 0x10c5 : []int32{11557}, + 0x10c7 : []int32{11559}, + 0x10cd : []int32{11565}, + 0x13f8 : []int32{5104}, + 0x13f9 : []int32{5105}, + 0x13fa : []int32{5106}, + 0x13fb : []int32{5107}, + 0x13fc : []int32{5108}, + 0x13fd : []int32{5109}, + 0x1c80 : []int32{1074}, + 0x1c81 : []int32{1076}, + 0x1c82 : []int32{1086}, + 0x1c83 : []int32{1089}, + 0x1c84 : []int32{1090}, + 0x1c85 : []int32{1090}, + 0x1c86 : []int32{1098}, + 0x1c87 : []int32{1123}, + 0x1c88 : []int32{42571}, + 0x1c90 : []int32{4304}, + 0x1c91 : []int32{4305}, + 0x1c92 : []int32{4306}, + 0x1c93 : []int32{4307}, + 0x1c94 : []int32{4308}, + 0x1c95 : []int32{4309}, + 0x1c96 : []int32{4310}, + 0x1c97 : []int32{4311}, + 0x1c98 : []int32{4312}, + 0x1c99 : []int32{4313}, + 0x1c9a : []int32{4314}, + 0x1c9b : []int32{4315}, + 0x1c9c : []int32{4316}, + 0x1c9d : []int32{4317}, + 0x1c9e : []int32{4318}, + 0x1c9f : []int32{4319}, + 0x1ca0 : []int32{4320}, + 0x1ca1 : []int32{4321}, + 0x1ca2 : []int32{4322}, + 0x1ca3 : []int32{4323}, + 0x1ca4 : []int32{4324}, + 0x1ca5 : []int32{4325}, + 0x1ca6 : []int32{4326}, + 0x1ca7 : []int32{4327}, + 0x1ca8 : []int32{4328}, + 0x1ca9 : []int32{4329}, + 0x1caa : []int32{4330}, + 0x1cab : []int32{4331}, + 0x1cac : []int32{4332}, + 0x1cad : []int32{4333}, + 0x1cae : []int32{4334}, + 0x1caf : []int32{4335}, + 0x1cb0 : []int32{4336}, + 0x1cb1 : []int32{4337}, + 0x1cb2 : []int32{4338}, + 0x1cb3 : []int32{4339}, + 0x1cb4 : []int32{4340}, + 0x1cb5 : []int32{4341}, + 0x1cb6 : []int32{4342}, + 0x1cb7 : []int32{4343}, + 0x1cb8 : []int32{4344}, + 0x1cb9 : []int32{4345}, + 0x1cba : []int32{4346}, + 0x1cbd : []int32{4349}, + 0x1cbe : []int32{4350}, + 0x1cbf : []int32{4351}, + 0x1e00 : []int32{7681}, + 0x1e02 : []int32{7683}, + 0x1e04 : []int32{7685}, + 0x1e06 : []int32{7687}, + 0x1e08 : []int32{7689}, + 0x1e0a : []int32{7691}, + 0x1e0c : []int32{7693}, + 0x1e0e : []int32{7695}, + 0x1e10 : []int32{7697}, + 0x1e12 : []int32{7699}, + 0x1e14 : []int32{7701}, + 0x1e16 : []int32{7703}, + 0x1e18 : []int32{7705}, + 0x1e1a : []int32{7707}, + 0x1e1c : []int32{7709}, + 0x1e1e : []int32{7711}, + 0x1e20 : []int32{7713}, + 0x1e22 : []int32{7715}, + 0x1e24 : []int32{7717}, + 0x1e26 : []int32{7719}, + 0x1e28 : []int32{7721}, + 0x1e2a : []int32{7723}, + 0x1e2c : []int32{7725}, + 0x1e2e : []int32{7727}, + 0x1e30 : []int32{7729}, + 0x1e32 : []int32{7731}, + 0x1e34 : []int32{7733}, + 0x1e36 : []int32{7735}, + 0x1e38 : []int32{7737}, + 0x1e3a : []int32{7739}, + 0x1e3c : []int32{7741}, + 0x1e3e : []int32{7743}, + 0x1e40 : []int32{7745}, + 0x1e42 : []int32{7747}, + 0x1e44 : []int32{7749}, + 0x1e46 : []int32{7751}, + 0x1e48 : []int32{7753}, + 0x1e4a : []int32{7755}, + 0x1e4c : []int32{7757}, + 0x1e4e : []int32{7759}, + 0x1e50 : []int32{7761}, + 0x1e52 : []int32{7763}, + 0x1e54 : []int32{7765}, + 0x1e56 : []int32{7767}, + 0x1e58 : []int32{7769}, + 0x1e5a : []int32{7771}, + 0x1e5c : []int32{7773}, + 0x1e5e : []int32{7775}, + 0x1e60 : []int32{7777}, + 0x1e62 : []int32{7779}, + 0x1e64 : []int32{7781}, + 0x1e66 : []int32{7783}, + 0x1e68 : []int32{7785}, + 0x1e6a : []int32{7787}, + 0x1e6c : []int32{7789}, + 0x1e6e : []int32{7791}, + 0x1e70 : []int32{7793}, + 0x1e72 : []int32{7795}, + 0x1e74 : []int32{7797}, + 0x1e76 : []int32{7799}, + 0x1e78 : []int32{7801}, + 0x1e7a : []int32{7803}, + 0x1e7c : []int32{7805}, + 0x1e7e : []int32{7807}, + 0x1e80 : []int32{7809}, + 0x1e82 : []int32{7811}, + 0x1e84 : []int32{7813}, + 0x1e86 : []int32{7815}, + 0x1e88 : []int32{7817}, + 0x1e8a : []int32{7819}, + 0x1e8c : []int32{7821}, + 0x1e8e : []int32{7823}, + 0x1e90 : []int32{7825}, + 0x1e92 : []int32{7827}, + 0x1e94 : []int32{7829}, + 0x1e96 : []int32{104, 817}, + 0x1e97 : []int32{116, 776}, + 0x1e98 : []int32{119, 778}, + 0x1e99 : []int32{121, 778}, + 0x1e9a : []int32{97, 702}, + 0x1e9b : []int32{7777}, + 0x1e9e : []int32{115, 115}, + 0x1ea0 : []int32{7841}, + 0x1ea2 : []int32{7843}, + 0x1ea4 : []int32{7845}, + 0x1ea6 : []int32{7847}, + 0x1ea8 : []int32{7849}, + 0x1eaa : []int32{7851}, + 0x1eac : []int32{7853}, + 0x1eae : []int32{7855}, + 0x1eb0 : []int32{7857}, + 0x1eb2 : []int32{7859}, + 0x1eb4 : []int32{7861}, + 0x1eb6 : []int32{7863}, + 0x1eb8 : []int32{7865}, + 0x1eba : []int32{7867}, + 0x1ebc : []int32{7869}, + 0x1ebe : []int32{7871}, + 0x1ec0 : []int32{7873}, + 0x1ec2 : []int32{7875}, + 0x1ec4 : []int32{7877}, + 0x1ec6 : []int32{7879}, + 0x1ec8 : []int32{7881}, + 0x1eca : []int32{7883}, + 0x1ecc : []int32{7885}, + 0x1ece : []int32{7887}, + 0x1ed0 : []int32{7889}, + 0x1ed2 : []int32{7891}, + 0x1ed4 : []int32{7893}, + 0x1ed6 : []int32{7895}, + 0x1ed8 : []int32{7897}, + 0x1eda : []int32{7899}, + 0x1edc : []int32{7901}, + 0x1ede : []int32{7903}, + 0x1ee0 : []int32{7905}, + 0x1ee2 : []int32{7907}, + 0x1ee4 : []int32{7909}, + 0x1ee6 : []int32{7911}, + 0x1ee8 : []int32{7913}, + 0x1eea : []int32{7915}, + 0x1eec : []int32{7917}, + 0x1eee : []int32{7919}, + 0x1ef0 : []int32{7921}, + 0x1ef2 : []int32{7923}, + 0x1ef4 : []int32{7925}, + 0x1ef6 : []int32{7927}, + 0x1ef8 : []int32{7929}, + 0x1efa : []int32{7931}, + 0x1efc : []int32{7933}, + 0x1efe : []int32{7935}, + 0x1f08 : []int32{7936}, + 0x1f09 : []int32{7937}, + 0x1f0a : []int32{7938}, + 0x1f0b : []int32{7939}, + 0x1f0c : []int32{7940}, + 0x1f0d : []int32{7941}, + 0x1f0e : []int32{7942}, + 0x1f0f : []int32{7943}, + 0x1f18 : []int32{7952}, + 0x1f19 : []int32{7953}, + 0x1f1a : []int32{7954}, + 0x1f1b : []int32{7955}, + 0x1f1c : []int32{7956}, + 0x1f1d : []int32{7957}, + 0x1f28 : []int32{7968}, + 0x1f29 : []int32{7969}, + 0x1f2a : []int32{7970}, + 0x1f2b : []int32{7971}, + 0x1f2c : []int32{7972}, + 0x1f2d : []int32{7973}, + 0x1f2e : []int32{7974}, + 0x1f2f : []int32{7975}, + 0x1f38 : []int32{7984}, + 0x1f39 : []int32{7985}, + 0x1f3a : []int32{7986}, + 0x1f3b : []int32{7987}, + 0x1f3c : []int32{7988}, + 0x1f3d : []int32{7989}, + 0x1f3e : []int32{7990}, + 0x1f3f : []int32{7991}, + 0x1f48 : []int32{8000}, + 0x1f49 : []int32{8001}, + 0x1f4a : []int32{8002}, + 0x1f4b : []int32{8003}, + 0x1f4c : []int32{8004}, + 0x1f4d : []int32{8005}, + 0x1f50 : []int32{965, 787}, + 0x1f52 : []int32{965, 787, 768}, + 0x1f54 : []int32{965, 787, 769}, + 0x1f56 : []int32{965, 787, 834}, + 0x1f59 : []int32{8017}, + 0x1f5b : []int32{8019}, + 0x1f5d : []int32{8021}, + 0x1f5f : []int32{8023}, + 0x1f68 : []int32{8032}, + 0x1f69 : []int32{8033}, + 0x1f6a : []int32{8034}, + 0x1f6b : []int32{8035}, + 0x1f6c : []int32{8036}, + 0x1f6d : []int32{8037}, + 0x1f6e : []int32{8038}, + 0x1f6f : []int32{8039}, + 0x1f80 : []int32{7936, 953}, + 0x1f81 : []int32{7937, 953}, + 0x1f82 : []int32{7938, 953}, + 0x1f83 : []int32{7939, 953}, + 0x1f84 : []int32{7940, 953}, + 0x1f85 : []int32{7941, 953}, + 0x1f86 : []int32{7942, 953}, + 0x1f87 : []int32{7943, 953}, + 0x1f88 : []int32{7936, 953}, + 0x1f89 : []int32{7937, 953}, + 0x1f8a : []int32{7938, 953}, + 0x1f8b : []int32{7939, 953}, + 0x1f8c : []int32{7940, 953}, + 0x1f8d : []int32{7941, 953}, + 0x1f8e : []int32{7942, 953}, + 0x1f8f : []int32{7943, 953}, + 0x1f90 : []int32{7968, 953}, + 0x1f91 : []int32{7969, 953}, + 0x1f92 : []int32{7970, 953}, + 0x1f93 : []int32{7971, 953}, + 0x1f94 : []int32{7972, 953}, + 0x1f95 : []int32{7973, 953}, + 0x1f96 : []int32{7974, 953}, + 0x1f97 : []int32{7975, 953}, + 0x1f98 : []int32{7968, 953}, + 0x1f99 : []int32{7969, 953}, + 0x1f9a : []int32{7970, 953}, + 0x1f9b : []int32{7971, 953}, + 0x1f9c : []int32{7972, 953}, + 0x1f9d : []int32{7973, 953}, + 0x1f9e : []int32{7974, 953}, + 0x1f9f : []int32{7975, 953}, + 0x1fa0 : []int32{8032, 953}, + 0x1fa1 : []int32{8033, 953}, + 0x1fa2 : []int32{8034, 953}, + 0x1fa3 : []int32{8035, 953}, + 0x1fa4 : []int32{8036, 953}, + 0x1fa5 : []int32{8037, 953}, + 0x1fa6 : []int32{8038, 953}, + 0x1fa7 : []int32{8039, 953}, + 0x1fa8 : []int32{8032, 953}, + 0x1fa9 : []int32{8033, 953}, + 0x1faa : []int32{8034, 953}, + 0x1fab : []int32{8035, 953}, + 0x1fac : []int32{8036, 953}, + 0x1fad : []int32{8037, 953}, + 0x1fae : []int32{8038, 953}, + 0x1faf : []int32{8039, 953}, + 0x1fb2 : []int32{8048, 953}, + 0x1fb3 : []int32{945, 953}, + 0x1fb4 : []int32{940, 953}, + 0x1fb6 : []int32{945, 834}, + 0x1fb7 : []int32{945, 834, 953}, + 0x1fb8 : []int32{8112}, + 0x1fb9 : []int32{8113}, + 0x1fba : []int32{8048}, + 0x1fbb : []int32{8049}, + 0x1fbc : []int32{945, 953}, + 0x1fbe : []int32{953}, + 0x1fc2 : []int32{8052, 953}, + 0x1fc3 : []int32{951, 953}, + 0x1fc4 : []int32{942, 953}, + 0x1fc6 : []int32{951, 834}, + 0x1fc7 : []int32{951, 834, 953}, + 0x1fc8 : []int32{8050}, + 0x1fc9 : []int32{8051}, + 0x1fca : []int32{8052}, + 0x1fcb : []int32{8053}, + 0x1fcc : []int32{951, 953}, + 0x1fd2 : []int32{953, 776, 768}, + 0x1fd3 : []int32{953, 776, 769}, + 0x1fd6 : []int32{953, 834}, + 0x1fd7 : []int32{953, 776, 834}, + 0x1fd8 : []int32{8144}, + 0x1fd9 : []int32{8145}, + 0x1fda : []int32{8054}, + 0x1fdb : []int32{8055}, + 0x1fe2 : []int32{965, 776, 768}, + 0x1fe3 : []int32{965, 776, 769}, + 0x1fe4 : []int32{961, 787}, + 0x1fe6 : []int32{965, 834}, + 0x1fe7 : []int32{965, 776, 834}, + 0x1fe8 : []int32{8160}, + 0x1fe9 : []int32{8161}, + 0x1fea : []int32{8058}, + 0x1feb : []int32{8059}, + 0x1fec : []int32{8165}, + 0x1ff2 : []int32{8060, 953}, + 0x1ff3 : []int32{969, 953}, + 0x1ff4 : []int32{974, 953}, + 0x1ff6 : []int32{969, 834}, + 0x1ff7 : []int32{969, 834, 953}, + 0x1ff8 : []int32{8056}, + 0x1ff9 : []int32{8057}, + 0x1ffa : []int32{8060}, + 0x1ffb : []int32{8061}, + 0x1ffc : []int32{969, 953}, + 0x2126 : []int32{969}, + 0x212a : []int32{107}, + 0x212b : []int32{229}, + 0x2132 : []int32{8526}, + 0x2160 : []int32{8560}, + 0x2161 : []int32{8561}, + 0x2162 : []int32{8562}, + 0x2163 : []int32{8563}, + 0x2164 : []int32{8564}, + 0x2165 : []int32{8565}, + 0x2166 : []int32{8566}, + 0x2167 : []int32{8567}, + 0x2168 : []int32{8568}, + 0x2169 : []int32{8569}, + 0x216a : []int32{8570}, + 0x216b : []int32{8571}, + 0x216c : []int32{8572}, + 0x216d : []int32{8573}, + 0x216e : []int32{8574}, + 0x216f : []int32{8575}, + 0x2183 : []int32{8580}, + 0x24b6 : []int32{9424}, + 0x24b7 : []int32{9425}, + 0x24b8 : []int32{9426}, + 0x24b9 : []int32{9427}, + 0x24ba : []int32{9428}, + 0x24bb : []int32{9429}, + 0x24bc : []int32{9430}, + 0x24bd : []int32{9431}, + 0x24be : []int32{9432}, + 0x24bf : []int32{9433}, + 0x24c0 : []int32{9434}, + 0x24c1 : []int32{9435}, + 0x24c2 : []int32{9436}, + 0x24c3 : []int32{9437}, + 0x24c4 : []int32{9438}, + 0x24c5 : []int32{9439}, + 0x24c6 : []int32{9440}, + 0x24c7 : []int32{9441}, + 0x24c8 : []int32{9442}, + 0x24c9 : []int32{9443}, + 0x24ca : []int32{9444}, + 0x24cb : []int32{9445}, + 0x24cc : []int32{9446}, + 0x24cd : []int32{9447}, + 0x24ce : []int32{9448}, + 0x24cf : []int32{9449}, + 0x2c00 : []int32{11312}, + 0x2c01 : []int32{11313}, + 0x2c02 : []int32{11314}, + 0x2c03 : []int32{11315}, + 0x2c04 : []int32{11316}, + 0x2c05 : []int32{11317}, + 0x2c06 : []int32{11318}, + 0x2c07 : []int32{11319}, + 0x2c08 : []int32{11320}, + 0x2c09 : []int32{11321}, + 0x2c0a : []int32{11322}, + 0x2c0b : []int32{11323}, + 0x2c0c : []int32{11324}, + 0x2c0d : []int32{11325}, + 0x2c0e : []int32{11326}, + 0x2c0f : []int32{11327}, + 0x2c10 : []int32{11328}, + 0x2c11 : []int32{11329}, + 0x2c12 : []int32{11330}, + 0x2c13 : []int32{11331}, + 0x2c14 : []int32{11332}, + 0x2c15 : []int32{11333}, + 0x2c16 : []int32{11334}, + 0x2c17 : []int32{11335}, + 0x2c18 : []int32{11336}, + 0x2c19 : []int32{11337}, + 0x2c1a : []int32{11338}, + 0x2c1b : []int32{11339}, + 0x2c1c : []int32{11340}, + 0x2c1d : []int32{11341}, + 0x2c1e : []int32{11342}, + 0x2c1f : []int32{11343}, + 0x2c20 : []int32{11344}, + 0x2c21 : []int32{11345}, + 0x2c22 : []int32{11346}, + 0x2c23 : []int32{11347}, + 0x2c24 : []int32{11348}, + 0x2c25 : []int32{11349}, + 0x2c26 : []int32{11350}, + 0x2c27 : []int32{11351}, + 0x2c28 : []int32{11352}, + 0x2c29 : []int32{11353}, + 0x2c2a : []int32{11354}, + 0x2c2b : []int32{11355}, + 0x2c2c : []int32{11356}, + 0x2c2d : []int32{11357}, + 0x2c2e : []int32{11358}, + 0x2c2f : []int32{11359}, + 0x2c60 : []int32{11361}, + 0x2c62 : []int32{619}, + 0x2c63 : []int32{7549}, + 0x2c64 : []int32{637}, + 0x2c67 : []int32{11368}, + 0x2c69 : []int32{11370}, + 0x2c6b : []int32{11372}, + 0x2c6d : []int32{593}, + 0x2c6e : []int32{625}, + 0x2c6f : []int32{592}, + 0x2c70 : []int32{594}, + 0x2c72 : []int32{11379}, + 0x2c75 : []int32{11382}, + 0x2c7e : []int32{575}, + 0x2c7f : []int32{576}, + 0x2c80 : []int32{11393}, + 0x2c82 : []int32{11395}, + 0x2c84 : []int32{11397}, + 0x2c86 : []int32{11399}, + 0x2c88 : []int32{11401}, + 0x2c8a : []int32{11403}, + 0x2c8c : []int32{11405}, + 0x2c8e : []int32{11407}, + 0x2c90 : []int32{11409}, + 0x2c92 : []int32{11411}, + 0x2c94 : []int32{11413}, + 0x2c96 : []int32{11415}, + 0x2c98 : []int32{11417}, + 0x2c9a : []int32{11419}, + 0x2c9c : []int32{11421}, + 0x2c9e : []int32{11423}, + 0x2ca0 : []int32{11425}, + 0x2ca2 : []int32{11427}, + 0x2ca4 : []int32{11429}, + 0x2ca6 : []int32{11431}, + 0x2ca8 : []int32{11433}, + 0x2caa : []int32{11435}, + 0x2cac : []int32{11437}, + 0x2cae : []int32{11439}, + 0x2cb0 : []int32{11441}, + 0x2cb2 : []int32{11443}, + 0x2cb4 : []int32{11445}, + 0x2cb6 : []int32{11447}, + 0x2cb8 : []int32{11449}, + 0x2cba : []int32{11451}, + 0x2cbc : []int32{11453}, + 0x2cbe : []int32{11455}, + 0x2cc0 : []int32{11457}, + 0x2cc2 : []int32{11459}, + 0x2cc4 : []int32{11461}, + 0x2cc6 : []int32{11463}, + 0x2cc8 : []int32{11465}, + 0x2cca : []int32{11467}, + 0x2ccc : []int32{11469}, + 0x2cce : []int32{11471}, + 0x2cd0 : []int32{11473}, + 0x2cd2 : []int32{11475}, + 0x2cd4 : []int32{11477}, + 0x2cd6 : []int32{11479}, + 0x2cd8 : []int32{11481}, + 0x2cda : []int32{11483}, + 0x2cdc : []int32{11485}, + 0x2cde : []int32{11487}, + 0x2ce0 : []int32{11489}, + 0x2ce2 : []int32{11491}, + 0x2ceb : []int32{11500}, + 0x2ced : []int32{11502}, + 0x2cf2 : []int32{11507}, + 0xa640 : []int32{42561}, + 0xa642 : []int32{42563}, + 0xa644 : []int32{42565}, + 0xa646 : []int32{42567}, + 0xa648 : []int32{42569}, + 0xa64a : []int32{42571}, + 0xa64c : []int32{42573}, + 0xa64e : []int32{42575}, + 0xa650 : []int32{42577}, + 0xa652 : []int32{42579}, + 0xa654 : []int32{42581}, + 0xa656 : []int32{42583}, + 0xa658 : []int32{42585}, + 0xa65a : []int32{42587}, + 0xa65c : []int32{42589}, + 0xa65e : []int32{42591}, + 0xa660 : []int32{42593}, + 0xa662 : []int32{42595}, + 0xa664 : []int32{42597}, + 0xa666 : []int32{42599}, + 0xa668 : []int32{42601}, + 0xa66a : []int32{42603}, + 0xa66c : []int32{42605}, + 0xa680 : []int32{42625}, + 0xa682 : []int32{42627}, + 0xa684 : []int32{42629}, + 0xa686 : []int32{42631}, + 0xa688 : []int32{42633}, + 0xa68a : []int32{42635}, + 0xa68c : []int32{42637}, + 0xa68e : []int32{42639}, + 0xa690 : []int32{42641}, + 0xa692 : []int32{42643}, + 0xa694 : []int32{42645}, + 0xa696 : []int32{42647}, + 0xa698 : []int32{42649}, + 0xa69a : []int32{42651}, + 0xa722 : []int32{42787}, + 0xa724 : []int32{42789}, + 0xa726 : []int32{42791}, + 0xa728 : []int32{42793}, + 0xa72a : []int32{42795}, + 0xa72c : []int32{42797}, + 0xa72e : []int32{42799}, + 0xa732 : []int32{42803}, + 0xa734 : []int32{42805}, + 0xa736 : []int32{42807}, + 0xa738 : []int32{42809}, + 0xa73a : []int32{42811}, + 0xa73c : []int32{42813}, + 0xa73e : []int32{42815}, + 0xa740 : []int32{42817}, + 0xa742 : []int32{42819}, + 0xa744 : []int32{42821}, + 0xa746 : []int32{42823}, + 0xa748 : []int32{42825}, + 0xa74a : []int32{42827}, + 0xa74c : []int32{42829}, + 0xa74e : []int32{42831}, + 0xa750 : []int32{42833}, + 0xa752 : []int32{42835}, + 0xa754 : []int32{42837}, + 0xa756 : []int32{42839}, + 0xa758 : []int32{42841}, + 0xa75a : []int32{42843}, + 0xa75c : []int32{42845}, + 0xa75e : []int32{42847}, + 0xa760 : []int32{42849}, + 0xa762 : []int32{42851}, + 0xa764 : []int32{42853}, + 0xa766 : []int32{42855}, + 0xa768 : []int32{42857}, + 0xa76a : []int32{42859}, + 0xa76c : []int32{42861}, + 0xa76e : []int32{42863}, + 0xa779 : []int32{42874}, + 0xa77b : []int32{42876}, + 0xa77d : []int32{7545}, + 0xa77e : []int32{42879}, + 0xa780 : []int32{42881}, + 0xa782 : []int32{42883}, + 0xa784 : []int32{42885}, + 0xa786 : []int32{42887}, + 0xa78b : []int32{42892}, + 0xa78d : []int32{613}, + 0xa790 : []int32{42897}, + 0xa792 : []int32{42899}, + 0xa796 : []int32{42903}, + 0xa798 : []int32{42905}, + 0xa79a : []int32{42907}, + 0xa79c : []int32{42909}, + 0xa79e : []int32{42911}, + 0xa7a0 : []int32{42913}, + 0xa7a2 : []int32{42915}, + 0xa7a4 : []int32{42917}, + 0xa7a6 : []int32{42919}, + 0xa7a8 : []int32{42921}, + 0xa7aa : []int32{614}, + 0xa7ab : []int32{604}, + 0xa7ac : []int32{609}, + 0xa7ad : []int32{620}, + 0xa7ae : []int32{618}, + 0xa7b0 : []int32{670}, + 0xa7b1 : []int32{647}, + 0xa7b2 : []int32{669}, + 0xa7b3 : []int32{43859}, + 0xa7b4 : []int32{42933}, + 0xa7b6 : []int32{42935}, + 0xa7b8 : []int32{42937}, + 0xa7ba : []int32{42939}, + 0xa7bc : []int32{42941}, + 0xa7be : []int32{42943}, + 0xa7c0 : []int32{42945}, + 0xa7c2 : []int32{42947}, + 0xa7c4 : []int32{42900}, + 0xa7c5 : []int32{642}, + 0xa7c6 : []int32{7566}, + 0xa7c7 : []int32{42952}, + 0xa7c9 : []int32{42954}, + 0xa7d0 : []int32{42961}, + 0xa7d6 : []int32{42967}, + 0xa7d8 : []int32{42969}, + 0xa7f5 : []int32{42998}, + 0xab70 : []int32{5024}, + 0xab71 : []int32{5025}, + 0xab72 : []int32{5026}, + 0xab73 : []int32{5027}, + 0xab74 : []int32{5028}, + 0xab75 : []int32{5029}, + 0xab76 : []int32{5030}, + 0xab77 : []int32{5031}, + 0xab78 : []int32{5032}, + 0xab79 : []int32{5033}, + 0xab7a : []int32{5034}, + 0xab7b : []int32{5035}, + 0xab7c : []int32{5036}, + 0xab7d : []int32{5037}, + 0xab7e : []int32{5038}, + 0xab7f : []int32{5039}, + 0xab80 : []int32{5040}, + 0xab81 : []int32{5041}, + 0xab82 : []int32{5042}, + 0xab83 : []int32{5043}, + 0xab84 : []int32{5044}, + 0xab85 : []int32{5045}, + 0xab86 : []int32{5046}, + 0xab87 : []int32{5047}, + 0xab88 : []int32{5048}, + 0xab89 : []int32{5049}, + 0xab8a : []int32{5050}, + 0xab8b : []int32{5051}, + 0xab8c : []int32{5052}, + 0xab8d : []int32{5053}, + 0xab8e : []int32{5054}, + 0xab8f : []int32{5055}, + 0xab90 : []int32{5056}, + 0xab91 : []int32{5057}, + 0xab92 : []int32{5058}, + 0xab93 : []int32{5059}, + 0xab94 : []int32{5060}, + 0xab95 : []int32{5061}, + 0xab96 : []int32{5062}, + 0xab97 : []int32{5063}, + 0xab98 : []int32{5064}, + 0xab99 : []int32{5065}, + 0xab9a : []int32{5066}, + 0xab9b : []int32{5067}, + 0xab9c : []int32{5068}, + 0xab9d : []int32{5069}, + 0xab9e : []int32{5070}, + 0xab9f : []int32{5071}, + 0xaba0 : []int32{5072}, + 0xaba1 : []int32{5073}, + 0xaba2 : []int32{5074}, + 0xaba3 : []int32{5075}, + 0xaba4 : []int32{5076}, + 0xaba5 : []int32{5077}, + 0xaba6 : []int32{5078}, + 0xaba7 : []int32{5079}, + 0xaba8 : []int32{5080}, + 0xaba9 : []int32{5081}, + 0xabaa : []int32{5082}, + 0xabab : []int32{5083}, + 0xabac : []int32{5084}, + 0xabad : []int32{5085}, + 0xabae : []int32{5086}, + 0xabaf : []int32{5087}, + 0xabb0 : []int32{5088}, + 0xabb1 : []int32{5089}, + 0xabb2 : []int32{5090}, + 0xabb3 : []int32{5091}, + 0xabb4 : []int32{5092}, + 0xabb5 : []int32{5093}, + 0xabb6 : []int32{5094}, + 0xabb7 : []int32{5095}, + 0xabb8 : []int32{5096}, + 0xabb9 : []int32{5097}, + 0xabba : []int32{5098}, + 0xabbb : []int32{5099}, + 0xabbc : []int32{5100}, + 0xabbd : []int32{5101}, + 0xabbe : []int32{5102}, + 0xabbf : []int32{5103}, + 0xfb00 : []int32{102, 102}, + 0xfb01 : []int32{102, 105}, + 0xfb02 : []int32{102, 108}, + 0xfb03 : []int32{102, 102, 105}, + 0xfb04 : []int32{102, 102, 108}, + 0xfb05 : []int32{115, 116}, + 0xfb06 : []int32{115, 116}, + 0xfb13 : []int32{1396, 1398}, + 0xfb14 : []int32{1396, 1381}, + 0xfb15 : []int32{1396, 1387}, + 0xfb16 : []int32{1406, 1398}, + 0xfb17 : []int32{1396, 1389}, + 0xff21 : []int32{65345}, + 0xff22 : []int32{65346}, + 0xff23 : []int32{65347}, + 0xff24 : []int32{65348}, + 0xff25 : []int32{65349}, + 0xff26 : []int32{65350}, + 0xff27 : []int32{65351}, + 0xff28 : []int32{65352}, + 0xff29 : []int32{65353}, + 0xff2a : []int32{65354}, + 0xff2b : []int32{65355}, + 0xff2c : []int32{65356}, + 0xff2d : []int32{65357}, + 0xff2e : []int32{65358}, + 0xff2f : []int32{65359}, + 0xff30 : []int32{65360}, + 0xff31 : []int32{65361}, + 0xff32 : []int32{65362}, + 0xff33 : []int32{65363}, + 0xff34 : []int32{65364}, + 0xff35 : []int32{65365}, + 0xff36 : []int32{65366}, + 0xff37 : []int32{65367}, + 0xff38 : []int32{65368}, + 0xff39 : []int32{65369}, + 0xff3a : []int32{65370}, + 0x10400 : []int32{66600}, + 0x10401 : []int32{66601}, + 0x10402 : []int32{66602}, + 0x10403 : []int32{66603}, + 0x10404 : []int32{66604}, + 0x10405 : []int32{66605}, + 0x10406 : []int32{66606}, + 0x10407 : []int32{66607}, + 0x10408 : []int32{66608}, + 0x10409 : []int32{66609}, + 0x1040a : []int32{66610}, + 0x1040b : []int32{66611}, + 0x1040c : []int32{66612}, + 0x1040d : []int32{66613}, + 0x1040e : []int32{66614}, + 0x1040f : []int32{66615}, + 0x10410 : []int32{66616}, + 0x10411 : []int32{66617}, + 0x10412 : []int32{66618}, + 0x10413 : []int32{66619}, + 0x10414 : []int32{66620}, + 0x10415 : []int32{66621}, + 0x10416 : []int32{66622}, + 0x10417 : []int32{66623}, + 0x10418 : []int32{66624}, + 0x10419 : []int32{66625}, + 0x1041a : []int32{66626}, + 0x1041b : []int32{66627}, + 0x1041c : []int32{66628}, + 0x1041d : []int32{66629}, + 0x1041e : []int32{66630}, + 0x1041f : []int32{66631}, + 0x10420 : []int32{66632}, + 0x10421 : []int32{66633}, + 0x10422 : []int32{66634}, + 0x10423 : []int32{66635}, + 0x10424 : []int32{66636}, + 0x10425 : []int32{66637}, + 0x10426 : []int32{66638}, + 0x10427 : []int32{66639}, + 0x104b0 : []int32{66776}, + 0x104b1 : []int32{66777}, + 0x104b2 : []int32{66778}, + 0x104b3 : []int32{66779}, + 0x104b4 : []int32{66780}, + 0x104b5 : []int32{66781}, + 0x104b6 : []int32{66782}, + 0x104b7 : []int32{66783}, + 0x104b8 : []int32{66784}, + 0x104b9 : []int32{66785}, + 0x104ba : []int32{66786}, + 0x104bb : []int32{66787}, + 0x104bc : []int32{66788}, + 0x104bd : []int32{66789}, + 0x104be : []int32{66790}, + 0x104bf : []int32{66791}, + 0x104c0 : []int32{66792}, + 0x104c1 : []int32{66793}, + 0x104c2 : []int32{66794}, + 0x104c3 : []int32{66795}, + 0x104c4 : []int32{66796}, + 0x104c5 : []int32{66797}, + 0x104c6 : []int32{66798}, + 0x104c7 : []int32{66799}, + 0x104c8 : []int32{66800}, + 0x104c9 : []int32{66801}, + 0x104ca : []int32{66802}, + 0x104cb : []int32{66803}, + 0x104cc : []int32{66804}, + 0x104cd : []int32{66805}, + 0x104ce : []int32{66806}, + 0x104cf : []int32{66807}, + 0x104d0 : []int32{66808}, + 0x104d1 : []int32{66809}, + 0x104d2 : []int32{66810}, + 0x104d3 : []int32{66811}, + 0x10570 : []int32{66967}, + 0x10571 : []int32{66968}, + 0x10572 : []int32{66969}, + 0x10573 : []int32{66970}, + 0x10574 : []int32{66971}, + 0x10575 : []int32{66972}, + 0x10576 : []int32{66973}, + 0x10577 : []int32{66974}, + 0x10578 : []int32{66975}, + 0x10579 : []int32{66976}, + 0x1057a : []int32{66977}, + 0x1057c : []int32{66979}, + 0x1057d : []int32{66980}, + 0x1057e : []int32{66981}, + 0x1057f : []int32{66982}, + 0x10580 : []int32{66983}, + 0x10581 : []int32{66984}, + 0x10582 : []int32{66985}, + 0x10583 : []int32{66986}, + 0x10584 : []int32{66987}, + 0x10585 : []int32{66988}, + 0x10586 : []int32{66989}, + 0x10587 : []int32{66990}, + 0x10588 : []int32{66991}, + 0x10589 : []int32{66992}, + 0x1058a : []int32{66993}, + 0x1058c : []int32{66995}, + 0x1058d : []int32{66996}, + 0x1058e : []int32{66997}, + 0x1058f : []int32{66998}, + 0x10590 : []int32{66999}, + 0x10591 : []int32{67000}, + 0x10592 : []int32{67001}, + 0x10594 : []int32{67003}, + 0x10595 : []int32{67004}, + 0x10c80 : []int32{68800}, + 0x10c81 : []int32{68801}, + 0x10c82 : []int32{68802}, + 0x10c83 : []int32{68803}, + 0x10c84 : []int32{68804}, + 0x10c85 : []int32{68805}, + 0x10c86 : []int32{68806}, + 0x10c87 : []int32{68807}, + 0x10c88 : []int32{68808}, + 0x10c89 : []int32{68809}, + 0x10c8a : []int32{68810}, + 0x10c8b : []int32{68811}, + 0x10c8c : []int32{68812}, + 0x10c8d : []int32{68813}, + 0x10c8e : []int32{68814}, + 0x10c8f : []int32{68815}, + 0x10c90 : []int32{68816}, + 0x10c91 : []int32{68817}, + 0x10c92 : []int32{68818}, + 0x10c93 : []int32{68819}, + 0x10c94 : []int32{68820}, + 0x10c95 : []int32{68821}, + 0x10c96 : []int32{68822}, + 0x10c97 : []int32{68823}, + 0x10c98 : []int32{68824}, + 0x10c99 : []int32{68825}, + 0x10c9a : []int32{68826}, + 0x10c9b : []int32{68827}, + 0x10c9c : []int32{68828}, + 0x10c9d : []int32{68829}, + 0x10c9e : []int32{68830}, + 0x10c9f : []int32{68831}, + 0x10ca0 : []int32{68832}, + 0x10ca1 : []int32{68833}, + 0x10ca2 : []int32{68834}, + 0x10ca3 : []int32{68835}, + 0x10ca4 : []int32{68836}, + 0x10ca5 : []int32{68837}, + 0x10ca6 : []int32{68838}, + 0x10ca7 : []int32{68839}, + 0x10ca8 : []int32{68840}, + 0x10ca9 : []int32{68841}, + 0x10caa : []int32{68842}, + 0x10cab : []int32{68843}, + 0x10cac : []int32{68844}, + 0x10cad : []int32{68845}, + 0x10cae : []int32{68846}, + 0x10caf : []int32{68847}, + 0x10cb0 : []int32{68848}, + 0x10cb1 : []int32{68849}, + 0x10cb2 : []int32{68850}, + 0x118a0 : []int32{71872}, + 0x118a1 : []int32{71873}, + 0x118a2 : []int32{71874}, + 0x118a3 : []int32{71875}, + 0x118a4 : []int32{71876}, + 0x118a5 : []int32{71877}, + 0x118a6 : []int32{71878}, + 0x118a7 : []int32{71879}, + 0x118a8 : []int32{71880}, + 0x118a9 : []int32{71881}, + 0x118aa : []int32{71882}, + 0x118ab : []int32{71883}, + 0x118ac : []int32{71884}, + 0x118ad : []int32{71885}, + 0x118ae : []int32{71886}, + 0x118af : []int32{71887}, + 0x118b0 : []int32{71888}, + 0x118b1 : []int32{71889}, + 0x118b2 : []int32{71890}, + 0x118b3 : []int32{71891}, + 0x118b4 : []int32{71892}, + 0x118b5 : []int32{71893}, + 0x118b6 : []int32{71894}, + 0x118b7 : []int32{71895}, + 0x118b8 : []int32{71896}, + 0x118b9 : []int32{71897}, + 0x118ba : []int32{71898}, + 0x118bb : []int32{71899}, + 0x118bc : []int32{71900}, + 0x118bd : []int32{71901}, + 0x118be : []int32{71902}, + 0x118bf : []int32{71903}, + 0x16e40 : []int32{93792}, + 0x16e41 : []int32{93793}, + 0x16e42 : []int32{93794}, + 0x16e43 : []int32{93795}, + 0x16e44 : []int32{93796}, + 0x16e45 : []int32{93797}, + 0x16e46 : []int32{93798}, + 0x16e47 : []int32{93799}, + 0x16e48 : []int32{93800}, + 0x16e49 : []int32{93801}, + 0x16e4a : []int32{93802}, + 0x16e4b : []int32{93803}, + 0x16e4c : []int32{93804}, + 0x16e4d : []int32{93805}, + 0x16e4e : []int32{93806}, + 0x16e4f : []int32{93807}, + 0x16e50 : []int32{93808}, + 0x16e51 : []int32{93809}, + 0x16e52 : []int32{93810}, + 0x16e53 : []int32{93811}, + 0x16e54 : []int32{93812}, + 0x16e55 : []int32{93813}, + 0x16e56 : []int32{93814}, + 0x16e57 : []int32{93815}, + 0x16e58 : []int32{93816}, + 0x16e59 : []int32{93817}, + 0x16e5a : []int32{93818}, + 0x16e5b : []int32{93819}, + 0x16e5c : []int32{93820}, + 0x16e5d : []int32{93821}, + 0x16e5e : []int32{93822}, + 0x16e5f : []int32{93823}, + 0x1e900 : []int32{125218}, + 0x1e901 : []int32{125219}, + 0x1e902 : []int32{125220}, + 0x1e903 : []int32{125221}, + 0x1e904 : []int32{125222}, + 0x1e905 : []int32{125223}, + 0x1e906 : []int32{125224}, + 0x1e907 : []int32{125225}, + 0x1e908 : []int32{125226}, + 0x1e909 : []int32{125227}, + 0x1e90a : []int32{125228}, + 0x1e90b : []int32{125229}, + 0x1e90c : []int32{125230}, + 0x1e90d : []int32{125231}, + 0x1e90e : []int32{125232}, + 0x1e90f : []int32{125233}, + 0x1e910 : []int32{125234}, + 0x1e911 : []int32{125235}, + 0x1e912 : []int32{125236}, + 0x1e913 : []int32{125237}, + 0x1e914 : []int32{125238}, + 0x1e915 : []int32{125239}, + 0x1e916 : []int32{125240}, + 0x1e917 : []int32{125241}, + 0x1e918 : []int32{125242}, + 0x1e919 : []int32{125243}, + 0x1e91a : []int32{125244}, + 0x1e91b : []int32{125245}, + 0x1e91c : []int32{125246}, + 0x1e91d : []int32{125247}, + 0x1e91e : []int32{125248}, + 0x1e91f : []int32{125249}, + 0x1e920 : []int32{125250}, + 0x1e921 : []int32{125251}, } diff --git a/vendor/github.com/yuin/goldmark/util/util.go b/vendor/github.com/yuin/goldmark/util/util.go index ef113c4ae..a817ec630 100644 --- a/vendor/github.com/yuin/goldmark/util/util.go +++ b/vendor/github.com/yuin/goldmark/util/util.go @@ -8,6 +8,7 @@ import ( "regexp" "sort" "strconv" + "unicode" "unicode/utf8" ) @@ -27,6 +28,7 @@ func NewCopyOnWriteBuffer(buffer []byte) CopyOnWriteBuffer { } // Write writes given bytes to the buffer. +// Write allocate new buffer and clears it at the first time. func (b *CopyOnWriteBuffer) Write(value []byte) { if !b.copied { b.buffer = make([]byte, 0, len(b.buffer)+20) @@ -35,7 +37,32 @@ func (b *CopyOnWriteBuffer) Write(value []byte) { b.buffer = append(b.buffer, value...) } +// WriteString writes given string to the buffer. +// WriteString allocate new buffer and clears it at the first time. +func (b *CopyOnWriteBuffer) WriteString(value string) { + b.Write(StringToReadOnlyBytes(value)) +} + +// Append appends given bytes to the buffer. +// Append copy buffer at the first time. +func (b *CopyOnWriteBuffer) Append(value []byte) { + if !b.copied { + tmp := make([]byte, len(b.buffer), len(b.buffer)+20) + copy(tmp, b.buffer) + b.buffer = tmp + b.copied = true + } + b.buffer = append(b.buffer, value...) +} + +// AppendString appends given string to the buffer. +// AppendString copy buffer at the first time. +func (b *CopyOnWriteBuffer) AppendString(value string) { + b.Append(StringToReadOnlyBytes(value)) +} + // WriteByte writes the given byte to the buffer. +// WriteByte allocate new buffer and clears it at the first time. func (b *CopyOnWriteBuffer) WriteByte(c byte) { if !b.copied { b.buffer = make([]byte, 0, len(b.buffer)+20) @@ -44,6 +71,18 @@ func (b *CopyOnWriteBuffer) WriteByte(c byte) { b.buffer = append(b.buffer, c) } +// AppendByte appends given bytes to the buffer. +// AppendByte copy buffer at the first time. +func (b *CopyOnWriteBuffer) AppendByte(c byte) { + if !b.copied { + tmp := make([]byte, len(b.buffer), len(b.buffer)+20) + copy(tmp, b.buffer) + b.buffer = tmp + b.copied = true + } + b.buffer = append(b.buffer, c) +} + // Bytes returns bytes of this buffer. func (b *CopyOnWriteBuffer) Bytes() []byte { return b.buffer @@ -91,6 +130,9 @@ func VisualizeSpaces(bs []byte) []byte { bs = bytes.Replace(bs, []byte("\t"), []byte("[TAB]"), -1) bs = bytes.Replace(bs, []byte("\n"), []byte("[NEWLINE]\n"), -1) bs = bytes.Replace(bs, []byte("\r"), []byte("[CR]"), -1) + bs = bytes.Replace(bs, []byte("\v"), []byte("[VTAB]"), -1) + bs = bytes.Replace(bs, []byte("\x00"), []byte("[NUL]"), -1) + bs = bytes.Replace(bs, []byte("\ufffd"), []byte("[U+FFFD]"), -1) return bs } @@ -110,30 +152,7 @@ func TabWidth(currentPos int) int { // width=2 is in the tab character. In this case, IndentPosition returns // (pos=1, padding=2) func IndentPosition(bs []byte, currentPos, width int) (pos, padding int) { - if width == 0 { - return 0, 0 - } - w := 0 - l := len(bs) - i := 0 - hasTab := false - for ; i < l; i++ { - if bs[i] == '\t' { - w += TabWidth(currentPos + w) - hasTab = true - } else if bs[i] == ' ' { - w++ - } else { - break - } - } - if w >= width { - if !hasTab { - return width, 0 - } - return i, w - width - } - return -1, -1 + return IndentPositionPadding(bs, currentPos, 0, width) } // IndentPositionPadding searches an indent position with the given width for the given line. @@ -147,9 +166,9 @@ func IndentPositionPadding(bs []byte, currentPos, paddingv, width int) (pos, pad i := 0 l := len(bs) for ; i < l; i++ { - if bs[i] == '\t' { + if bs[i] == '\t' && w < width { w += TabWidth(currentPos + w) - } else if bs[i] == ' ' { + } else if bs[i] == ' ' && w < width { w++ } else { break @@ -162,52 +181,56 @@ func IndentPositionPadding(bs []byte, currentPos, paddingv, width int) (pos, pad } // DedentPosition dedents lines by the given width. +// +// Deprecated: This function has bugs. Use util.IndentPositionPadding and util.FirstNonSpacePosition. func DedentPosition(bs []byte, currentPos, width int) (pos, padding int) { - if width == 0 { - return 0, 0 - } - w := 0 - l := len(bs) - i := 0 - for ; i < l; i++ { - if bs[i] == '\t' { - w += TabWidth(currentPos + w) - } else if bs[i] == ' ' { - w++ - } else { - break - } - } - if w >= width { - return i, w - width - } - return i, 0 + if width == 0 { + return 0, 0 + } + w := 0 + l := len(bs) + i := 0 + for ; i < l; i++ { + if bs[i] == '\t' { + w += TabWidth(currentPos + w) + } else if bs[i] == ' ' { + w++ + } else { + break + } + } + if w >= width { + return i, w - width + } + return i, 0 } // DedentPositionPadding dedents lines by the given width. // This function is mostly same as DedentPosition except this function // takes account into additional paddings. +// +// Deprecated: This function has bugs. Use util.IndentPositionPadding and util.FirstNonSpacePosition. func DedentPositionPadding(bs []byte, currentPos, paddingv, width int) (pos, padding int) { - if width == 0 { - return 0, paddingv - } - - w := 0 - i := 0 - l := len(bs) - for ; i < l; i++ { - if bs[i] == '\t' { - w += TabWidth(currentPos + w) - } else if bs[i] == ' ' { - w++ - } else { - break - } - } - if w >= width { - return i - paddingv, w - width - } - return i - paddingv, 0 + if width == 0 { + return 0, paddingv + } + + w := 0 + i := 0 + l := len(bs) + for ; i < l; i++ { + if bs[i] == '\t' { + w += TabWidth(currentPos + w) + } else if bs[i] == ' ' { + w++ + } else { + break + } + } + if w >= width { + return i - paddingv, w - width + } + return i - paddingv, 0 } // IndentWidth calculate an indent width for the given line. @@ -249,6 +272,10 @@ func FirstNonSpacePosition(bs []byte) int { // If codeSpan is set true, it ignores characters in code spans. // If allowNesting is set true, closures correspond to nested opener will be // ignored. +// +// Deprecated: This function can not handle newlines. Many elements +// can be existed over multiple lines(e.g. link labels). +// Use text.Reader.FindClosure. func FindClosure(bs []byte, opener, closure byte, codeSpan, allowNesting bool) int { i := 0 opened := 1 @@ -668,7 +695,7 @@ func URLEscape(v []byte, resolveReference bool) []byte { n = i continue } - if int(u8len) >= len(v) { + if int(u8len) > len(v) { u8len = int8(len(v) - 1) } if u8len == 0 { @@ -754,7 +781,7 @@ func FindEmailIndex(b []byte) int { var spaces = []byte(" \t\n\x0b\x0c\x0d") -var spaceTable = [256]int8{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +var spaceTable = [256]int8{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} var punctTable = [256]int8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} @@ -777,11 +804,21 @@ func IsPunct(c byte) bool { return punctTable[c] == 1 } +// IsPunctRune returns true if the given rune is a punctuation, otherwise false. +func IsPunctRune(r rune) bool { + return int32(r) <= 256 && IsPunct(byte(r)) || unicode.IsPunct(r) +} + // IsSpace returns true if the given character is a space, otherwise false. func IsSpace(c byte) bool { return spaceTable[c] == 1 } +// IsSpaceRune returns true if the given rune is a space, otherwise false. +func IsSpaceRune(r rune) bool { + return int32(r) <= 256 && IsSpace(byte(r)) || unicode.IsSpace(r) +} + // IsNumeric returns true if the given character is a numeric, otherwise false. func IsNumeric(c byte) bool { return c >= '0' && c <= '9' diff --git a/vendor/github.com/yuin/goldmark/util/util_unsafe.go b/vendor/github.com/yuin/goldmark/util/util_unsafe.go index beeae2936..d09881104 100644 --- a/vendor/github.com/yuin/goldmark/util/util_unsafe.go +++ b/vendor/github.com/yuin/goldmark/util/util_unsafe.go @@ -13,8 +13,11 @@ func BytesToReadOnlyString(b []byte) string { } // StringToReadOnlyBytes returns bytes converted from given string. -func StringToReadOnlyBytes(s string) []byte { +func StringToReadOnlyBytes(s string) (bs []byte) { sh := (*reflect.StringHeader)(unsafe.Pointer(&s)) - bh := reflect.SliceHeader{Data: sh.Data, Len: sh.Len, Cap: sh.Len} - return *(*[]byte)(unsafe.Pointer(&bh)) + bh := (*reflect.SliceHeader)(unsafe.Pointer(&bs)) + bh.Data = sh.Data + bh.Cap = sh.Len + bh.Len = sh.Len + return } diff --git a/vendor/modules.txt b/vendor/modules.txt index 2f4348f65..386744f99 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -853,7 +853,7 @@ github.com/xdg/stringprep # github.com/yohcop/openid-go v1.0.0 ## explicit github.com/yohcop/openid-go -# github.com/yuin/goldmark v1.1.30 +# github.com/yuin/goldmark v1.4.13 ## explicit github.com/yuin/goldmark github.com/yuin/goldmark/ast From 9f4d56ed05269a248593342f6b9e58dab2246abb Mon Sep 17 00:00:00 2001 From: ychao_1983 Date: Tue, 2 Aug 2022 14:26:16 +0800 Subject: [PATCH 08/30] fix-2476 --- templates/repo/cloudbrain/benchmark/index.tmpl | 2 +- templates/repo/debugjob/index.tmpl | 2 +- templates/repo/modelarts/inferencejob/index.tmpl | 2 +- templates/repo/modelarts/trainjob/index.tmpl | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/repo/cloudbrain/benchmark/index.tmpl b/templates/repo/cloudbrain/benchmark/index.tmpl index c6283e2e1..8a2fbd51b 100755 --- a/templates/repo/cloudbrain/benchmark/index.tmpl +++ b/templates/repo/cloudbrain/benchmark/index.tmpl @@ -30,7 +30,7 @@
    diff --git a/templates/repo/debugjob/index.tmpl b/templates/repo/debugjob/index.tmpl index ee020a8ca..206b99a4e 100755 --- a/templates/repo/debugjob/index.tmpl +++ b/templates/repo/debugjob/index.tmpl @@ -230,7 +230,7 @@ {{$.i18n.Tr "repo.modelarts.notebook"}} {{$.i18n.Tr "repo.modelarts.train_job"}} + href="{{.RepoLink}}/modelarts/train-job?listType=all">{{$.i18n.Tr "repo.modelarts.train_job"}} {{$.i18n.Tr "repo.modelarts.infer_job"}} diff --git a/templates/repo/modelarts/trainjob/index.tmpl b/templates/repo/modelarts/trainjob/index.tmpl index 3e6645727..46c1b9a02 100755 --- a/templates/repo/modelarts/trainjob/index.tmpl +++ b/templates/repo/modelarts/trainjob/index.tmpl @@ -33,7 +33,7 @@
    From 23d326df38def4825382c6adaae23111cc4dfd0b Mon Sep 17 00:00:00 2001 From: ychao_1983 Date: Tue, 2 Aug 2022 14:44:44 +0800 Subject: [PATCH 09/30] =?UTF-8?q?notebook=E6=96=87=E4=BB=B6markdown?= =?UTF-8?q?=E4=B8=AD=E7=BA=AFhtml=E4=B8=AD=E7=9A=84=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- templates/repo/view_file.tmpl | 69 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/templates/repo/view_file.tmpl b/templates/repo/view_file.tmpl index 91ec9b0bb..72446c3fe 100755 --- a/templates/repo/view_file.tmpl +++ b/templates/repo/view_file.tmpl @@ -133,16 +133,79 @@ function submitDeleteForm() { $("#delete-file-form").submit() } } + + +const baseUrls = {}; +const justDomain = /^[^:]+:\/*[^/]*$/; +const protocol = /^([^:]+:)[\s\S]*$/; +const domain = /^([^:]+:\/*[^/]*)[\s\S]*$/; +const originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i; +function rtrim(str, c, invert) { + const l = str.length; + if (l === 0) { + return ''; + } + let suffLen = 0; + while (suffLen < l) { + const currChar = str.charAt(l - suffLen - 1); + if (currChar === c && !invert) { + suffLen++; + } else if (currChar !== c && invert) { + suffLen++; + } else { + break; + } + } + + return str.slice(0, l - suffLen); +} +function resolveUrl(base, href) { + if (!baseUrls[' ' + base]) { + if (justDomain.test(base)) { + baseUrls[' ' + base] = base + '/'; + } else { + baseUrls[' ' + base] = rtrim(base, '/', true); + } + } + base = baseUrls[' ' + base]; + const relativeBase = base.indexOf(':') === -1; + + if (href.substring(0, 2) === '//') { + if (relativeBase) { + return href; + } + return base.replace(protocol, '$1') + href; + } else if (href.charAt(0) === '/') { + if (relativeBase) { + return href; + } + return base.replace(domain, '$1') + href; + } else { + return base + href; + } +} function showNoteBook(){ - var isNoteBook = {{.IsNoteBook}} + var isNoteBook = {{.IsNoteBook}}; if (isNoteBook) { - var jsonStr = "{{.FileContent}}" + var jsonStr = "{{.FileContent}}"; + var baseUrl={{.FileParentURL}}; nb.markdown.setOptions({ - baseUrl: {{.FileParentURL}} + baseUrl: baseUrl }); var notebook = nb.parse(JSON.parse(jsonStr)); var rendered = notebook.render(); $("#notebook").append(rendered); + + $("#notebook img").each(function(){ + + var oldSrc = $(this).attr('src'); + if (!originIndependentUrl.test(oldSrc)){ + var newSrc=resolveUrl(baseUrl,oldSrc); + $(this).attr('src', newSrc); + + } + + }); Prism.highlightAll(); } } From 72faea06549cbbde59bdf4323af2863c7e38560d Mon Sep 17 00:00:00 2001 From: zouap Date: Tue, 2 Aug 2022 15:30:07 +0800 Subject: [PATCH 10/30] #2586 Signed-off-by: zouap --- models/user_business_analysis.go | 11 ++++- routers/repo/cloudbrain.go | 2 +- routers/repo/modelarts.go | 69 +++++++++++++++------------- templates/repo/cloudbrain/trainjob/show.tmpl | 4 +- 4 files changed, 52 insertions(+), 34 deletions(-) diff --git a/models/user_business_analysis.go b/models/user_business_analysis.go index a36bd4736..0c67a569a 100644 --- a/models/user_business_analysis.go +++ b/models/user_business_analysis.go @@ -412,7 +412,16 @@ func QueryUserStaticDataAll(opts *UserBusinessAnalysisQueryOptions) ([]*UserBusi func QueryDataForUserDefineFromDb(opts *UserBusinessAnalysisQueryOptions, key string) ([]*UserBusinessAnalysis, int64) { statictisSess := xStatistic.NewSession() defer statictisSess.Close() - cond := "data_date='" + key + "'" + + var cond = builder.NewCond() + cond = cond.And( + builder.Eq{"data_date": key}, + ) + if len(opts.UserName) > 0 { + cond = cond.And( + builder.Like{"name", opts.UserName}, + ) + } allCount, err := statictisSess.Where(cond).Count(new(UserBusinessAnalysis)) if err == nil { if allCount > 0 { diff --git a/routers/repo/cloudbrain.go b/routers/repo/cloudbrain.go index 32c5ea9f6..15c7a26fe 100755 --- a/routers/repo/cloudbrain.go +++ b/routers/repo/cloudbrain.go @@ -886,7 +886,7 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo } } - + ctx.Data["datasetDownload"] = GetCloudBrainDataSetInfo(task.Uuid, false) ctx.Data["task"] = task labelName := strings.Fields(task.LabelName) ctx.Data["LabelName"] = labelName diff --git a/routers/repo/modelarts.go b/routers/repo/modelarts.go index 43f4a6e73..4be1389a2 100755 --- a/routers/repo/modelarts.go +++ b/routers/repo/modelarts.go @@ -302,34 +302,7 @@ func NotebookShow(ctx *context.Context) { datasetDownload := make([]models.DatasetDownload, 0) if ctx.IsSigned { if task.Uuid != "" && task.UserID == ctx.User.ID { - uuidList := strings.Split(task.Uuid, ";") - for _, uuidStr := range uuidList { - attachment, err := models.GetAttachmentByUUID(uuidStr) - if err != nil { - log.Error("GetAttachmentByUUID failed:%v", err.Error()) - return - } - dataset, err := models.GetDatasetByID(attachment.DatasetID) - if err != nil { - log.Error("GetDatasetByID failed:%v", err.Error()) - return - } - repo, err := models.GetRepositoryByID(dataset.RepoID) - if err != nil { - log.Error("GetRepositoryByID failed:%v", err.Error()) - return - } - datasetDownload = append(datasetDownload, models.DatasetDownload{ - DatasetName: attachment.Name, - DatasetDownloadLink: attachment.S3DownloadURL(), - RepositoryLink: repo.Link() + "/datasets", - }) - - } - // datasetName, err := GetDatasetNameByUUID(task.Uuid) - // if err == nil { - // task.DatasetName = datasetName - // } + datasetDownload = GetCloudBrainDataSetInfo(task.Uuid, true) } } user, err := models.GetUserByID(task.UserID) @@ -375,6 +348,39 @@ func NotebookShow(ctx *context.Context) { ctx.HTML(200, tplModelArtsNotebookShow) } +func GetCloudBrainDataSetInfo(uuid string, isNeedDown bool) []models.DatasetDownload { + datasetDownload := make([]models.DatasetDownload, 0) + + uuidList := strings.Split(uuid, ";") + for _, uuidStr := range uuidList { + attachment, err := models.GetAttachmentByUUID(uuidStr) + if err != nil { + log.Error("GetAttachmentByUUID failed:%v", err.Error()) + return datasetDownload + } + dataset, err := models.GetDatasetByID(attachment.DatasetID) + if err != nil { + log.Error("GetDatasetByID failed:%v", err.Error()) + return datasetDownload + } + repo, err := models.GetRepositoryByID(dataset.RepoID) + if err != nil { + log.Error("GetRepositoryByID failed:%v", err.Error()) + return datasetDownload + } + url := "" + if isNeedDown { + url = attachment.S3DownloadURL() + } + datasetDownload = append(datasetDownload, models.DatasetDownload{ + DatasetName: attachment.Name, + DatasetDownloadLink: url, + RepositoryLink: repo.Link() + "/datasets", + }) + } + return datasetDownload +} + func setShowSpecBySpecialPoolConfig(ctx *context.Context, findSpec bool, task *models.Cloudbrain) { modelarts.InitSpecialPool() if modelarts.SpecialPools != nil && !findSpec { @@ -1758,7 +1764,7 @@ func TrainJobShow(ctx *context.Context) { return } ctx.Data["canNewJob"] = canNewJob - + datasetList := make([][]models.DatasetDownload, 0) //将运行参数转化为epoch_size = 3, device_target = Ascend的格式 for i, task := range VersionListTasks { @@ -1781,7 +1787,7 @@ func TrainJobShow(ctx *context.Context) { } else { VersionListTasks[i].Parameters = "" } - + datasetList = append(datasetList, GetCloudBrainDataSetInfo(task.Uuid, false)) VersionListTasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain) VersionListTasks[i].CanModify = cloudbrain.CanModifyJob(ctx, &task.Cloudbrain) } @@ -1793,6 +1799,7 @@ func TrainJobShow(ctx *context.Context) { ctx.Data["displayJobName"] = VersionListTasks[0].DisplayJobName ctx.Data["version_list_task"] = VersionListTasks ctx.Data["version_list_count"] = VersionListCount + ctx.Data["datasetList"] = datasetList ctx.Data["canDownload"] = cloudbrain.CanModifyJob(ctx, &VersionListTasks[0].Cloudbrain) ctx.HTML(http.StatusOK, tplModelArtsTrainJobShow) } @@ -2515,7 +2522,7 @@ func InferenceJobShow(ctx *context.Context) { ctx.Data["displayJobName"] = task.DisplayJobName ctx.Data["task"] = task ctx.Data["canDownload"] = cloudbrain.CanModifyJob(ctx, task) - + ctx.Data["datasetDownload"] = GetCloudBrainDataSetInfo(task.Uuid, false) tempUids := []int64{} tempUids = append(tempUids, task.UserID) JobCreater, err := models.GetUserNamesByIDs(tempUids) diff --git a/templates/repo/cloudbrain/trainjob/show.tmpl b/templates/repo/cloudbrain/trainjob/show.tmpl index e4d8ff346..ca4e84a08 100644 --- a/templates/repo/cloudbrain/trainjob/show.tmpl +++ b/templates/repo/cloudbrain/trainjob/show.tmpl @@ -428,7 +428,9 @@
    - {{.DatasetName}} + {{range $m ,$n := $.datasetDownload}} + {{.DatasetName}} + {{end}}
    From faba3350fddc554d822eb72dbef1913c41753b59 Mon Sep 17 00:00:00 2001 From: zouap Date: Tue, 2 Aug 2022 15:40:08 +0800 Subject: [PATCH 11/30] #2586 Signed-off-by: zouap --- templates/repo/cloudbrain/inference/show.tmpl | 4 +++- templates/repo/cloudbrain/show.tmpl | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/templates/repo/cloudbrain/inference/show.tmpl b/templates/repo/cloudbrain/inference/show.tmpl index 055e403bd..c57a6fc66 100644 --- a/templates/repo/cloudbrain/inference/show.tmpl +++ b/templates/repo/cloudbrain/inference/show.tmpl @@ -468,7 +468,9 @@
    - {{.DatasetName}} + {{range $m ,$n := $.datasetDownload}} + {{.DatasetName}} + {{end}}
    diff --git a/templates/repo/cloudbrain/show.tmpl b/templates/repo/cloudbrain/show.tmpl index 0c53f7fce..d111fe123 100755 --- a/templates/repo/cloudbrain/show.tmpl +++ b/templates/repo/cloudbrain/show.tmpl @@ -412,7 +412,9 @@
    - {{.DatasetName}} + {{range $m ,$n := $.datasetDownload}} + {{.DatasetName}} + {{end}}
    From 15a85da2949e99a3cc237e40bbb9e8e98feda432 Mon Sep 17 00:00:00 2001 From: zouap Date: Tue, 2 Aug 2022 15:42:46 +0800 Subject: [PATCH 12/30] #2586 Signed-off-by: zouap --- templates/repo/grampus/trainjob/show.tmpl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/templates/repo/grampus/trainjob/show.tmpl b/templates/repo/grampus/trainjob/show.tmpl index 5d4321736..8111ec735 100755 --- a/templates/repo/grampus/trainjob/show.tmpl +++ b/templates/repo/grampus/trainjob/show.tmpl @@ -428,7 +428,9 @@
    - {{.DatasetName}} + {{range $m ,$n := $.datasetDownload}} + {{.DatasetName}} + {{end}}
    From 5581b4cd1169b7350725312b5396b761f2560ad2 Mon Sep 17 00:00:00 2001 From: ychao_1983 Date: Tue, 2 Aug 2022 17:30:52 +0800 Subject: [PATCH 13/30] fix-2617 --- routers/repo/grampus.go | 9 +++++---- routers/repo/modelarts.go | 25 +++++++++++++++++-------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/routers/repo/grampus.go b/routers/repo/grampus.go index 76f2bd98c..f193704d4 100755 --- a/routers/repo/grampus.go +++ b/routers/repo/grampus.go @@ -45,8 +45,7 @@ func GrampusTrainJobGPUNew(ctx *context.Context) { ctx.ServerError("get new train-job info failed", err) return } - waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeC2Net, models.GPUResource, models.JobTypeTrain) - ctx.Data["WaitCount"] = waitCount + ctx.HTML(http.StatusOK, tplGrampusTrainJobGPUNew) } @@ -57,8 +56,6 @@ func GrampusTrainJobNPUNew(ctx *context.Context) { ctx.ServerError("get new train-job info failed", err) return } - waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeC2Net, models.NPUResource, models.JobTypeTrain) - ctx.Data["WaitCount"] = waitCount ctx.HTML(200, tplGrampusTrainJobNPUNew) } @@ -131,8 +128,12 @@ func grampusTrainJobNewDataPrepare(ctx *context.Context, processType string) err if processType == grampus.ProcessorTypeGPU { ctx.Data["datasetType"] = models.TypeCloudBrainOne + waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeC2Net, models.GPUResource, models.JobTypeTrain) + ctx.Data["WaitCount"] = waitCount } else if processType == grampus.ProcessorTypeNPU { ctx.Data["datasetType"] = models.TypeCloudBrainTwo + waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeC2Net, models.NPUResource, models.JobTypeTrain) + ctx.Data["WaitCount"] = waitCount } return nil diff --git a/routers/repo/modelarts.go b/routers/repo/modelarts.go index 43f4a6e73..130d9f5ab 100755 --- a/routers/repo/modelarts.go +++ b/routers/repo/modelarts.go @@ -119,8 +119,7 @@ func MustEnableModelArts(ctx *context.Context) { func NotebookNew(ctx *context.Context) { notebookNewDataPrepare(ctx) - waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") - ctx.Data["WaitCount"] = waitCount + ctx.HTML(200, tplModelArtsNotebookNew) } @@ -150,6 +149,9 @@ func notebookNewDataPrepare(ctx *context.Context) error { ctx.Data["datasetType"] = models.TypeCloudBrainTwo + waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") + ctx.Data["WaitCount"] = waitCount + return nil } @@ -670,8 +672,6 @@ func TrainJobNew(ctx *context.Context) { ctx.ServerError("get new train-job info failed", err) return } - waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") - ctx.Data["WaitCount"] = waitCount ctx.HTML(200, tplModelArtsTrainJobNew) } @@ -741,6 +741,8 @@ func trainJobNewDataPrepare(ctx *context.Context) error { } ctx.Data["config_list"] = configList.ParaConfigs ctx.Data["datasetType"] = models.TypeCloudBrainTwo + waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") + ctx.Data["WaitCount"] = waitCount return nil } @@ -857,6 +859,8 @@ func trainJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModelArts ctx.Data["dataset_name"] = datasetNames ctx.Data["branch_name"] = form.BranchName ctx.Data["datasetType"] = models.TypeCloudBrainTwo + waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") + ctx.Data["WaitCount"] = waitCount return nil } @@ -868,8 +872,6 @@ func TrainJobNewVersion(ctx *context.Context) { ctx.ServerError("get new train-job info failed", err) return } - waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") - ctx.Data["WaitCount"] = waitCount ctx.HTML(200, tplModelArtsTrainJobVersionNew) } @@ -962,6 +964,8 @@ func trainJobNewVersionDataPrepare(ctx *context.Context) error { return err } ctx.Data["config_list"] = configList.ParaConfigs + waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") + ctx.Data["WaitCount"] = waitCount return nil } @@ -1053,6 +1057,8 @@ func versionErrorDataPrepare(ctx *context.Context, form auth.CreateModelArtsTrai } ctx.Data["config_list"] = configList.ParaConfigs ctx.Data["datasetType"] = models.TypeCloudBrainTwo + waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") + ctx.Data["WaitCount"] = waitCount return nil } @@ -2317,8 +2323,7 @@ func InferenceJobNew(ctx *context.Context) { ctx.ServerError("get new inference-job info failed", err) return } - waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") - ctx.Data["WaitCount"] = waitCount + ctx.HTML(200, tplModelArtsInferenceJobNew) } func inferenceJobNewDataPrepare(ctx *context.Context) error { @@ -2389,6 +2394,8 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error { }) ctx.Data["MODEL_COUNT"] = model_count ctx.Data["datasetType"] = models.TypeCloudBrainTwo + waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") + ctx.Data["WaitCount"] = waitCount return nil } @@ -2462,6 +2469,8 @@ func inferenceJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModel ctx.Data["ckpt_name"] = form.CkptName ctx.Data["train_url"] = form.TrainUrl ctx.Data["datasetType"] = models.TypeCloudBrainTwo + waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") + ctx.Data["WaitCount"] = waitCount return nil } From efed4b0819d12138a79468acf90d73935120ca8e Mon Sep 17 00:00:00 2001 From: zouap Date: Tue, 2 Aug 2022 17:33:14 +0800 Subject: [PATCH 14/30] #2586 Signed-off-by: zouap --- routers/repo/grampus.go | 2 +- templates/repo/modelarts/inferencejob/show.tmpl | 4 +++- templates/repo/modelarts/trainjob/show.tmpl | 8 +++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/routers/repo/grampus.go b/routers/repo/grampus.go index 76f2bd98c..65dcbcb11 100755 --- a/routers/repo/grampus.go +++ b/routers/repo/grampus.go @@ -695,7 +695,7 @@ func GrampusTrainJobShow(ctx *context.Context) { taskList := make([]*models.Cloudbrain, 0) taskList = append(taskList, task) ctx.Data["version_list_task"] = taskList - + ctx.Data["datasetDownload"] = GetCloudBrainDataSetInfo(task.Uuid, false) ctx.Data["canDownload"] = cloudbrain.CanModifyJob(ctx, task) ctx.Data["displayJobName"] = task.DisplayJobName diff --git a/templates/repo/modelarts/inferencejob/show.tmpl b/templates/repo/modelarts/inferencejob/show.tmpl index 14bb5cf24..fcecaee47 100644 --- a/templates/repo/modelarts/inferencejob/show.tmpl +++ b/templates/repo/modelarts/inferencejob/show.tmpl @@ -409,7 +409,9 @@ td, th {
    - {{.DatasetName}} + {{range $m ,$n := $.datasetDownload}} + {{.DatasetName}} + {{end}}
    diff --git a/templates/repo/modelarts/trainjob/show.tmpl b/templates/repo/modelarts/trainjob/show.tmpl index e61fafcdd..f20d25bed 100755 --- a/templates/repo/modelarts/trainjob/show.tmpl +++ b/templates/repo/modelarts/trainjob/show.tmpl @@ -460,7 +460,13 @@
    - {{.DatasetName}} + {{range $m ,$n := $.datasetDownload}} + {{if eq $k $m}} + {{range $f ,$g := $n}} + {{.DatasetName}} + {{end}} + {{end}} + {{end}}
    From bc17f9a9c4c7b44d762b46c481737e11c2cc2787 Mon Sep 17 00:00:00 2001 From: zouap Date: Tue, 2 Aug 2022 17:43:36 +0800 Subject: [PATCH 15/30] #2586 Signed-off-by: zouap --- templates/repo/modelarts/trainjob/show.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/repo/modelarts/trainjob/show.tmpl b/templates/repo/modelarts/trainjob/show.tmpl index f20d25bed..c0c0418ba 100755 --- a/templates/repo/modelarts/trainjob/show.tmpl +++ b/templates/repo/modelarts/trainjob/show.tmpl @@ -460,7 +460,7 @@
    - {{range $m ,$n := $.datasetDownload}} + {{range $m ,$n := $.datasetList}} {{if eq $k $m}} {{range $f ,$g := $n}} {{.DatasetName}} From 809ddc49666d2314b3b2ce2765379d00b309d98d Mon Sep 17 00:00:00 2001 From: ychao_1983 Date: Tue, 2 Aug 2022 17:44:25 +0800 Subject: [PATCH 16/30] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routers/repo/grampus.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/repo/grampus.go b/routers/repo/grampus.go index f193704d4..dd4faa485 100755 --- a/routers/repo/grampus.go +++ b/routers/repo/grampus.go @@ -472,7 +472,7 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain //todo: upload code (send to file_server todo this work?) if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.OutputPath); err != nil { log.Error("Failed to obsMkdir_output: %s (%v)", repo.FullName(), err) - grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU) ctx.RenderWithErr("Failed to obsMkdir_output", tplGrampusTrainJobNPUNew, &form) return } From 04cf265ef05a18764e4ae2164ade1c21ed6bfae0 Mon Sep 17 00:00:00 2001 From: ychao_1983 Date: Wed, 3 Aug 2022 09:46:41 +0800 Subject: [PATCH 17/30] =?UTF-8?q?=E4=BF=AE=E6=AD=A3num=5Fpulls=E5=92=8Cnum?= =?UTF-8?q?=5Fissues=E6=95=B0=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- models/repo.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/models/repo.go b/models/repo.go index feb6fd3ef..5e11df2b6 100755 --- a/models/repo.go +++ b/models/repo.go @@ -2250,6 +2250,18 @@ func CheckRepoStats(ctx context.Context) error { "UPDATE `repository` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE repo_id=?) WHERE id=?", "repository count 'num_stars'", }, + //Repository.NumIssues + { + "SELECT repo.id FROM `repository` repo WHERE repo.num_issues!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_pull=false)", + "UPDATE `repository` SET num_issues=(SELECT COUNT(*) FROM `issue` WHERE repo_id=? AND is_pull=false) WHERE id=?", + "repository count 'num_issues'", + }, + //Repository.NumPulls + { + "SELECT repo.id FROM `repository` repo WHERE repo.num_pulls!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_pull=true)", + "UPDATE `repository` SET num_pulls=(SELECT COUNT(*) FROM `issue` WHERE repo_id=? AND is_pull=true) WHERE id=?", + "repository count 'num_pulls'", + }, // Label.NumIssues { "SELECT label.id FROM `label` WHERE label.num_issues!=(SELECT COUNT(*) FROM `issue_label` WHERE label_id=label.id)", From 5f9e214c9614bd3f0c515484910bbdda699df539 Mon Sep 17 00:00:00 2001 From: zouap Date: Wed, 3 Aug 2022 09:47:51 +0800 Subject: [PATCH 18/30] #2586 Signed-off-by: zouap --- templates/repo/modelmanage/showinfo.tmpl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/templates/repo/modelmanage/showinfo.tmpl b/templates/repo/modelmanage/showinfo.tmpl index a4577fe20..159e89cbf 100644 --- a/templates/repo/modelmanage/showinfo.tmpl +++ b/templates/repo/modelmanage/showinfo.tmpl @@ -125,6 +125,10 @@ + 训练任务 + + + {{$.i18n.Tr "repo.modelarts.code_version"}} @@ -279,6 +283,8 @@ function transObj(data){ WorkServerNumber:TrainTaskInfo.WorkServerNumber || '--', Parameters:Parameters, EngineName:EngineName, + DisplayJobName:TrainTaskInfo.DisplayJobName || '--', + TrainJobVersionName:TrainTaskInfo.VersionName || '--', } let initModelAcc = { Accuracy: modelAcc.Accuracy || '--', @@ -365,6 +371,11 @@ function renderInfo(obj,accObj,id){ $('#CodeBranch').append(html) } + else if(key==="DisplayJobName"){ + let versionName = obj["TrainJobVersionName"] + let html = `${versionName}` + $('#DisplayJobName').append(html) + } else if(key==="Parameters"){ if(obj[key]==='--'){ $(`#${key}`).text(obj[key]) From 7a37c2875d2e2e1842119828e3fca71388fdf355 Mon Sep 17 00:00:00 2001 From: zouap Date: Wed, 3 Aug 2022 10:09:25 +0800 Subject: [PATCH 19/30] #2586 Signed-off-by: zouap --- templates/repo/modelmanage/showinfo.tmpl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/templates/repo/modelmanage/showinfo.tmpl b/templates/repo/modelmanage/showinfo.tmpl index 159e89cbf..93852b052 100644 --- a/templates/repo/modelmanage/showinfo.tmpl +++ b/templates/repo/modelmanage/showinfo.tmpl @@ -284,7 +284,7 @@ function transObj(data){ Parameters:Parameters, EngineName:EngineName, DisplayJobName:TrainTaskInfo.DisplayJobName || '--', - TrainJobVersionName:TrainTaskInfo.VersionName || '--', + TrainJobVersionName:TrainTaskInfo.VersionName || '', } let initModelAcc = { Accuracy: modelAcc.Accuracy || '--', @@ -372,6 +372,8 @@ function renderInfo(obj,accObj,id){ } else if(key==="DisplayJobName"){ + $(`#${key}`).text(obj[key]) + $(`#${key}`).attr("title",obj[key]) let versionName = obj["TrainJobVersionName"] let html = `${versionName}` $('#DisplayJobName').append(html) From dc1bc115d88de2002e7673fb29e69167b2da57e2 Mon Sep 17 00:00:00 2001 From: zouap Date: Wed, 3 Aug 2022 10:39:45 +0800 Subject: [PATCH 20/30] #2586 Signed-off-by: zouap --- templates/repo/modelmanage/showinfo.tmpl | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/templates/repo/modelmanage/showinfo.tmpl b/templates/repo/modelmanage/showinfo.tmpl index 93852b052..a4201910f 100644 --- a/templates/repo/modelmanage/showinfo.tmpl +++ b/templates/repo/modelmanage/showinfo.tmpl @@ -126,7 +126,11 @@ 训练任务 - + + + + + {{$.i18n.Tr "repo.modelarts.code_version"}} @@ -201,6 +205,7 @@ {{template "base/footer" .}}