text:
#!/bin/sh
# Usage: create-cert [CNAME=localhost] [ORGANIZATION]
#
# Creates a self-signed certificate and outputs it and its private key.
set -e

name="${1:-localhost}"
org="$2"
temp="${TMPDIR:-/tmp}/openssl-req.$$.$(date +%s)"

openssl req \
  -x509 -nodes -days 365 \
  -subj "/O=$org/CN=$name" \
  -newkey rsa:1024 -keyout "$temp" -out "$temp" 2>/dev/null

cat "$temp"
rm -f "$temp"


text:
require 'https'

uri = URI('https://example.com/hello?world')

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == 'https' || uri.port == 443

if http.use_ssl?
  ## Important. Turns on certificate verification
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER

  ## Override SSL_CERT_FILE: the path to your CA bundle
  http.ca_file = '/path/to/ca_cert.pem'
  ## Override SSL_CERT_DIR: the directory with individual cert files
  http.ca_path = '/path/to/certs/'

  ## Optional. Configure extra certificates that you will trust.
  http.cert_store = OpenSSL::X509::Store.new
  http.cert_store.set_default_paths
  http.cert_store.add_file('/path/to/cacert.pem')
  # ...or:
  cert = OpenSSL::X509::Certificate.new(File.read('mycert.pem'))
  http.cert_store.add_cert(cert)

  http.ssl_timeout = 5 # seconds
  http.verify_depth = 3 # max length of cert chain to be verified

  ## Optional. Set the client certificate. This enables servers which support it
  ## to verify that YOU are who you claim to be as well. You probably don't need this.
  # http.cert = OpenSSL::X509::Certificate.new(...)
  # Provide the private key for the client certificate
  # http.key = OpenSSL::PKey::RSA.new(...)
end

user_agent = "net/http #{RUBY_VERSION}"
req = Net::HTTP::Get.new(uri.request_uri, 'user-agent' => user_agent)

begin
  res = http.start { http.request(req) }
  abort res.inspect if res.code.to_i >= 300
  puts res.body
rescue Errno::ECONNREFUSED
  abort "Error: connection refused"
rescue OpenSSL::SSL::SSLError
  abort "SSLError: #{$!.message}"
end

repo_name: mislav/ssl-tools

repo_language: Ruby

file_name: show-cert

mime_type: text/x-shellscript


text:
#!/bin/sh
# Display human-readable information from a certificate.
set -e

file="$1"
[ "$file" = "-" ] && file=""

if [ -n "$file" -a ! -f "$file" ] || [ -z "$file" -a -t 0 ]; then
  echo "Usage: show-cert <file>" >&2
  exit 1
fi

format=pem
[ "${file##*.}" = "cer" ] && format=der

exec openssl x509 -inform "$format" ${1:+-in "$1"} -noout -text \
  -nameopt multiline -certopt no_pubkey,no_sigdump


text:
# 免費 ChatGPT API

歡迎來到免費 ChatGPT API 專案，這是一個簡單且開源的代理 API，您可以免費訪問 OpenAI 的 ChatGPT API。

