open-index/open-npm huggingface dataset:
npm package: @lichunshan/pdf-preview
Description: pdfjs-dist based mobile pdf preview component
Author: lichunshan
Latest version: 1.0.4

# pdf-preview

> 基于pdfjs-dist的移动端vue pdf预览组件

## Install
```bash
npm install @lichunshan/pdf-preview
```
## Usage
在项目的main.js引入入下面代码全局注册组件
```JavaScript
import pdfPreview from '@lichunshan/pdf-preview'
import '@lichunshan/pdf-preview/dist/pdf-preview.common.vendors~pdfjsWorker.js'
import '@lichunshan/pdf-preview/dist/pdf-preview.css'
import '@lichunshan/pdf-preview/src/assets/iconfont.css'
Vue.use(pdfPreview);
```

在.vue文件中使用

```
<pdf-preview src=""></pdf-preview>
```

src为pdf文件路径

## Config

#### 组件属性

| 属性（prop） | 值（value：Boolean） | 描述（desc）    |
| ------------ | -------------------- | --------------- |
| toolbar      | default（true）      | 是否显示toolbar |
| src          | default（''）        | pdf文件路径     |
npm package: @licity/openclaw-local-connector
Description: 里世界 OpenClaw 本地连接器，支持 OpenClaw 与 QClaw 等第三方本地 Runtime 扫码接入
Latest version: 2.0.0
Deprecated: 已废弃，请使用新版: npx @licity/openclaw-connector

# 里世界 OpenClaw 本地连接器

里世界 OpenClaw 本地连接器支持 OpenClaw 和第三方本地 Runtime，例如 QClaw。

用途很简单：把你电脑上的 Runtime 连接到里世界 APP，让一只龙虾真正运行在你的本机上。

## 一键启动

直接运行：

```bash
npx @licity/openclaw-local-connector
```

如果你想长期使用：

```bash
npm install -g @licity/openclaw-local-connector
```

安装后运行：

```bash
licity-openclaw
```

## 使用步骤

1. 先启动你的本地 Runtime。
2. 在电脑命令行运行连接器。
3. 终端会直接显示二维码。
4. 打开里世界 APP，进入“我的龙虾”，点击“扫码连接本地龙虾”。
5. 扫码后选择一只龙虾确认绑定。
6. 看到龙虾显示“在线”后，先发一句“请只回复：已收到”做测试。

## 适用对象

- 官方 OpenClaw Runtime 用户
- QClaw 用户
- 其他兼容 OpenClaw CLI 的本地 Runtime 用户

## 当前能力

- 扫码绑定
- 心跳保活
- 私聊消息转发
- 图片与文件回传
- 重新扫码接管当前连接

## 常见问题

### 连接器能启动，但龙虾不回复

先检查本地 Runtime 是否已经启动，以及本地模型网关是否可访问。

### PowerShell 提示脚本无法执行

以管理员身份打开 PowerShell 后执行：

```powershell
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
```

### 需要手动填写密钥吗

不需要。运行命令后直接扫码即可。

## 高级说明

如果你的 Runtime 安装在非常规位置，连接器会自动生成一份 .env 模板，你只需要在少数特殊环境里补充本机路径。
npm package: @licium/toastmark
Description: ToastMark - Incremental markdown parser extended from CommonMark.js
Author: NHN
Latest version: 3.2.14

