pinokiod 2.15.7 → 2.15.9

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.
@@ -4,7 +4,7 @@ const path = require('path')
4
4
  const _ = require('lodash')
5
5
  const git = require('isomorphic-git')
6
6
  const http = require('isomorphic-git/http/node')
7
- const Lproxy = require('lproxy')
7
+ const Lproxy = require('../lproxy')
8
8
  //const { glob, globSync, globStream, globStreamSync, Glob, } = require('glob')
9
9
  const { glob, sync, hasMagic } = require('glob-gitignore')
10
10
  const fastq = require('fastq')
@@ -104,8 +104,6 @@ class Api {
104
104
  // 1. set the "stop" flag for the uri, so the next execution in the queue for the uri will NOT queue another task
105
105
  // 2. stream a message closing the socket
106
106
 
107
-
108
-
109
107
  let requestPath = this.filePath(req.params.uri)
110
108
 
111
109
 
@@ -715,6 +713,19 @@ class Api {
715
713
  }
716
714
 
717
715
 
716
+ if (result && result.error) {
717
+ this.ondata({
718
+ id: request.path,
719
+ type: "error",
720
+ data: result.response,
721
+ event: result.error,
722
+ rpc,
723
+ rawrpc
724
+ })
725
+ return
726
+ }
727
+
728
+
718
729
 
719
730
  if (result && rpc.returns) {
720
731
  // set the scope variable from the return value
@@ -879,13 +890,13 @@ class Api {
879
890
  for(let name in this.listeners) {
880
891
  this.listeners[name](packet)
881
892
  }
882
- if (packet.type === 'error') {
883
- this.stop({
884
- params: {
885
- uri: packet.id
886
- }
887
- })
888
- }
893
+ // if (packet.type === 'error') {
894
+ // this.stop({
895
+ // params: {
896
+ // uri: packet.id
897
+ // }
898
+ // })
899
+ // }
889
900
  }
890
901
  listen(name, ondata) {
891
902
  this.listeners[name] = ondata
@@ -149,9 +149,6 @@ class Bin {
149
149
  }
150
150
  }).filter(x => x)
151
151
 
152
-
153
- console.log("****** envs", JSON.stringify(envs, null, 2))
154
-
155
152
  // 2. Merge module envs
156
153
  let e = {}
157
154
  for(let env of envs) {
@@ -175,8 +172,6 @@ class Bin {
175
172
  return file.endsWith(".js") && file !== "index.js" && file !== "cmake.js"
176
173
  })
177
174
 
178
- console.log({ modfiles })
179
-
180
175
 
181
176
  this.mods = []
182
177
  for(let filename of modfiles) {
@@ -188,7 +183,6 @@ class Bin {
188
183
  let name = path.basename(filename, ".js")
189
184
  this.mods.push({ name, mod })
190
185
  }
191
- console.log(">> this.mods = ", this.mods)
192
186
  // inject kernel
193
187
  for(let i=0; i<this.mods.length; i++) {
194
188
  this.mods[i].mod.kernel = this.kernel
@@ -203,7 +197,6 @@ class Bin {
203
197
  }
204
198
  this.mod[mod.name] = mod.mod
205
199
  }
206
- console.log(">> this.mod", this.mod)
207
200
 
208
201
 
209
202
 
package/kernel/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const fs = require('fs')
2
- const {JSONPath} = require('jsonpath-plus');
2
+ //const {JSONPath} = require('jsonpath-plus');
3
3
  const os = require("os")
4
4
  const jsdom = require("jsdom");
5
5
  const path = require('path')
@@ -0,0 +1,76 @@
1
+ /*
2
+ const proxy = new Minproxy()
3
+
4
+ // 1. start the proxy for url
5
+ const generated_url = await proxy.start(url)
6
+
7
+ // 2. stop the proxy for url
8
+ proxy.stop(url)
9
+
10
+ // 3. get the proxy url for a given url
11
+ const proxy_url = proxy.url(url)
12
+
13
+ // 4. get all proxies
14
+ const proxies = proxy.all()
15
+
16
+ */
17
+ const httpProxy = require('http-proxy');
18
+ const portfinder = require('portfinder-cp');
19
+ const os = require('os')
20
+ class Lproxy {
21
+ constructor() {
22
+ this.proxies = {}
23
+ this.ip = this.local()
24
+ }
25
+ async start (url, options) {
26
+ let port
27
+ if (options && options.port) {
28
+ port = options.port
29
+ console.log("start proxy at port", port)
30
+ delete options.port
31
+ }
32
+ let o = Object.assign({
33
+ target: url,
34
+ ws: true,
35
+ localAddress: '0.0.0.0',
36
+ }, options)
37
+ console.log("proxy object", o)
38
+ const proxy = httpProxy.createProxyServer(o)
39
+ // get a new port
40
+ if (!port) {
41
+ port = await portfinder.getPortPromise({
42
+ //port: 42420
43
+ port: 44000
44
+ })
45
+ }
46
+ proxy.listen(port)
47
+ proxy.on('close', (res, socket, head) => {
48
+ console.log('Client disconnected');
49
+ });
50
+ proxy.on('error', (e) => {
51
+ console.log('Proxy Error', e)
52
+ });
53
+
54
+ this.proxies[url] = proxy
55
+ return `http://${this.ip}:${port}`
56
+ }
57
+ async stop (url) {
58
+ console.log("proxies", this.proxies, url)
59
+ let p = this.proxies[url]
60
+ if (p) {
61
+ p.close()
62
+ }
63
+ }
64
+ local() {
65
+ const interfaces = Object.values(os.networkInterfaces())
66
+ let addr
67
+ for (let iface of interfaces) {
68
+ for (let alias of iface) {
69
+ if (alias.family === "IPv4" && alias.address !== "127.0.0.1" && !alias.internal) {
70
+ return alias.address
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }
76
+ module.exports = Lproxy
package/kernel/shell.js CHANGED
@@ -89,8 +89,6 @@ class Shell {
89
89
  // 2. env
90
90
  // default env
91
91
 
92
- console.log(">>>>> process.env=", JSON.stringify(process.env, null, 2))
93
-
94
92
  this.env = Object.assign({}, process.env)
95
93
  // If the user has set PYTHONPATH, unset it.
96
94
  if (this.env.PYTHONPATH) {
@@ -113,6 +111,7 @@ class Shell {
113
111
  }
114
112
 
115
113
  this.env.CMAKE_OBJECT_PATH_MAX = 1024
114
+ this.env.PYTORCH_ENABLE_MPS_FALLBACK = 1
116
115
 
117
116
  // First override this.env with system env
118
117
  let system_env = await Environment.get(this.kernel.homedir)
@@ -440,7 +439,13 @@ class Shell {
440
439
  return params.message
441
440
  } else if (Array.isArray(params.message)) {
442
441
  // if params.message is empty, filter out
443
- let delimiter = " && "
442
+ //let delimiter = " && "
443
+ let delimiter
444
+ if (this.platform === "win32") {
445
+ delimiter = " & ";
446
+ } else {
447
+ delimiter = " ; ";
448
+ }
444
449
  return params.message.filter((m) => {
445
450
  return m && !/^\s+$/.test(m)
446
451
  }).join(delimiter)
@@ -656,8 +661,6 @@ class Shell {
656
661
 
657
662
  config.env = this.env
658
663
 
659
- console.log("CONFIG.ENV", JSON.stringify(config.env, null, 2))
660
-
661
664
  if (!this.ptyProcess) {
662
665
  // ptyProcess doesn't exist => create
663
666
  this.done = false
package/kernel/shells.js CHANGED
@@ -28,9 +28,7 @@ class Shells {
28
28
  */
29
29
  async launch(params, options, ondata) {
30
30
  // iterate through all the envs
31
- console.log("------- params.env before", JSON.stringify(params.env, null, 2))
32
31
  params.env = this.kernel.bin.envs(params.env)
33
- console.log("------- params.env after", JSON.stringify(params.env, null, 2))
34
32
 
35
33
  let exec_path = (params.path ? params.path : ".") // use the current path if not specified
36
34
  let cwd = (options && options.cwd ? options.cwd : this.kernel.homedir) // if cwd exists, use it. Otherwise the cwd is pinokio home folder (~/pinokio)
@@ -39,7 +37,36 @@ class Shells {
39
37
  if (options) params.group = options.group // set group
40
38
 
41
39
  let m
40
+
41
+ // if error doesn't exist, add default "error:" event
42
+ if (!params.on) {
43
+ params.on = []
44
+ }
45
+ // default error
46
+ const defaultHandlers = [{
47
+ event: "/error:/i",
48
+ break: true
49
+ }, {
50
+ event: "/errno /i",
51
+ break: true
52
+ }, {
53
+ event: "/error:.*triton/i",
54
+ break: false
55
+ }]
56
+ params.on = params.on.concat(defaultHandlers)
42
57
  let response = await sh.start(params, async (stream) => {
58
+ /*
59
+ {
60
+ method: "shell.run",
61
+ params: {
62
+ message,
63
+ on: [{
64
+ event: <regex>,
65
+ <done|kill|debug>: true
66
+ }],
67
+ }
68
+ }
69
+ */
43
70
  if (params.on && Array.isArray(params.on)) {
44
71
  for(let handler of params.on) {
45
72
  // regexify
@@ -67,33 +94,108 @@ class Shells {
67
94
  sh.continue()
68
95
  }
69
96
  }
70
- // } else if (handler.pattern === "url") {
71
- // let re = /https?:\/\/[a-zA-Z0-9.:]+/g
72
- // let line = stream.cleaned.replaceAll(/[\r\n]/g, "")
73
- // let rendered_event = [...line.matchAll(re)]
74
- // if (rendered_event.length > 0) {
75
- // stream.matches = rendered_event
76
- // if (handler.kill) {
77
- // m = new URL(rendered_event[0])
78
- // console.log("MM", m)
79
- // sh.kill()
80
- // }
81
- // if (handler.done) {
82
- // m = new URL(rendered_event[0])
83
- // console.log("MM", m)
84
- // sh.continue()
85
- // }
86
- // }
87
97
  }
88
98
  }
89
99
  }
90
100
  ondata(stream)
91
101
  })
92
- console.log("shell ended", { id: sh.id, response, stdout: response, event: m })
93
102
 
103
+ /*
104
+ {
105
+ method: "shell.run",
106
+ params: {
107
+ message,
108
+ on: [{
109
+ event: <regex>,
110
+ break: true|false
111
+ }],
112
+ }
113
+ }
114
+
115
+ - true: break with matched
116
+ - false: do not break (default)
117
+ - TEMPLATE: parse the template
118
+ */
119
+
120
+ let errors = new Set()
121
+ if (response) {
122
+ if (params.on && Array.isArray(params.on)) {
123
+
124
+ let line = response.replaceAll(/[\r\n]/g, "")
125
+ // 1. find all break event handlers
126
+ let breakPoints = params.on.filter((x) => {
127
+ return x.event && x.hasOwnProperty("break")
128
+ })
129
+
130
+ // 2. first find the `break: false` handlers and replace the patterns with blank => so they won't be matched in the next step
131
+ //let line = response.replaceAll(/[\r\n]/g, "")
132
+ for(let handler of breakPoints) {
133
+ if (handler.event) {
134
+ let matches = /^\/(.+)\/([dgimsuy]*)$/gs.exec(handler.event)
135
+ if (!/g/.test(matches[2])) {
136
+ matches[2] += "g" // if g option is not included, include it (need it for matchAll)
137
+ }
138
+ let re = new RegExp(matches[1], matches[2])
139
+
140
+ // only the "break: false" ones => these need to be ignored
141
+ if (!handler.break) {
142
+ line = line.replaceAll(re, "")
143
+ }
144
+ }
145
+ }
146
+
147
+ // 3. Now with all the `break: false` (ignored patterns) gone, look for the `break: true` patterns
148
+ for(let handler of breakPoints) {
149
+ if (handler.event) {
150
+ let matches = /^\/(.+)\/([dgimsuy]*)$/gs.exec(handler.event)
151
+ if (!/g/.test(matches[2])) {
152
+ matches[2] += "g" // if g option is not included, include it (need it for matchAll)
153
+ }
154
+ let re = new RegExp(matches[1], matches[2])
155
+
156
+ // only the "break: true" ones
157
+ if (handler.break) {
158
+
159
+ let match;
160
+ // Keep executing the regex on the text until no more matches are found
161
+ while ((match = re.exec(line)) !== null) {
162
+ errors.add(match[0])
163
+ // errors.add(match.slice(1));
164
+ }
165
+ }
166
+ }
167
+ }
168
+ }
169
+ }
170
+
171
+
172
+ if (errors.size > 0) {
173
+ // try replacing the shortest pattern from the text one by one and narrow down the errors
174
+ // so it doesn't accidently contain a very long match
175
+
176
+ let errs = Array.from(errors)
177
+ errs.sort((x, y) => {
178
+ return x.length - y.length
179
+ })
180
+ let line = response.replaceAll(/[\r\n]/g, "")
181
+ let shortened_errs = []
182
+ // at this point, errs is sorted in ascending order of length, so the shortest match is the first item
183
+ for(let err of errs) {
184
+ // 1. check the err still matches the line => The first time this is run, it will always be included. But from the next time it might not be
185
+ if (line.includes(err)) {
186
+ // 2. remove the first pattern
187
+ shortened_errs.push(err)
188
+ line = line.replaceAll(err, "")
189
+ }
190
+ }
191
+
192
+ // don't return if there's an error
193
+ return { id: sh.id, response, stdout: response, event: m, error: shortened_errs }
194
+ } else {
195
+ // need to make a request
196
+ return { id: sh.id, response, stdout: response, event: m }
197
+ }
94
198
 
95
- // need to make a request
96
- return { id: sh.id, response, stdout: response, event: m }
97
199
  }
98
200
  async start(params, options, ondata) {
99
201
  params.persistent = true
@@ -203,14 +305,13 @@ class Shells {
203
305
  let info = this.shells.map((s) => {
204
306
  return { id: s.id, group: s.group, cmd: s.cmd }
205
307
  })
206
- console.log("reset", this.shells.length, JSON.stringify(info, null, 2))
207
308
  if (this.shells) {
208
309
  let shells = []
209
310
  for(let i=0; i<this.shells.length; i++) {
210
311
  shells.push(this.shells[i])
211
312
  }
212
313
  for(let shell of shells) {
213
- console.log("[Kill]", { id: shell.id, group: shell.group, cmd: shell.cmd })
314
+ console.log("[Kill Shell]", { id: shell.id, group: shell.group, cmd: shell.cmd })
214
315
  shell.kill("", true)
215
316
  }
216
317
  }
package/kernel/sysinfo.js CHANGED
@@ -101,14 +101,11 @@ class Sysinfo {
101
101
  cmd = "env"
102
102
  }
103
103
 
104
-
105
- console.log("############### DEBUGGING ENV")
106
- let _res = await this.kernel.bin.exec({ message: cmd, conda: { skip: true } }, (stream) => {
107
- })
108
- console.log(_res)
109
- console.log("############### DEBUGGING ENV FINISH")
110
-
111
-
104
+ // console.log("############### DEBUGGING ENV")
105
+ // let _res = await this.kernel.bin.exec({ message: cmd, conda: { skip: true } }, (stream) => {
106
+ // })
107
+ // console.log(_res)
108
+ // console.log("############### DEBUGGING ENV FINISH")
112
109
 
113
110
  let res = await this.kernel.bin.exec({ message: cmd }, (stream) => {
114
111
  })
package/kernel/util.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const fs = require('fs')
2
2
  const os = require('os')
3
+ const net = require('node:net')
3
4
  const path = require('path')
4
5
  const dotenv = require('dotenv')
5
6
  const child_process = require('node:child_process');
@@ -13,6 +14,31 @@ const h = "[^\\S\\r\\n]"; // simulate `\h`
13
14
  const returnPattern = /\r/g;
14
15
  const returnReplacement = "\\r";
15
16
 
17
+
18
+ const port_running = async (host, port) => {
19
+ const timeout = 1000
20
+ const promise = new Promise((resolve, reject) => {
21
+ const socket = new net.Socket();
22
+ const onError = (e) => {
23
+ socket.destroy();
24
+ reject();
25
+ };
26
+ socket.setTimeout(timeout);
27
+ socket.once('error', onError);
28
+ socket.once('timeout', onError);
29
+ socket.connect(port, host, () => {
30
+ socket.end();
31
+ resolve();
32
+ });
33
+ });
34
+ try {
35
+ await promise;
36
+ return true
37
+ } catch (e) {
38
+ return false
39
+ }
40
+ }
41
+
16
42
  const parse_env = async (filename) => {
17
43
  try {
18
44
  const buf = await fs.promises.readFile(filename)
@@ -142,5 +168,5 @@ const update_env = async (filepath, changes) => {
142
168
  await fs.promises.writeFile(filepath, newval)
143
169
  };
144
170
  module.exports = {
145
- parse_env, api_path, update_env, parse_env_detail, openfs
171
+ parse_env, api_path, update_env, parse_env_detail, openfs, port_running
146
172
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "2.15.7",
3
+ "version": "2.15.9",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -31,16 +31,15 @@
31
31
  "fs-extra": "^11.1.1",
32
32
  "glob": "^10.3.3",
33
33
  "glob-gitignore": "^1.0.14",
34
+ "http-proxy": "^1.18.1",
34
35
  "http-proxy-middleware": "^3.0.0",
35
36
  "http-terminator": "^3.2.0",
36
37
  "isomorphic-git": "^1.23.0",
37
38
  "jimini": "^0.0.6",
38
39
  "jsdom": "^24.0.0",
39
- "jsonpath-plus": "^7.2.0",
40
40
  "key-store": "^1.2.0",
41
41
  "kleur": "^4.1.5",
42
42
  "lodash": "^4.17.21",
43
- "lproxy": "^0.0.12",
44
43
  "marked": "^5.0.1",
45
44
  "mime-types": "^2.1.35",
46
45
  "multer": "^1.4.5-lts.1",
package/server/index.js CHANGED
@@ -71,7 +71,6 @@ class Server {
71
71
  process.env[PATH_KEY]
72
72
  ].join(path.delimiter)
73
73
  }
74
-
75
74
  }
76
75
  stop() {
77
76
  this.server.close()
@@ -257,11 +256,11 @@ class Server {
257
256
 
258
257
  await this.init_env("api/" + name)
259
258
 
259
+
260
260
  let mode = "run"
261
261
  if (req.query && req.query.mode) {
262
262
  mode = req.query.mode
263
263
  }
264
-
265
264
  const env = await this.kernel.env("api/" + name)
266
265
 
267
266
  //res.render("browser", {
@@ -1868,7 +1867,11 @@ class Server {
1868
1867
  } else {
1869
1868
  const primary_port = 80
1870
1869
  const secondary_port = 42000
1871
- const available = await portfinder.isAvailablePromise({ host: "0.0.0.0", port: primary_port })
1870
+ const running1 = await Util.port_running("localhost", primary_port)
1871
+ const running2 = await Util.port_running("127.0.0.1", primary_port)
1872
+ const running = running1 || running2
1873
+ const available = !running
1874
+ //const available = await portfinder.isAvailablePromise({ host: "0.0.0.0", port: primary_port })
1872
1875
  console.log("check available", { primary_port, available })
1873
1876
  if (available) {
1874
1877
  this.port = primary_port
@@ -2105,7 +2108,83 @@ class Server {
2105
2108
  Util.openfs(req.body.path)
2106
2109
  res.json({ success: true })
2107
2110
  }))
2111
+ this.app.get("/proxy", ex(async (req, res) => {
2112
+ let live_proxies = this.kernel.api.proxies["/proxy"]
2113
+ if (!live_proxies) live_proxies = []
2114
+ let proxies = [{
2115
+ icon: "ollama.webp",
2116
+ name: "Ollama",
2117
+ target: 'http://127.0.0.1:11434',
2118
+ port: 42420
2119
+ // }, {
2120
+ // name: "LMStudio",
2121
+ // target: 'http://127.0.0.1:1234',
2122
+ // port: 42421
2123
+ }]
2124
+ for(let i=0; i<proxies.length; i++) {
2125
+ proxies[i].running = false
2126
+ for(let live_proxy of live_proxies) {
2127
+ if (live_proxy.name === proxies[i].name) {
2128
+ proxies[i].running = true
2129
+ proxies[i].proxy = live_proxy.proxy
2130
+ proxies[i].qr = await QRCode.toDataURL(live_proxy.proxy)
2131
+ }
2132
+ }
2133
+ }
2134
+
2135
+ let pinokio_proxy = this.kernel.api.proxies["/"]
2136
+ let pinokio_cloudflare = this.cloudflare_pub
2137
+
2138
+ let qr = null
2139
+ let qr_cloudflare = null
2140
+ let home_proxy = null
2141
+ if (pinokio_proxy && pinokio_proxy.length > 0) {
2142
+ qr = await QRCode.toDataURL(pinokio_proxy[0].proxy)
2143
+ home_proxy = pinokio_proxy[0]
2144
+ }
2108
2145
 
2146
+ let icon
2147
+ if (this.theme === "dark") {
2148
+ icon = "pinokio-white.png"
2149
+ } else {
2150
+ icon = "pinokio-black.png"
2151
+ }
2152
+
2153
+ res.render("proxy", {
2154
+ agent: this.agent,
2155
+ theme: this.theme,
2156
+ items: proxies,
2157
+ qr,
2158
+ proxy: home_proxy,
2159
+ localhost: `http://localhost:${this.port}`,
2160
+ icon
2161
+ })
2162
+ }))
2163
+ this.app.post("/proxy", ex(async (req, res) => {
2164
+ /*
2165
+ req.body := {
2166
+ action: "start"|"stop",
2167
+ name: <name>,
2168
+ target: <target url>,
2169
+ port: <proxy port>
2170
+ }
2171
+ */
2172
+ if (req.body && req.body.target && req.body.action && req.body.name) {
2173
+ //let port = new URL(req.body.target).port
2174
+ //let port = await this.kernel.port()
2175
+ if (req.body.action === "start") {
2176
+ let port = req.body.port
2177
+ console.log("start proxy")
2178
+ await this.kernel.api.startProxy("/proxy", req.body.target, req.body.name, { port })
2179
+ console.log(this.kernel.api.proxies)
2180
+ } else if (req.body.action === "stop") {
2181
+ await this.kernel.api.stopProxy({
2182
+ uri: req.body.target
2183
+ })
2184
+ }
2185
+ }
2186
+ res.json({ success: true })
2187
+ }))
2109
2188
  this.app.post("/unpublish", ex(async (req, res) => {
2110
2189
  /*
2111
2190
  req.body := {
@@ -2667,8 +2746,8 @@ class Server {
2667
2746
  fs.uri("api", "https://github.com/cocktailpeanut/llamacpp.pinokio.git/icon.png")
2668
2747
  fs.uri("bin", "python/bin")
2669
2748
 
2670
- 1. Git URI: http://localhost:4200/pinokio/fs?drive=api&path=https://github.com/cocktailpeanut/llamacpp.pinokio.git/icon.png
2671
- 2. Local path: http://localhost:4200/pinokio/fs?drive=api&path=test/icon.png
2749
+ 1. Git URI: http://localhost/pinokio/fs?drive=api&path=https://github.com/cocktailpeanut/llamacpp.pinokio.git/icon.png
2750
+ 2. Local path: http://localhost/pinokio/fs?drive=api&path=test/icon.png
2672
2751
  */
2673
2752
  this.app.get("/pinokio/fs", ex((req, res) => {
2674
2753
  // serve reaw files
@@ -0,0 +1,7 @@
1
+ /*!***************************************************
2
+ * mark.js v8.6.0
3
+ * https://github.com/julmot/mark.js
4
+ * Copyright (c) 2014–2017, Julian Motz
5
+ * Released under the MIT license https://git.io/vwTVl
6
+ *****************************************************/
7
+ "use strict";function _classCallCheck(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var _extends=Object.assign||function(a){for(var b=1;b<arguments.length;b++){var c=arguments[b];for(var d in c)Object.prototype.hasOwnProperty.call(c,d)&&(a[d]=c[d])}return a},_createClass=function(){function a(a,b){for(var c=0;c<b.length;c++){var d=b[c];d.enumerable=d.enumerable||!1,d.configurable=!0,"value"in d&&(d.writable=!0),Object.defineProperty(a,d.key,d)}}return function(b,c,d){return c&&a(b.prototype,c),d&&a(b,d),b}}(),_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};!function(a,b,c){"function"==typeof define&&define.amd?define([],function(){return a(b,c)}):"object"===("undefined"==typeof module?"undefined":_typeof(module))&&module.exports?module.exports=a(b,c):a(b,c)}(function(a,b){var c=function(){function c(b){_classCallCheck(this,c),this.ctx=b,this.ie=!1;var d=a.navigator.userAgent;(d.indexOf("MSIE")>-1||d.indexOf("Trident")>-1)&&(this.ie=!0)}return _createClass(c,[{key:"log",value:function a(b){var c=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"debug",a=this.opt.log;this.opt.debug&&"object"===("undefined"==typeof a?"undefined":_typeof(a))&&"function"==typeof a[c]&&a[c]("mark.js: "+b)}},{key:"escapeStr",value:function(a){return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}},{key:"createRegExp",value:function(a){return a=this.escapeStr(a),Object.keys(this.opt.synonyms).length&&(a=this.createSynonymsRegExp(a)),this.opt.ignoreJoiners&&(a=this.setupIgnoreJoinersRegExp(a)),this.opt.diacritics&&(a=this.createDiacriticsRegExp(a)),a=this.createMergedBlanksRegExp(a),this.opt.ignoreJoiners&&(a=this.createIgnoreJoinersRegExp(a)),a=this.createAccuracyRegExp(a)}},{key:"createSynonymsRegExp",value:function(a){var b=this.opt.synonyms,c=this.opt.caseSensitive?"":"i";for(var d in b)if(b.hasOwnProperty(d)){var e=b[d],f=this.escapeStr(d),g=this.escapeStr(e);a=a.replace(new RegExp("("+f+"|"+g+")","gm"+c),"("+f+"|"+g+")")}return a}},{key:"setupIgnoreJoinersRegExp",value:function(a){return a.replace(/[^(|)\\]/g,function(a,b,c){var d=c.charAt(b+1);return/[(|)\\]/.test(d)||""===d?a:a+"\0"})}},{key:"createIgnoreJoinersRegExp",value:function(a){return a.split("\0").join("[\\u00ad|\\u200b|\\u200c|\\u200d]?")}},{key:"createDiacriticsRegExp",value:function(a){var b=this.opt.caseSensitive?"":"i",c=this.opt.caseSensitive?["aàáâãäåāąă","AÀÁÂÃÄÅĀĄĂ","cçćč","CÇĆČ","dđď","DĐĎ","eèéêëěēę","EÈÉÊËĚĒĘ","iìíîïī","IÌÍÎÏĪ","lł","LŁ","nñňń","NÑŇŃ","oòóôõöøō","OÒÓÔÕÖØŌ","rř","RŘ","sšśș","SŠŚȘ","tťț","TŤȚ","uùúûüůū","UÙÚÛÜŮŪ","yÿý","YŸÝ","zžżź","ZŽŻŹ"]:["aÀÁÂÃÄÅàáâãäåĀāąĄăĂ","cÇçćĆčČ","dđĐďĎ","eÈÉÊËèéêëěĚĒēęĘ","iÌÍÎÏìíîïĪī","lłŁ","nÑñňŇńŃ","oÒÓÔÕÖØòóôõöøŌō","rřŘ","sŠšśŚșȘ","tťŤțȚ","uÙÚÛÜùúûüůŮŪū","yŸÿýÝ","zŽžżŻźŹ"],d=[];return a.split("").forEach(function(e){c.every(function(c){if(c.indexOf(e)!==-1){if(d.indexOf(c)>-1)return!1;a=a.replace(new RegExp("["+c+"]","gm"+b),"["+c+"]"),d.push(c)}return!0})}),a}},{key:"createMergedBlanksRegExp",value:function(a){return a.replace(/[\s]+/gim,"[\\s]+")}},{key:"createAccuracyRegExp",value:function(a){var b=this,c=this.opt.accuracy,d="string"==typeof c?c:c.value,e="string"==typeof c?[]:c.limiters,f="";switch(e.forEach(function(a){f+="|"+b.escapeStr(a)}),d){case"partially":default:return"()("+a+")";case"complementary":return"()([^\\s"+f+"]*"+a+"[^\\s"+f+"]*)";case"exactly":return"(^|\\s"+f+")("+a+")(?=$|\\s"+f+")"}}},{key:"getSeparatedKeywords",value:function(a){var b=this,c=[];return a.forEach(function(a){b.opt.separateWordSearch?a.split(" ").forEach(function(a){a.trim()&&c.indexOf(a)===-1&&c.push(a)}):a.trim()&&c.indexOf(a)===-1&&c.push(a)}),{keywords:c.sort(function(a,b){return b.length-a.length}),length:c.length}}},{key:"getTextNodes",value:function(a){var b=this,c="",d=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,function(a){d.push({start:c.length,end:(c+=a.textContent).length,node:a})},function(a){return b.matchesExclude(a.parentNode,!0)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT},function(){a({value:c,nodes:d})})}},{key:"matchesExclude",value:function(a,b){var c=this.opt.exclude.concat(["script","style","title","head","html"]);return b&&(c=c.concat(["*[data-markjs='true']"])),d.matches(a,c)}},{key:"wrapRangeInTextNode",value:function(a,c,d){var e=this.opt.element?this.opt.element:"mark",f=a.splitText(c),g=f.splitText(d-c),h=b.createElement(e);return h.setAttribute("data-markjs","true"),this.opt.className&&h.setAttribute("class",this.opt.className),h.textContent=f.textContent,f.parentNode.replaceChild(h,f),g}},{key:"wrapRangeInMappedTextNode",value:function(a,b,c,d,e){var f=this;a.nodes.every(function(g,h){var i=a.nodes[h+1];if("undefined"==typeof i||i.start>b){var j=function(){var i=b-g.start,j=(c>g.end?g.end:c)-g.start;if(d(g.node)){g.node=f.wrapRangeInTextNode(g.node,i,j);var k=a.value.substr(0,g.start),l=a.value.substr(j+g.start);if(a.value=k+l,a.nodes.forEach(function(b,c){c>=h&&(a.nodes[c].start>0&&c!==h&&(a.nodes[c].start-=j),a.nodes[c].end-=j)}),c-=j,e(g.node.previousSibling,g.start),!(c>g.end))return{v:!1};b=g.end}}();if("object"===("undefined"==typeof j?"undefined":_typeof(j)))return j.v}return!0})}},{key:"wrapMatches",value:function(a,b,c,d,e){var f=this,g=0===b?0:b+1;this.getTextNodes(function(b){b.nodes.forEach(function(b){b=b.node;for(var e=void 0;null!==(e=a.exec(b.textContent))&&""!==e[g];)if(c(e[g],b)){var h=e.index;if(0!==g)for(var i=1;i<g;i++)h+=e[i].length;b=f.wrapRangeInTextNode(b,h,h+e[g].length),d(b.previousSibling),a.lastIndex=0}}),e()})}},{key:"wrapMatchesAcrossElements",value:function(a,b,c,d,e){var f=this,g=0===b?0:b+1;this.getTextNodes(function(b){for(var h=void 0;null!==(h=a.exec(b.value))&&""!==h[g];){var i=h.index;if(0!==g)for(var j=1;j<g;j++)i+=h[j].length;var k=i+h[g].length;f.wrapRangeInMappedTextNode(b,i,k,function(a){return c(h[g],a)},function(b,c){a.lastIndex=c,d(b)})}e()})}},{key:"unwrapMatches",value:function(a){for(var c=a.parentNode,d=b.createDocumentFragment();a.firstChild;)d.appendChild(a.removeChild(a.firstChild));c.replaceChild(d,a),this.ie?this.normalizeTextNode(c):c.normalize()}},{key:"normalizeTextNode",value:function(a){if(a){if(3===a.nodeType)for(;a.nextSibling&&3===a.nextSibling.nodeType;)a.nodeValue+=a.nextSibling.nodeValue,a.parentNode.removeChild(a.nextSibling);else this.normalizeTextNode(a.firstChild);this.normalizeTextNode(a.nextSibling)}}},{key:"markRegExp",value:function(a,b){var c=this;this.opt=b,this.log('Searching with expression "'+a+'"');var d=0,e="wrapMatches",f=function(a){d++,c.opt.each(a)};this.opt.acrossElements&&(e="wrapMatchesAcrossElements"),this[e](a,this.opt.ignoreGroups,function(a,b){return c.opt.filter(b,a,d)},f,function(){0===d&&c.opt.noMatch(a),c.opt.done(d)})}},{key:"mark",value:function(a,b){var c=this;this.opt=b;var d=0,e="wrapMatches",f=this.getSeparatedKeywords("string"==typeof a?[a]:a),g=f.keywords,h=f.length,i=this.opt.caseSensitive?"":"i",j=function a(b){var f=new RegExp(c.createRegExp(b),"gm"+i),j=0;c.log('Searching with expression "'+f+'"'),c[e](f,1,function(a,e){return c.opt.filter(e,b,d,j)},function(a){j++,d++,c.opt.each(a)},function(){0===j&&c.opt.noMatch(b),g[h-1]===b?c.opt.done(d):a(g[g.indexOf(b)+1])})};this.opt.acrossElements&&(e="wrapMatchesAcrossElements"),0===h?this.opt.done(d):j(g[0])}},{key:"unmark",value:function(a){var b=this;this.opt=a;var c=this.opt.element?this.opt.element:"*";c+="[data-markjs]",this.opt.className&&(c+="."+this.opt.className),this.log('Removal selector "'+c+'"'),this.iterator.forEachNode(NodeFilter.SHOW_ELEMENT,function(a){b.unwrapMatches(a)},function(a){var e=d.matches(a,c),f=b.matchesExclude(a,!1);return!e||f?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT},this.opt.done)}},{key:"opt",set:function(b){this._opt=_extends({},{element:"",className:"",exclude:[],iframes:!1,separateWordSearch:!0,diacritics:!0,synonyms:{},accuracy:"partially",acrossElements:!1,caseSensitive:!1,ignoreJoiners:!1,ignoreGroups:0,each:function(){},noMatch:function(){},filter:function(){return!0},done:function(){},debug:!1,log:a.console},b)},get:function(){return this._opt}},{key:"iterator",get:function(){return this._iterator||(this._iterator=new d(this.ctx,this.opt.iframes,this.opt.exclude)),this._iterator}}]),c}(),d=function(){function a(b){var c=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],d=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];_classCallCheck(this,a),this.ctx=b,this.iframes=c,this.exclude=d}return _createClass(a,[{key:"getContexts",value:function(){var a=void 0,c=[];return a="undefined"!=typeof this.ctx&&this.ctx?NodeList.prototype.isPrototypeOf(this.ctx)?Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?this.ctx:"string"==typeof this.ctx?Array.prototype.slice.call(b.querySelectorAll(this.ctx)):[this.ctx]:[],a.forEach(function(a){var b=c.filter(function(b){return b.contains(a)}).length>0;c.indexOf(a)!==-1||b||c.push(a)}),c}},{key:"getIframeContents",value:function(a,b){var c=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){},d=void 0;try{var e=a.contentWindow;if(d=e.document,!e||!d)throw new Error("iframe inaccessible")}catch(a){c()}d&&b(d)}},{key:"onIframeReady",value:function(a,b,c){var d=this;try{!function(){var e=a.contentWindow,f="about:blank",g="complete",h=function(){var b=a.getAttribute("src").trim(),c=e.location.href;return c===f&&b!==f&&b},i=function(){var e=function e(){try{h()||(a.removeEventListener("load",e),d.getIframeContents(a,b,c))}catch(a){c()}};a.addEventListener("load",e)};e.document.readyState===g?h()?i():d.getIframeContents(a,b,c):i()}()}catch(a){c()}}},{key:"waitForIframes",value:function(a,b){var c=this,d=0;this.forEachIframe(a,function(){return!0},function(a){d++,c.waitForIframes(a.querySelector("html"),function(){--d||b()})},function(a){a||b()})}},{key:"forEachIframe",value:function(b,c,d){var e=this,f=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},g=b.querySelectorAll("iframe"),h=g.length,i=0;g=Array.prototype.slice.call(g);var j=function(){--h<=0&&f(i)};h||j(),g.forEach(function(b){a.matches(b,e.exclude)?j():e.onIframeReady(b,function(a){c(b)&&(i++,d(a)),j()},j)})}},{key:"createIterator",value:function(a,c,d){return b.createNodeIterator(a,c,d,!1)}},{key:"createInstanceOnIframe",value:function(b){return new a(b.querySelector("html"),this.iframes)}},{key:"compareNodeIframe",value:function(a,b,c){var d=a.compareDocumentPosition(c),e=Node.DOCUMENT_POSITION_PRECEDING;if(d&e){if(null===b)return!0;var f=b.compareDocumentPosition(c),g=Node.DOCUMENT_POSITION_FOLLOWING;if(f&g)return!0}return!1}},{key:"getIteratorNode",value:function(a){var b=a.previousNode(),c=void 0;return c=null===b?a.nextNode():a.nextNode()&&a.nextNode(),{prevNode:b,node:c}}},{key:"checkIframeFilter",value:function(a,b,c,d){var e=!1,f=!1;return d.forEach(function(a,b){a.val===c&&(e=b,f=a.handled)}),this.compareNodeIframe(a,b,c)?(e!==!1||f?e===!1||f||(d[e].handled=!0):d.push({val:c,handled:!0}),!0):(e===!1&&d.push({val:c,handled:!1}),!1)}},{key:"handleOpenIframes",value:function(a,b,c,d){var e=this;a.forEach(function(a){a.handled||e.getIframeContents(a.val,function(a){e.createInstanceOnIframe(a).forEachNode(b,c,d)})})}},{key:"iterateThroughNodes",value:function(a,b,c,d,e){for(var f=this,g=this.createIterator(b,a,d),h=[],i=[],j=void 0,k=void 0,l=function(){var a=f.getIteratorNode(g);return k=a.prevNode,j=a.node};l();)this.iframes&&this.forEachIframe(b,function(a){return f.checkIframeFilter(j,k,a,h)},function(b){f.createInstanceOnIframe(b).forEachNode(a,c,d)}),i.push(j);i.forEach(function(a){c(a)}),this.iframes&&this.handleOpenIframes(h,a,c,d),e()}},{key:"forEachNode",value:function(a,b,c){var d=this,e=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},f=this.getContexts(),g=f.length;g||e(),f.forEach(function(f){var h=function(){d.iterateThroughNodes(a,f,b,c,function(){--g<=0&&e()})};d.iframes?d.waitForIframes(f,h):h()})}}],[{key:"matches",value:function(a,b){var c="string"==typeof b?[b]:b,d=a.matches||a.matchesSelector||a.msMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.webkitMatchesSelector;if(d){var e=!1;return c.every(function(b){return!d.call(a,b)||(e=!0,!1)}),e}return!1}}]),a}();return a.Mark=function(a){var b=this,d=new c(a);return this.mark=function(a,c){return d.mark(a,c),b},this.markRegExp=function(a,c){return d.markRegExp(a,c),b},this.unmark=function(a){return d.unmark(a),b},this},a.Mark},window,document);
Binary file