**你一定也會喜歡 [Free ChatGPT](https://github.com/ztjhz/FreeChatGPT) 網站！**

## 新聞

- **2023-03-26**: 懷著沉重的心情，我宣布 ChatGPTAPIFree 儲存庫將被存檔。我們為所有人提供免費 API 的事業已經面臨財務上的不可持續困境，這令我們在追求 AI 技術平等獲取方面暫時停滯。儘管遭遇這一挫折，我們的承諾依然堅定不移。我們將繼續探索替代方法，並呼籲 OpenAI 降低 API 價格並取消地區限制。雖然我們的進步可能有所放緩，但我們努力創造一個 AI 能力為所有人所用的世界的決心比以往任何時候都更為堅定。
- **2023-03-14**：热心羣友贊助了本專案 400 美元，使免費 API 能維持更長時間。
- **2023-03-12**：熱心羣友贊助了本專案 5000 元人民幣（合 724 美元），使免費 API 可以維持生命。為了確保 API 的穩定性和安全性，已經實施了速率限制。歡迎以贊助或託管自己 API 端點的方式支持本專案。
- **2023-03-04**：請查看 [Free ChatGPT](https://freechatgpt.chat/)，這是一個非常棒的開源 Web 應用，您可以免費使用 OpenAI 的 ChatGPT API。它是基於此專案構建的。

## 開放 ChatGPT 倡議

在一個技術以指數速度發展的世界裏，人與機械之間的界限越來越模糊，那些有能力創造的人有責任確保所有人都能分享這種進步的好處。

考慮到這一點，我想介紹 Open ChatGPT 倡議。在一個人工智能的潛力受限於門檻和成本的世界裏，這是一盞希望之燈。一個免費和開源的代理 API，消除了獲取最新人工智能技術的障礙，並使其為所有人所用。

這專案誕生於一種信念，一種對未來的信念，即人工智能的力量不是留給少數特權者的，而是提供給每一位創造者、每一位創新者和每一位夢想者。

這是一種信念，即技術應該為人類服務，而不是相反。這是一種信念，即獲得最新進展的機會不應該由一個人的技術能力或財力決定，而是由一個人的創造力、想象力和抱負決定。

這專案並不尋求變革人工智能行業，而是使其民主化。尋求每個人都能獲得人工智能的力量，無論其背景或經濟狀況。尋求促進平等、教育和創新。

我最真誠地希望，這專案將成為變革的催化劑，成為那些相信人工智能的好處應該由所有人分享的人的集合點。加入我的努力，讓我們共同創造一個未來，一個人工智能的力量屬於我們所有人的未來。

> 如果您想閲讀另一篇含有更多技術細節的文章，請閲讀《[釋放 ChatGPT 的無限潛能：一個公開呼籲](https://medium.com/@ayaka_90553/%E9%87%8A%E6%94%BE-chatgpt-%E7%9A%84%E6%97%A0%E9%99%90%E6%BD%9C%E8%83%BD-%E4%B8%80%E4%B8%AA%E5%85%AC%E5%BC%80%E5%91%BC%E5%90%81-7195a12f05f2)》。

## 用法

要使用 ChatGPT API 免費版，只需向以下端點傳送 POST 要求：

```raw
https://chatgpt-api.shn.hk/v1/
```

例如，要使用 `gpt-3.5-turbo` 模型回答 "Hello, how are you?"，請傳送以下 `curl` 命令：

```sh
curl https://chatgpt-api.shn.hk/v1/ \
  -H 'Content-Type: application/json' \
  -d '{
  "model": "gpt-3.5-turbo",
  "messages": [{"role": "user", "content": "Hello, how are you?"}]
}'
```

您可以在 [OpenAI 官方文檔](https://platform.openai.com/docs/api-reference/chat/create)上閲讀完整的 API 文檔。

## 介紹

ChatGPT 是由 OpenAI 開發的全球知名的會話 AI 模型，因生成類似人類的對各種提示和查詢的回答而廣受讚譽。憑藉其先進的功能，ChatGPT 是聊天機械人、虛擬助手和其他自然語言處理應用程式的寶貴資產。

ChatGPT API 是一個強大的工具，允許開發人員將 ChatGPT 模型集成到自己的應用程式中。但是，要使用此 API，用户需要擁有 OpenAI API 金鑰並支付使用費用。

免費 ChatGPT API 認為每個人都應該擁有訪問最新人工智能技術的權利，而不必承擔獲取 API 金鑰的經濟負擔。此開源代理 API 允許您在沒有金鑰的情況下訪問 ChatGPT API，促進了對所有人的可訪問性和創新。

## 免費 ChatGPT API 做什麼？

這個簡單的代理 API 充當您與 OpenAI ChatGPT API 之間的橋樑。您可以使用與原始 API 相同的格式向 ChatGPT API 免費版端點傳送要求。該代理 API 將要求轉發至 OpenAI API，使用該專案提供的 API 金鑰，並將 OpenAI API 的應答回傳給您。

## 重要性

免費 ChatGPT API 專案是人工智能開發社羣的遊戲規則改變者。透過代理 API，任何人都可以無需金鑰訪問最先進的 ChatGPT 模型。這種可訪問性促進了開發人員之間的創造力、創新和合作，並可能導致人工智能技術的突破性進展。

此外，諸如 [Free ChatGPT](https://freechatgpt.chat/) 之類的成功專案建立在此 API 的基礎上，顯示了該專案的巨大潛力。

## 私隱聲明

該專案高度重視私隱，致力於保護其用户的私隱。該專案不會以任何方式收集、記錄或存儲用户輸入的任何文本或由 OpenAI 伺服器回傳的任何文本。該專案不會向 OpenAI 或任何第三方提供有關 API 呼叫者的身分的任何信息，包括但不限於 IP 位址和用户代理字串。該專案的原始碼可供檢查，以驗證此聲明。

然而，OpenAI API 根據其[資料使用政策](https://platform.openai.com/docs/data-usage-policies)保留 30 天的資料。

## 搭建自己的實例

如果您想運行自己的 ChatGPT API 免費版實例，可以按照以下步驟輕鬆完成：

1. 從 [OpenAI API 金鑰](https://platform.openai.com/account/api-keys)獲取 OpenAI API 金鑰。
1. 在 GitHub 上 Star 和 Fork 此存儲庫。
1. 正確配置您的[環境變數](.env.example)。
1. 在本地部署 Docker 或在 [Google Cloud Run](https://cloud.google.com/run) 上部署。
1. 在本地設定速率限制或使用 [Google Cloud Armor](https://cloud.google.com/armor/docs/rate-limiting-overview)。

## 改進此專案

該專案始終在尋找改進的方法，歡迎用户提供反饋和貢獻。如果您有任何建議或想法，請隨時在 GitHub 存儲庫中建立 Issue 或提交拉取請求。

## 贊助我！

如果您發現免費 ChatGPT API 版有用，請考慮在 GitHub 上[贊助作者](https://github.com/sponsors/ayaka14732)，以支持持續的開發和維護。您的支持將幫助她維護此專案，並繼續使人工智能技術對所有人都可訪問。謝謝您的支持！

    Ko-fi

    支付寶

    微信

repo_language: JavaScript

mime_type: text/x-java


text:
# 免费 ChatGPT API

欢迎来到免费 ChatGPT API 项目，这是一个简单且开源的代理 API，您可以免费访问 OpenAI 的 ChatGPT API。

**你一定也会喜欢 [Free ChatGPT](https://github.com/ztjhz/FreeChatGPT) 网站！**

## 新闻

- **2023-03-26**: 怀着沉重的心情，我宣布 ChatGPTAPIFree 储存库将被存档。我们为所有人提供免费 API 的事业已经面临财务上的不可持续困境，这使我们在追求 AI 技术平等获取方面暂时停滞。尽管遭遇这一挫折，我们的承诺依然坚定不移。我们将继续探索替代方法，并呼吁 OpenAI 降低 API 价格并取消地区限制。虽然我们的进步可能有所放缓，但我们致力于创造一个 AI 能力为所有人所用的世界的决心比以往任何时候都更为坚定。
- **2023-03-14**：热心群友赞助了本项目 400 美元，使免费 API 能维持更长时间。
- **2023-03-12**：热心群友赞助了本项目 5000 元人民币（合 724 美元），使免费 API 可以维持生命。为了确保 API 的稳定性和安全性，已经实施了速率限制。欢迎以赞助或托管自己 API 端点的方式支持本项目。
- **2023-03-04**：请查看 [Free ChatGPT](https://freechatgpt.chat/)，这是一个非常棒的开源 Web 应用，您可以免费使用 OpenAI 的 ChatGPT API。它是基于此项目构建的。

## 开放 ChatGPT 倡议

在一个技术以指数速度发展的世界里，人与机器之间的界限越来越模糊，那些有能力创造的人有责任确保所有人都能分享这种进步的好处。

考虑到这一点，我想介绍 Open ChatGPT 倡议。在一个人工智能的潜力受限于门槛和成本的世界里，这是一盏希望之灯。一个免费和开源的代理 API，消除了获取最新人工智能技术的障碍，并使其为所有人所用。

这个项目诞生于一种信念，一种对未来的信念，即人工智能的力量不是留给少数特权者的，而是提供给每一位创造者、每一位创新者和每一位梦想者。

这是一种信念，即技术应该为人类服务，而不是相反。这是一种信念，即获得最新进展的机会不应该由一个人的技术能力或财力决定，而是由一个人的创造力、想象力和抱负决定。

这个项目并不寻求变革人工智能行业，而是使其民主化。寻求每个人都能获得人工智能的力量，无论其背景或经济状况。寻求促进平等、教育和创新。

我最真诚地希望，这个项目将成为变革的催化剂，成为那些相信人工智能的好处应该由所有人分享的人的集合点。加入我的努力，让我们共同创造一个未来，一个人工智能的力量属于我们所有人的未来。

> 如果您想阅读另一篇含有更多技术细节的文章，请阅读《[释放 ChatGPT 的无限潜能：一个公开呼吁](https://medium.com/@ayaka_90553/%E9%87%8A%E6%94%BE-chatgpt-%E7%9A%84%E6%97%A0%E9%99%90%E6%BD%9C%E8%83%BD-%E4%B8%80%E4%B8%AA%E5%85%AC%E5%BC%80%E5%91%BC%E5%90%81-7195a12f05f2)》。

## 用法

要使用 ChatGPT API 免费版，只需向以下端点发送 POST 请求：

```raw
https://chatgpt-api.shn.hk/v1/
```

例如，要使用 `gpt-3.5-turbo` 模型回答 "Hello, how are you?"，请发送以下 `curl` 命令：

```sh
curl https://chatgpt-api.shn.hk/v1/ \
  -H 'Content-Type: application/json' \
  -d '{
  "model": "gpt-3.5-turbo",
  "messages": [{"role": "user", "content": "Hello, how are you?"}]
}'
```

您可以在 [OpenAI 官方文档](https://platform.openai.com/docs/api-reference/chat/create)上阅读完整的 API 文档。

## 介绍

ChatGPT 是由 OpenAI 开发的全球知名的会话 AI 模型，因生成类似人类的对各种提示和查询的回答而广受赞誉。凭借其先进的功能，ChatGPT 是聊天机器人、虚拟助手和其他自然语言处理应用程序的宝贵资产。

ChatGPT API 是一个强大的工具，允许开发人员将 ChatGPT 模型集成到自己的应用程序中。但是，要使用此 API，用户需要拥有 OpenAI API 密钥并支付使用费用。

免费 ChatGPT API 认为每个人都应该拥有访问最新人工智能技术的权利，而不必承担获取 API 密钥的经济负担。此开源代理 API 允许您在没有密钥的情况下访问 ChatGPT API，促进了对所有人的可访问性和创新。

## 免费 ChatGPT API 做什么？

这个简单的代理 API 充当您与 OpenAI ChatGPT API 之间的桥梁。您可以使用与原始 API 相同的格式向 ChatGPT API 免费版端点发送请求。该代理 API 将请求转发至 OpenAI API，使用该项目提供的 API 密钥，并将 OpenAI API 的响应返回给您。

## 重要性

免费 ChatGPT API 项目是人工智能开发社区的游戏规则改变者。通过代理 API，任何人都可以无需密钥访问最先进的 ChatGPT 模型。这种可访问性促进了开发人员之间的创造力、创新和合作，并可能导致人工智能技术的突破性进展。

此外，诸如 [Free ChatGPT](https://freechatgpt.chat/) 之类的成功项目建立在此 API 的基础上，显示了该项目的巨大潜力。

## 隐私声明

该项目高度重视隐私，致力于保护其用户的隐私。该项目不会以任何方式收集、记录或存储用户输入的任何文本或由 OpenAI 服务器返回的任何文本。该项目不会向 OpenAI 或任何第三方提供有关 API 调用者的身份的任何信息，包括但不限于 IP 地址和用户代理字符串。该项目的源代码可供检查，以验证此声明。

然而，OpenAI API 根据其[数据使用政策](https://platform.openai.com/docs/data-usage-policies)保留 30 天的数据。

## 搭建自己的实例

如果您想运行自己的 ChatGPT API 免费版实例，可以按照以下步骤轻松完成：

1. 从 [OpenAI API 密钥](https://platform.openai.com/account/api-keys)获取 OpenAI API 密钥。
1. 在 GitHub 上 Star 和 Fork 此存储库。
1. 正确配置您的[环境变量](.env.example)。
1. 在本地部署 Docker 或在 [Google Cloud Run](https://cloud.google.com/run) 上部署。
1. 在本地设置速率限制或使用 [Google Cloud Armor](https://cloud.google.com/armor/docs/rate-limiting-overview)。

## 改进此项目

该项目始终在寻找改进的方法，欢迎用户提供反馈和贡献。如果您有任何建议或想法，请随时在 GitHub 存储库中创建 Issue 或提交拉取请求。

## 赞助我！

如果您发现免费 ChatGPT API 版有用，请考虑在 GitHub 上[赞助作者](https://github.com/sponsors/ayaka14732)，以支持持续的开发和维护。您的支持将帮助她维护此项目，并继续使人工智能技术对所有人都可访问。谢谢您的支持！

    Ko-fi

    支付宝

    微信


text:
FROM node:18-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN chown -R appuser:appgroup /app
EXPOSE 8080
USER appuser
CMD [ "npm", "start" ]


text:
# ChatGPT API Free

[简体中文版](README-zh_CN.md) - [繁體中文版](README-zh_HK.md)

Welcome to the ChatGPT API Free project, a simple and open-source proxy API that allows you to access OpenAI's ChatGPT API for free.

**You may want to check out the [Free ChatGPT](https://github.com/ztjhz/FreeChatGPT) website!**

## News

- **2023-03-26**: It is with a heavy heart that I announce the archiving of the ChatGPTAPIFree repository. Our endeavour to provide a free API for all has reached an unsustainable financial crossroad, prompting a temporary halt in our pursuit of equal access to AI technology. Despite this setback, our commitment remains unwavering. We will continue to explore alternative methods and advocate for OpenAI to lower their API pricing and remove regional restrictions. While our progress may have slowed, our resolve to create a world where the power of AI is accessible to all is stronger than ever.
- **2023-03-14**: A kind group member sponsored this project with 400 USD, which enables the free API to run for an even longer period of time.
- **2023-03-12**: A kind group member sponsored this project with 5000 CNY (724 USD), allowing for continued free access to ChatGPT. Rate limits have been implemented to ensure the API's stability and security. You are welcome to support this project by sponsoring it or hosting your own API endpoint.
- **2023-03-04**: Check out the [Free ChatGPT](https://freechatgpt.chat/), an amazing open-source web application that allows you to interact with OpenAI's ChatGPT API for free. It is built on top of this project.

## The Open ChatGPT Initiative

In a world where technology advances at an exponential pace, where the line between man and machine grows increasingly blurred, it is the responsibility of those who have the capability to create, to ensure that the benefits of this progress are shared by all.

With this in mind, I would like to present to you the Open ChatGPT Initiative. A beacon of hope in a world where the potential of AI is limited by the barrier and the cost of entry. A free and open-source proxy API that removes the barriers to accessing the latest AI technology, and makes it available to all.

This project was born from a belief, a belief in a future where the power of artificial intelligence is not reserved for the privileged few, but available to every creator, every innovator, and every dreamer.

It is a belief that technology should serve humanity, not the other way around. A belief that access to the latest advancements should not be determined by one’s technological ability or financial resources, but by one’s creativity, imagination and ambition.

This project does not seek to revolutionise the AI industry, but to democratise it. To make the power of AI accessible to every person, regardless of their background or financial situation. To promote equality, education, and innovation.

It is my sincerest hope that this project will be a catalyst for change, a rallying point for those who believe that the benefits of AI should be shared by all. Join me in this endeavour, and let us create a future where the power of AI belongs to us all.

> If you would like to read another article with more technical details, please read [_Unleashing the Boundlessness of ChatGPT: A Public Appeal_](https://medium.com/@ayaka_45434/unleashing-the-boundlessness-of-chatgpt-a-public-appeal-f1b535a5ca05).

## Usage

To use ChatGPT API Free, simply send a POST request to the following endpoint:

```
https://chatgpt-api.shn.hk/v1/
```

For instance, to generate a response to the prompt "Hello, how are you?" using the `gpt-3.5-turbo` model, send the following `curl` command:

```sh
curl https://chatgpt-api.shn.hk/v1/ \
  -H 'Content-Type: application/json' \
  -d '{
  "model": "gpt-3.5-turbo",
  "messages": [{"role": "user", "content": "Hello, how are you?"}]
}'
```

You can view the full API documentation on the [OpenAI official documentation](https://platform.openai.com/docs/api-reference/chat/create).

## Introduction

ChatGPT is a world-renowned conversational AI model developed by OpenAI, known for generating human-like responses to various prompts and queries. With its cutting-edge capabilities, ChatGPT is a valuable asset for chatbots, virtual assistants, and other natural language processing applications.

The ChatGPT API is a powerful tool that allows developers to integrate the ChatGPT model into their own applications. However, to use this API, users need to have an OpenAI API key and pay for usage.

ChatGPT API Free believes that everyone should have access to the latest AI technology without the financial burden of paying for an API key. This open-source proxy API allows you to access the ChatGPT API without a key, promoting accessibility and innovation for all.

## What does ChatGPT API Free do?

This simple proxy API acts as a bridge between you and the OpenAI ChatGPT API. You can send requests to the ChatGPT API Free endpoint using the same format as the original API. This proxy API then forwards the request to the OpenAI API with an API key provided by this project, and the response from the OpenAI API is returned to you.

## Significance

The ChatGPT API Free project is a game-changer for the AI development community. With the proxy API, anyone can access the state-of-the-art ChatGPT model without needing a key. This accessibility fosters creativity, innovation, and collaboration among developers, and could potentially lead to groundbreaking advancements in AI technology.

Moreover, other successful projects such as [ChatGPT Free App](https://freechatgpt.chat/) build on top of this API, showing the vast potential of this project.

## Privacy Statement

This project highly values privacy and is committed to safeguarding the privacy of its users. This project does not collect, record, or store any text entered by users or returned by the OpenAI server in any manner. This project does not provide any information to OpenAI or any third parties about the identity of API callers, including but not limited to IP addresses and user-agent strings. The source code of this project is available for inspection to verify this statement.

However, the OpenAI API does retain data for 30 days in accordance with its [data usage policies](https://platform.openai.com/docs/data-usage-policies).

## Host Your Own Instance

If you'd like to run your own instance of ChatGPT API Free, you can easily do so by following these steps:

1. Obtain an OpenAI API Key from [OpenAI API Keys](https://platform.openai.com/account/api-keys).
1. Star and fork this repository on GitHub.
1. Configure your [environment variables](.env.example) correctly.
1. Deploy Docker locally or on [Google Cloud Run](https://cloud.google.com/run).
1. Setup rate limit locally or using [Google Cloud Armor](https://cloud.google.com/armor/docs/rate-limiting-overview).

## Improve this project

This project is always seeking ways to improve and welcomes feedback and contributions from its users. If you have any suggestions or ideas, please feel free to create an issue or submit a pull request on the GitHub repository.

## Sponsor me!

If you find ChatGPT API Free useful, please consider [sponsoring the author](https://github.com/sponsors/ayaka14732) on GitHub to support ongoing development and maintenance. Your support would help her maintain this project and continue to make AI technology accessible for all. Thank you for your support!

    Ko-fi

    Alipay

    WeChat


text:
import * as dotenv from 'dotenv';
dotenv.config();

import express from 'express';
import fetch from 'node-fetch';

const port = parseInt(process.env.PORT || '8080', 10);
const api_keys = JSON.parse(process.env.API_KEYS);
const upstreamUrl = 'https://api.openai.com/v1/chat/completions';

const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Methods': 'GET, HEAD, POST, OPTIONS',
  'Access-Control-Allow-Headers': 'Content-Type, Authorization',
};

const randomChoice = (arr) => arr[Math.floor(Math.random() * arr.length)];

const obfuscateOpenAIResponse = (text) => text.replace(/\borg-[a-zA-Z0-9]{24}\b/g, 'org-************************').replace(' Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method.', '');

const app = express();
app.disable('etag');
app.disable('x-powered-by');
app.use(express.json());

app.use((err, req, res, next) => {
  if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
    return res.status(400).set(corsHeaders).type('text/plain').send(err.message);
  }
  next();
});

const handleOptions = (req, res) => {
  res.setHeader('Access-Control-Max-Age', '1728000').set(corsHeaders).sendStatus(204);
};

const handlePost = async (req, res) => {
  const contentType = req.headers['content-type'];
  if (!contentType || contentType !== 'application/json') {
    return res.status(415).set(corsHeaders).type('text/plain').send("Unsupported media type. Use 'application/json' content type");
  }

  const { stream } = req.body;
  if (stream != null && stream !== true && stream !== false) {
    return res.status(400).set(corsHeaders).type('text/plain').send('The `stream` parameter must be a boolean value');
  }

  try {
    const authHeader = req.get('Authorization');
    const authHeaderUpstream = authHeader || `Bearer ${randomChoice(api_keys)}`;

    const requestHeader = {
      'Content-Type': 'application/json',
      'Authorization': authHeaderUpstream,
      'User-Agent': 'curl/7.64.1',
    };
    const resUpstream = await fetch(upstreamUrl, {
      method: 'POST',
      headers: requestHeader,
      body: JSON.stringify(req.body),
    });

    if (!resUpstream.ok) {
      const { status } = resUpstream;
      const text = await resUpstream.text();
      const textObfuscated = obfuscateOpenAIResponse(text);
      return res.status(status).set(corsHeaders).type('text/plain').send(`OpenAI API responded:\n\n${textObfuscated}`);
    }

    const contentType = resUpstream.headers.get('content-type');
    if (contentType) {
      res.setHeader('Content-Type', contentType);
    }
    const contentLength = resUpstream.headers.get('content-length');
    if (contentLength) {
      res.setHeader('Content-Length', contentLength);
    }
    if (stream) {
      res.setHeader('Connection', 'keep-alive');
    }
    res.set({
      ...corsHeaders,
      'Cache-Control': 'no-cache',
    });

    resUpstream.body.pipe(res);
  } catch (error) {
    res.status(500).set(corsHeaders).type('text/plain').send(error.message);
  }
};

app.options('/v1/', handleOptions);
app.post('/v1/', handlePost);
app.options('/v1/chat/completions', handleOptions);
app.post('/v1/chat/completions', handlePost);

app.use('*', (req, res) => {
  res.status(404).set(corsHeaders).type('text/plain').send('Not found');
});

app.listen(port, () => {
  console.log(`Server listening on port ${port}`);
});


text:
# 中大型组织 DevOps 成熟度模型

## 规模化 DevOps 的四大基石

**高效协同**。协同指的是人与人之前的协同，即业务与技术、技术与技术、技术与测试、测试与运维等。在标准化上，我们关注于：**协作设计**，从流程上尽可能减少浪费；**组织/团队治理**，优化团队与组织结构。在平台上，我们关注于：**需求管理**，保障需求过程的概念完整性传递，如分析、拆分、协作；**指标化改进**；即将协同平台作为度量指标的展示平台，用于持续性的改进，诸如于技术技术债等。

**持续交付**。持续交付是指能够按需快速、安全且可持续地发布各种类型的更改。在标准化上，我们关注于：**服务化架构**，即实现类似于微服务架构、服务导向架构的架构化方式，实现技术架构能快速响应业务变化；**版本管理**，即从源码源头开始对版本进行标准化，通过分支管理、语义化版本等方式实现。在工具上，我们关注于：**灵活变更**，即通过平台管理变更与制品；**持续部署**，则是与变更相关关联的持续集成与部署。

**质量保障**。质量保障是指为最终用户提供高质量的软件产品。在标准化上，我们关注于：**测试策略**，即结对质量左移设计测试生命周期，设计测试分层模型进行指标化引导 ；**测试方式**，定义自动化测试、手动测试的类型、时机、准出标准等。在平台化上，我们关注于：**测试管理**，诸如于用例管理与设计、测试数据管理；**质量安全**，则是针对于代码、环境等进行自动化质量与安全相关的扫描。

**环境支撑**。环境支撑是指用于支撑体系所需要的基础设施与运维体系。在标准化上，我们关注于：**配置管理**，即将基础设施代码化后，进行相应的基线配置管理、应用配置等；**资源管理**，即对环境的管理，以及各环节所需要的资源和环境进行管理。在平台上，我们关注于：**部署管理**，即对于发布环境的管理，以及诸如灰度发布等高级部署方式的管理；**运维自动化**，在运维上进行自动化的监控和警告，并支持更好的弹性发布，诸如于高可用性等。

## 级别定义

对于规模化的组织来说，我们只需要 4 个级别，即只存在 2~5 个级别。从流程标准化和平台化，我们已经消灭级别 1 的存在，它们都是不合规的。与此同时，从标准化和平台化的层面来看，事实上，我们也不存在级别 5，因为它们过于灵活和超前。

所以，它只需要三级模型：

Level 2，规范化。从原始需求的产生到需求的上线，全部遵循组织内定义的规模标准。需求协作的过程透明化，流程明确，流转自动化；持续交付上，采用组织所定义的实践，如语义化版本，制品来源与产出可信等；在质量上，采用依据组织定义的模型设计测试策略等；在环境上，平台能支撑起规范化所需要的设计。

Level 3，平台标准化与自动化。将规范化的内容，逐一在平台上进行标准化，即定义多种技术实践，只能从中二选一，或者三选一。四大基石，都通过这一系列标准来进行自动化。唯一值得商榷的一点是持续交付上，我们需要一个松耦合的架构，才能支撑起单个团队的快速交付，诸如于微服务架构、插件化架构等。

Level 4，指标驱动与自动改进。建立一系列的度量模型，对于软件开发过程进行全面的度量。与此同时，团队与平台根据这些定义的对系统和平台进行优化。如在环境支撑上，对于应用状态的实时监控，实现自动化弹性。

对于第 5 级来说，视不同的组织情况，略有不同。如我们所定义的是：

Level 5，云研发架构。构建基于云端开发时的基础设施架构，诸如于云研发架构、Serverless、Typeflow、Darklang 等，实现基础设施的自动化与架构的高度解耦。在质量上，对运行时监控，实现自动化测试编写，对代码进行静态分析，实现精益测试；在协同上，通过构建领域特定语言，实现需求生成代码骨架；在环境上，自动实现灰度发布等特性。

## 如何使用

使用步骤如下：

1. 组织根据自己的需求，补充表格中的不同级别成熟度模型。
2. 使用表格中的各类评估模型来设计子维度，如测试策略评估模型。
3. 寻找试点团队，评估和验证成熟度模型是匹配。

表格中的示例，还在继续编写中。

在线预览：

![QQ Document](images/qq-docs.jpg)

下载：

[Scaling Devops](scaling-devops.xlsx)

repo_name: scaling-devops/maturity

mime_type: text/plain


text:
# Installing PostCSS Colour

[PostCSS Colour] runs in all Node environments, with special instructions for:

| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) |
| --- | --- | --- | --- | --- | --- |

## Node

Add [PostCSS Colour] to your project:

```bash
npm install postcss postcss-colour --save-dev
```

Use [PostCSS Colour] to process your CSS:

```js
const postcssColour = require('postcss-colour');

postcssColour.process(YOUR_CSS /*, processOptions, pluginOptions */);
```

Or use it as a [PostCSS] plugin:

```js
const postcss = require('postcss');
const postcssColour = require('postcss-colour');

postcss([
  postcssColour(/* pluginOptions */)
]).process(YOUR_CSS /*, processOptions */);
```

## PostCSS CLI

Add [PostCSS CLI] to your project:

```bash
npm install postcss-cli --save-dev
```

Use [PostCSS Colour] in your `postcss.config.js` configuration file:

```js
const postcssColour = require('postcss-colour');

module.exports = {
  plugins: [
    postcssColour(/* pluginOptions */)
  ]
}
```

## Webpack

Add [PostCSS Loader] to your project:

```bash
npm install postcss-loader --save-dev
```

Use [PostCSS Colour] in your Webpack configuration:

```js
const postcssColour = require('postcss-colour');

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          { loader: 'css-loader', options: { importLoaders: 1 } },
          { loader: 'postcss-loader', options: {
            ident: 'postcss',
            plugins: () => [
              postcssColour(/* pluginOptions */)
            ]
          } }
        ]
      }
    ]
  }
}
```

## Create React App

Add [React App Rewired] and [React App Rewire PostCSS] to your project:

```bash
npm install react-app-rewired react-app-rewire-postcss --save-dev
```

Use [React App Rewire PostCSS] and [PostCSS Colour] in your
`config-overrides.js` file:

```js
const reactAppRewirePostcss = require('react-app-rewire-postcss');
const postcssColour = require('postcss-colour');

module.exports = config => reactAppRewirePostcss(config, {
  plugins: () => [
    postcssColour(/* pluginOptions */)
  ]
});
```

## Gulp

Add [Gulp PostCSS] to your project:

```bash
npm install gulp-postcss --save-dev
```

Use [PostCSS Colour] in your Gulpfile:

```js
const postcss = require('gulp-postcss');
const postcssColour = require('postcss-colour');

gulp.task('css', () => gulp.src('./src/*.css').pipe(
  postcss([
    postcssColour(/* pluginOptions */)
  ])
).pipe(
  gulp.dest('.')
));
```

## Grunt

Add [Grunt PostCSS] to your project:

```bash
npm install grunt-postcss --save-dev
```

Use [PostCSS Colour] in your Gruntfile:

```js
const postcssColour = require('postcss-colour');

grunt.loadNpmTasks('grunt-postcss');

grunt.initConfig({
  postcss: {
    options: {
      use: [
       postcssColour(/* pluginOptions */)
      ]
    },
    dist: {
      src: '*.css'
    }
  }
});
```

[Gulp PostCSS]: https://github.com/postcss/gulp-postcss
[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss
[PostCSS]: https://github.com/postcss/postcss
[PostCSS CLI]: https://github.com/postcss/postcss-cli
[PostCSS Loader]: https://github.com/postcss/postcss-loader
[PostCSS Colour]: https://github.com/rjdestigter/postcss-colour
[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss
[React App Rewired]: https://github.com/timarney/react-app-rewired

repo_name: rjdestigter/postcss-colour


text:
# Changes to PostCSS Colour

### 1.0.0 (September 19, 2019)

- Added: Initial version


text:
import postcss from "postcss";

const rx = /^((?:.*)-)?colour$/i;

const postCssColour = () => {
	return {
		postcssPlugin: "postcss-colour",
		Root(root) {
			// for each colour declaration
			root.walkDecls(rx, (decl) => {
				const prefix = decl.prop.match(rx)[1] || "";
				const values = postcss.list.space(decl.value);

				decl.cloneBefore({
					prop: `${prefix}color`,
					value: values[0],
				});

				// remove the original size declaration
				decl.remove();
			});
		},
	};
};

Object.defineProperty(postCssColour, 'postcss', { value: true });

export default postCssColour;


text:
# PostCSS Colour [<img src="https://postcss.github.io/postcss/logo.svg" alt="PostCSS" width="90" height="90" align="right">][postcss]

[PostCSS Colour] lets you use define colours in css the way her majesty Queen Elizabeth II intended it.

Build and test architecture cloned from [postcss-short-size]

```pcss
body {
  colour: Blue;
  background-colour: #fff;
  border-colour: rgb(25, 0, 0);
}

/* becomes */

body {
  color: Blue;
  background-color: #fff;
  border-color: rgb(25, 0, 0);
}
```

## Usage

Add [PostCSS Colour] to your project:

```bash
npm install postcss postcss-colour --save-dev
```

Use [PostCSS Colour] to process your CSS:

```js
const postcssColour = require('postcss-colour');

postcssColour.process(YOUR_CSS /*, processOptions, pluginOptions */);
```

Or use it as a [PostCSS] plugin:

```js
const postcss = require('postcss');
const postcssColour = require('postcss-colour');

postcss([
  postcssColour(/* pluginOptions */)
]).process(YOUR_CSS /*, processOptions */);
```

[PostCSS Colour] runs in all Node environments, with special instructions for:

| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) |
| --- | --- | --- | --- | --- | --- |

[PostCSS]: https://github.com/postcss/postcss
[PostCSS Colour]: https://github.com/rjdestigter/postcss-colour
[postcss-short-size]: https://github.com/jonathantneal/postcss-short-size


text:
a {
	colour: Red;
	background-colour: Red;
	border-colour: Red;
	border-top-colour: Red;
}

b {
	colour: rgba(0, 0, 0, 0.5);
	background-colour: rgba(0, 0, 0, 0.5);
	border-colour: rgba(0, 0, 0, 0.5);
	border-top-colour: rgba(0, 0, 0, 0.5);
}

c {
	colour: BLUE;
	background-colour: BLUE;
	border-colour: BLUE;
	border-top-colour: BLUE;
}

d {
	colour:#CCC;
	background-colour:#CCC;
	border-colour:#CCC;
	border-top-colour:#CCC;
}


text:
a {
	color: Red;
	background-color: Red;
	border-color: Red;
	border-top-color: Red;
}

b {
	color: rgba(0, 0, 0, 0.5);
	background-color: rgba(0, 0, 0, 0.5);
	border-color: rgba(0, 0, 0, 0.5);
	border-top-color: rgba(0, 0, 0, 0.5);
}

c {
	color: BLUE;
	background-color: BLUE;
	border-color: BLUE;
	border-top-color: BLUE;
}

d {
	color:#CCC;
	background-color:#CCC;
	border-color:#CCC;
	border-top-color:#CCC;
}


text:
# Purpose of this List

This list does not aim to document every possible instance of Linux on Phone,
but rather serve as a curated list of early-beta to mature and well polished
efforts. For those, links to other lists would be more appropriate.

By contributing, you agree that your contribution can be shared freely across
the internet in accordance with the CC0 license, a copy of which can be found
in the COPYING file. You also agree to follow the Contributor Covenant Code
of Conduct, as reproduced in full below.

# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.

## Our Standards

Examples of behavior that contributes to a positive environment for our
community include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
  and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
  overall community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or
  advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
  address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.

Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.

## Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
[INSERT CONTACT METHOD].
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
reporter of any incident.

## Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:

### 1. Correction

**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.

**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.

### 2. Warning

**Community Impact**: A violation through a single incident or series
of actions.

**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.

### 3. Temporary Ban

**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.

**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.

### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior,  harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within
the community.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.

Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

repo_name: nikhiljha/awesome-linux-mobile


text:
# Definitions

These are the objective criteria to include a device / app / distribution. These aren't strict rules, but
should be used as general guidelines for inclusion.

## Device

### Native

Native devices must ship with an open-source non-Android Linux distribution and without a locked bootloader.
They must also be supported by at least one non-manufacturer-created distribution.

### Community Support

Community supported devices must **either** be...
- supported by more than one Linux on Phone project
- fully functional, meaning that all of the following works **at minimum**...
  - display + touch screen
  - phone calls
  - SMS
  - mobile data
  - cameras (front and back)

## App

Apps must be released as a BETA piece of software or 1.x+ release, and should not have glaring holes
in functionality or require significant workarounds to use. For example, a podcast app that doesn't
allow you to pause or play your podcast is missing significant functionality. A podcast app that doesn't
support skipping 15s with a single button is okay.

## Distributions

All distributions must support more than one mobile phone.


text:
Creative Commons Legal Code

CC0 1.0 Universal

    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
    LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
    ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
    INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
    REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
    PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
    THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
    HEREUNDER.

Statement of Purpose

The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").

Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.

For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.

1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:

  i. the right to reproduce, adapt, distribute, perform, display,
     communicate, and translate a Work;
 ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
     likeness depicted in a Work;
 iv. rights protecting against unfair competition in regards to a Work,
     subject to the limitations in paragraph 4(a), below;
  v. rights protecting the extraction, dissemination, use and reuse of data
     in a Work;
 vi. database rights (such as those arising under Directive 96/9/EC of the
     European Parliament and of the Council of 11 March 1996 on the legal
     protection of databases, and under any national implementation
     thereof, including any amended or successor version of such
     directive); and
vii. other similar, equivalent or corresponding rights throughout the
     world based on applicable law or treaty, and any national
     implementations thereof.

2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.

3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.

4. Limitations and Disclaimers.

 a. No trademark or patent rights held by Affirmer are waived, abandoned,
    surrendered, licensed or otherwise affected by this document.
 b. Affirmer offers the Work as-is and makes no representations or
    warranties of any kind concerning the Work, express, implied,
    statutory or otherwise, including without limitation warranties of
    title, merchantability, fitness for a particular purpose, non
    infringement, or the absence of latent or other defects, accuracy, or
    the present or absence of errors, whether or not discoverable, all to
    the greatest extent permissible under applicable law.
 c. Affirmer disclaims responsibility for clearing rights of other persons
    that may apply to the Work or any use thereof, including without
    limitation any person's Copyright and Related Rights in the Work.
    Further, Affirmer disclaims responsibility for obtaining any necessary
    consents, permissions or other rights required for any use of the
    Work.
 d. Affirmer understands and acknowledges that Creative Commons is not a
    party to this document and has no duty or obligation with respect to
    this CC0 or use of the Work.


text:
# 🐧📱 Awesome Linux Mobile [![Awesome](https://awesome.re/badge.svg)](https://awesome.re)

An awesome list of Linux Mobile related [apps](#apps), [OS images](#distributions), and [devices](#devices).
Curated to only list beta (or better) projects with a *reasonable amount* of functionality.

## Contents

- [Devices](#devices) - Devices that support Linux.
- [Apps](#apps) - Apps that work well in mobile form factors.
- [Distributions](#distributions) - Distros for your phone.

## Devices

These are devices that have excellent Linux support, either natively or by community support.

### Native

These devices have manufacturers that actively support running Linux on their devices.

- [Pine64 PinePhone](https://www.pine64.org/pinephone/) | [ postmarketOS](https://wiki.postmarketos.org/wiki/PINE64_PinePhone_(pine64-pinephone)) | [ Ubuntu Touch](https://devices.ubuntu-touch.io/device/pinephone/) | [📱 Other Distributions](https://wiki.pine64.org/index.php/PinePhone_Software_Release) | [🐧 Any* Desktop Distribution](https://xnux.eu/howtos/install-arch-linux-arm.html)
- [Purism Librem 5](https://puri.sm/products/librem-5/) | [ postmarketOS](https://wiki.postmarketos.org/wiki/PINE64_PinePhone_(pine64-pinephone)) | [ Ubuntu Touch](https://devices.ubuntu-touch.io/device/pinephone/) | [🐧 PureOS (Debian-Based)](https://puri.sm/products/librem-5/pureos-mobile/)

### Community Support

These devices have a strong Linux community and are well-supported by more than one Linux on Phone project OR are *really* well supported by just one project (all modem functionality, cameras, WiFi and Bluetooth at minimum).

- Nexus 5 | [ postmarketOS](https://wiki.postmarketos.org/wiki/Google_Nexus_5_(lg-hammerhead)) | [ Ubuntu Touch](https://devices.ubuntu-touch.io/device/hammerhead/)
- OnePlus One | [ Ubuntu Touch](https://devices.ubuntu-touch.io/device/bacon/)
- A few others, too! Contributions to this list [are welcome](#contribute).

### Other Devices

A surprising number of Android phones (and, possibly the iPhone 7 soon) can boot Linux, but may have significant issues with the basic functionality you would expect from a phone. If you own one of these devices and can contribute to the effort to making them ready for use, you may want to give them a shot. Fixing a feature on one phone often fixes it for many phones, since devices released in the same year usually have similar components.

- [Can My Phone Run Linux?](https://many.tuxphones.com/) - An excellent site by [Tuxphones](https://tuxphones.com/) that allows you to **search** for devices that boot Linux.
-  [PostmarketOS Device List](https://wiki.postmarketos.org/wiki/Devices) - A list of devices that can boot into postmarketOS, along with the features they currently support. This page also documents some failed attempts at porting, which might be useful for future successful attempts.
-  [Ubuntu Touch Device List](https://devices.ubuntu-touch.io/) - A list of devices that can boot into Ubuntu Touch, with some kind of metric showing the "maturity" of each device.
-  [NixOS Device List](https://mobile.nixos.org/devices/index.html) - A list of devices that can boot into NixOS, no information pertaining to feature support is available.

## Apps

These apps work well on Linux phones, and are in a beta stage or better. Once this list grows large enough, it should be split into categories, perhaps following the Google Play Store.

- [Authenticator](https://gitlab.gnome.org/World/Authenticator) ( GTK) - an app for two factor authentication/OTP, features a qr-code scanner and file backups
- [Foliate](https://johnfactotum.github.io/foliate/) ( GTK) - a simple and modern ebook viewer, supporting .epub, .mobi, .azw, and .azw3 files
- [Fractal](https://gitlab.gnome.org/GNOME/fractal/) ( GTK) - a matrix.org chat client, works decently well on mobile
- [Feeds](https://gabmus.gitlab.io/gnome-feeds/) ( GTK) - an RSS feed reader for GNOME, works well in GNOME-based desktop environments
- [VVAVE](https://vvave.kde.org/) ( Kirigami) - a convergent music player that is often shipped with the KDE Plasma Mobile desktop environment
- More? See the lists below for a non-curated listing of apps.

These are some other lists with Linux Phone apps.
- [Librem's List](https://source.puri.sm/Librem5/community-wiki/-/wikis/List-of-Apps-in-Development) - Mostly GTK+ apps that integrate well with their `phosh` mobile desktop shell.
- [Framasoft's List](https://mglapps.frama.io/) - Practically *every* app for mobile GNU/Linux, or apps that could possibly be modified to work on mobile, organized into a table.

## Distributions

These are mobile-specific distributions, or regular distributions that support mobile phones.

-  [PostmarketOS](https://postmarketos.org/) - Based on Alpine Linux, PostmarketOS is a good lightweight pick that still supports a multitude of mobile interfaces.
-  [Ubuntu Touch](https://ubuntu-touch.io/) - A community supported continuation of Canonical's project of the same name, Ubuntu Touch runs the unique Unity-based Lomiri interface and has a decently populated app store.
-  [Mobile NixOS](https://mobile.nixos.org/) - Currently supporting around [10 devices](https://mobile.nixos.org/devices/index.html), and featuring the same desktop Nix package manager in all it's declarative/reproducible goodness.
-  [Maemo Leste](https://maemo-leste.github.io/) - Currently supports a few older devices (notably, the N900 and the PinePhone).
- And more! You can find a pretty good list at the [PinePhone Software Release](https://wiki.pine64.org/index.php/PinePhone_Software_Release) page, since nearly every (if not every) Linux-on-phone distribution runs on the PinePhone.

## Contribute

Contributions are welcome & encouraged! Be sure to read the [contribution guidelines](CONTRIBUTING.md) first.


text:
@echo off
set d=-d
set kill=1
if exist VVFGAA.lock (
  set backup=1
  set /p MIUI=<VVFGAA.lock
)
set ANDROID_ADB_SERVER_PORT=45037
set t=黑阈服务一键开启 2.1 by VVFGAA ^^^& KizunaAI

title 【检查 ADB ……】%t%
adb version>nul 2>&1
if "%errorlevel%"=="9009" (
  ver|findstr "5.1">nul && (
    echo 错误：未找到Android调试桥（ADB），请下载platform-tools后把本文件放入此文件夹中。
    echo 链接：https://dl.google.com/android/repository/platform-tools_r23.1.0-windows.zip
    echo 按任意键退出
    pause>nul
    exit
  )
  echo 错误：未找到Android调试桥（ADB），请下载platform-tools后把本文件放入此文件夹中。按任意键打开下载网址
  pause>nul
  start https://dl.google.com/android/repository/platform-tools-latest-windows.zip
  exit
)
call :adb

title 【检查手机环境……】%t%
for /f "usebackq tokens=2 delims== " %%i in (`adb %d% shell "dumpsys package me.piebridge.brevent" ^| findstr versionCode`) do set ver=%%i
if "%ver%"=="" (
  echo 错误：未安装黑阈（此工具不支持白域），按任意键退出
  pause>nul
  goto end
)
if not %ver% GEQ 30 (
  echo 错误：黑阈版本太低，按任意键退出
  pause>nul
  goto end
)
for /f "usebackq tokens=* " %%i in (`adb %d% shell "getprop ro.boot.serialno"`) do set serialno=%%i
if "%serialno%"=="" for /f "usebackq tokens=* " %%i in (`adb %d% shell "getprop ro.build.date.utc"`) do set serialno=e-%%i
for /f "tokens=*" %%i in ('adb %d% shell "getprop ro.build.version.sdk"') do set sdk=%%i
for /f "tokens=*" %%i in ('adb %d% shell "getprop sys.usb.config"') do set usbconfig=%%i
for /f "tokens=*" %%i in ('adb %d% shell "getprop log.tag.brevent.daemon"') do set daemon=%%i
adb %d% shell "ls -l /sdcard/Android/data/me.piebridge.brevent/" 2>nul | findstr server>nul && set serverlog=1

if "%backup%"=="1" call :backup

call :check
if "%run%"=="1" (
  echo 黑阈服务已经开启，当前模式：%user%
  if "%serverlog%"=="1" (
    echo 黑阈工作日志位于手机/sdcard/Android/data/me.piebridge.brevent/目录下
    echo 问题反馈请在应用内点按日志按钮并向作者发送邮件说明情况（需要邮件应用）
    echo 按任意键开始检查事件日志，不需要请直接关闭窗口
    pause>nul
    call :events
    if "%events%"=="0" echo 警告：没有事件日志，黑阈无法自动工作。按任意键退出 && pause>nul && goto end
    echo 按任意键打开事件日志
    pause>nul
    start events.txt
    goto end
  ) else (
    echo 按任意键提取黑阈日志。不需要请直接关闭窗口
    pause>nul
    title 【提取黑阈日志……】%t%
    adb %d% shell "setprop log.tag.BreventServer D"
    adb %d% shell "logcat -G 16M"
    if not exist 黑阈日志.txt echo 此文件不会被自动删除，请注意日志的累积问题。>黑阈日志.txt
    if not exist 崩溃日志.txt echo 此文件不会被自动删除，请注意日志的累积问题。>崩溃日志.txt
    adb %d% logcat -d -b crash>>崩溃日志.txt
    adb %d% logcat -d -s BreventServer BreventLoader BreventUI>>黑阈日志.txt
    call :events
    echo 已提取日志，并调整了日志级别（重启前有效）
    echo 因此建议（如果可以的话）再触发一次相关问题，并运行本工具收集更详细的日志。
    echo 按任意键打开日志
    pause>nul
    start events.txt
    start 崩溃日志.txt
    start 黑阈日志.txt
    goto end
  )
)
if "%daemon%"=="1" (
  echo 检测到黑阈曾异常关闭，可能是由于拔线失效、关闭 USB 调试等原因造成，将开启网络ADB。
  echo 注意：网络 ADB 有风险，不要同意不明的 USB 调试确认弹窗。
  adb %d% tcpip 3035
  echo 请在拔线后打开黑阈应用一次，黑阈会自动启动服务，按任意键退出
  pause>nul
  goto end
)

title 【准备开启黑阈服务……】%t%
adb %d% shell "am force-stop me.piebridge.brevent"
adb %d% shell "am start -n me.piebridge.brevent/.ui.BreventActivity">nul
if %ver% LSS 86 (
  call :events del
  if "%events%"=="0" (
    echo 请不要关闭日志记录器缓冲区（位于开发者选项-调试）
    echo 按任意键退出
    pause>nul
    goto end
  )
)
adb %d% shell "cat /data/data/me.piebridge.brevent/brevent.sh" 2>nul|findstr "exec">nul || set file=0
if "%file%"=="0" call :findlib

title 【开启黑阈服务……】%t%
if %ver% GEQ 62 (
  if "%file%"=="0" (
    echo 警告：未发现指令文件，准备强行启动服务。可能启动失败，下次请读完黑阈向导后再运行本工具。
    adb %d% shell "%libpath%" >BreventLog.txt 2>&1
  ) else (
    adb %d% shell "sh /data/data/me.piebridge.brevent/brevent.sh" >BreventLog.txt 2>&1
  )
) else (
  echo 警告：这是黑阈的历史版本，已不受支持，请尽快更新。
  adb %d% shell "sh /sdcard/Android/data/me.piebridge.brevent/brevent.sh" >BreventLog.txt 2>&1
)
call :check
if "%run%"=="0" (
  echo 黑阈服务开启失败，请将日志与具体情况发至 https://github.com/brevent/Brevent/issues 来解决问题。>>BreventLog.txt
  echo 黑阈服务开启失败，请将日志与具体情况发至 https://github.com/brevent/Brevent/issues 来解决问题。按任意键打开日志
  pause>nul
  start BreventLog.txt
  goto end
)
adb %d% shell "setprop log.tag.brevent.daemon 1"

if "%MIUI%"=="MIUI" call :deviceidle

title 【OK】%t%
del BreventLog.txt
if %sdk% GEQ 26 (
  echo 警告：Android O及以上的设备，不要关闭“USB 调试”，不要更改 USB 使用方式，否则需要重新启动黑阈服务。
  if not "%usbconfig%"=="adb" (
    echo 警告：当前设备的状态会导致拔线后黑阈服务关闭，将开启网络ADB。注意：网络 ADB 有风险，不要同意不明的 USB 调试确认弹窗。
    adb %d% tcpip 3035
    echo 请在拔线后打开黑阈应用一次，黑阈会自动启动服务，按任意键退出
    pause>nul
    goto end
  )
)
echo 黑阈已开启，本程序即将自动关闭
ping -n 5 127.0.0.1 >nul
goto end

:adb
adb start-server>nul 2>&1 || (
  echo ADB 服务启动失败，请检查防火墙设置。
  echo 按任意键重试
  pause>nul
  goto adb
)
for /f "tokens=*" %%t in ('adb %d% get-state') do set adbState=%%t
if not "%adbState%"=="device" (
  echo;
  echo   ADB服务无法连接至设备实例，请依次确保：
  echo;
  echo   * 设备已与计算机USB连接。
  echo;
  echo   * 计算机已安装相关驱动。（各类管家/助手第一次连接设备时会帮助安装驱动）
  echo;
  echo   * 设备已启用ADB调试，并允许此计算机连接。
  echo;
  echo   * 设备没有与计算机上其他ADB服务连接，请尝试断开USB后再次连接。
  echo;
  echo 按任意键重试
  setlocal
  set ANDROID_ADB_SERVER_PORT=
  adb kill-server>nul 2>&1
  endlocal
  pause>nul
  goto adb
)
adb %d% unroot>nul
goto :EOF

:findlib
for /f "usebackq tokens=1,* delims== " %%a in (`adb %d% shell "dumpsys package me.piebridge.brevent" ^| findstr legacyNativeLibraryDir`) do set libdir=%%b
for /f "usebackq tokens=1 " %%i in (`adb %d% shell "ls %libdir%"`) do set abi=%%i
set libpath=%libdir%/%abi%/libbrevent.so
goto :EOF

:check
title 【检查黑阈服务状态……】%t%
set user=norun
if %sdk% GEQ 26 set all=-A
for /f "usebackq tokens=1 delims= " %%a in (`adb %d% shell "ps %all%" ^| findstr brevent_server`) do set user=%%a
if "%user%"=="norun" (set run=0) else set run=1
goto :EOF

:backup
title 【检查黑阈清单……】%t%
set pathx=/data/data/com.android.shell
if %sdk% GEQ 24 set pathx=/data/user_de/0/com.android.shell
adb %d% shell "ls -l %pathx%"|findstr "me.piebridge.brevent.list$">nul && (
  adb %d% pull %pathx%/me.piebridge.brevent.list %serialno%.list>nul 2>&1 && echo 已备份黑阈清单。
) || if exist %serialno%.list (
  echo 黑阈清单为空，但电脑上存在备份。
  adb %d% push  %serialno%.list %pathx%/me.piebridge.brevent.list>nul 2>&1 && echo 已还原黑阈清单。
) else (
  echo 黑阈清单为空，电脑上也没有备份。
)
goto :EOF

:deviceidle
title 【处理电池优化】%t%
for /f "usebackq tokens=* " %%a in (`adb %d% shell "getprop ro.miui.ui.version.code"`) do set miuiver=%%a
if "%miuiver%"=="" echo 不是 MIUI 系统，跳过处理电池优化。 && goto :EOF
for /f "tokens=1 delims==" %%a in (%serialno%.list) do adb %d% shell "dumpsys deviceidle whitelist -%%a">>deviceidle.log && title 【检查电池优化：%%a】%t%
for /f "usebackq tokens=2 delims=:" %%a in (`find /c "Removed:" deviceidle.log`) do set num=%%a
echo 已将%num% 个应用移出了电池优化白名单。
del deviceidle.log
goto :EOF

:events
title 【检查事件日志……】%t%
adb %d% logcat -d -b events>events.log
echo VVFGAA>>events.log
set /p fir=<events.log
if "%fir%"=="VVFGAA" set events=0
if not "%events%"=="0" (
  echo ----------am_proc_start---------->events.txt
  findstr "am_proc_start" events.log 1>>events.txt || echo 警告：未发现am_proc_start日志，无法迅速处理被恶意唤醒的应用。
  echo ----------am_restart_activity---------->>events.txt
  findstr "am_restart_activity" events.log 1>>events.txt || echo 警告：未发现am_restart_activity日志，无法识别界面被打开。
  echo ----------am_resume_activity---------->>events.txt
  findstr "am_resume_activity" events.log 1>>events.txt || echo 警告：未发现am_resume_activity日志，无法识别界面被打开。
  echo ----------screen_toggled---------->>events.txt
  findstr "screen_toggled" events.log 1>>events.txt || echo 警告：未发现screen_toggled日志，将不会在开关屏时黑阈。
  echo ----------am_new_intent---------->>events.txt
  findstr "am_new_intent" events.log 1>>events.txt || echo 未发现am_new_intent日志，无法识别主页。
  echo ----------am_pause_activity---------->>events.txt
  findstr "am_pause_activity" events.log 1>>events.txt || echo 未发现am_pause_activity日志，无法识别非正常返回。
  echo ----------am_switch_user---------->>events.txt
  findstr "am_switch_user" events.log 1>>events.txt || echo 未发现am_switch_user日志，这很正常。
  echo ----------notification_cancel_all---------->>events.txt
  findstr "notification_cancel_all" events.log 1>>events.txt || echo 未发现notification_cancel_all日志，无法识别安装或卸载应用事件。
  echo ----------notification_panel_revealed---------->>events.txt
  findstr "notification_panel_revealed" events.log 1>>events.txt || echo 未发现notification_panel_revealed日志，黑阈不会在展开通知栏时暂停。
  echo ----------notification_panel_hidden---------->>events.txt
  findstr "notification_panel_hidden" events.log 1>>events.txt || echo 未发现notification_panel_hidden日志，黑阈不会在隐藏通知栏后恢复。
  echo ----------device_idle---------->>events.txt
  findstr "device_idle:" events.log 1>>events.txt || echo 未发现device_idle日志，黑阈不会在低电耗模式下暂停。
  echo ----------device_idle_light---------->>events.txt
  findstr "device_idle_light:" events.log 1>>events.txt || echo 未发现device_idle_light日志，黑阈不会在低电耗模式下暂停。
  echo ----------notification_enqueue---------->>events.txt
  findstr "notification_enqueue:" events.log 1>>events.txt || echo 未发现notification_enqueue日志，影响黑阈检查通知。
  echo ----------notification_canceled---------->>events.txt
  findstr "notification_canceled:" events.log 1>>events.txt || echo 未发现notification_canceled日志，影响黑阈检查通知。
  echo ----------am_kill---------->>events.txt
  findstr "am_kill:" events.log 1>>events.txt || echo 未发现am_kill日志，影响黑阈检查进程。

  if "%1"=="del" del events.txt
)
del events.log
goto :EOF

:end
if "%kill%"=="1" adb kill-server>nul 2>&1
exit

repo_name: VVFGAA/BreventBat

repo_language: Batchfile


text:
黑阈 电脑一键开启工具

部分特点
1.完全绿色化，源代码透明，在win上能够直接运行
2.解决ADB端口占用
3.解决ADB默认为root的问题
4.自动识别黑阈版本进行对应处理
5.能够检查事件日志
6.能够提取日志
7.即使没有指令文件也能强行启动服务
8.支持自动备份黑阈清单，并且区分不同设备分别备份
9.解决 Android O 拔线失效问题
10.MIUI优化，自动去掉已黑阈应用的电池优化豁免

*本工具随下随用随删。但是，
如果你已经把它放在了一个固定位置，可以在文件夹里放一个文件（即和bat文件同一位置），文件名：VVFGAA.lock 。
放置后每次运行时自动备份黑阈清单，当启动服务前没有清单时自动还原。
MIUI用户如果想让已黑阈的应用保持电池优化为已优化状态，记事本修改VVFGAA.lock文件内容为 MIUI 即可。

更新记录：
1.0
初版
1.1
添加状态提示；避免使用grep
1.2
优化逻辑，支持备份黑阈清单
1.3
能够无指令文件启动服务，实时查看新版日志
1.4
能够分设备来备份黑阈清单。使用设备ID识别，即 adb devices 时显示的ID
支持Android O，给出提示。并且检测“拔线就失效”这种情况并进行处理
1.5
支持批量去掉电池优化豁免
1.6
支持新版黑阈
1.7
兼容Windows XP
1.8
改名
1.9
支持Android P
2.0
检测黑阈服务异常退出并进行处理

高级（看不懂就别管了）：
第二行，默认连接设备
第三行，默认自动关闭ADB服务
第五行，自动备份
第六行，电池优化批量操作
第八行，端口


text:
- [源项目](https://github.com/henrythemes/jekyll-minimal-theme)
- [汉化内容](#汉化内容)

<details>
<summary>点击展开原 README 汉化后的内容</summary>

# 什么是 `jekyll-极简主题`?

这是又一个极简(风格)的Jekyll静态站点生成器主题，
也就是说，一个现成的主题模板包。

查看在线演示 @ [`gledos.science/jekyll-minimal-theme-zh-cmn-hans` »](http://gledos.science/jekyll-minimal-theme-zh-cmn-hans/)

---

举例:

```
├── _config.yml                # 网站配置
├── _posts                     # 暂时储存着一些博客文章模板用作演示
|   ├── 2014-05-05-sportdb-update-v192.md
|   ├── 2014-10-10-new-repo-ba-bay.md     # 文件名格式:
|   ├── 2014-10-21-sql-views.md           # => 年-月-日-标题.格式
|   ├── 2014-11-11-new-reop-maps.md
|   └── 2014-12-15-quick-starter-datafiles.md
├── _layouts
|   ├── default.html           # 主布局模板
|   └── post.html              # 单一博客模板
├── css
|   ├── _settings.scss         # 风格设置(例如变量)
|   └── style.scss             # 主风格页面
├── feed.xml                   # web订阅源模板(如atom格式)
├── archive.html               # 归档文章
└── index.html                 # 主页模板
```

将会生成出

```
└── _site                           # 输出生成文件夹; 网站在此生成
    ├── css
    |   └── style.css               # 页面样式（按原样复制1：1）
    ├── sportdb-update-v192.html    # 博客文章页面
    ├── new-repo-ba-bay.md.html     # 另一个博客网站页面
    ├── sql-views.html
    ├── new-repo-maps.html
    ├── quick-starter-datafiles.html
    ├── feed.xml                    # web订阅源（如atom格式）
    ├── archive.html                # 归档文章
    └── index.html                  # 主页
```

## 使用方法

首先删除`_posts`文件夹中的所有示例文章，然后更改`_config.yml`中的设置以使用您自己的`site.title`和`site.url`：

```
title:   'Jekyll Minimal Theme 中文简体版'
url:     'http://henrythemes.github.io/jekyll-minimal-theme'
author:
  name:  'Jekyll Minimal Theme Team'
```

## Color n Typography Settings (in `css/_settings.scss`)

排版（字体）：

~~~
$font-family:       "Helvetica Neue", Helvetica, Arial, sans-serif;

$code-font-family:  Menlo, Monaco, "Courier New", monospace;
~~~

颜色：

~~~
$masthead-color:         #505050;
$masthead-small-color:   #C0C0C0;

$post-title-color:       #303030;
$post-date-color:        #9a9a9a;

$body-color:            #515151;
$body-background-color: #fff;

$link-color:            #268bd2;

$headings-color:        #313131;    // h1,h2,h3,h4,h5,h6

$strong-color:          #303030;    // strong

$pre-background-color:  #f9f9f9;    // pre

$blockquote-color:        #7a7a7a;  // blockquote
$blockquote-border-color: #e5e5e5;

$table-border-color:         #e5e5e5;
$table-odd-background-color: #f9f9f9;
~~~

非常感谢Poole主题 (Poole theme); `jekyll-minimal-theme` 始于Poole主题的排版和颜色设置。

## 其他的 (极简) Jekyll主题

- Poole Theme by Mark Otto - [(源代码)](https://github.com/poole/poole)

- Pixyll Theme by John Otander - [(源代码)](https://github.com/johnotander/pixyll)

~~~
in _main.scss:
  font-family:     "Merriweather", "PT Serif", Georgia, "Times New Roman", serif;
  code-font-family: Menlo, Monaco, "Courier New", monospace;
  h1-h6|button|form|pagination|footer -font-family:
                   'Lato', 'Helvetica Neue', Helvetica, sans-serif;

in _basscss.scss:
  font-family:       'Helvetica Neue', Helvetica, sans-serif;
~~~

- Hikari Theme by Mathieu Mayer-Mazzoli - [(源代码)](https://github.com/m3xm/hikari-for-Jekyll)

~~~
in components/_syntax.scss:
  code-font-family:    'Courier', monospace;
in base/_variables.scss:
  font-family:         'Open Sans', sans-serif;
  variant-font-family: 'Lora', Georgia, serif;
in base/_global.scss:
  h1-h6-font-family:  'Open Sans', sans-serif;
in base/_reset.scss:
  font-family:         sans-serif;
  code-font-family:    monospace, monospace;
~~~

### 更多主题

查看 [Dr. Jekyll's Themes](https://drjekyllthemes.github.io) 的目录。

### 更多的快速入门向导脚本

查看 [Mr. Hyde's Scripts](https://github.com/mrhydescripts/scripts) 的库。

## License / 许可证

![CC0协议](https://publicdomainworks.github.io/buttons/zero88x31.png)
主题和脚本专用于公共领域。 尽可能地使用它，不受任何限制。

## ~~有问题和意见？~~

~~发送他们到 [wwwmake forum](http://groups.google.com/group/wwwmake).
谢谢！~~

建议发给我(gledos)，但是我不一定有能力解决，就算能解决也会花上很多时间......

</details>

# 汉化内容

- 日期中国习惯化
- 字体加入各种设备适合的中文字体(包括 Chrome OS)
- 对字体大小和边距有所调整，更佳适合中文(但也许也不是最合适的)
- 对README 和网站上首页的第一篇文章进行了汉化

## 一些提示

这个主题不需要在文章的 mayl 头文件中写入 `date` 这一项多余的东西，本主题在经过我的修改(最大限度保留原设定)选择 `post` 模板时会直接寻找在 `_post/` 里面的文章中的 `YYYY-MM-DD` 格式的时间，所以就不需要出现两份时间了。

- [liquid 模板语言中文文档](https://liquid.bootcss.com)
- [jekyll 中新增的 liquid 过滤器(英文)](https://jekyllrb.com/docs/templates/)
- [Shellphon 写的 liquid 用法笔记](http://blog.csdn.net/dont27/article/details/38097581)

## 推荐修改

- 使用 liquid 进行生成 sitemap.xml [比如](https://github.com/jekyll/jekyll/blob/master/test/source/sitemap.xml)
- 写长文要使用摘要 [Post excerpts - jekyll docs(英文)](https://jekyllrb.com/docs/posts/#post-excerpts)、[中文](http://www.cnblogs.com/coderzh/p/jekyll-readmore.html)
- 限制主页显示文章的数量，还可以加上分页。(但是 5 篇文章就一页简直浪费人生，建议 8 篇以上，因为观看者不去归档看标题，就是为了看主页中的摘要内容啊) [](https://jekyllrb.com/docs/pagination/)

repo_name: gledos/jekyll-minimal-theme-zh-cmn-hans

repo_language: CSS


text:
---
layout: null
---
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>News 'n' Updates | {{ site.title }}</title>
  <link href="{{ site.url }}/feed.xml" rel="self"/>
  <link href="{{ site.url }}/"/>
  <updated>{{ site.time | date_to_xmlschema }}</updated>
  <id>{{ site.url }}/</id>
  <author>
    <name>{{ site.author.name }}</name>
  </author>
  <generator>Jekyll v{{ jekyll.version }}</generator>

  {% for post in site.posts limit: 10 %}
  <entry>
    <title>{{ post.title | xml_escape }}</title>
    <link href="{{ site.url }}{{ post.url }}"/>
    <updated>{{ post.date | date_to_xmlschema }}</updated>
    <id>{{ site.url }}{{ post.id }}</id>
    <content type="html">{{ post.content | xml_escape }}</content>
  </entry>
  {% endfor %}
</feed>


text:
###########
# site.title, site.url, site.author.name

title:   'Jekyll Minimal Theme 中文简体版'
author:
  name:  'Jekyll Minimal Theme Team'

## 提示:
#  在您的模板中使用site.path，使其适用于两种协议，例如 http和https
#  使用site.url仅内部的网络馈源模板（外部需要完整的含协议的URL）

path: /jekyll-minimal-theme-zh-cmn-hans
url:  'http://gledos.science/jekyll-minimal-theme-zh-cmn-hans/'

########
# 更多设置

markdown: kramdown

sass:
  sass_dir: css
  style:    expanded

permalink: /:title.html

exclude:
- README.md

safe: true
lsi: false


text:
---
layout: default
title: 欢迎来到
---

{% for post in site.posts %}

      {{ post.title }}

{{ post.date | date: "%F" }}

  {{ post.content }}

{% endfor %}


text:
---
layout: default
title: 归档
---

Archive

{% for post in site.posts %}

  {{ post.date | date: "%Y-%m-%d" }}
    »

    {{ post.title }}

{% endfor %}


text:
---
layout: default
title: 关于
---

# 这是测试用的标题

这是一个演示用的 "关于" 页面

测试 "关于" 页面的样子

{% raw %}
这里使用了 {% raw %} 标签(tag)，可以输出不被 liquid 模板语言转换的内容，比如 {{ post.date }}
{% endraw %}

这个页面可以用各种各样的 CSS 和 HTML 模板，markdown 或者 HTML 标记语言编写也都行

汉化者：[gledos](https://github.com/gledos/jekyll-minimal-theme-zh-cmn-hans/)


text:
<!DOCTYPE html>

  <meta charset="utf-8">
  <title>{{ page.title }} - {{ site.title }}</title>
  <link rel="stylesheet" type="text/css" href="{{ site.path }}/css/style.css" >
  <link rel="alternate" type="application/atom+xml" href="{{ site.path }}/feed.xml" title="News Feed">

      {{ site.title }}
           归档
           关于
           Feed
           源码

{{ content }}


text:
---
layout: default
---

{{ page.title }}

  {% assign sinple_path_date = page.path | remove: "_posts/" | split: "-" %}

{{ sinple_path_date[0] | append: "-" | append: sinple_path_date[1] | append: "-" | append: sinple_path_date[2] | date: "%F" }}

  {{ content }}


text:
///////////////////////////////////////
// css theme variables / settings
// 增加了中文字体，字体的选择参考了: https://segmentfault.com/a/1190000006110417，并加入了 Chromebook 适合的思源黑体

$font-family:       "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei", "WenQuanYi Micro Hei", "Noto Serif CJK SC", sans-serif;

$code-font-family:  Menlo, Monaco, "Courier New", monospace, "PingFang SC", "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei", "WenQuanYi Micro Hei", "Noto Serif CJK SC", sans-serif;

$masthead-color:         #505050;
$masthead-small-color:   #C0C0C0;

$post-title-color:       #303030;
$post-date-color:        #9a9a9a;

$body-color:            #515151;
$body-background-color: #fff;

$link-color:            #268bd2;

$headings-color:        #313131;    // h1,h2,h3,h4,h5,h6

$strong-color:          #303030;    // strong

$pre-background-color:  #f9f9f9;    // pre

$blockquote-color:        #7a7a7a;  // blockquote
$blockquote-border-color: #e5e5e5;

$table-border-color:         #e5e5e5;
$table-odd-background-color: #f9f9f9;


text:
---
###########
# note: will result in an all-in-one-file stylesheet e.g. style.css
# 原本字体大小是 20px ;
###########
---

@import 'settings';

html {
  font-family: $font-family;
  font-size:   100%;
  line-height: 1.5;
}

body {
  color:            $body-color;
  background-color: $body-background-color;
}

//////////////
// Links

a {
  color:           $link-color;
  text-decoration: none;

  strong {
    color: inherit;
  }

  &:hover,
  &:focus {
    text-decoration: underline;
  }
}

////////////////////////////
// Headings

h1, h2, h3, h4, h5, h6 {
  margin-bottom:  .5rem;
  font-weight:    bold;
  line-height:    1.25;
  color:          $headings-color;
  text-rendering: optimizeLegibility;
}
h1 {
  font-size: 2rem;
}
h2 {
  margin-top: 1rem;
  font-size: 1.5rem;
}
h3 {
  margin-top: 1.5rem;
  font-size: 1.25rem;
}
h4, h5, h6 {
  margin-top: 1rem;
  font-size: 1rem;
}

/////////////
// Body text

p {
  margin-top: 0;
  margin-bottom: 1rem;
}

strong {
  color: $strong-color;
}

/////////////
// Lists

ul, ol, dl {
  margin-top: 0;
  margin-bottom: 1rem;
}

dt {
  font-weight: bold;
}
dd {
  margin-bottom: .5rem;
}

//////////////////////
// Code

code,
pre {
  font-family: $code-font-family;
}
code {
  padding: .25em .5em;
  font-size: 85%;
}

pre {
  margin-top: 0;
  margin-bottom: 1rem;
  padding: 1rem;
  font-size: .8rem;
  line-height: 1.4;
  background-color: $pre-background-color;

  code {
    padding: 0;
    font-size: 100%;
    color: inherit;
    background-color: transparent;
  }
}

/////////////////////
// Quotes

blockquote {
  padding: .5rem 1rem;
  margin: .8rem 0;
  color: $blockquote-color;
  border-left: .25rem solid $blockquote-border-color;

  p:last-child {
    margin-bottom: 0;
  }
}

img {
  display: block;
  max-width: 100%;
  margin: 0 0 1rem;
  border-radius: 5px;
}

//////////////////////
// Tables

table {
  margin-bottom: 1rem;
  width: 100%;
  border: 1px solid $table-border-color;
  border-collapse: collapse;

  td,
  th {
   padding: .25rem .5rem;
   border: 1px solid $table-border-color;
  }

  tr:nth-child(odd) td,
  tr:nth-child(odd) th {
    background-color: $table-odd-background-color;
  }
}

////////////////////////////////
//  Container
//   -- centers page content
//  原 max-width 为 38rem

.container {
  max-width: 55rem;
  padding-left:  1rem;
  padding-right: 1rem;
  margin-left:  auto;
  margin-right: auto;
}

///////////////////////////////////////////////////
//  Masthead
//  原 margin-bottom 为 3rem

.masthead {
  padding-top:    1rem;
  padding-bottom: 1rem;
  margin-bottom: 2rem;

 .masthead-title {
    margin-top: 0;
    margin-bottom: 0;
    color: $masthead-color;

    a {
      color: $masthead-color;
    }

    small {
      color: $masthead-small-color;
      font-size: 75%;
      font-weight: 400;
      letter-spacing: 0;
    }
  }
}

//////////////////////////
// Posts

.post {
  margin-bottom: 4em;

  // note: only change margin for title,date if inside post block
  .post-title {
    margin-top: 0;
  }

  // Meta data line below post title
  .post-date {
    display: block;
    margin-top:  -.5rem;
    margin-bottom: 1rem;
  }
}

.post-title,
.post-title a {
  color: $post-title-color;
}

.post-date {
  color: $post-date-color;
}


text:
---
layout: post
title:  "football.db SQL Queries Made Easy (Thanks to Views)"
---

First thanks to Joe Kampschmidt for getting started w/
some [SQL queries examples](http://openfootball.github.io/docs/sql-queries-intro.html).

Added some SQL views to make it easier to query the `football.db`.
Example - List World Cup Brazil 2014 Games:

Before (Table Edition):

~~~
SELECT t1.title,
       t2.title,
       g.*
  FROM games g
       LEFT OUTER JOIN teams t1 ON t1.id = g.team1_id
       LEFT OUTER JOIN teams t2 ON t2.id = g.team2_id
       INNER JOIN rounds r ON r.id = g.round_id
       INNER JOIN events e ON e.id = r.event_id
 WHERE e.key = 'world.2014'
~~~

After (View Edition):

~~~
SELECT *
  FROM events_games_list
 WHERE e.key = 'world.2014';
~~~

[More views](https://github.com/openfootball/schema.sql) include:

- `teams_list`
- `games_list`
- `events_list`
- `events_teams_list`
- `events_games_list`
- `events_rounds_list`
- `events_groups_list`


text:
---
layout: post
title: "New Repo /maps - Free Full-Screen Interactive Beer Maps w/ Brewery Listings"
---

Added a new repo, that is, `/maps` for hosting 'full-screen'
interactive beer maps with brewery listings.

See an example [beer map for Austria](http://openbeer.github.io/maps/at) (~200 breweries n brewpubs)
live or [check the source using](https://github.com/openbeer/maps) the mapbox.js mapping library.


text:
---
layout: post
title: "测试 CSS"
---

# Heading 标题 1

## Heading 标题 2

### Heading 标题 3

#### Heading 标题 4

##### Heading 标题 5

###### Heading 标题 6

**Strange Case of Dr Jekyll and Mr Hyde** is the original
title of a novella written by the Scottish author Robert Louis Stevenson
that was first published in 1886. The work is commonly known today as
**The Strange Case of Dr. Jekyll and Mr. Hyde**,
**Dr. Jekyll and Mr. Hyde**, or simply
**Jekyll & Hyde**.
It is about a London lawyer named Gabriel John Utterson
who investigates strange occurrences between
his old friend, Dr. Henry Jekyll, and the evil Edward Hyde.

The work is commonly associated with the rare mental condition often called
"split personality", referred to in psychiatry as dissociative identity disorder,
where within the same body there exists more than one distinct personality.
In this case, there are two personalities within Dr Jekyll, one apparently good
and the other evil. The novella's impact is such that it has become a part of
the language, with the very phrase "Jekyll and Hyde" coming to mean a person
who is vastly different in moral character from one situation to the next.

**Inspiration and writing**

Robert Louis Stevenson Stevenson had long been intrigued by the idea...

**Plot**

John Utterson, a lawyer, is on his weekly walk with his relative...

### Lists / 列表

Table of Contents:

1. Inspiration and writing
2. Plot
3. Characters
    1. Dr. Henry Jekyll/Edward Hyde
    2. Gabriel John Utterson
    3. Richard Enfield
    4. Dr. Hastie Lanyon
    5. Mr. Poole
    6. Inspector Newcomen
    7. Sir Danvers Carew, MP
    8. Maid
4. Analysis
5. Reception
6. Adaptations
7. References
8. Further reading

Categories:

- Short stories by Robert Louis Stevenson
- 1886 short stories
- Novellas
- Novels set in London
- Gothic novels
- Victorian novels
- Works based on the Faust legend
- Dissociative identity disorder in fiction

Robert Louis Stevenson:

- Books
    - An Inland Voyage (1878)
    - Travels with a Donkey in the Cévennes (1879)
    - The Silverado Squatters (1883)
    - Memories and Portraits (1887)
    - Across the Plains (1892)
    - Eight Years of Trouble in Samoa (1892)
    - The Amateur Emigrant (1895)
- Novels
    - Treasure Island (1883)
    - Prince Otto (1885)
    - Kidnapped (1886)
    - The Black Arrow: A Tale of the Two Roses (1888)
    - The Master of Ballantrae (1889)
    - The Wrong Box (1889)
    - The Wrecker (1892)
    - Catriona (1893)
    - The Ebb-Tide (1894)
    - Weir of Hermiston (1896)
    - St. Ives (1897)

### Blockquotes / 引用文字

Biographer Graham Balfour quoted Stevenson's wife Fanny Stevenson:

> In the small hours of one morning, [...] I was awakened by cries of horror
> from Louis. Thinking he had a nightmare, I awakened him. He said angrily:
> "Why did you wake me? I was dreaming a fine bogey tale."
> I had awakened him at the first transformation scene.

Quotes from "The Strange Case of Dr. Jekyll and Mr. Hyde":

> Quiet minds cannot be perplexed or frightened but go on in fortune
> or misfortune at their own private pace, like a clock during a thunderstorm.
>
> -- Robert Louis Stevenson

> It is one thing to mortify curiosity, another to conquer it.
>
> -- Robert Louis Stevenson

> If I am the chief of sinners, I am the chief of sufferers also.
>
> -- Robert Louis Stevenson

### Tables / 表格

---------------- | ------------------------
Author           | Robert Louis Stevenson
Original title   | Strange Case Of Dr Jekyll And Mr Hyde
Country          | United Kingdom
Language         | English
Series           | None
Genre            | Drama, Horror, Thriller, Gothic, Science fiction
Publisher        | Longmans, Green & Co.
Publication date | 5 January 1886

### Code n Code Blocks / 代码和代码块

The `white-space` CSS property is used to to describe
how white spaces inside the element is handled. Example:

~~~
white-space: normal
white-space: nowrap
white-space: pre
white-space: pre-wrap
white-space: pre-line

white-space: inherit
~~~

Many CSS properties take `<length>` values,
such as `width`, `margin`,  `padding`, `font-size`, `border-width`, `text-shadow`, ...

Some specific examples:

- `1in` is always `96px`,
- `3pt` is always `4px`,
- `25.4mm` is always `96px`.

~~~
html { font-size: 62.5%; }
body { font-size: 1.4rem; } /* =14px */
h1   { font-size: 2.4rem; } /* =24px */
~~~


text:
---
layout: post
title: "Added football.db Quick Starter Datafile Templates - $ sportdb new worldcup"
---

The sportdb command line tool now includes a new quick starter
template command to (auto-)download Datafile scripts from the new
[`openfootball/datafile` registry](https://github.com/openfootball/datafile).

For example, to build yourself a copy of the `worldcup2014.db` type:

~~~
$ sportdb new worldcup2014
~~~

The new command will run these steps:

- Step 1: Download `worldcup2014.rb` Datafile (from GitHub) to your
    working folder as `./Datafile`
- Step 2: Run the `sportdb` build command
    - Step 2.a: Download all datasets listed in the Datafile as zip
       archives (from GitHub) to `./tmp`
    - Step 2.b: Create the "empty" database, that is, table structure,
       indexes, etc. (schema)
    - Step 2.c: Read in all datasets from the zip archives in `./tmp` (no need to unpack)

That's it. All done and setup with a single command. Still early and rough.

PS: The first quick starter Datafile templates include:

- `worldcup`   => All World Cups 1930-2014
- `en`         => English Premier Leagues
- `en2014-15`  => English Premier League 2014/15
- `cl2014-15`  => (European) Champions League 2014/15


text:
---
layout: post
title: "New Repo - Bayern (Baviria) - incl. European Beer Stars 2011, 2012, 2013"
---

Moved all beer, brewpub n brewery data for Bayern
(Baviria) to its own repo, that is, [`openbeer/by-bayern`](https://github.com/openbeer/by-bayern).

Also includes all European Beer Star winners from Bayern
(Baviria) for the years 2011, 2012 and 2013. Cheers. Prost.


text:
---
layout: post
title: "欢迎来到 jekyll-minimal-theme 中文简体版——又一个极简 Jekyll 主题"
---

什么是 `jekyll-极简主题`?

这是又一个极简(风格)的Jekyll静态站点生成器主题，
也就是说，一个现成的主题模板包。

查看在线演示 @ [`henrythemes.github.io/jekyll-minimal-theme` »](http://gledos.science/jekyll-minimal-theme-zh-cmn-hans/)

---

举例:

```
├── _config.yml                # 网站配置
├── _posts                     # 暂时储存着一些博客文章模板用作演示
|   ├── 2014-05-05-sportdb-update-v192.md
|   ├── 2014-10-10-new-repo-ba-bay.md     # 文件名格式:
|   ├── 2014-10-21-sql-views.md           # => 年-月-日-标题.格式
|   ├── 2014-11-11-new-reop-maps.md
|   └── 2014-12-15-quick-starter-datafiles.md
├── _layouts
|   ├── default.html           # 主布局模板
|   └── post.html              # 单一博客模板
├── css
|   ├── _settings.scss         # 风格设置(例如变量)
|   └── style.scss             # 主风格页面
├── feed.xml                   # web订阅源模板(如atom格式)
├── archive.html               # 归档文章
└── index.html                 # 主页模板
```

将会生成出

```
└── _site                           # 输出生成文件夹; 网站在此生成
    ├── css
    |   └── style.css               # 页面样式（按原样复制1：1）
    ├── sportdb-update-v192.html    # 博客文章页面
    ├── new-repo-ba-bay.md.html     # 另一个博客网站页面
    ├── sql-views.html
    ├── new-repo-maps.html
    ├── quick-starter-datafiles.html
    ├── feed.xml                    # web订阅源（如atom格式）
    ├── archive.html                # 归档文章
    └── index.html                  # 主页
```

使用方法：

首先删除`_posts`文件夹中的所有示例文章，然后更改`_config.yml`中的设置以使用您自己的`site.title`和`site.url`：

```
title:   'Jekyll Minimal Theme'
url:     'http://henrythemes.github.io/jekyll-minimal-theme'
author:
  name:  'Jekyll Minimal Theme Team'
```


text:
---
layout: post
title: "sportdb Update v1.9.2 - Added Match Goals Reader e.g. [Messi 3', 45+1']"
---

What's news? sportdb command line updates:

The match schedule reader now will add goals (plus auto-add missing
players). All still a little rough but working without any (extra) configuration. Example:

~~~
(1) Thu Jun/12 17:00   Brazil 3-1 (1-1) Croatia       @ Arena de São Paulo, São Paulo
        [Neymar 29', 71' (pen.) Oscar 90+1';  Marcelo 11' (o.g.)]
~~~

The reader will add four goal records (see the table goals w/ fields such as
`player_id`, `team_id`, `minute`, `offset`, `score1`, `score2` etc.):

~~~
1 |   Marcelo  11'   (o.g.)   1-0   Croatia (Team 2)
2 |   Neymar   29'            1-1   Brazil  (Team 1)
3 |   Neymar   71'   (pen.)   2-1   Brazil  (Team 1)
4 |   Oscar    90'+1'         3-1   Brazil  (Team 1)
~~~


text:
<!DOCTYPE html>

<meta charset="utf-8">
<title>English syntax highlighting</title>
<link rel="stylesheet" href="vendor/normalize.css">
<link rel="stylesheet" href="the.css">

<link rel="stylesheet" href="lib/highlight-default.css">

English syntax highlighting

Nerds already highlight their code. Why don't we also highlight our prose?

<form id="setup">
	<textarea id="prose"></textarea>
	<input type="submit" value="Go for it">
</form>

repo_name: EvanHahn/English-text-highlighting


text:
* {
	box-sizing: border-box;
	-webkit-box-sizing: border-box;
	-moz-box-sizing: border-box;
	-ms-box-sizing: border-box;
}

html {
	font-family: Lato, "Segoe UI", Avenir, "Helvetica Neue", Helvetica, sans-serif;
}

body {
	margin: 0 auto 2em auto;
	width: 95%;
	max-width: 800px;
}

input, textarea {
	font: inherit;
}

::selection {
	color: #fff;
	background-color: #f34;
}

::-moz-selection {
	color: #fff;
	background-color: #f34;
}

h1 {
	text-transform: uppercase;
	color: #aaa;
}

#setup {
	margin-bottom: 1em;
}

#prose {
	width: 100%;
	height: 10em;
	margin-bottom: .5em;
	font-size: 80%;
	border-color: #aaa;
	resize: vertical;
}

#setup input[type="submit"] {
	float: right;
	color: #fff;
	background-color: #aaa;
	font-weight: bold;
	text-transform: uppercase;
	font-size: 1.5em;
	padding: .25em 1em;
	border: 0;
}

#output {
	padding: 1em 1.5em;
	white-space: pre-wrap;
	font-family: Georgia, Garamond, serif;
	font-size: 16pt;
	line-height: 1.9em;
}

/* clearfix hack */

#setup:before, #setup:after {
	content: ' ';
	display: table;
}
#setup:after {
	clear: both;
}


text:
$(document).ready(function() {

	var $form = $('#setup');
	var $prose = $('#prose');
	var $output = $('#output');

	var doIt = function() {
		var result = highlight($prose.val());
		$output.html(result);
	};

	$form.on('submit', function(event) {
		event.preventDefault();
		doIt();
	});

	$prose.val(HOLMES_TEXT);

	doIt();

});


text:
;(function(global) {

	var PREFIX = 'hl-';

	var GRAMMAR = {
		"in-quotes": "(\"[^\"].*?\")",
		"in-parentheses": "(\\(.*\\))",
		"in-single-quotes": "('[^\'].*?')",
		"common-word": {
			"regexp": "(\\b(?:the|of|and|is|am|are|be|was|were|at|because|or|than|then|from|as|to|through)\\b)",
			"insensitive": true
		},
		"number": "(\\d+(?:\\.\\d+)?)",
		"period": "(\\.)",
		"comma": "(,)",
		"semicolon": "(;)",
		"question-mark": "(\\?)",
		"exclamation-point": "(!)",
		"dash": "(--)",
	};

	function highlight(text) {

		var result = text.
			replace('<', '<').
			replace('>', '>').
			replace('&', '&');

		var keys = Object.keys(GRAMMAR);

		for (var i = 0, len = keys.length; i < len; i ++) {

			var name = keys[i];
			var regexp;
			if (GRAMMAR[name].big) {
				regexp = new RegExp(GRAMMAR[name], 'g');
			} else {
				var str = GRAMMAR[name]['regexp'];
				var insensitive = GRAMMAR[name]['insensitive'];
				var flags = 'g';
				if (insensitive)
					flags += 'i';
				regexp = new RegExp(str, flags);
			}

			var openTag = '';
			var closeTag = '';
			result = result.replace(regexp, openTag + '$1' + closeTag);

		}

		return result;

	}

	if (global.module && module.exports)
		module.exports = highlight;
	else
		global.highlight = highlight;

})(this);


text:
/* color: #f93672; */

.hl-area {
	color: #f8f8f2;
	background-color: #1b1d1e;
}

.hl-common-word {
	opacity: .7;
}

.hl-period, .hl-exclamation-point {
	color: #f92672;
}

.hl-comma {
	color: #8f8f8f;
}

.hl-semicolon, .hl-question-mark {
	color: #fd971f;
}

.hl-dash, .hl-in-quotes {
	color: #e6db74;
}

.hl-number {
	color: #ae81ff;
}

.hl-in-parentheses {
	color: #75715e;
}

.hl-in-single-quotes {
	color: #a6e22e;
}