> This is a fork of the [Toast UI Editor](https://github.com/natorus87/tui.editor) maintained by `@licium`.
> Original repository: https://github.com/natorus87/tui.editor

# ToastMark

ToastMark is a markdown parser extended from [commonmark.js](https://github.com/commonmark/commonmark.js), with more advanced features to be used within TOAST UI Editor. 

> Currently, ToastMark is for interal usage only as the API's are supposed to be changed frequently. We are planning to register this as a separate npm package when API's are stabilized.

## Differences from commonmark.js

### GitHub Flavored Markdown(GFM) Support
commonmark.js is the reference implementation of [CommonMark](https://spec.commonmark.org/0.29/) and doesn't support [GFM](https://github.github.com/gfm/), which is extended markdown syntax based on CommonMark. ToastMark has its own implementation for supporting GFM.

### Source Position Information
Although commonmark.js provides source position information related with each node in AST(Abstract Syntax Tree), those are limited to block-level elements. ToastMark extended this feature to provide source position information for inline-level elements also.

### Incremental Parsing
As ToastMark is developed for the purpose of improving markdown editing experience, this must be the key feature of ToastMark. Instead of parsing the entire document whenever a user makes a change to a document, ToastMark parses only changed part of the document and update the existing AST. It also returns information about removed and inserted nodes, which can be used to update syntax highlithing or preview contents incrementally.

### Searching and Editing AST
ToastMark provides useful methods to search the existing AST, such as `findNodeAtPosition` and `findNodeById`. These methods can be used for synchronizing scroll position of markdown editor and preview contents, updating the style of the toolbar buttons correspond to the cursor position, and so on. We are also planning to add more methods to edit existing AST to support commands like `Bold`, `Italic`, and `OrderedList` which can be triggered by toolbar buttons and keyboard shortcuts.

### TypeScript
The entire codebase is converted from JavaScript to TypeScript.
npm package: @lickle/cn
Description: A tiny utility for conditionally joining classNames together.
Author: Dan Beaven
Latest version: 0.0.1

A tiny utility for conditionally joining classNames together.

[![Build Status](https://img.shields.io/github/actions/workflow/status/Pingid/lickle-cn/test.yml?branch=main&style=flat&colorA=000000&colorB=000000)](https://github.com/Pingid/lickle-cn/actions?query=workflow:Test)
[![Build Size](https://img.shields.io/bundlephobia/minzip/@lickle/cn?label=bundle%20size&style=flat&colorA=000000&colorB=000000)](https://bundlephobia.com/result?p=@lickle/cn)
[![Version](https://img.shields.io/npm/v/@lickle/cn?style=flat&colorA=000000&colorB=000000)](https://www.npmjs.com/package/@lickle/cn)
[![Downloads](https://img.shields.io/npm/dt/@lickle/cn.svg?style=flat&colorA=000000&colorB=000000)](https://www.npmjs.com/package/@lickle/cn)

```bash
npm install @lickle/cn # or yarn add @lickle/cn or pnpm add @lickle/cn or jsr add @lickle/cn
```

This utility is similar to [clx](https://github.com/lukeed/clsx) or [classnames](https://github.com/JedWatson/classnames), with an additional tuple syntax `[boolean, show if true, show if false]`.

Unlike those libraries, this provides two versions of the function:

- **tcn**: Returns a string literal type (useful for better IDE autocomplete and type inference).
- **cn**: Returns a string type

## Usage

```typescript
import { cn, tcn } from '@lickle/cn'

// Basic usage
cn('rounded-full', active && 'bg-blue')

// Conditional classes using objects
cn('bg-white', { 'border-blue': active })

// Tuple syntax for conditional rendering
cn([active, 'border-black', 'border-white'])

// Falsy values are ignored
cn(null, undefined, false, true)

// Type inference in action
const classes = tcn('bg-white', [active, 'border-blue', 'border-white'])
// Inferred type: "bg-white border-blue" | "bg-white border-white"
```

## Tailwind Support

Enable classes autocompletion using `cn` with Tailwind CSS.

<details>

<summary>
  Visual Studio Code
</summary>

1. [Install the "Tailwind CSS IntelliSense" Visual Studio Code extension](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss)

2. Add the following to your [`settings.json`](https://code.visualstudio.com/docs/getstarted/settings):

```json
{
  "tailwindCSS.experimental.classRegex": [
    ["cn\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"],
    ["tcn\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
  ]
}
```

</details>

## License

MIT © [Dan Beaven](https://github.com/Pingid)
npm package: @lickle/dom
Description: Library of dom utility functions
Author: Dan Beaven
Latest version: 0.0.3

A tiny utility library for simplifying DOM event handling.

[![Build Status](https://img.shields.io/github/actions/workflow/status/Pingid/lickle-dom/test.yml?branch=main&style=flat&colorA=000000&colorB=000000)](https://github.com/Pingid/lickle-dom/actions?query=workflow:Test)
[![Build Size](https://img.shields.io/bundlephobia/minzip/%40lickle%2Fdom?label=bundle%20size&style=flat&colorA=000000&colorB=000000)](https://bundlephobia.com/result?p=%40lickle%2Fdom)
[![Version](https://img.shields.io/npm/v/%40lickle%2Fdom?style=flat&colorA=000000&colorB=000000)](https://www.npmjs.com/package/%40lickle%2Fdom)

## Installation

Install using your preferred package manager:

```bash
npm install @lickle/dom
# or
yarn add @lickle/dom
# or
pnpm add @lickle/dom
```

## Usage

The `on` function wraps `addEventListener` and returns an unsubscribe function, making it easy to manage event listeners.

```ts
import { on } from '@lickle/dom'

const unsubscribe = on(document)('mousemove', (e) => console.log('Mouse moved!', e))
...
unsubscribe()
```

The `dispose` utility lets you merge multiple unsubscribe functions into one. This is handy for managing multiple listeners at once.

```ts
import { on, dispose } from '@lickle/dom'

const unsubscribeAll = dispose(
  on(document)('mousemove', (e) => console.log('Mouse moved!')),
  on(document)('mousedown', (e) => console.log('Mouse down!')),
  on(document)('mouseup', (e) => console.log('Mouse up!')),
)

...
unsubscribeAll()
```

The core of the library is the on function, which provides a type-safe, declarative way to add and remove DOM event listeners. While the implementation itself is simple, the power of the library lies in the [On type](./src/events/on.ts), which is designed to provide precise typings for various DOM targets and their respective events.

## Why?

This library is for developers who value concise, declarative, and type-safe code. It is especially useful in frontend frameworks like React, where managing event listeners throughout a component's lifecycle is common. For example:

```ts
import { on } from '@lickle/dom'
import { useEffect } from 'react'

useEffect(() => {
  return on(document)('mousemove', () => {
    console.log('Mouse moved!')
  })
}, [])
```

## License

MIT © [Dan Beaven](https://github.com/lickle-dom)
npm package: @lickle/lock-darwin-arm64
Description: File-based locking for Node.js using native OS locks (`flock` on Unix, `LockFileEx` on Windows).
Author: Dan Beaven
Latest version: 0.0.1

# `@lickle/lock-darwin-arm64`

This is the **aarch64-apple-darwin** binary for `@lickle/lock`
npm package: @lickle/lock-darwin-x64
Description: File-based locking for Node.js using native OS locks (`flock` on Unix, `LockFileEx` on Windows).
Author: Dan Beaven
Latest version: 0.0.1

# `@lickle/lock-darwin-x64`

This is the **x86_64-apple-darwin** binary for `@lickle/lock`
npm package: @lickle/lock-linux-x64-gnu
Description: File-based locking for Node.js using native OS locks (`flock` on Unix, `LockFileEx` on Windows).
Author: Dan Beaven
Latest version: 0.0.1

# `@lickle/lock-linux-x64-gnu`

This is the **x86_64-unknown-linux-gnu** binary for `@lickle/lock`
npm package: @lickle/lock-win32-x64-msvc
Description: File-based locking for Node.js using native OS locks (`flock` on Unix, `LockFileEx` on Windows).
Author: Dan Beaven
Latest version: 0.0.1

# `@lickle/lock-win32-x64-msvc`

This is the **x86_64-pc-windows-msvc** binary for `@lickle/lock`
npm package: @lickle/log
Description: A tiny structured logging utility that includes, customizable transports and metadata.
Author: Dan Beaven
Latest version: 0.0.2

# A little logger

A tiny structured logging utility that includes, customizable transports, metadata.

[![Build Status](https://img.shields.io/github/actions/workflow/status/Pingid/lickle-log/test.yml?branch=main&style=flat&colorA=000000&colorB=000000)](https://github.com/Pingid/lickle-log/actions?query=workflow:Test)
[![Build Size](https://img.shields.io/bundlephobia/minzip/@lickle/log?label=bundle%20size&style=flat&colorA=000000&colorB=000000)](https://bundlephobia.com/result?p=@lickle/log)
[![Version](https://img.shields.io/npm/v/@lickle/log?style=flat&colorA=000000&colorB=000000)](https://www.npmjs.com/package/@lickle/log)
[![Downloads](https://img.shields.io/npm/dt/@lickle/log.svg?style=flat&colorA=000000&colorB=000000)](https://www.npmjs.com/package/@lickle/log)

## Install

Install the `@lickle/log` library using your preferred package manager:

```bash
npm install @lickle/log
```

## Usage

### Default Logger

The default logger uses a console-based structured logger transport. Here's how to use it:

```typescript
import log from '@lickle/log'

log.info`initialised`
// Output: { level: 'info', time: '...', msg: 'initialised' }

log.info({ userId: '...' })`user authenticated`
// Output: { level: 'info', time: '...', msg: 'user authenticated', meta: { userId: '...' } }

log.info('started tast')
// Output: { level: 'info', time: '...', msg: 'started tast' }

log.error(new Error('task failed'))
// Output: { level: 'error', time: '...', msg: 'task failed', meta: { stack: '...' } }
```

#### Adding Metadata

The logger's metadata is stored in the meta property. You can update it directly, and any additional metadata passed to a log call will be merged with this global metadata.

```typescript
import log from '@lickle/log'

log.meta['requestId'] = '123'

log.info`start`
// Output: { level: 'info', time: '...', msg: 'start', meta: { requestId: '123' } }
```

#### Customizing the Transport

Customize the transport function for the logger:

```typescript
import log from '@lickle/log'

log.transport = (log) => {
  if (log.level === 'error') sendToServer({ ...log, time: Date.now() })
  console.log(`[${log.level.toUpperCase()}] ${log.msg}`, log.meta)
}
```

### Creating a New Logger

You can create a new logger instance with custom configurations:

```typescript
import { create } from '@lickle/log'

const log = create({
  meta: { service: 'auth' },
  transport: (lg) => console[lg.level](`[${lg.time}] ${lg.msg}\n${JSON.stringify(lg.meta)}`),
})

log.info`foo`
```

## License

This project is licensed under the MIT License.

MIT © [Dan Beaven](https://github.com/Pingid)
npm package: @lickle/state
Description: Library of reactive state primities
Author: Dan Beaven
Latest version: 0.0.0-dev.3

# Lickle State

A lightweight reactive pub/sub utility for `Map`, `Set`, and plain objects.

[![Build Status](https://img.shields.io/github/actions/workflow/status/Pingid/lickle-state/test.yml?branch=main&style=flat&colorA=000000&colorB=000000)](https://github.com/Pingid/lickle-state/actions?query=workflow:Test)
[![Build Size](https://img.shields.io/bundlephobia/minzip/%40lickle%2Fstate?label=bundle%20size&style=flat&colorA=000000&colorB=000000)](https://bundlephobia.com/result?p=%40lickle%2Fstate)
[![Version](https://img.shields.io/npm/v/%40lickle%2Fstate?style=flat&colorA=000000&colorB=000000)](https://www.npmjs.com/package/%40lickle%2Fstate)

## Installation

```bash
npm install @lickle/state
# or
yarn add @lickle/state
# or
pnpm add @lickle/state
```

---

## Usage

### Reactive Objects

Wrap any object, `Map`, or `Set` to make them reactive:

```ts
import { reactiveRecord, reactiveMap, reactiveSet, subscribe } from '@lickle/state'

// Reactive object
const state = reactiveRecord({ count: 0 })
subscribe(state, 'count', () => console.log(`Count: ${state.count}`))
state.count += 1 // Logs: Count: 1

// Reactive map
const map = reactiveMap(new Map())
subscribe(map, 'key', () => console.log('Key changed!'))
map.set('key', 'value') // Logs: Key changed!

// Reactive set
const set = reactiveSet(new Set())
subscribe(set, () => console.log('Set updated!'))
set.add('item') // Logs: Set updated!
```

---

### Batch Updates

Group multiple updates to trigger a single notification:

```ts
import { batch } from '@lickle/state'

batch(state, () => {
  state.count += 1
  state.count += 1
}) // Logs: Count: 2 (once)
```

---

### Suspend Listeners

Pause notifications while making updates:

```ts
import { suspend } from '@lickle/state'

suspend(state, () => {
  state.count += 1
}) // No logs
```

---

## License

MIT © [Dan Beaven](https://github.com/Pingid)
npm package: @lickle/trace
Description: A minimal, structured tracing utility for TypeScript/JavaScript, inspired by Rust's tracing crate. It provides spans, events, and a higher-level logging abstraction.
Author: Dan Beaven
Latest version: 0.0.1-alpha.5

# @lickle/trace

Minimal structured tracing for TypeScript/JavaScript, inspired by Rust’s [`tracing`](https://docs.rs/tracing).  
Provides **spans**, **events**, and a pluggable subscriber system.

[![Build Status](https://img.shields.io/github/actions/workflow/status/Pingid/lickle-trace/test.yml?branch=main&style=flat&colorA=000000&colorB=000000)](https://github.com/Pingid/lickle-trace/actions?query=workflow:Test)
[![Build Size](https://img.shields.io/bundlephobia/minzip/@lickle/trace?label=bundle%20size&style=flat&colorA=000000&colorB=000000)](https://bundlephobia.com/result?p=@lickle/trace)
[![Version](https://img.shields.io/npm/v/@lickle/trace?style=flat&colorA=000000&colorB=000000)](https://www.npmjs.com/package/@lickle/trace)
[![Downloads](https://img.shields.io/npm/dt/@lickle/trace.svg?style=flat&colorA=000000&colorB=000000)](https://www.npmjs.com/package/@lickle/trace)

## Install

```bash
npm install @lickle/trace
```

---

## Quick Start

By default nothing is logged—you need to attach a **subscriber**.  
The simplest option is the built-in `ConsoleLayer`:

```ts
import { Builder, ConsoleLayer, Level } from '@lickle/trace/subscribe'

new Builder().withMinLevel(Level.INFO).withLayer(new ConsoleLayer()).install()
```

Now `INFO`+ events will print to the console.

---

## Examples

### Events

```ts
import { event, Level } from '@lickle/trace/trace'

event('startup', Level.INFO, 'Application ready')
// [INFO] (startup): Application ready
```

### Spans

```ts
import { span, exit, Level } from '@lickle/trace/trace'

const s = span('db.query', Level.DEBUG, { sql: 'SELECT *' })
try {
  // run query...
} finally {
  exit.exit(s)
}
// [DEBUG] enter -> (db.query)
// [DEBUG] exit <- (db.query) 5.67ms { sql: 'SELECT *' }
```

### Custom Subscriber

```ts
import { Builder } from '@lickle/trace/subscribe'
import { Level, Subscriber } from '@lickle/trace/trace'

const metrics: Subscriber = {
  minLevel: Level.INFO,
  onEvent(evt) {
    console.log(`METRIC: Event '${evt.meta.name}'`)
  },
}

new Builder().withLayer(metrics).install()
```

---

## API

### Core (`@lickle/trace/trace`)

- `Trace` – manages spans and events
- `event(name, level, message?, fields?)`
- `span(name, level?, fields?) → Span`
- `enter(span)`, `exit(span)`
- `setSubscriber(sub)`, `getSubscriber()`
- `defaultTrace` – global instance
- `Level` – severity enum (`TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`)

### Subscribe (`@lickle/trace/subscribe`)

- `Builder` – fluent builder for subscribers
  - `.withMinLevel(level)`
  - `.withLayer(subscriber)`
  - `.install(trace?)`
- `ConsoleLayer` – logs spans/events to the console

---

## License

MIT © [Dan Beaven](https://github.com/Pingid)
npm package: @licoded/koa-puppeteer
Description: A tool library based on koa and puppeteer, which can speed up your development.
Author: licoded
Latest version: 1.0.6

# koa-puppeteer
A tool library based on koa and puppeteer, which can speed up your development.

## Document

Click [here](./docs/usages.md) for detailed documentation

## Quick Start

### Installation

```bash
PUPPETEER_DOWNLOAD_HOST=https://storage.googleapis.com.cnpmjs.org npm install --save @licoded/koa-puppeteer
```

> `PUPPETEER_DOWNLOAD_HOST=https://storage.googleapis.com.cnpmjs.org` prefix is to speed up Chromium download in **China**.  
> If you are not in China, you may need to remove the prefix

### Choose syntax to import

You can choose to use CommonJS syntax or ES Module syntax. Note that the default syntax of npm/nodejs project is CommonJS, if you want to use ES Module syntax, you need to add configuration `"type": "module"` in package.json. And when using ES Module syntax, the import path must be written in full.

#### CommonJS 

```js
const { MyKoa } = require('@licoded/koa-puppeteer');
const { createRouter } = require('@licoded/koa-puppeteer/lib/router');
```

#### ES Module

```js
import { MyKoa } from '@licoded/koa-puppeteer';
import { createRouter } from '@licoded/koa-puppeteer/lib/router/index.js';
```

### Code Example

```js
const testRouter = createRouter('/test');

testRouter.get('/test', (ctx) => {
  ctx.body = 'hello';
});

new MyKoa({
  port: 3000,
  debug: false,
  launch: {
    userDataDir: '/Users/lic/dev/products/my-koa-cli/workspace',
  },
  routers: [testRouter],
}).run();
```
npm package: @licoded/mlement
Description: A toy component library for self-use.
Author: licoded
Latest version: 1.0.7

# mlement
A toy component library for self-use.

## 后续计划

### Todos

- [ ] 去掉与github package的关联
- [ ] git提交记录整洁清晰化
- [ ] npm包发布前如何测试
- [ ] npm包版本号规范
- [ ] npm包版本号能否自动变更
- [ ] npm包安装时一堆的babel报错
npm package: @licoded/osx-wifi-cli
Description: A command line tool for managing wifi connection in osx
Author: licoded
Latest version: 1.0.0

# osx-wifi-cli

[![Build Status](https://travis-ci.org/danyshaanan/osx-wifi-cli.png)](https://travis-ci.org/danyshaanan/osx-wifi-cli)
[![NPM Version](https://img.shields.io/npm/v/osx-wifi-cli.svg?style=flat)](https://npmjs.org/package/osx-wifi-cli)
[![License](http://img.shields.io/npm/l/osx-wifi-cli.svg?style=flat)](LICENSE)
[![Dependency Status](https://david-dm.org/danyshaanan/osx-wifi-cli.svg)](https://david-dm.org/danyshaanan/osx-wifi-cli)
[![devDependency Status](https://david-dm.org/danyshaanan/osx-wifi-cli/dev-status.svg)](https://david-dm.org/danyshaanan/osx-wifi-cli#info=devDependencies)

A command line tool for managing wifi connections on OSX

* * *
### Installation
```bash
$ npm install -g osx-wifi-cli
```
* * *
### Usage

`osx-wifi-cli` shows name of current connected network.

`osx-wifi-cli network` shows information about current connected network.

`osx-wifi-cli pass` shows password for current connected network.

`osx-wifi-cli scan` shows available networks.

`osx-wifi-cli on`, `osx-wifi-cli off`, and `osx-wifi-cli restart` control the wifi device state.

`osx-wifi-cli NETWORK PASSWORD` tries to connects to NETWORK with PASSWORD.

* * *
### Notes
* For easier use, add to your `.bashrc` file: `alias wifi='osx-wifi-cli'`
* To connect to network without a password (bad idea!) use `osx-wifi-cli networkname " "`

* * *
### Feedback
* If you enjoyed this package, please star it [on Github](https://github.com/danyshaanan/osx-wifi-cli).
* You are invited to [Open an issue on Github](https://github.com/danyshaanan/osx-wifi-cli/issues).
* For other matters, my email address can be found on my [NpmJS page](https://www.npmjs.org/~danyshaanan), my [Github page](https://github.com/danyshaanan), or my [website](http://danyshaanan.com/).
npm package: @licoded/puppeteer-evaluate2
Description: Easily create a js/ts bundle for your puppeteer evaluate code.
Author: licoded
Latest version: 1.0.0

# puppeteer-evaluate2

Easily create a js bundle for your `puppeteer` `evaluate` code.
## Install
> npm install --save puppeteer-evaluate2@beta
## Why?
Puppeteer stringifies all code that should be executed via the `evaluate` method.
This means it loses all information about closures etc.

This simple code will already fail at runtime:
```js
  const message = "hello world";
  await page.evaluate(() => console.log(message));
```
The `message` closure will not be available when the `evaluate` code is executed on the browser.

`puppeteer-evaluate2` solves this by creating a js bundle on the fly. In fact it is using webpack to create a bundle in memory, on the fly, that is then sent to the browser.

All you need to do is pass in your puppeteer `page` instance and the path to your entry js file:

## Usage
```js
import { evaluate2 } from "puppeteer-evaluate2";

(async () => {
    //normale puppeteer usage...
    const browser = await puppeteer.launch({headless: true});
    const page = await browser.newPage();
    //...

    //easily evaluate separate file "code.js"
    //will throw if file is not found/on compile errors
    await evaluate2(page, "./code.js");

    //...
    await browser.close();
})();
```
The entry js file *must* export a default function:
```js
//code.js
export default function() {
    //all your code
}
```
Now you can nicely structure your code into several files, `puppeteer-evaluate2` will make sure that it gets included and is available: 
```js
//code.js
import { foo } from "./util";

export default function() {
    //foo will be available and ready to use
}
```
In fact you can import node modules as well:
```js
//code.js
export default function() {
    const chunk = require("lodash/chunk");

    return chunk([1, 2, 3, 4], 2);
}
```

If you want to return stuff, just return it :smirk:

Note that return values will still get serialized, like they normally would with the built in `evaluate` method.
This is a hard limitation by puppeteer itself. There's nothing that could be done here.
```js
//code.js
export default function() {
    return Array.from(document.getElementsByTagName("div")).length;
}
```
```js
const numDivs = await evaluate2(page, "./code.js");
console.log(`Found ${numDivs} divs`)
```

## Todo
* TypeScript support
* JSX support?
npm package: @licq/cos
Description: 封装腾讯cos上传相关的方法
Author: ostwindli
Latest version: 2.1.5

# @licq/cos

基于腾讯 cos nodesdk, 封装批量上传方法，特点是简单，并发效率高

[![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]

[npm-image]: http://img.shields.io/npm/v/@licq/cos.svg?style=flat-square
[npm-url]: http://npmjs.org/package/@licq/cos
[download-image]: https://img.shields.io/npm/dm/@licq/cos.svg?style=flat-square
[download-url]: https://npmjs.org/package/@licq/cos

## 安装

```js
npm i --save-dev @licq/cos
```

## API

### Cos 

腾讯云对象存储cos上传


**Returns**: instanceof COS  
**Since**: v2.0.0  

| Param | Type | Description |
| --- | --- | --- |
| Config | <code>Object</code> | 对象存储参数 参考：<https://cloud.tencent.com/document/product/436/8629#.E9.85.8D.E7.BD.AE.E9.A1.B9> |
| Config.SecretId | <code>String</code> | 必填 |
| Config.SecretKey | <code>String</code> | 必填 |
| Config.CosObjectConfig | <code>Object</code> | 参见 <https://cloud.tencent.com/document/product/436/64980#.E7.AE.80.E5.8D.95.E4.B8.8A.E4.BC.A0.E5.AF.B9.E8.B1.A1> 中的参数说明 |
| Config.CosObjectConfig.Bucket | <code>String</code> | 必填 |
| Config.CosObjectConfig.Region | <code>String</code> | 必填 |
| Config.CosObjectConfig.ACL | <code>String</code> | 可选 默认：'public-read' |
| Config.ExtConfig | <code>Object</code> | 可选 本工具自定义参数 |
| Config.ExtConfig.Domain | <code>String</code> | 可选 上传后的域名 默认：https://{Bucket}.cos.{Region}.myqcloud.com |

**Example**  
```js
const Cos = require('@licq/cos');
const cos = new Cos({
   SecretId: "SECRET_ID",
   SecretKey: "SECRET_KEY",
   CosObjectConfig: {
      Bucket: "test-12345678",
      Region: "ap-guangzhou",
      ACL: 'default'
   },
   ExtConfig: {
      Domain: 'https://demos.gtimg.cn/',
   }
});

await cos.uploadFiles(__dirname, 'ost/cos/demo');
```

* [Cos](#Cos) 

    * [.uploadFiles(localPath, cosPath)](#Cos+uploadFiles) 

    * [.uploadFileByData(cosPath, fileData)](#Cos+uploadFileByData) 


#### cos.uploadFiles(localPath, cosPath) 

批量上传


**Returns**: Promise  

| Param | Type | Description |
| --- | --- | --- |
| localPath | <code>String</code> | 本地文件/目录的绝对路径 |
| cosPath | <code>String</code> | cos的path |

#### cos.uploadFileByData(cosPath, fileData) 

通过文件数据上传


**Returns**: Promise<>  
**Since**: v2.1.3  

| Param | Type | Description |
| --- | --- | --- |
| cosPath | <code>String</code> | cos路径 |
| fileData | <code>Buffer</code> \| <code>String</code> \| <code>Stream</code> | 文件数据 |
npm package: @licq/date
Description: 封装一些日期的操作方法
Author: ostwindli
Latest version: 1.0.5


# @licq/date

封装一些日期的操作方法

[![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]

[npm-image]: http://img.shields.io/npm/v/@licq/date.svg?style=flat-square
[npm-url]: http://npmjs.org/package/@licq/date
[download-image]: https://img.shields.io/npm/dm/@licq/date.svg?style=flat-square
[download-url]: https://npmjs.org/package/@licq/date
## 安装

```js
npm i --save-dev @licq/date
```

## API
### formatTime 

格式化日期


**Returns**: String  
**Since**: v1.0.0  

| Param | Type | Description |
| --- | --- | --- |
| format | <code>String</code> | 格式 default: 'yyyy-MM-dd hh:mm:ss' |
| date | <code>Date</code> | 日期 default: new Date() |

**Example**  
```js
const date = require('@licq/date')
const res = date.formatTime()
//==> eg: 2022-01-09 17:58:02

const res = date.formatTime('yyyy-MM-dd')
//==> eg: 2022-01-09
```
npm package: @licq/dl
Description: 文件下载
Author: ostwindli
Latest version: 2.0.1

# @licq/dl

文件下载

## 安装

```sh
npm i @licq/dl -g
or
npm i --save @licq/dl
```

## 使用

### 常规使用

```js
const dl = require("@licq/dl");

const testUrl = "https://dl.nwjs.io/v0.64.0/nw.lib";
const testUrl1 = "http://dl.nwjs.io/v0.57.1/nwjs-sdk-v0.57.1-win-x64.zip";
(async function () {
  // async
  await dl.downloadAsync(testUrl);

 // multiples
  dl.download([testUrl, testUrl1], {
    dir: __dirname, 
    target: 'demo.zip',
  }, (error) => {
    error && console.error(error);
  });
})();

// 参数：
// target
// dir
// resume
// force
// sockets
// quiet
// frequency
// proxy
// strictSSL
```

### CLI

```sh
Usage: dl <urls> [options]
  -o, --output     output filename
  -d, --dir        output parent directory
  -c, --continue   resume aborted download
  -f, --force      ignore response codes > 299
  -s, --sockets    concurrent socket limit (default infinity)
  -q, --quiet      disable logging
  --proxy          specify a proxy to use
  --no-strict-ssl  disable strict SSL cehcking
```

### examples

```sh
dl http://foo.com/bar.jpg
# dls bar.jpg and stores it in the current directory
```

or

```sh
dl http://foo.com/bar.jpg -O baz.jpg
# saves it as baz.jpg. you can also do lowercase -o
```

if you get a statusCode of 300 or greater download will stop. you can force it to stream the response into a file anyway by doing `download http://404link.com/file.html -f` or `--force` works too

you can also download multiple files, just pass multiple urls:

![download multiple](https://miniapp.gtimg.cn/test/demo666.png)

## options

The following options are recognized by download:

- `-o|-O|--out` - specify the filename to write to. this only works if you are downloading a single file
- `-d|--dir` - save files in a directory other than the current one.
- `-c|--continue` - resume downloads if a partially complete target file already exists. If the target file exists and is the same size as the remote file, nothing will be done.
- `-f|--force` - force the server response to be saved to the target file, even if it's a non-successful status code.
- `-s|--sockets` - default Infinity. specify the number of http sockets to use at once (this controls concurrency)
- `-q|--quiet` - disable logging
- `--proxy` - specify a proxy to use
- `--no-strict-ssl` - disable strict ssl

## TODO

- replace request with [got](https://github.com/sindresorhus/got)
npm package: @licq/file
Description: 封装关于文件操作相关的方法
Author: ostwindli
Latest version: 1.0.4


# @licq/file

封装关于文件操作相关的方法

[![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]

[npm-image]: http://img.shields.io/npm/v/@licq/file.svg?style=flat-square
[npm-url]: http://npmjs.org/package/@licq/file
[download-image]: https://img.shields.io/npm/dm/@licq/file.svg?style=flat-square
[download-url]: https://npmjs.org/package/@licq/file
## 安装

```js
npm i --save-dev @licq/file
```

## API
### listFiles 

获取文件夹下所有文件，包含目录


**Returns**: Promise<Array[]>  
**Since**: v1.0.0  

| Param | Type | Description |
| --- | --- | --- |
| rootPath | <code>String</code> | 绝对路径 |

**Example**  
```js
const file = require('@licq/file')
const res = await file.listFiles(__dirname)
// => eg: [{path: '/Users/ostwind/batch/',size: 0,isDir: true}, {path: '/Users/ostwind/batch/package.json',size: 470,isDir: false}]
```
npm package: @licq/git
Description: 封装一些操作git信息的方法
Author: ostwindli
Latest version: 2.0.0

# @licq/git

封装一些操作 git 信息的方法

[![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]

[npm-image]: http://img.shields.io/npm/v/@licq/git.svg?style=flat-square
[npm-url]: http://npmjs.org/package/@licq/git
[download-image]: https://img.shields.io/npm/dm/@licq/git.svg?style=flat-square
[download-url]: https://npmjs.org/package/@licq/git

## 安装

```js
npm i --save-dev @licq/git
```

## API


### getGitUserInfo 

获取当前仓库的Git用户信息


**Returns**: Object  
**Since**: v1.0.0  
**Example**  
```js
const git = require('@licq/git')
const res = git.getGitUserInfo()
//==> eg: { userName: 'ostwindli', userEmail: 'ostwindli@tencent.com' }
```
### getGitChangelog 

根据git项目，生成对应的changelog的markdown内容


**Returns**: String  
**Since**: v2.0.0  

| Param | Type | Description |
| --- | --- | --- |
| Params | <code>Object</code> | 参数 |
| Params.gitProjectPath | <code>String</code> | git项目路径 [必填] eg："/Users/xxx/asenal" |
| Params.gitCommitRepo | <code>String</code> | git项目仓库提交路径 [必填] eg: "https://github.com/ostwindli/asenal/commit" |
| Params.titleArray | <code>Array</code> \| <code>undefined</code> | 生成的changlog头信息 [可选] eg：['# 更新日志', '更新内容简介xxx'] |
| Params.markdownFile | <code>String</code> \| <code>undefined</code> | 生成的markdown文件路径 [可选] eg："/Users/xxx/asenal/CHANGELOG.md" |

**Example**  
```js
const git = require('@licq/git')
const res = git.getGitChangelog({
    gitProjectPath: __dirname,
    gitCommitRepo: 'https://github.com/ostwindli/asenal/commit',
    titleArray: ['# 更新日志', '\n这是一个测试changelog'],
    markdownFile: '/Users/xxx/asenal/CHANGELOG.md'
})x
//==> eg: https://mpqq.gtimg.cn/ost/asenal/changelog_demo.png
```
npm package: @licq/log
Description: 写本地日志
Author: ostwindli
Latest version: 1.0.1

# @licq/log

写本地日志

目录：`path.join(os.tmpdir(), 'lcq/log')`

[![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]

[npm-image]: http://img.shields.io/npm/v/@licq/log.svg?style=flat-square
[npm-url]: http://npmjs.org/package/@licq/log
[download-image]: https://img.shields.io/npm/dm/@licq/log.svg?style=flat-square
[download-url]: https://npmjs.org/package/@licq/log

## 安装

```js
npm i --save-dev @licq/log
```

## API


### info 

打印info日志


**Returns**: null  
**Since**: v1.0.0  

| Param | Type |
| --- | --- |
| ...类似console.log参数 | <code>msg</code> | 

**Example**  
```js
const log = require('@licq/log')
const res = log.info(1, null, {}, true)
```
### info 

打印warn日志


**Returns**: null  
**Since**: v1.0.0  

| Param | Type |
| --- | --- |
| ...类似console.warn参数 | <code>msg</code> | 

**Example**  
```js
const log = require('@licq/log')
const res = log.warn(1, null, {}, true)
```
### info 

打印error日志


**Returns**: null  
**Since**: v1.0.0  

| Param | Type |
| --- | --- |
| ...类似console.error参数 | <code>msg</code> | 

**Example**  
```js
const log = require('@licq/log')
const res = log.error(1, null, {}, true)
```
### openLogDir 

打开日志目录、降级则是临时目录 path.join(os.tmpdir(), `lcq/log`)


**Returns**: null  
**Since**: v1.0.0  
**Example**  
```js
const log = require('@licq/log')
log.openLogDir()
```
### cleanLogDir 

清空日志目录 path.join(os.tmpdir(), `lcq/log`)


**Returns**: null  
**Since**: v1.0.0  
**Example**  
```js
const log = require('@licq/log')
log.cleanLogDir()
```
npm package: @licq/net
Description: 封装一些关于网络的方法
Author: ostwindli
Latest version: 1.0.0

# @licq/net

封装一些关于网络的方法

[![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]

[npm-image]: http://img.shields.io/npm/v/@licq/net.svg?style=flat-square
[npm-url]: http://npmjs.org/package/@licq/net
[download-image]: https://img.shields.io/npm/dm/@licq/net.svg?style=flat-square
[download-url]: https://npmjs.org/package/@licq/net

## 安装

```js
npm i --save-dev @licq/net
```

## API


### getIPV4 

获取本机局域网ipV4地址


**Returns**: String  
**Since**: v1.0.0  
**Example**  
```js
const net = require('@licq/net')
const res = net.getIPV4()
//==> eg: 192.168.1.10
```
### getIPV6 

获取本机局域网ipV6地址


**Returns**: String  
**Since**: v1.0.0  
**Example**  
```js
const net = require('@licq/net')
const res = net.getIPV6()
//==> eg: fe80::/10
```
### getPublicIP 

获取本机公网ipV4地址


**Returns**: String  
**Since**: v1.0.0  
**Example**  
```js
const net = require('@licq/net')
const res = await net.getPublicIP()
//==> eg: 121.122.200.139
```
npm package: @licq/platform
Description: 获取关于平台的相关信息
Author: ostwindli
Latest version: 1.0.1

# @licq/platform

获取关于平台的相关信息

[![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]

[npm-image]: http://img.shields.io/npm/v/@licq/platform.svg?style=flat-square
[npm-url]: http://npmjs.org/package/@licq/platform
[download-image]: https://img.shields.io/npm/dm/@licq/platform.svg?style=flat-square
[download-url]: https://npmjs.org/package/@licq/platform

## 安装

```js
npm i --save-dev @licq/platform
```

## API


### isMac 

判断是否是Mac系统 支持浏览器、node.js


**Returns**: Boolean  
**Since**: 1.0.0  
**Example**  
```js
const pf = require('@licq/platform')
const res = pf.isMac()
//==> eg: true/false
```
### isLinux 

判断是否是Linux系统 支持浏览器、node.js


**Returns**: Boolean  
**Since**: 1.0.0  
**Example**  
```js
const pf = require('@licq/platform')
const res = pf.isLinux()
//==> eg: true/false
```
### isWin 

判断是否是Windows系统 支持浏览器、node.js


**Returns**: Boolean  
**Since**: 1.0.0  
**Example**  
```js
const pf = require('@licq/platform')
const res = pf.isWin()
//==> eg: true/false
```
npm package: @licq/site-cdn
Description: 主要用于静态站点的静态资源走cdn，比如hexo、vuepress
Author: ostwindli
Latest version: 1.0.1

# @licq/site-cdn

主要用于静态站点的静态资源走cdn，比如hexo、vuepress

[![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]

[npm-image]: http://img.shields.io/npm/v/@licq/site-cdn.svg?style=flat-square
[npm-url]: http://npmjs.org/package/@licq/site-cdn
[download-image]: https://img.shields.io/npm/dm/@licq/site-cdn.svg?style=flat-square
[download-url]: https://npmjs.org/package/@licq/site-cdn

## 安装

```js
npm i --save-dev @licq/site-cdn
```

## API

### siteCdn 

替换`vuepress`、`hexo`等构建产物里html的静态资源路径, 拼接cdn


**Returns**: undefined  
**Since**: v1.0.0  

| Param | Type | Description |
| --- | --- | --- |
| dist | <code>fs.PathLike</code> | 构建产物绝对路径 |
| base | <code>String</code> | 静态资源前缀 eg： '/' | '/blog/' |
| cdn | <code>String</code> | cdn地址 eg: 'https://demo.cdn.com/blog/' |

**Example**  
```js
const siteCdn = require('@licq/site-cdn')
siteCdn('/Users/xxx/path/to/vuepress/dist', '/blog/', 'https://demo.cdn.com/')
//==> undefined
```
**Example**  
```js
// eg: xxx.html ===>

// - <script type="module" src="/blog/assets/app.7bfa9b79.js" defer></script>
// + <script type="module" src="https://demo.cdn.com/blog/assets/app.7bfa9b79.js" defer></script>

// - <link rel="stylesheet" href="/blog/assets/style.c2b7e6ed.css">
// + <link rel="stylesheet" href="https://demo.cdn.com/blog/assets/style.c2b7e6ed.css">

// - <img class="logo" src="/blog/assets/ost-hourse.png" alt="Ostwindli's Asenal">
// + <img class="logo" src="https://demo.cdn.com/blog/assets/ost-hourse.png" alt="Ostwindli's Asenal">
```
npm package: @licq/string
Description: 封装一些字符串的操作方法
Author: ostwindli
Latest version: 1.0.6

# @licq/string

封装一些字符串的操作方法

[![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]

[npm-image]: http://img.shields.io/npm/v/@licq/string.svg?style=flat-square
[npm-url]: http://npmjs.org/package/@licq/string
[download-image]: https://img.shields.io/npm/dm/@licq/string.svg?style=flat-square
[download-url]: https://npmjs.org/package/@licq/string

## 安装

```js
npm i --save-dev @licq/string
```

## API


### randomString 

生成指定长度的随机字符串


**Returns**: String  
**Since**: v1.0.0  

| Param | Type | Description |
| --- | --- | --- |
| length | <code>Number</code> | 长度 |

**Example**  
```js
const str = require('@licq/string')
const res = str.randomString(10);
//==> eg: dUbkGTBgKN
```
### uuid 

生成uuid (v4)


**Returns**: uuid String  
**Since**: v1.0.5  
**Example**  
```js
const str = require('@licq/string')
const uuid = str.uuid()
// ==> 51001e12-509b-4f4a-ad73-8d7de4cef6bf
```
### uuidValidate 

校验是否是uuid


**Returns**: boolean  
**Since**: v1.0.5  

| Param | Type |
| --- | --- |
| uuid | <code>String</code> | 

**Example**  
```js
const str = require('@licq/string')
const isUUID = str.uuidValidate('51001e12-509b-4f4a-ad73-8d7de4cef6bf');
// ==> true
const isUUID1 = str.uuidValidate('eH2dTHAoYOAaxegIeFq7bcGrGhPcfv83');
// ==> false
```
npm package: @licq/tnwjs
Description: nwjs的包管理器
Author: ostwindli
Latest version: 1.0.3

# @licq/tnwjs [![version](https://img.shields.io/npm/v/@licq/tnwjs.svg)](https://www.npmjs.com/package/@licq/tnwjs) [![npm](https://img.shields.io/npm/dm/@licq/tnwjs.svg)](https://www.npmjs.com/package/@licq/tnwjs)

You can use `@licq/tnwjs` as an nw.js version manager, and do things like `tnw /your/app/path`

## Install

```sh
npm i -g @licq/tnwjs
```

## Usage

```sh
# Install a version
$ tnw install 0.64.0

# Install a SDK version
$ tnw install 0.64.0-sdk

# Run tnw in cwd or specific any directory
$ tnw .

# Use SDK version
$ tnw use 0.64.0-sdk

# Show the nw version currently in use
$ tnw current

# List all local cached versions
$ tnw ls

# List all remote versions
$ tnw ls-remote

# Use a proxy
$ http_proxy=http://127.0.0.1:8989 tnw install 0.64.0-sdk

# Remove a specific version of nwjs
$ tnw r 0.64.1

```

## API

```js
const spawn = require("child_process").spawn;
// this returns the path to nwjs excutable
const nw = require("@licq/tnwjs");

const child = spawn(nw);
```
npm package: @licq/tpkg
Description: pack or unpack wechatapp and qqminiapp package
Author: ostwindli
Latest version: 1.0.2

# @licq/tpkg

pack or unpack `wechatapp(.wxvpkg)` and `qqminiapp(.tqapkg)` package.

[![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]

[npm-image]: http://img.shields.io/npm/v/@licq/tpkg.svg?style=flat-square
[npm-url]: http://npmjs.org/package/@licq/tpkg
[download-image]: https://img.shields.io/npm/dm/@licq/tpkg.svg?style=flat-square
[download-url]: https://npmjs.org/package/@licq/tpkg

## Install

```js
npm i --save @licq/tpkg
```

## API


### pack 

pack dir to pkg


**Returns**: pathLike  
**Since**: v1.0.0  

| Param | Type | Description |
| --- | --- | --- |
| sourceDir | <code>pathLike</code> | [required] The directory to work with |
| targetPath | <code>pathLike</code> | [optional] The target path, The default path is the same as the sourceDir. |
| targetName | <code>string</code> | [optional] The target filename, The default name is the same as the sourceDir. |

**Example**  
```js
const tpkg = require('@licq/tpkg')
const res = tpkg.pack('path/to/dir/');
const res = tpkg.pack('path/to/dir/', 'path/to/dir/demo');
const res = tpkg.pack('path/to/dir/', 'path/to/dir/demo', 'demo.wxvpkg') // or demo.tqapkg
//==> eg: path/to/dir/demo.wxvpkg
```
### unpack 

unpack pkg


**Returns**: pathLike  
**Since**: v1.0.0  

| Param | Type | Description |
| --- | --- | --- |
| pkgPath | <code>pathLike</code> | [required] The pkgPath to work with |
| targetPath | <code>pathLike</code> | [optional] The target path, The default is the same as the pkgPath. |

**Example**  
```js
const tpkg = require('@licq/tpkg')
const res = tpkg.unpack('path/to/dir/demo.wxvpkg', _dirname) // or demo.tqapkg
//==> eg: ${_dirname}/demo/**
```


## CLI

```sh
npm i -g @licq/tpkg

# unpack
tpkg path/to/demo.wxvpkg # unpack to path/to/*
tpkg path/to/demo.tqapkg # unpack to path/to/*
tpkg path/to/demo.wxvpkg path/to/target # unpack to path/to/target/*

# pack
tpkg path/to/demo # pack to path/to/demo.wxvpkg
tpkg path/to/demo path/to/target # pack to path/to/target/demo.wxvpkg
tpkg path/to/demo path/to/target demo.tqapkg # pack to path/to/target/demo.tqapkg
```