w-trade-backtest 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +9 -0
- package/.eslintignore +3 -0
- package/.eslintrc.js +55 -0
- package/.jsdoc +25 -0
- package/README.md +167 -0
- package/SECURITY.md +5 -0
- package/babel.config.js +16 -0
- package/dist/renderOrdersTable.js +217 -0
- package/dist/renderOrdersTimeline.js +159 -0
- package/dist/renderProfitPlot.js +198 -0
- package/dist/renderSummary.js +194 -0
- package/dist/tmp.html +232 -0
- package/dist/w-trade-backtest.umd.js +32 -0
- package/dist/w-trade-backtest.umd.js.map +1 -0
- package/docs/calcOrders.mjs.html +278 -0
- package/docs/calcOrdersRatio.mjs.html +146 -0
- package/docs/calcOrdersSummary.mjs.html +506 -0
- package/docs/calcOrdersSummarySimple.mjs.html +207 -0
- package/docs/calcSummary.mjs.html +201 -0
- package/docs/closeAndSummaryOrders.mjs.html +265 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
- package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
- package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +978 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1049 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
- package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
- package/docs/genReport.mjs.html +196 -0
- package/docs/genReportCore.mjs.html +128 -0
- package/docs/global.html +4231 -0
- package/docs/index.html +84 -0
- package/docs/runStrategies.mjs.html +244 -0
- package/docs/runStrategy.mjs.html +455 -0
- package/docs/scripts/collapse.js +39 -0
- package/docs/scripts/commonNav.js +28 -0
- package/docs/scripts/linenumber.js +25 -0
- package/docs/scripts/nav.js +12 -0
- package/docs/scripts/polyfill.js +4 -0
- package/docs/scripts/prettify/Apache-License-2.0.txt +202 -0
- package/docs/scripts/prettify/lang-css.js +2 -0
- package/docs/scripts/prettify/prettify.js +28 -0
- package/docs/scripts/search.js +99 -0
- package/docs/styles/jsdoc.css +776 -0
- package/docs/styles/prettify.css +80 -0
- package/g.mjs +146 -0
- package/package.json +30 -0
- package/script.txt +19 -0
- package/src/WTradeBacktest.mjs +27 -0
- package/src/calcOrders.mjs +206 -0
- package/src/calcOrdersRatio.mjs +74 -0
- package/src/calcOrdersSummary.mjs +434 -0
- package/src/calcOrdersSummarySimple.mjs +135 -0
- package/src/calcSummary.mjs +129 -0
- package/src/closeAndSummaryOrders.mjs +193 -0
- package/src/genReport.mjs +124 -0
- package/src/genReportCore.mjs +56 -0
- package/src/ott.mjs +28 -0
- package/src/readJson.mjs +26 -0
- package/src/renderOrdersTable.js +217 -0
- package/src/renderOrdersTimeline.js +159 -0
- package/src/renderProfitPlot.js +198 -0
- package/src/renderSummary.js +194 -0
- package/src/runStrategies.mjs +172 -0
- package/src/runStrategy.mjs +383 -0
- package/src/tmp.html +232 -0
- package/src/writeJson.mjs +31 -0
- package/src/writeTxt.mjs +19 -0
- package/test/unit-WTradeBacktest.test.mjs +541 -0
- package/toolg/addVersion.mjs +4 -0
- package/toolg/cleanFolder.mjs +5 -0
- package/toolg/gDistRollup.mjs +51 -0
- package/toolg/gDocsExams.mjs +48 -0
- package/toolg/modifyReadme.mjs +4 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<title>genReport.mjs - Documentation</title>
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
<script src="scripts/prettify/prettify.js"></script>
|
|
10
|
+
<script src="scripts/prettify/lang-css.js"></script>
|
|
11
|
+
<!--[if lt IE 9]>
|
|
12
|
+
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
13
|
+
<![endif]-->
|
|
14
|
+
<link type="text/css" rel="stylesheet" href="styles/prettify.css">
|
|
15
|
+
<link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
|
|
16
|
+
<script src="scripts/nav.js" defer></script>
|
|
17
|
+
|
|
18
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
19
|
+
</head>
|
|
20
|
+
<body>
|
|
21
|
+
|
|
22
|
+
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
|
|
23
|
+
<label for="nav-trigger" class="navicon-button x">
|
|
24
|
+
<div class="navicon"></div>
|
|
25
|
+
</label>
|
|
26
|
+
|
|
27
|
+
<label for="nav-trigger" class="overlay"></label>
|
|
28
|
+
|
|
29
|
+
<nav >
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#calcOrders">calcOrders</a></li><li><a href="global.html#calcOrdersRatio">calcOrdersRatio</a></li><li><a href="global.html#calcOrdersSummary">calcOrdersSummary</a></li><li><a href="global.html#calcOrdersSummarySimple">calcOrdersSummarySimple</a></li><li><a href="global.html#calcSummary">calcSummary</a></li><li><a href="global.html#closeAndSummaryOrders">closeAndSummaryOrders</a></li><li><a href="global.html#genReport">genReport</a></li><li><a href="global.html#genReportCore">genReportCore</a></li><li><a href="global.html#runStrategies">runStrategies</a></li><li><a href="global.html#runStrategy">runStrategy</a></li></ul>
|
|
33
|
+
|
|
34
|
+
</nav>
|
|
35
|
+
|
|
36
|
+
<div id="main">
|
|
37
|
+
|
|
38
|
+
<h1 class="page-title">genReport.mjs</h1>
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
<section>
|
|
47
|
+
<article>
|
|
48
|
+
<pre class="prettyprint source linenums"><code>import path from 'path'
|
|
49
|
+
import _ from 'lodash-es'
|
|
50
|
+
import w from 'wsemi'
|
|
51
|
+
import calcSummary from './calcSummary.mjs'
|
|
52
|
+
import genReportCore from './genReportCore.mjs'
|
|
53
|
+
import readJson from './readJson.mjs'
|
|
54
|
+
import writeJson from './writeJson.mjs'
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* 由orders.json產製績效html報表
|
|
59
|
+
*
|
|
60
|
+
* 讀取orders.json(已結算訂單陣列)後,經calcSummary統計摘要,再以genReportCore產出html報表
|
|
61
|
+
* 訂單須為已結算形(含uProfitOrLoss、uEquity等欄位),未結算單(timeEnd為空)仍可計算,計入summary.numTradeUnsettled
|
|
62
|
+
* fpOrders非有效字串或非檔案、內容非有效陣列時throw
|
|
63
|
+
*
|
|
64
|
+
* Unit Test: {@link https://github.com/yuda-lyu/w-trade-backtest/blob/master/test/unit-WTradeBacktest.test.mjs Github}
|
|
65
|
+
* @function
|
|
66
|
+
* @param {Function} ott 輸入時區時間函數,傳入時間字串回傳dayjs時間物件(可用src/ott.mjs或自行以dayjs包裝)
|
|
67
|
+
* @param {String} fpOrders 輸入orders.json檔案路徑字串
|
|
68
|
+
* @param {Object} [opt={}] 輸入設定物件,預設{}
|
|
69
|
+
* @param {String} [opt.fpOut=''] 輸入輸出html檔案路徑字串,預設為與orders.json同資料夾之report.html
|
|
70
|
+
* @param {String} [opt.name=''] 輸入報表標題字串,預設為orders.json所在資料夾名
|
|
71
|
+
* @param {Number} [opt.uIni=null] 輸入初始資金數值,預設由首筆已結算單推回(uEquity - uCumuProfitOrLoss),推不出則為1000
|
|
72
|
+
* @param {String} [opt.timeOhlcStart=''] 輸入摘要統計起始秒時間字串,影響btDays與年化,預設由訂單最早timeStart推得,注意訂單起訖僅為「有單的範圍」,若實際回測窗較寬(頭尾無單)年化會被高估,建議明給
|
|
73
|
+
* @param {String} [opt.timeOhlcEnd=''] 輸入摘要統計結束秒時間字串,預設由訂單最晚timeEnd(未平倉單取timeStart)推得
|
|
74
|
+
* @param {Boolean} [opt.withWriteSummary=false] 輸入是否同時輸出summary.json(與fpOut同資料夾)布林值,預設false
|
|
75
|
+
* @returns {Promise} 回傳Promise,resolve為物件,內含orders(訂單陣列)、summary(摘要物件)、fpOut(輸出html路徑)欄位
|
|
76
|
+
* @example
|
|
77
|
+
*
|
|
78
|
+
* import fs from 'fs'
|
|
79
|
+
*
|
|
80
|
+
* //orders為已結算訂單陣列(如runStrategy、runStrategies或closeAndSummaryOrders產出)
|
|
81
|
+
* let orders = [{
|
|
82
|
+
* mode: 'long',
|
|
83
|
+
* timeStart: '2020-01-01T00:00:00',
|
|
84
|
+
* priceStart: 100,
|
|
85
|
+
* uTrade: 100,
|
|
86
|
+
* priceTakeProfit: 105,
|
|
87
|
+
* priceStopLoss: 97,
|
|
88
|
+
* timeEnd: '2020-01-01T04:00:00',
|
|
89
|
+
* priceEnd: 105,
|
|
90
|
+
* modeResult: 'profit',
|
|
91
|
+
* uFee: 0.05,
|
|
92
|
+
* uProfitOrLoss: 4.9,
|
|
93
|
+
* rProfitOrLoss: 0.049,
|
|
94
|
+
* uCumuProfitOrLoss: 4.9,
|
|
95
|
+
* uEquity: 1004.9,
|
|
96
|
+
* }]
|
|
97
|
+
*
|
|
98
|
+
* fs.mkdirSync('./result', { recursive: true })
|
|
99
|
+
* fs.writeFileSync('./result/orders.json', JSON.stringify(orders), 'utf8')
|
|
100
|
+
*
|
|
101
|
+
* let r = await genReport(ott, './result/orders.json', { name: '示範策略', uIni: 1000 })
|
|
102
|
+
* console.log(r.summary.numTrade, r.summary.rWin, r.summary.uEquityFinal)
|
|
103
|
+
* // => 1 100.00% 1004.9
|
|
104
|
+
* console.log(fs.readdirSync('./result'))
|
|
105
|
+
* // => [ 'orders.json', 'report.html' ]
|
|
106
|
+
*
|
|
107
|
+
*/
|
|
108
|
+
let genReport = async (ott, fpOrders, opt = {}) => {
|
|
109
|
+
|
|
110
|
+
//check
|
|
111
|
+
if (!w.isestr(fpOrders)) {
|
|
112
|
+
throw new Error(`invalid fpOrders`)
|
|
113
|
+
}
|
|
114
|
+
if (!w.fsIsFile(fpOrders)) {
|
|
115
|
+
throw new Error(`fpOrders[${fpOrders}] is not a file`)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
//orders
|
|
119
|
+
let orders = readJson(fpOrders)
|
|
120
|
+
if (!w.isearr(orders)) {
|
|
121
|
+
throw new Error(`orders in fpOrders[${fpOrders}] is not an effective array`)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
//fpOut
|
|
125
|
+
let fpOut = _.get(opt, 'fpOut', '')
|
|
126
|
+
if (!w.isestr(fpOut)) {
|
|
127
|
+
fpOut = path.resolve(path.dirname(fpOrders), 'report.html')
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
//name
|
|
131
|
+
let name = _.get(opt, 'name', '')
|
|
132
|
+
if (!w.isestr(name)) {
|
|
133
|
+
name = path.basename(path.dirname(path.resolve(fpOrders)))
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
//uIni, 未給則由首筆已結算單推回(calcOrders 定義 uEquity = uIni + uCumuProfitOrLoss)
|
|
137
|
+
let uIni = _.get(opt, 'uIni', null)
|
|
138
|
+
if (!w.isnum(uIni)) {
|
|
139
|
+
let o = _.find(orders, (o) => w.isnum(o.uEquity) && w.isnum(o.uCumuProfitOrLoss))
|
|
140
|
+
uIni = o ? o.uEquity - o.uCumuProfitOrLoss : 1000
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
//timeOhlcStart, timeOhlcEnd, 未給則由訂單起訖推得
|
|
144
|
+
let timeOhlcStart = _.get(opt, 'timeOhlcStart', '')
|
|
145
|
+
if (!w.isestr(timeOhlcStart)) {
|
|
146
|
+
timeOhlcStart = _.min(_.map(orders, 'timeStart'))
|
|
147
|
+
}
|
|
148
|
+
let timeOhlcEnd = _.get(opt, 'timeOhlcEnd', '')
|
|
149
|
+
if (!w.isestr(timeOhlcEnd)) {
|
|
150
|
+
timeOhlcEnd = _.max(_.map(orders, (o) => w.isestr(o.timeEnd) ? o.timeEnd : o.timeStart))
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
//withWriteSummary
|
|
154
|
+
let withWriteSummary = _.get(opt, 'withWriteSummary', false)
|
|
155
|
+
|
|
156
|
+
//calcSummary
|
|
157
|
+
let summary = await calcSummary(ott, uIni, orders, timeOhlcStart, timeOhlcEnd)
|
|
158
|
+
|
|
159
|
+
//writeJson
|
|
160
|
+
if (withWriteSummary) {
|
|
161
|
+
writeJson(path.resolve(path.dirname(fpOut), 'summary.json'), { name, summary }, { structured: true })
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
//genReportCore
|
|
165
|
+
genReportCore({ name, orders, summary }, fpOut)
|
|
166
|
+
|
|
167
|
+
return { orders, summary, fpOut }
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
export default genReport
|
|
172
|
+
</code></pre>
|
|
173
|
+
</article>
|
|
174
|
+
</section>
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
</div>
|
|
182
|
+
|
|
183
|
+
<br class="clear">
|
|
184
|
+
|
|
185
|
+
<footer>
|
|
186
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sun Aug 02 2026 20:09:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
187
|
+
</footer>
|
|
188
|
+
|
|
189
|
+
<script>prettyPrint();</script>
|
|
190
|
+
<script src="scripts/polyfill.js"></script>
|
|
191
|
+
<script src="scripts/linenumber.js"></script>
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
</body>
|
|
196
|
+
</html>
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<title>genReportCore.mjs - Documentation</title>
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
<script src="scripts/prettify/prettify.js"></script>
|
|
10
|
+
<script src="scripts/prettify/lang-css.js"></script>
|
|
11
|
+
<!--[if lt IE 9]>
|
|
12
|
+
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
13
|
+
<![endif]-->
|
|
14
|
+
<link type="text/css" rel="stylesheet" href="styles/prettify.css">
|
|
15
|
+
<link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
|
|
16
|
+
<script src="scripts/nav.js" defer></script>
|
|
17
|
+
|
|
18
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
19
|
+
</head>
|
|
20
|
+
<body>
|
|
21
|
+
|
|
22
|
+
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
|
|
23
|
+
<label for="nav-trigger" class="navicon-button x">
|
|
24
|
+
<div class="navicon"></div>
|
|
25
|
+
</label>
|
|
26
|
+
|
|
27
|
+
<label for="nav-trigger" class="overlay"></label>
|
|
28
|
+
|
|
29
|
+
<nav >
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#calcOrders">calcOrders</a></li><li><a href="global.html#calcOrdersRatio">calcOrdersRatio</a></li><li><a href="global.html#calcOrdersSummary">calcOrdersSummary</a></li><li><a href="global.html#calcOrdersSummarySimple">calcOrdersSummarySimple</a></li><li><a href="global.html#calcSummary">calcSummary</a></li><li><a href="global.html#closeAndSummaryOrders">closeAndSummaryOrders</a></li><li><a href="global.html#genReport">genReport</a></li><li><a href="global.html#genReportCore">genReportCore</a></li><li><a href="global.html#runStrategies">runStrategies</a></li><li><a href="global.html#runStrategy">runStrategy</a></li></ul>
|
|
33
|
+
|
|
34
|
+
</nav>
|
|
35
|
+
|
|
36
|
+
<div id="main">
|
|
37
|
+
|
|
38
|
+
<h1 class="page-title">genReportCore.mjs</h1>
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
<section>
|
|
47
|
+
<article>
|
|
48
|
+
<pre class="prettyprint source linenums"><code>import path from 'path'
|
|
49
|
+
import fs from 'fs'
|
|
50
|
+
import { fileURLToPath } from 'url'
|
|
51
|
+
import writeTxt from './writeTxt.mjs'
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
//模板資產(tmp.html, render*.js)與本模組同資料夾, 以模組位置解析, 不依賴 cwd
|
|
55
|
+
let fd = path.dirname(fileURLToPath(import.meta.url))
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* 產出html回測報告
|
|
59
|
+
*
|
|
60
|
+
* 讀取與本模組同資料夾之模板資產(tmp.html與render*.js),置換{name}、{orders}、{summary}後寫出html
|
|
61
|
+
* 報告內含權益曲線、訂單表格、時間軸與摘要
|
|
62
|
+
*
|
|
63
|
+
* Unit Test: {@link https://github.com/yuda-lyu/w-trade-backtest/blob/master/test/unit-WTradeBacktest.test.mjs Github}
|
|
64
|
+
* @function
|
|
65
|
+
* @param {Object} r 輸入報告物件,需含name(報告名稱字串)、orders(訂單陣列)、summary(摘要物件)欄位
|
|
66
|
+
* @param {String} fpOut 輸入輸出html檔案路徑字串
|
|
67
|
+
* @returns {undefined} 無回傳,於fpOut寫出html報告
|
|
68
|
+
* @example
|
|
69
|
+
*
|
|
70
|
+
* //rr為runStrategies範例之回傳{orders,summary}
|
|
71
|
+
* genReportCore({ name: '示範策略', orders: rr.orders, summary: rr.summary }, './report.html')
|
|
72
|
+
* // => 於'./report.html'寫出html報告
|
|
73
|
+
*
|
|
74
|
+
*/
|
|
75
|
+
let genReportCore = (r, fpOut) => {
|
|
76
|
+
|
|
77
|
+
let rd = (fn) => {
|
|
78
|
+
let fp = path.resolve(fd, fn)
|
|
79
|
+
let h = fs.readFileSync(fp, 'utf8')
|
|
80
|
+
return h
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let h = rd('tmp.html')
|
|
84
|
+
let hPlot = rd('renderProfitPlot.js')
|
|
85
|
+
let hTable = rd('renderOrdersTable.js')
|
|
86
|
+
let hTimeline = rd('renderOrdersTimeline.js')
|
|
87
|
+
let hSummary = rd('renderSummary.js')
|
|
88
|
+
|
|
89
|
+
h = h.replace(`{renderProfitPlot}`, hPlot)
|
|
90
|
+
h = h.replace(`{renderOrdersTable}`, hTable)
|
|
91
|
+
h = h.replace(`{renderOrdersTimeline}`, hTimeline)
|
|
92
|
+
h = h.replace(`{renderSummary}`, hSummary)
|
|
93
|
+
h = h.replace(`{name}`, r.name)
|
|
94
|
+
h = h.replace(`{orders}`, JSON.stringify(r.orders))
|
|
95
|
+
h = h.replace(`{summary}`, JSON.stringify(r.summary))
|
|
96
|
+
|
|
97
|
+
//writeTxt
|
|
98
|
+
writeTxt(fpOut, h)
|
|
99
|
+
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
export default genReportCore
|
|
104
|
+
</code></pre>
|
|
105
|
+
</article>
|
|
106
|
+
</section>
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<br class="clear">
|
|
116
|
+
|
|
117
|
+
<footer>
|
|
118
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sun Aug 02 2026 20:09:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
119
|
+
</footer>
|
|
120
|
+
|
|
121
|
+
<script>prettyPrint();</script>
|
|
122
|
+
<script src="scripts/polyfill.js"></script>
|
|
123
|
+
<script src="scripts/linenumber.js"></script>
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
</body>
|
|
128
|
+
</html>
|