├── docs ├── .nojekyll ├── yard │ ├── css │ │ ├── common.css │ │ ├── full_list.css │ │ └── style.css │ ├── frames.html │ ├── file_list.html │ ├── class_list.html │ ├── top-level-namespace.html │ ├── Version.html │ ├── file.LICENSE.html │ ├── index.html │ ├── file.README.html │ ├── _index.html │ ├── method_list.html │ ├── js │ │ ├── full_list.js │ │ └── app.js │ ├── HashIdentifier.html │ └── HashIdentifier │ │ └── Chf.html ├── _navbar.md ├── _media │ └── logo.png ├── about.md ├── pages │ ├── demo.md │ ├── publishing.md │ ├── documentation.md │ ├── quick-start.md │ ├── usage.md │ └── install.md ├── CHANGELOG.md ├── _sidebar.md ├── _coverpage.md ├── README.md ├── index.html ├── why.md └── vendor │ ├── prismjs │ └── components │ │ └── prism-ruby.min.js │ ├── plugins │ ├── search.min.js │ └── emoji.min.js │ ├── themes │ └── vue.css │ └── docsify.js ├── .ruby-version ├── .yardopts ├── .gitignore ├── .yardopts-dev ├── lib ├── haiti │ ├── version.rb │ └── hash.rb └── haiti.rb ├── Gemfile ├── bin ├── haiti_console └── haiti ├── Rakefile ├── .editorconfig ├── .rubocop.yml ├── test └── test_haiti.rb ├── LICENSE.txt ├── Gemfile.lock ├── README.md └── haiti.gemspec /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.7.0 2 | -------------------------------------------------------------------------------- /docs/yard/css/common.css: -------------------------------------------------------------------------------- 1 | /* Override this file with custom rules */ -------------------------------------------------------------------------------- /.yardopts: -------------------------------------------------------------------------------- 1 | --output-dir docs/yard 2 | - 3 | --main README.md 4 | LICENSE.txt -------------------------------------------------------------------------------- /docs/_navbar.md: -------------------------------------------------------------------------------- 1 | - [Home](/) 2 | - [Source](https://github.com/Orange-Cyberdefense/haiti/) 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .yardoc 2 | *.gem 3 | /pkg 4 | /doc 5 | /vendor 6 | .bundle/ 7 | /node_modules 8 | .git 9 | -------------------------------------------------------------------------------- /docs/_media/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Orange-Cyberdefense/haiti/HEAD/docs/_media/logo.png -------------------------------------------------------------------------------- /.yardopts-dev: -------------------------------------------------------------------------------- 1 | --output-dir docs/yard 2 | --protected 3 | --private 4 | - 5 | --main README.md 6 | LICENSE.txt -------------------------------------------------------------------------------- /docs/about.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | ## Logo 4 | 5 | Logo made with [DesignEvo](https://www.designevo.com). 6 | -------------------------------------------------------------------------------- /lib/haiti/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Version 4 | VERSION = '1.0.0' 5 | end 6 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | 5 | # Specify your gem's dependencies in .gemspec 6 | gemspec 7 | -------------------------------------------------------------------------------- /bin/haiti_console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require 'haiti' 5 | require 'irb' 6 | 7 | IRB.start(__FILE__) 8 | -------------------------------------------------------------------------------- /docs/pages/demo.md: -------------------------------------------------------------------------------- 1 | # Demonstration 2 | 3 | [![asciicast](https://asciinema.org/a/rvErLcy4gudHsfMqyOMSctDXU.svg)](https://asciinema.org/a/rvErLcy4gudHsfMqyOMSctDXU) 4 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake/testtask' 2 | require 'bundler/gem_tasks' 3 | 4 | Rake::TestTask.new do |t| 5 | t.libs << 'test' 6 | end 7 | 8 | desc 'Run tests' 9 | task default: :test 10 | 11 | -------------------------------------------------------------------------------- /docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [Unreleased] 2 | 3 | - bin: code simplification & lint 4 | 5 | ## [1.0.0] 6 | 7 | - lib: Fix a file loading path of prototypes 8 | - doc: Fix gem name 9 | - bin: remove useless haiti_setup 10 | 11 | ## [0.0.1] 12 | 13 | - Initial version 14 | -------------------------------------------------------------------------------- /docs/_sidebar.md: -------------------------------------------------------------------------------- 1 | - Getting started 2 | 3 | - [Quick start](pages/quick-start.md) 4 | - [Installation](pages/install.md) 5 | - [Usage](pages/usage.md) 6 | - [Demo](pages/demo.md) 7 | 8 | - Guide 9 | 10 | - [Documentation](pages/documentation.md) 11 | - [Publishing](pages/publishing.md) 12 | 13 | - [Why?](why.md) 14 | - [About](about.md) 15 | - [Changelog](CHANGELOG.md) 16 | -------------------------------------------------------------------------------- /docs/_coverpage.md: -------------------------------------------------------------------------------- 1 | logo 2 | 3 | # HAITI 4 | 5 | > _**HA**sh **I**den**T**if**I**er_ 6 | 7 | - 270+ hash types detected 8 | - Hashcat and John the Ripper references 9 | - CLI tool & library 10 | - Hackable 11 | 12 | [GitHub](https://github.com/Orange-Cyberdefense/haiti/) 13 | [Get Started](pages/quick-start?id=quick-start) 14 | 15 | ![color](#ffffff) 16 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | 11 | # ruby 12 | [*.rb] 13 | charset = utf-8 14 | indent_style = space 15 | indent_size = 2 16 | trim_trailing_whitespace = true 17 | 18 | # keep source format 19 | [data/prototypes.json] 20 | indent_style = space 21 | indent_size = 4 22 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # HAITI 2 | 3 | > _**HA**sh **I**den**T**if**I**er_ 4 | 5 | ## What is it? 6 | 7 | A CLI tool to identify the hash type of a given hash. 8 | 9 | ## Features 10 | 11 | - 270+ hash types detected 12 | - Hashcat and John the Ripper references 13 | - CLI tool & library 14 | - Hackable 15 | 16 | ## References 17 | 18 | Homepage / Documentation: https://orange-cyberdefense.github.io/haiti/ 19 | 20 | ## Author 21 | 22 | Made by Alexandre ZANNI ([@noraj](https://github.com/noraj)), pentester from Orange Cyberdefense. 23 | -------------------------------------------------------------------------------- /docs/yard/frames.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Documentation by YARD 0.9.20 6 | 7 | 13 | 17 | 18 | -------------------------------------------------------------------------------- /docs/pages/publishing.md: -------------------------------------------------------------------------------- 1 | # Publishing 2 | 3 | ## On Rubygems.org 4 | 5 | ``` 6 | $ git tag -a vx.x.x 7 | $ git push --follow-tags 8 | $ gem push haiti-hash-x.x.x.gem 9 | ``` 10 | 11 | See https://guides.rubygems.org/publishing/. 12 | 13 | On new release don't forget to rebuild the library documentation: 14 | 15 | ``` 16 | $ bundle exec yard doc 17 | ``` 18 | 19 | An to be sure all tests pass! 20 | 21 | ``` 22 | $ rake 23 | ``` 24 | 25 | ## On BlackArch 26 | 27 | BA process 28 | 29 | On new release don't forget to rebuild the library documentation: 30 | 31 | ``` 32 | $ bundle exec yard doc 33 | ``` 34 | 35 | An to be sure all tests pass! 36 | 37 | ``` 38 | $ rake 39 | ``` 40 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | # Metrics 2 | AllCops: 3 | TargetRubyVersion: 2.4 4 | 5 | Layout/HashAlignment: 6 | Include: 7 | - 'lib/**/*.rb' 8 | Layout/LineLength: 9 | Include: 10 | - 'lib/**/*.rb' 11 | Metrics/AbcSize: 12 | Enabled: false 13 | Metrics/ClassLength: 14 | Max: 200 15 | Metrics/CyclomaticComplexity: 16 | Enabled: false 17 | Metrics/BlockNesting: 18 | Exclude: 19 | - 'bin/*' 20 | Metrics/MethodLength: 21 | Max: 25 22 | Metrics/PerceivedComplexity: 23 | Max: 10 24 | Style/HashEachMethods: 25 | Enabled: true 26 | Style/RedundantReturn: 27 | Enabled: false 28 | Style/HashTransformKeys: 29 | Enabled: true 30 | Style/HashTransformValues: 31 | Enabled: true 32 | -------------------------------------------------------------------------------- /docs/pages/documentation.md: -------------------------------------------------------------------------------- 1 | # Documentation 2 | 3 | ## CLI doc 4 | 5 | See [Usage](pages/usage.md?id=cli). 6 | 7 | ## Server locally 8 | 9 | ``` 10 | $ npm i docsify-cli -g 11 | $ docsify serve docs 12 | ``` 13 | 14 | ## Library doc 15 | 16 | The output directory of the library documentation will be `docs/yard`. 17 | 18 | You can consult it online [here](https://orange-cyberdefense.github.io/haiti/yard/). 19 | 20 | ### Building locally: for library users 21 | 22 | For developers who only want to use the HAITI library. 23 | 24 | ``` 25 | $ bundle exec yard doc 26 | ``` 27 | 28 | ### Building locally: for HAITI developer 29 | 30 | For developers who want to participate to HAITI development. 31 | 32 | ``` 33 | $ bundle exec yard doc --yardopts .yardopts-dev 34 | ``` 35 | -------------------------------------------------------------------------------- /lib/haiti/hash.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class HashIdentifier 4 | # Cryptographic hash function object 5 | class Chf 6 | # @return [String] name of the identified hash type 7 | attr_reader :name 8 | # @return [String] John the Ripper hash reference. nil if unknown. 9 | attr_reader :john 10 | # @return [String] Hashcat hash ID. nil if unknown. 11 | attr_reader :hashcat 12 | # @return [Boolean] Display by default or not. If true it is displayed in 13 | # extended mode only, mostly hash type using salt. 14 | attr_reader :extended 15 | 16 | def initialize(mode) 17 | @name = mode['name'] 18 | @john = mode['john'] 19 | @hashcat = mode['hashcat'] 20 | @extended = mode['extended'] 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /test/test_haiti.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'minitest/autorun' 4 | require 'haiti' 5 | 6 | class HaitiTest < Minitest::Test 7 | def setup 8 | @hash = '5f4dcc3b5aa765d61d8327deb882cf99' 9 | @hi = HashIdentifier.new(@hash) 10 | end 11 | 12 | def test_hashidentifier_hash 13 | assert_equal(@hash, @hi.hash) 14 | end 15 | 16 | def test_hashidentifier_type 17 | assert_instance_of(Array, @hi.type) 18 | assert_instance_of(HashIdentifier:: Chf, @hi.type[0]) 19 | end 20 | 21 | def test_hashidentifier_type_non_existing 22 | hash = 'uuu' 23 | hi = HashIdentifier.new(hash) 24 | assert_empty(hi.type) 25 | end 26 | 27 | def test_chf 28 | assert_equal('MD2', @hi.type[0].name) 29 | assert_equal('md2', @hi.type[0].john) 30 | assert_nil(@hi.type[0].hashcat) 31 | assert_equal(false, @hi.type[0].extended) 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /docs/pages/quick-start.md: -------------------------------------------------------------------------------- 1 | # Quick start 2 | 3 | ## Quick install 4 | 5 | ``` 6 | $ gem install haiti-hash 7 | ``` 8 | 9 | ## Default usage: CLI 10 | 11 | ``` 12 | $ haiti 786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce 13 | SHA-512 [HC: 1700] [JtR: raw-sha512] 14 | Whirlpool [HC: 6100] [JtR: whirlpool] 15 | Salsa10 16 | Salsa20 17 | SHA3-512 [HC: 17600] [JtR: raw-sha3] 18 | Keccak-512 [HC: 18000] [JtR: raw-keccak] 19 | Blake2 [HC: 600] [JtR: raw-blake2] 20 | Skein-512 [JtR: skein-512] 21 | Skein-1024(512) 22 | ``` 23 | 24 | ## Default usage: library 25 | 26 | ```ruby 27 | require 'haiti' 28 | 29 | # Instantiate a HashIdentifier object that will automatically identify 30 | # the hash type 31 | hi = HashIdentifier.new('786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce') 32 | 33 | # Loop over the hash type candidates and retrieve data 34 | hi.type.each do |type| 35 | name = type.name 36 | hashcat_id = type.hashcat 37 | john_ref = type.john 38 | end 39 | ``` 40 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019-2020 Alexandre ZANNI 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /lib/haiti.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Ruby internal 4 | require 'json' 5 | # Project internal 6 | require 'haiti/version' 7 | require 'haiti/hash' 8 | 9 | # The global Hash Identifier class 10 | class HashIdentifier 11 | # Constants 12 | include Version 13 | PROTOTYPES = JSON.parse(File.read(File.join(__dir__, '../data/prototypes.json'))) 14 | 15 | # @return [String] the hash (as provided) 16 | # @example 17 | # '5f4dcc3b5aa765d61d8327deb882cf99' 18 | attr_reader :hash 19 | 20 | # @return [Array] list of {Chf} objects, representing the identified 21 | # hashes 22 | attr_reader :type 23 | 24 | # A new instance of hash identifier 25 | # @param hash [String] the hash to identify 26 | def initialize(hash) 27 | @hash = hash 28 | @type = identify(hash) 29 | end 30 | 31 | private 32 | 33 | # Check which hash types are matching the provided hash 34 | # @param hash [String] the hash to identify 35 | # @return [Array] list of {Chf} objects, representing the identified 36 | # hashes 37 | def identify(hash) 38 | res = [] 39 | PROTOTYPES.each do |prototype| 40 | reg = Regexp.new prototype['regex'], Regexp::IGNORECASE 41 | next unless reg.match?(hash) 42 | 43 | prototype['modes'].each do |mode| 44 | res << Chf.new(mode) 45 | end 46 | end 47 | return res 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | haiti-hash (1.0.0) 5 | docopt (~> 0.6) 6 | paint (~> 2.2) 7 | 8 | GEM 9 | remote: https://rubygems.org/ 10 | specs: 11 | ast (2.4.0) 12 | commonmarker (0.21.0) 13 | ruby-enum (~> 0.5) 14 | concurrent-ruby (1.1.5) 15 | docopt (0.6.1) 16 | github-markup (3.0.4) 17 | i18n (1.8.2) 18 | concurrent-ruby (~> 1.0) 19 | minitest (5.14.1) 20 | paint (2.2.0) 21 | parallel (1.19.1) 22 | parser (2.7.1.3) 23 | ast (~> 2.4.0) 24 | rainbow (3.0.0) 25 | rake (13.0.1) 26 | redcarpet (3.5.0) 27 | regexp_parser (1.7.1) 28 | rexml (3.2.4) 29 | rubocop (0.85.1) 30 | parallel (~> 1.10) 31 | parser (>= 2.7.0.1) 32 | rainbow (>= 2.2.2, < 4.0) 33 | regexp_parser (>= 1.7) 34 | rexml 35 | rubocop-ast (>= 0.0.3) 36 | ruby-progressbar (~> 1.7) 37 | unicode-display_width (>= 1.4.0, < 2.0) 38 | rubocop-ast (0.0.3) 39 | parser (>= 2.7.0.1) 40 | ruby-enum (0.7.2) 41 | i18n 42 | ruby-progressbar (1.10.1) 43 | unicode-display_width (1.7.0) 44 | yard (0.9.25) 45 | 46 | PLATFORMS 47 | ruby 48 | 49 | DEPENDENCIES 50 | bundler (~> 2.1) 51 | commonmarker (~> 0.21) 52 | github-markup (~> 3.0) 53 | haiti-hash! 54 | minitest (~> 5.12) 55 | rake (~> 13.0) 56 | redcarpet (~> 3.5) 57 | rubocop (~> 0.80) 58 | yard (~> 0.9) 59 | 60 | BUNDLED WITH 61 | 2.1.4 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HAITI 2 | 3 | [![Gem Version](https://badge.fury.io/rb/haiti-hash.svg)](https://badge.fury.io/rb/haiti-hash) 4 | ![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/Orange-Cyberdefense/haiti) 5 | [![GitHub forks](https://img.shields.io/github/forks/Orange-Cyberdefense/haiti)](https://github.com/Orange-Cyberdefense/haiti/network) 6 | [![GitHub stars](https://img.shields.io/github/stars/Orange-Cyberdefense/haiti)](https://github.com/Orange-Cyberdefense/haiti/stargazers) 7 | [![GitHub license](https://img.shields.io/github/license/Orange-Cyberdefense/haiti)](https://github.com/Orange-Cyberdefense/haiti/blob/master/LICENSE.txt) 8 | [![Rawsec's CyberSecurity Inventory](https://inventory.rawsec.ml/img/badges/Rawsec-inventoried-FF5050_flat.svg)](https://inventory.rawsec.ml/tools.html#Haiti) 9 | 10 | [![Packaging status](https://repology.org/badge/vertical-allrepos/haiti.svg)](https://repology.org/project/haiti/versions) 11 | 12 | ![](https://orange-cyberdefense.github.io/haiti/_media/logo.png) 13 | 14 | > _**HA**sh **I**den**T**if**I**er_ 15 | 16 | ## What is it? 17 | 18 | A CLI tool to identify the hash type of a given hash. 19 | 20 | ## Features 21 | 22 | - 270+ hash types detected 23 | - Hashcat and John the Ripper references 24 | - CLI tool & library 25 | - Hackable 26 | 27 | ## References 28 | 29 | Homepage / Documentation: https://orange-cyberdefense.github.io/haiti/ 30 | 31 | ## Author 32 | 33 | Made by Alexandre ZANNI ([@noraj](https://github.com/noraj)), pentester from Orange Cyberdefense. 34 | -------------------------------------------------------------------------------- /docs/pages/usage.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | 3 | ## CLI 4 | 5 | ``` 6 | $ haiti -h 7 | HAITI (HAsh IdenTifIer) 8 | 9 | Usage: 10 | haiti [options] 11 | haiti -h | --help 12 | haiti --version 13 | 14 | Options: 15 | --no-color Disable colorized output 16 | -e, --extended List all possible hash algorithms including ones using salt 17 | --short Display in a short format: do not display hashcat and john the ripper references 18 | --hashcat-only Show only hashcat references 19 | --john-only Show only john the ripper references 20 | --debug Display arguments 21 | -h, --help Show this screen 22 | --version Show version 23 | 24 | Examples: 25 | haiti -e d41d8cd98f00b204e9800998ecf8427e 26 | haiti --no-color --short d41d8cd98f00b204e9800998ecf8427e 27 | ``` 28 | 29 | ## Library 30 | 31 | ```ruby 32 | require 'haiti' 33 | 34 | # Instantiate a HashIdentifier object that will automatically identify 35 | # the hash type 36 | hi = HashIdentifier.new('786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce') 37 | 38 | # Loop over the hash type candidates and retrieve data 39 | hi.type.each do |type| 40 | # name of the hash function 41 | name = type.name 42 | # hashcat ID 43 | hashcat_id = type.hashcat 44 | # John the Ripper reference 45 | john_ref = type.john 46 | # Hash with salt 47 | extended = type.extended 48 | end 49 | ``` 50 | 51 | ## Console 52 | 53 | Launch `irb` with the library loaded. 54 | 55 | ``` 56 | $ haiti_console 57 | irb(main):001:0> 58 | ``` 59 | -------------------------------------------------------------------------------- /docs/why.md: -------------------------------------------------------------------------------- 1 | ## Why? 2 | 3 | hashID is unmaintained since March 2015, hash-identifier is unmaintained since 4 | March 2018 and Dagon since June 2018. They all have no/wrong/erroneous support 5 | for modern hashes like Keccak/SHA3/Blake2 etc. 6 | Also a tool like hash-identifier which is fully interractive and has no options 7 | is not handy for scripting. 8 | The most interresting tool is hashID (for hash identification) but since it is 9 | unmaintained for more than 5 years, issue and open PR are stacking, bugs remain 10 | and some features keep lacking. 11 | 12 | That's what motivated me to create a *new* tool and by the way adding color 13 | support and a library. The lib is especially good for scripting since one 14 | doesn't have to wrap a CLI tool in a sub-process. 15 | 16 | Tool | Maintained | Color | Ref. | Library | Lang | ️:hash: 17 | ---------------------|------------|-------|------|---------|------|--------------- 18 | haiti | ✅ | ✅ | ✅ | ✅ | 💎 | ✅ 19 | [hashID][1] | ❌ | ❌ | ✅ | ❌ | 🐍 | ⭕️ 20 | [hash-identifier][2] | ❌ | ❌ | ❌ | ❌ | 🐍 | ❌ 21 | [Dagon][3] | ❌ | ⭕️ | ❌ | ❌ | 🐍 | ⭕️ 22 | 23 | Legend: 24 | 25 | - Ref.: hashcat and john the ripper matching reference 26 | - ✅: feature supported 27 | - ❌: feature not supported 28 | - ⭕️: feature partially support 29 | - 💎: Ruby 30 | - 🐍: Python 31 | - :hash: correct modern hashes support 32 | 33 | [1]:https://github.com/psypanda/hashID 34 | [2]:https://github.com/blackploit/hash-identifier 35 | [3]:https://github.com/Ekultek/Dagon 36 | -------------------------------------------------------------------------------- /docs/yard/file_list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | File List 19 | 20 | 21 | 22 |
23 |
24 |

File List

25 |
26 | 27 | 28 | Classes 29 | 30 | 31 | 32 | Methods 33 | 34 | 35 | 36 | Files 37 | 38 | 39 |
40 | 41 | 42 |
43 | 44 |
    45 | 46 | 47 |
  • 48 | 49 |
  • 50 | 51 | 52 |
  • 53 | 54 |
  • 55 | 56 | 57 | 58 |
59 |
60 | 61 | 62 | -------------------------------------------------------------------------------- /docs/pages/install.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | ## Production 4 | 5 | ### Install from rubygems.org 6 | 7 | ``` 8 | $ gem install haiti-hash 9 | ``` 10 | 11 | Gem: [haiti-hash](https://rubygems.org/gems/haiti-hash) 12 | 13 | ### Install from BlackArch 14 | 15 | From the repository: 16 | 17 | ``` 18 | # pacman -S haiti 19 | ``` 20 | 21 | From git: 22 | 23 | ``` 24 | # blackman -i haiti 25 | ``` 26 | 27 | PKGBUILD: [haiti](https://github.com/BlackArch/blackarch/blob/master/packages/haiti/PKGBUILD) 28 | 29 | ### Install from ArchLinux 30 | 31 | Manually: 32 | 33 | ``` 34 | $ git clone https://aur.archlinux.org/haiti.git 35 | $ cd haiti 36 | $ makepkg -sic 37 | ``` 38 | 39 | With an AUR helper ([Pacman wrappers](https://wiki.archlinux.org/index.php/AUR_helpers#Pacman_wrappers)), eg. pikaur: 40 | 41 | ``` 42 | $ pikaur -S haiti 43 | ``` 44 | 45 | AUR: [haiti](https://aur.archlinux.org/packages/haiti/) 46 | 47 | ## Development 48 | 49 | It's better to use [rbenv](https://github.com/rbenv/rbenv) to have latests version of ruby and to avoid trashing your system ruby. 50 | 51 | ### Install from rubygems.org 52 | 53 | ``` 54 | $ gem install --development haiti-hash 55 | ``` 56 | 57 | ### Build from git 58 | 59 | Just replace `x.x.x` with the gem version you see after `gem build`. 60 | 61 | ``` 62 | $ git clone https://github.com/Orange-Cyberdefense/haiti.git haiti 63 | $ cd haiti 64 | $ gem install bundler 65 | $ bundler install 66 | $ gem build haiti.gemspec 67 | $ gem install haiti-x.x.x.gem 68 | ``` 69 | 70 | Note: if an automatic install is needed you can get the version with `$ gem build haiti.gemspec | grep Version | cut -d' ' -f4`. 71 | 72 | ### Run the library in irb without installing the gem 73 | 74 | From local file: 75 | 76 | ``` 77 | $ irb -Ilib -rhaiti 78 | ``` 79 | 80 | From the installed gem: 81 | 82 | ``` 83 | $ haiti_console 84 | ``` 85 | 86 | Same for the CLI tool: 87 | 88 | ``` 89 | $ ruby -Ilib -rhaiti bin/haiti 90 | ``` 91 | -------------------------------------------------------------------------------- /bin/haiti: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # Ruby internal 5 | require 'pp' 6 | # Project internal 7 | require 'haiti' 8 | # External 9 | require 'docopt' 10 | require 'paint' 11 | 12 | doc = <<~DOCOPT 13 | HAITI (HAsh IdenTifIer) 14 | 15 | Usage: 16 | haiti [options] 17 | haiti -h | --help 18 | haiti --version 19 | 20 | Options: 21 | --no-color Disable colorized output 22 | -e, --extended List all possible hash algorithms including ones using salt 23 | --short Display in a short format: do not display hashcat and john the ripper references 24 | --hashcat-only Show only hashcat references 25 | --john-only Show only john the ripper references 26 | --debug Display arguments 27 | -h, --help Show this screen 28 | --version Show version 29 | 30 | Examples: 31 | haiti -e d41d8cd98f00b204e9800998ecf8427e 32 | haiti --no-color --short d41d8cd98f00b204e9800998ecf8427e 33 | DOCOPT 34 | 35 | begin 36 | args = Docopt.docopt(doc, version: HashIdentifier::VERSION) 37 | Paint.mode = 0 if args['--no-color'] 38 | pp args if args['--debug'] 39 | # use case 1, using the tool 40 | if args[''] 41 | hi = HashIdentifier.new(args['']) 42 | if hi.type.empty? 43 | puts 'Unknown hash type' 44 | exit(0) 45 | end 46 | hi.type.each do |type| 47 | next if type.extended && !args['--extended'] 48 | 49 | print Paint[type.name, :bold] 50 | unless type.hashcat.nil? || args['--short'] || args['--john-only'] 51 | print Paint[" [HC: #{type.hashcat}]", :blue] 52 | end 53 | unless type.john.nil? || args['--short'] || args['--hashcat-only'] 54 | print Paint[" [JtR: #{type.john}]", :green] 55 | end 56 | puts 57 | end 58 | end 59 | # use case 2, help: already handled by docopt 60 | # use case 3, version: already handled by docopt 61 | rescue Docopt::Exit => e 62 | puts e.message 63 | end 64 | -------------------------------------------------------------------------------- /haiti.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'lib/haiti/version' 4 | 5 | Gem::Specification.new do |s| 6 | s.name = 'haiti-hash' 7 | s.version = Version::VERSION 8 | s.platform = Gem::Platform::RUBY 9 | s.date = '2020-03-02' 10 | s.summary = 'HAsh IdenTifIer' 11 | s.description = 'A CLI tool to identify the hash type of a given hash.' 12 | s.authors = ['Alexandre ZANNI'] 13 | s.email = 'alexandre.zanni@engineer.com' 14 | s.homepage = 'https://orange-cyberdefense.github.io/haiti/' 15 | s.license = 'MIT' 16 | 17 | s.files = Dir['bin/*'] + Dir['lib/**/*.rb'] + Dir['data/*.json'] 18 | s.files += ['LICENSE.txt'] 19 | s.bindir = 'bin' 20 | s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) } 21 | s.require_paths = ['lib'] 22 | 23 | s.metadata = { 24 | 'yard.run' => 'yard', 25 | 'bug_tracker_uri' => 'https://github.com/Orange-Cyberdefense/haiti/issues', 26 | 'changelog_uri' => 'https://github.com/Orange-Cyberdefense/haiti/blob/master/docs/CHANGELOG.md', 27 | 'documentation_uri' => 'https://orange-cyberdefense.github.io/haiti/', 28 | 'homepage_uri' => 'https://orange-cyberdefense.github.io/haiti/', 29 | 'source_code_uri' => 'https://github.com/Orange-Cyberdefense/haiti/' 30 | } 31 | 32 | s.required_ruby_version = '~> 2.4' 33 | 34 | s.add_runtime_dependency('docopt', '~> 0.6') # for argument parsing 35 | s.add_runtime_dependency('paint', '~> 2.2') # for colorized ouput 36 | 37 | s.add_development_dependency('bundler', '~> 2.1') 38 | s.add_development_dependency('commonmarker', '~> 0.21') # for GMF support in YARD 39 | s.add_development_dependency('github-markup', '~> 3.0') # for GMF support in YARD 40 | s.add_development_dependency('minitest', '~> 5.12') 41 | s.add_development_dependency('rake', '~> 13.0') 42 | s.add_development_dependency('redcarpet', '~> 3.5') # for GMF support in YARD 43 | s.add_development_dependency('rubocop', '~> 0.80') 44 | s.add_development_dependency('yard', '~> 0.9') 45 | end 46 | -------------------------------------------------------------------------------- /docs/vendor/prismjs/components/prism-ruby.min.js: -------------------------------------------------------------------------------- 1 | !function(e){e.languages.ruby=e.languages.extend("clike",{comment:[/#.*/,{pattern:/^=begin\s[\s\S]*?^=end/m,greedy:!0}],keyword:/\b(?:alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|protected|private|public|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/});var n={pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"tag"},rest:e.languages.ruby}};delete e.languages.ruby.function,e.languages.insertBefore("ruby","keyword",{regex:[{pattern:/%r([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0,greedy:!0}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:{pattern:/(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/,lookbehind:!0},"method-definition":{pattern:/(\bdef\s+)[\w.]+/,lookbehind:!0,inside:{function:/\w+$/,rest:e.languages.ruby}}}),e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|Fixnum|Float|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,constant:/\b[A-Z]\w*(?:[?!]|\b)/}),e.languages.ruby.string=[{pattern:/%[qQiIwWxs]?([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/,greedy:!0,inside:{interpolation:n}},{pattern:/("|')(?:#\{[^}]+\}|\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0,inside:{interpolation:n}}],e.languages.rb=e.languages.ruby}(Prism); -------------------------------------------------------------------------------- /docs/yard/class_list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Class List 19 | 20 | 21 | 22 |
23 |
24 |

Class List

25 |
26 | 27 | 28 | Classes 29 | 30 | 31 | 32 | Methods 33 | 34 | 35 | 36 | Files 37 | 38 | 39 |
40 | 41 | 42 |
43 | 44 | 49 |
50 | 51 | 52 | -------------------------------------------------------------------------------- /docs/yard/top-level-namespace.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Top Level Namespace 8 | 9 | — Documentation by YARD 0.9.20 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 |
36 | 61 | 62 |

Top Level Namespace 63 | 64 | 65 | 66 |

67 |
68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
80 | 81 |

Defined Under Namespace

82 |

83 | 84 | 85 | Modules: Version 86 | 87 | 88 | 89 | Classes: HashIdentifier 90 | 91 | 92 |

93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 |
103 | 104 | 109 | 110 |
111 | 112 | -------------------------------------------------------------------------------- /docs/yard/Version.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Module: Version 8 | 9 | — Documentation by YARD 0.9.20 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 |
36 | 61 | 62 |

Module: Version 63 | 64 | 65 | 66 |

67 |
68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 |
78 |
Included in:
79 |
HashIdentifier
80 |
81 | 82 | 83 | 84 |
85 |
Defined in:
86 |
lib/haiti/version.rb
87 |
88 | 89 |
90 | 91 | 92 | 93 |

94 | Constant Summary 95 | collapse 96 |

97 | 98 |
99 | 100 |
VERSION = 101 | 102 |
103 |
'0.0.1'
104 | 105 |
106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 |
117 | 118 | 123 | 124 |
125 | 126 | -------------------------------------------------------------------------------- /docs/yard/file.LICENSE.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | File: LICENSE 8 | 9 | — Documentation by YARD 0.9.20 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 |
36 | 59 | 60 |
The MIT License (MIT)

Copyright (c) 2019 Alexandre ZANNI

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
61 | 62 | 67 | 68 |
69 | 70 | -------------------------------------------------------------------------------- /docs/yard/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | File: README 8 | 9 | — Documentation by YARD 0.9.20 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 |
36 | 59 | 60 |

HAITI

61 | 62 |

Gem Version 63 | GitHub tag (latest SemVer) 64 | GitHub forks 65 | GitHub stars 66 | GitHub license

67 | 68 |

Packaging status

69 | 70 |

71 | 72 |
73 |

HAsh Iden*TifI*er

74 |
75 | 76 |

What is it?

77 | 78 |

A CLI tool to identify the hash type of a given hash.

79 | 80 |

Features

81 | 82 |
    83 |
  • 270+ hash types detected
  • 84 |
  • Hashcat and John the Ripper references
  • 85 |
  • CLI tool & library
  • 86 |
  • Hackable
  • 87 |
88 | 89 |

References

90 | 91 |

Homepage / Documentation: https://orange-cyberdefense.github.io/haiti/

92 | 93 |

Author

94 | 95 |

Made by Alexandre ZANNI (@noraj), pentester from Orange Cyberdefense.

96 |
97 | 98 | 103 | 104 |
105 | 106 | -------------------------------------------------------------------------------- /docs/yard/file.README.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | File: README 8 | 9 | — Documentation by YARD 0.9.20 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 |
36 | 59 | 60 |

HAITI

61 | 62 |

Gem Version 63 | GitHub tag (latest SemVer) 64 | GitHub forks 65 | GitHub stars 66 | GitHub license

67 | 68 |

Packaging status

69 | 70 |

71 | 72 |
73 |

HAsh Iden*TifI*er

74 |
75 | 76 |

What is it?

77 | 78 |

A CLI tool to identify the hash type of a given hash.

79 | 80 |

Features

81 | 82 |
    83 |
  • 270+ hash types detected
  • 84 |
  • Hashcat and John the Ripper references
  • 85 |
  • CLI tool & library
  • 86 |
  • Hackable
  • 87 |
88 | 89 |

References

90 | 91 |

Homepage / Documentation: https://orange-cyberdefense.github.io/haiti/

92 | 93 |

Author

94 | 95 |

Made by Alexandre ZANNI (@noraj), pentester from Orange Cyberdefense.

96 |
97 | 98 | 103 | 104 |
105 | 106 | -------------------------------------------------------------------------------- /docs/yard/_index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Documentation by YARD 0.9.20 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 32 | 33 |
34 | 54 | 55 |

Documentation by YARD 0.9.20

56 |
57 |

Alphabetic Index

58 | 59 |

File Listing

60 | 70 | 71 |
72 |

Namespace Listing A-Z

73 | 74 | 75 | 76 | 77 | 78 | 79 | 123 | 124 |
80 | 81 | 82 |
    83 |
  • C
  • 84 |
      85 | 86 |
    • 87 | Chf 88 | 89 | (HashIdentifier) 90 | 91 |
    • 92 | 93 |
    94 |
95 | 96 | 97 |
    98 |
  • H
  • 99 | 107 |
108 | 109 | 110 |
    111 |
  • V
  • 112 |
      113 | 114 |
    • 115 | Version 116 | 117 |
    • 118 | 119 |
    120 |
121 | 122 |
125 | 126 |
127 | 128 |
129 | 130 | 135 | 136 |
137 | 138 | -------------------------------------------------------------------------------- /docs/yard/method_list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Method List 19 | 20 | 21 | 22 |
23 |
24 |

Method List

25 |
26 | 27 | 28 | Classes 29 | 30 | 31 | 32 | Methods 33 | 34 | 35 | 36 | Files 37 | 38 | 39 |
40 | 41 | 42 |
43 | 44 |
    45 | 46 | 47 |
  • 48 |
    49 | #extended 50 | HashIdentifier::Chf 51 |
    52 |
  • 53 | 54 | 55 |
  • 56 |
    57 | #hash 58 | HashIdentifier 59 |
    60 |
  • 61 | 62 | 63 |
  • 64 |
    65 | #hashcat 66 | HashIdentifier::Chf 67 |
    68 |
  • 69 | 70 | 71 |
  • 72 |
    73 | #initialize 74 | HashIdentifier 75 |
    76 |
  • 77 | 78 | 79 |
  • 80 |
    81 | #initialize 82 | HashIdentifier::Chf 83 |
    84 |
  • 85 | 86 | 87 |
  • 88 |
    89 | #john 90 | HashIdentifier::Chf 91 |
    92 |
  • 93 | 94 | 95 |
  • 96 |
    97 | #name 98 | HashIdentifier::Chf 99 |
    100 |
  • 101 | 102 | 103 |
  • 104 |
    105 | #type 106 | HashIdentifier 107 |
    108 |
  • 109 | 110 | 111 | 112 |
113 |
114 | 115 | 116 | -------------------------------------------------------------------------------- /docs/yard/css/full_list.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; 4 | font-size: 13px; 5 | height: 101%; 6 | overflow-x: hidden; 7 | background: #fafafa; 8 | } 9 | 10 | h1 { padding: 12px 10px; padding-bottom: 0; margin: 0; font-size: 1.4em; } 11 | .clear { clear: both; } 12 | .fixed_header { position: fixed; background: #fff; width: 100%; padding-bottom: 10px; margin-top: 0; top: 0; z-index: 9999; height: 70px; } 13 | #search { position: absolute; right: 5px; top: 9px; padding-left: 24px; } 14 | #content.insearch #search, #content.insearch #noresults { background: url(data:image/gif;base64,R0lGODlhEAAQAPYAAP///wAAAPr6+pKSkoiIiO7u7sjIyNjY2J6engAAAI6OjsbGxjIyMlJSUuzs7KamppSUlPLy8oKCghwcHLKysqSkpJqamvT09Pj4+KioqM7OzkRERAwMDGBgYN7e3ujo6Ly8vCoqKjY2NkZGRtTU1MTExDw8PE5OTj4+PkhISNDQ0MrKylpaWrS0tOrq6nBwcKysrLi4uLq6ul5eXlxcXGJiYoaGhuDg4H5+fvz8/KKiohgYGCwsLFZWVgQEBFBQUMzMzDg4OFhYWBoaGvDw8NbW1pycnOLi4ubm5kBAQKqqqiQkJCAgIK6urnJyckpKSjQ0NGpqatLS0sDAwCYmJnx8fEJCQlRUVAoKCggICLCwsOTk5ExMTPb29ra2tmZmZmhoaNzc3KCgoBISEiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCAAAACwAAAAAEAAQAAAHaIAAgoMgIiYlg4kACxIaACEJCSiKggYMCRselwkpghGJBJEcFgsjJyoAGBmfggcNEx0flBiKDhQFlIoCCA+5lAORFb4AJIihCRbDxQAFChAXw9HSqb60iREZ1omqrIPdJCTe0SWI09GBACH5BAkIAAAALAAAAAAQABAAAAdrgACCgwc0NTeDiYozCQkvOTo9GTmDKy8aFy+NOBA7CTswgywJDTIuEjYFIY0JNYMtKTEFiRU8Pjwygy4ws4owPyCKwsMAJSTEgiQlgsbIAMrO0dKDGMTViREZ14kYGRGK38nHguHEJcvTyIEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDAggPg4iJAAMJCRUAJRIqiRGCBI0WQEEJJkWDERkYAAUKEBc4Po1GiKKJHkJDNEeKig4URLS0ICImJZAkuQAhjSi/wQyNKcGDCyMnk8u5rYrTgqDVghgZlYjcACTA1sslvtHRgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCQARAtOUoQRGRiFD0kJUYWZhUhKT1OLhR8wBaaFBzQ1NwAlkIszCQkvsbOHL7Y4q4IuEjaqq0ZQD5+GEEsJTDCMmIUhtgk1lo6QFUwJVDKLiYJNUd6/hoEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4uen4ICCA+IkIsDCQkVACWmhwSpFqAABQoQF6ALTkWFnYMrVlhWvIKTlSAiJiVVPqlGhJkhqShHV1lCW4cMqSkAR1ofiwsjJyqGgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCSMhREZGIYYGY2ElYebi56fhyWQniSKAKKfpaCLFlAPhl0gXYNGEwkhGYREUywag1wJwSkHNDU3D0kJYIMZQwk8MjPBLx9eXwuETVEyAC/BOKsuEjYFhoEAIfkECQgAAAAsAAAAABAAEAAAB2eAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4ueICImip6CIQkJKJ4kigynKaqKCyMnKqSEK05StgAGQRxPYZaENqccFgIID4KXmQBhXFkzDgOnFYLNgltaSAAEpxa7BQoQF4aBACH5BAkIAAAALAAAAAAQABAAAAdogACCg4SFggJiPUqCJSWGgkZjCUwZACQkgxGEXAmdT4UYGZqCGWQ+IjKGGIUwPzGPhAc0NTewhDOdL7Ykji+dOLuOLhI2BbaFETICx4MlQitdqoUsCQ2vhKGjglNfU0SWmILaj43M5oEAOwAAAAAAAAAAAA==) no-repeat center left; } 15 | #full_list { padding: 0; list-style: none; margin-left: 0; margin-top: 80px; font-size: 1.1em; } 16 | #full_list ul { padding: 0; } 17 | #full_list li { padding: 0; margin: 0; list-style: none; } 18 | #full_list li .item { padding: 5px 5px 5px 12px; } 19 | #noresults { padding: 7px 12px; background: #fff; } 20 | #content.insearch #noresults { margin-left: 7px; } 21 | li.collapsed ul { display: none; } 22 | li a.toggle { cursor: default; position: relative; left: -5px; top: 4px; text-indent: -999px; width: 10px; height: 9px; margin-left: -10px; display: block; float: left; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK8AAACvABQqw0mAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTM5jWRgMAAAAVdEVYdENyZWF0aW9uIFRpbWUAMy8xNC8wOeNZPpQAAAE2SURBVDiNrZTBccIwEEXfelIAHUA6CZ24BGaWO+FuzZAK4k6gg5QAdGAq+Bxs2Yqx7BzyL7Llp/VfzZeQhCTc/ezuGzKKnKSzpCxXJM8fwNXda3df5RZETlIt6YUzSQDs93sl8w3wBZxCCE10GM1OcWbWjB2mWgEH4Mfdyxm3PSepBHibgQE2wLe7r4HjEidpnXMYdQPKEMJcsZ4zs2POYQOcaPfwMVOo58zsAdMt18BuoVDPxUJRacELbXv3hUIX2vYmOUvi8C8ydz/ThjXrqKqqLbDIAdsCKBd+Wo7GWa7o9qzOQHVVVXeAbs+yHHCH4aTsaCOQqunmUy1yBUAXkdMIfMlgF5EXLo2OpV/c/Up7jG4hhHcYLgWzAZXUc2b2ixsfvc/RmNNfOXD3Q/oeL9axJE1yT9IOoUu6MGUkAAAAAElFTkSuQmCC) no-repeat bottom left; } 23 | li.collapsed a.toggle { opacity: 0.5; cursor: default; background-position: top left; } 24 | li { color: #888; cursor: pointer; } 25 | li.deprecated { text-decoration: line-through; font-style: italic; } 26 | li.odd { background: #f0f0f0; } 27 | li.even { background: #fafafa; } 28 | .item:hover { background: #ddd; } 29 | li small:before { content: "("; } 30 | li small:after { content: ")"; } 31 | li small.search_info { display: none; } 32 | a, a:visited { text-decoration: none; color: #05a; } 33 | li.clicked > .item { background: #05a; color: #ccc; } 34 | li.clicked > .item a, li.clicked > .item a:visited { color: #eee; } 35 | li.clicked > .item a.toggle { opacity: 0.5; background-position: bottom right; } 36 | li.collapsed.clicked a.toggle { background-position: top right; } 37 | #search input { border: 1px solid #bbb; border-radius: 3px; } 38 | #full_list_nav { margin-left: 10px; font-size: 0.9em; display: block; color: #aaa; } 39 | #full_list_nav a, #nav a:visited { color: #358; } 40 | #full_list_nav a:hover { background: transparent; color: #5af; } 41 | #full_list_nav span:after { content: ' | '; } 42 | #full_list_nav span:last-child:after { content: ''; } 43 | 44 | #content h1 { margin-top: 0; } 45 | li { white-space: nowrap; cursor: normal; } 46 | li small { display: block; font-size: 0.8em; } 47 | li small:before { content: ""; } 48 | li small:after { content: ""; } 49 | li small.search_info { display: none; } 50 | #search { width: 170px; position: static; margin: 3px; margin-left: 10px; font-size: 0.9em; color: #888; padding-left: 0; padding-right: 24px; } 51 | #content.insearch #search { background-position: center right; } 52 | #search input { width: 110px; } 53 | 54 | #full_list.insearch ul { display: block; } 55 | #full_list.insearch .item { display: none; } 56 | #full_list.insearch .found { display: block; padding-left: 11px !important; } 57 | #full_list.insearch li a.toggle { display: none; } 58 | #full_list.insearch li small.search_info { display: block; } 59 | -------------------------------------------------------------------------------- /docs/vendor/plugins/search.min.js: -------------------------------------------------------------------------------- 1 | !function(){var f={},u={EXPIRE_KEY:"docsify.search.expires",INDEX_KEY:"docsify.search.index"};function h(e){var n={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};return String(e).replace(/[&<>"'/]/g,function(e){return n[e]})}function o(o,r){var e,n,t="auto"===o.paths,s=(e=o.namespace)?u.EXPIRE_KEY+"/"+e:u.EXPIRE_KEY,c=(n=o.namespace)?u.INDEX_KEY+"/"+n:u.INDEX_KEY,a=localStorage.getItem(s)l.length&&(o=l.length);var r="..."+h(l).substring(i,o).replace(t,''+e+"")+"...";c+=r}}),0\n

'+e.title+"

\n

"+e.content+"

\n\n"}),t.classList.add("show"),a.classList.add("show"),t.innerHTML=s||'

'+d+"

",c.hideOtherSidebarContent&&(i.classList.add("hide"),o.classList.add("hide"))}function l(e){c=e}function r(e,n){var t,a,i,o,r=n.router.parse().query.s;l(e),Docsify.dom.style("\n.sidebar {\n padding-top: 0;\n}\n\n.search {\n margin-bottom: 20px;\n padding: 6px;\n border-bottom: 1px solid #eee;\n}\n\n.search .input-wrap {\n display: flex;\n align-items: center;\n}\n\n.search .results-panel {\n display: none;\n}\n\n.search .results-panel.show {\n display: block;\n}\n\n.search input {\n outline: none;\n border: none;\n width: 100%;\n padding: 0 7px;\n line-height: 36px;\n font-size: 14px;\n}\n\n.search input::-webkit-search-decoration,\n.search input::-webkit-search-cancel-button,\n.search input {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n.search .clear-button {\n width: 36px;\n text-align: right;\n display: none;\n}\n\n.search .clear-button.show {\n display: block;\n}\n\n.search .clear-button svg {\n transform: scale(.5);\n}\n\n.search h2 {\n font-size: 17px;\n margin: 10px 0;\n}\n\n.search a {\n text-decoration: none;\n color: inherit;\n}\n\n.search .matching-post {\n border-bottom: 1px solid #eee;\n}\n\n.search .matching-post:last-child {\n border-bottom: 0;\n}\n\n.search p {\n font-size: 14px;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n.search p.empty {\n text-align: center;\n}\n\n.app-name.hide, .sidebar-nav.hide {\n display: none;\n}"),function(e){void 0===e&&(e="");var n='
\n \n
\n \n \n \n \n \n
\n
\n
\n ',t=Docsify.dom.create("div",n),a=Docsify.dom.find("aside");Docsify.dom.toggleClass(t,"search"),Docsify.dom.before(a,t)}(r),a=Docsify.dom.find("div.search"),i=Docsify.dom.find(a,"input"),o=Docsify.dom.find(a,".input-wrap"),Docsify.dom.on(a,"click",function(e){return"A"!==e.target.tagName&&e.stopPropagation()}),Docsify.dom.on(i,"input",function(n){clearTimeout(t),t=setTimeout(function(e){return s(n.target.value.trim())},100)}),Docsify.dom.on(o,"click",function(e){"INPUT"!==e.target.tagName&&(i.value="",s())}),r&&setTimeout(function(e){return s(r)},500)}function p(e,n){l(e),function(e,n){var t=Docsify.dom.getNode('.search input[type="search"]');if(t)if("string"==typeof e)t.placeholder=e;else{var a=Object.keys(e).filter(function(e){return-1 .item .object_link a')[0]; 50 | var e = evt.originalEvent; 51 | var newEvent = new MouseEvent(evt.originalEvent.type); 52 | newEvent.initMouseEvent(e.type, e.canBubble, e.cancelable, e.view, e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget); 53 | elem.dispatchEvent(newEvent); 54 | evt.preventDefault(); 55 | return false; 56 | }); 57 | } 58 | 59 | function enableToggles() { 60 | // show/hide nested classes on toggle click 61 | $('#full_list a.toggle').on('click', function(evt) { 62 | evt.stopPropagation(); 63 | evt.preventDefault(); 64 | $(this).parent().parent().toggleClass('collapsed'); 65 | highlight(); 66 | }); 67 | } 68 | 69 | function populateSearchCache() { 70 | $('#full_list li .item').each(function() { 71 | var $node = $(this); 72 | var $link = $node.find('.object_link a'); 73 | if ($link.length > 0) { 74 | searchCache.push({ 75 | node: $node, 76 | link: $link, 77 | name: $link.text(), 78 | fullName: $link.attr('title').split(' ')[0] 79 | }); 80 | } 81 | }); 82 | } 83 | 84 | function enableSearch() { 85 | $('#search input').keyup(function(event) { 86 | if (ignoredKeyPress(event)) return; 87 | if (this.value === "") { 88 | clearSearch(); 89 | } else { 90 | performSearch(this.value); 91 | } 92 | }); 93 | 94 | $('#full_list').after(""); 95 | } 96 | 97 | function ignoredKeyPress(event) { 98 | if ( 99 | (event.keyCode > ignoreKeyCodeMin && event.keyCode < ignoreKeyCodeMax) || 100 | (event.keyCode == commandKey) 101 | ) { 102 | return true; 103 | } else { 104 | return false; 105 | } 106 | } 107 | 108 | function clearSearch() { 109 | clearSearchTimeout(); 110 | $('#full_list .found').removeClass('found').each(function() { 111 | var $link = $(this).find('.object_link a'); 112 | $link.text($link.text()); 113 | }); 114 | $('#full_list, #content').removeClass('insearch'); 115 | $clicked.parents().removeClass('collapsed'); 116 | highlight(); 117 | } 118 | 119 | function performSearch(searchString) { 120 | clearSearchTimeout(); 121 | $('#full_list, #content').addClass('insearch'); 122 | $('#noresults').text('').hide(); 123 | partialSearch(searchString, 0); 124 | } 125 | 126 | function partialSearch(searchString, offset) { 127 | var lastRowClass = ''; 128 | var i = null; 129 | for (i = offset; i < Math.min(offset + 50, searchCache.length); i++) { 130 | var item = searchCache[i]; 131 | var searchName = (searchString.indexOf('::') != -1 ? item.fullName : item.name); 132 | var matchString = buildMatchString(searchString); 133 | var matchRegexp = new RegExp(matchString, caseSensitiveMatch ? "" : "i"); 134 | if (searchName.match(matchRegexp) == null) { 135 | item.node.removeClass('found'); 136 | item.link.text(item.link.text()); 137 | } 138 | else { 139 | item.node.addClass('found'); 140 | item.node.removeClass(lastRowClass).addClass(lastRowClass == 'r1' ? 'r2' : 'r1'); 141 | lastRowClass = item.node.hasClass('r1') ? 'r1' : 'r2'; 142 | item.link.html(item.name.replace(matchRegexp, "$&")); 143 | } 144 | } 145 | if(i == searchCache.length) { 146 | searchDone(); 147 | } else { 148 | searchTimeout = setTimeout(function() { 149 | partialSearch(searchString, i); 150 | }, 0); 151 | } 152 | } 153 | 154 | function searchDone() { 155 | searchTimeout = null; 156 | highlight(); 157 | if ($('#full_list li:visible').size() === 0) { 158 | $('#noresults').text('No results were found.').hide().fadeIn(); 159 | } else { 160 | $('#noresults').text('').hide(); 161 | } 162 | $('#content').removeClass('insearch'); 163 | } 164 | 165 | function buildMatchString(searchString, event) { 166 | caseSensitiveMatch = searchString.match(/[A-Z]/) != null; 167 | var regexSearchString = RegExp.escape(searchString); 168 | if (caseSensitiveMatch) { 169 | regexSearchString += "|" + 170 | $.map(searchString.split(''), function(e) { return RegExp.escape(e); }). 171 | join('.+?'); 172 | } 173 | return regexSearchString; 174 | } 175 | 176 | function highlight() { 177 | $('#full_list li:visible').each(function(n) { 178 | $(this).removeClass('even odd').addClass(n % 2 == 0 ? 'odd' : 'even'); 179 | }); 180 | } 181 | 182 | /** 183 | * Expands the tree to the target element and its immediate 184 | * children. 185 | */ 186 | function expandTo(path) { 187 | var $target = $(document.getElementById('object_' + path)); 188 | $target.addClass('clicked'); 189 | $target.removeClass('collapsed'); 190 | $target.parentsUntil('#full_list', 'li').removeClass('collapsed'); 191 | if($target[0]) { 192 | window.scrollTo(window.scrollX, $target.offset().top - 250); 193 | highlight(); 194 | } 195 | } 196 | 197 | function windowEvents(event) { 198 | var msg = event.data; 199 | if (msg.action === "expand") { 200 | expandTo(msg.path); 201 | } 202 | return false; 203 | } 204 | 205 | window.addEventListener("message", windowEvents, false); 206 | 207 | $(document).ready(function() { 208 | escapeShortcut(); 209 | navResizer(); 210 | enableLinks(); 211 | enableToggles(); 212 | populateSearchCache(); 213 | enableSearch(); 214 | }); 215 | 216 | })(); 217 | -------------------------------------------------------------------------------- /docs/vendor/plugins/emoji.min.js: -------------------------------------------------------------------------------- 1 | !function(){var o=["+1","100","1234","8ball","a","ab","abc","abcd","accept","aerial_tramway","airplane","alarm_clock","alien","ambulance","anchor","angel","anger","angry","anguished","ant","apple","aquarius","aries","arrow_backward","arrow_double_down","arrow_double_up","arrow_down","arrow_down_small","arrow_forward","arrow_heading_down","arrow_heading_up","arrow_left","arrow_lower_left","arrow_lower_right","arrow_right","arrow_right_hook","arrow_up","arrow_up_down","arrow_up_small","arrow_upper_left","arrow_upper_right","arrows_clockwise","arrows_counterclockwise","art","articulated_lorry","astonished","athletic_shoe","atm","b","baby","baby_bottle","baby_chick","baby_symbol","back","baggage_claim","balloon","ballot_box_with_check","bamboo","banana","bangbang","bank","bar_chart","barber","baseball","basketball","bath","bathtub","battery","bear","bee","beer","beers","beetle","beginner","bell","bento","bicyclist","bike","bikini","bird","birthday","black_circle","black_joker","black_large_square","black_medium_small_square","black_medium_square","black_nib","black_small_square","black_square_button","blossom","blowfish","blue_book","blue_car","blue_heart","blush","boar","boat","bomb","book","bookmark","bookmark_tabs","books","boom","boot","bouquet","bow","bowling","bowtie","boy","bread","bride_with_veil","bridge_at_night","briefcase","broken_heart","bug","bulb","bullettrain_front","bullettrain_side","bus","busstop","bust_in_silhouette","busts_in_silhouette","cactus","cake","calendar","calling","camel","camera","cancer","candy","capital_abcd","capricorn","car","card_index","carousel_horse","cat","cat2","cd","chart","chart_with_downwards_trend","chart_with_upwards_trend","checkered_flag","cherries","cherry_blossom","chestnut","chicken","children_crossing","chocolate_bar","christmas_tree","church","cinema","circus_tent","city_sunrise","city_sunset","cl","clap","clapper","clipboard","clock1","clock10","clock1030","clock11","clock1130","clock12","clock1230","clock130","clock2","clock230","clock3","clock330","clock4","clock430","clock5","clock530","clock6","clock630","clock7","clock730","clock8","clock830","clock9","clock930","closed_book","closed_lock_with_key","closed_umbrella","cloud","clubs","cn","cocktail","coffee","cold_sweat","collision","computer","confetti_ball","confounded","confused","congratulations","construction","construction_worker","convenience_store","cookie","cool","cop","copyright","corn","couple","couple_with_heart","couplekiss","cow","cow2","credit_card","crescent_moon","crocodile","crossed_flags","crown","cry","crying_cat_face","crystal_ball","cupid","curly_loop","currency_exchange","curry","custard","customs","cyclone","dancer","dancers","dango","dart","dash","date","de","deciduous_tree","department_store","diamond_shape_with_a_dot_inside","diamonds","disappointed","disappointed_relieved","dizzy","dizzy_face","do_not_litter","dog","dog2","dollar","dolls","dolphin","door","doughnut","dragon","dragon_face","dress","dromedary_camel","droplet","dvd","e-mail","ear","ear_of_rice","earth_africa","earth_americas","earth_asia","egg","eggplant","eight","eight_pointed_black_star","eight_spoked_asterisk","electric_plug","elephant","email","end","envelope","envelope_with_arrow","es","euro","european_castle","european_post_office","evergreen_tree","exclamation","expressionless","eyeglasses","eyes","facepunch","factory","fallen_leaf","family","fast_forward","fax","fearful","feelsgood","feet","ferris_wheel","file_folder","finnadie","fire","fire_engine","fireworks","first_quarter_moon","first_quarter_moon_with_face","fish","fish_cake","fishing_pole_and_fish","fist","five","flags","flashlight","flipper","floppy_disk","flower_playing_cards","flushed","foggy","football","footprints","fork_and_knife","fountain","four","four_leaf_clover","fr","free","fried_shrimp","fries","frog","frowning","fu","fuelpump","full_moon","full_moon_with_face","game_die","gb","gem","gemini","ghost","gift","gift_heart","girl","globe_with_meridians","goat","goberserk","godmode","golf","grapes","green_apple","green_book","green_heart","grey_exclamation","grey_question","grimacing","grin","grinning","guardsman","guitar","gun","haircut","hamburger","hammer","hamster","hand","handbag","hankey","hash","hatched_chick","hatching_chick","headphones","hear_no_evil","heart","heart_decoration","heart_eyes","heart_eyes_cat","heartbeat","heartpulse","hearts","heavy_check_mark","heavy_division_sign","heavy_dollar_sign","heavy_exclamation_mark","heavy_minus_sign","heavy_multiplication_x","heavy_plus_sign","helicopter","herb","hibiscus","high_brightness","high_heel","hocho","honey_pot","honeybee","horse","horse_racing","hospital","hotel","hotsprings","hourglass","hourglass_flowing_sand","house","house_with_garden","hurtrealbad","hushed","ice_cream","icecream","id","ideograph_advantage","imp","inbox_tray","incoming_envelope","information_desk_person","information_source","innocent","interrobang","iphone","it","izakaya_lantern","jack_o_lantern","japan","japanese_castle","japanese_goblin","japanese_ogre","jeans","joy","joy_cat","jp","key","keycap_ten","kimono","kiss","kissing","kissing_cat","kissing_closed_eyes","kissing_heart","kissing_smiling_eyes","koala","koko","kr","lantern","large_blue_circle","large_blue_diamond","large_orange_diamond","last_quarter_moon","last_quarter_moon_with_face","laughing","leaves","ledger","left_luggage","left_right_arrow","leftwards_arrow_with_hook","lemon","leo","leopard","libra","light_rail","link","lips","lipstick","lock","lock_with_ink_pen","lollipop","loop","loud_sound","loudspeaker","love_hotel","love_letter","low_brightness","m","mag","mag_right","mahjong","mailbox","mailbox_closed","mailbox_with_mail","mailbox_with_no_mail","man","man_with_gua_pi_mao","man_with_turban","mans_shoe","maple_leaf","mask","massage","meat_on_bone","mega","melon","memo","mens","metal","metro","microphone","microscope","milky_way","minibus","minidisc","mobile_phone_off","money_with_wings","moneybag","monkey","monkey_face","monorail","moon","mortar_board","mount_fuji","mountain_bicyclist","mountain_cableway","mountain_railway","mouse","mouse2","movie_camera","moyai","muscle","mushroom","musical_keyboard","musical_note","musical_score","mute","nail_care","name_badge","neckbeard","necktie","negative_squared_cross_mark","neutral_face","new","new_moon","new_moon_with_face","newspaper","ng","night_with_stars","nine","no_bell","no_bicycles","no_entry","no_entry_sign","no_good","no_mobile_phones","no_mouth","no_pedestrians","no_smoking","non-potable_water","nose","notebook","notebook_with_decorative_cover","notes","nut_and_bolt","o","o2","ocean","octocat","octopus","oden","office","ok","ok_hand","ok_woman","older_man","older_woman","on","oncoming_automobile","oncoming_bus","oncoming_police_car","oncoming_taxi","one","open_book","open_file_folder","open_hands","open_mouth","ophiuchus","orange_book","outbox_tray","ox","package","page_facing_up","page_with_curl","pager","palm_tree","panda_face","paperclip","parking","part_alternation_mark","partly_sunny","passport_control","paw_prints","peach","pear","pencil","pencil2","penguin","pensive","performing_arts","persevere","person_frowning","person_with_blond_hair","person_with_pouting_face","phone","pig","pig2","pig_nose","pill","pineapple","pisces","pizza","point_down","point_left","point_right","point_up","point_up_2","police_car","poodle","poop","post_office","postal_horn","postbox","potable_water","pouch","poultry_leg","pound","pouting_cat","pray","princess","punch","purple_heart","purse","pushpin","put_litter_in_its_place","question","rabbit","rabbit2","racehorse","radio","radio_button","rage","rage1","rage2","rage3","rage4","railway_car","rainbow","raised_hand","raised_hands","raising_hand","ram","ramen","rat","recycle","red_car","red_circle","registered","relaxed","relieved","repeat","repeat_one","restroom","revolving_hearts","rewind","ribbon","rice","rice_ball","rice_cracker","rice_scene","ring","rocket","roller_coaster","rooster","rose","rotating_light","round_pushpin","rowboat","ru","rugby_football","runner","running","running_shirt_with_sash","sa","sagittarius","sailboat","sake","sandal","santa","satellite","satisfied","saxophone","school","school_satchel","scissors","scorpius","scream","scream_cat","scroll","seat","secret","see_no_evil","seedling","seven","shaved_ice","sheep","shell","ship","shipit","shirt","shit","shoe","shower","signal_strength","six","six_pointed_star","ski","skull","sleeping","sleepy","slot_machine","small_blue_diamond","small_orange_diamond","small_red_triangle","small_red_triangle_down","smile","smile_cat","smiley","smiley_cat","smiling_imp","smirk","smirk_cat","smoking","snail","snake","snowboarder","snowflake","snowman","sob","soccer","soon","sos","sound","space_invader","spades","spaghetti","sparkle","sparkler","sparkles","sparkling_heart","speak_no_evil","speaker","speech_balloon","speedboat","squirrel","star","star2","stars","station","statue_of_liberty","steam_locomotive","stew","straight_ruler","strawberry","stuck_out_tongue","stuck_out_tongue_closed_eyes","stuck_out_tongue_winking_eye","sun_with_face","sunflower","sunglasses","sunny","sunrise","sunrise_over_mountains","surfer","sushi","suspect","suspension_railway","sweat","sweat_drops","sweat_smile","sweet_potato","swimmer","symbols","syringe","tada","tanabata_tree","tangerine","taurus","taxi","tea","telephone","telephone_receiver","telescope","tennis","tent","thought_balloon","three","thumbsdown","thumbsup","ticket","tiger","tiger2","tired_face","tm","toilet","tokyo_tower","tomato","tongue","top","tophat","tractor","traffic_light","train","train2","tram","triangular_flag_on_post","triangular_ruler","trident","triumph","trolleybus","trollface","trophy","tropical_drink","tropical_fish","truck","trumpet","tshirt","tulip","turtle","tv","twisted_rightwards_arrows","two","two_hearts","two_men_holding_hands","two_women_holding_hands","u5272","u5408","u55b6","u6307","u6708","u6709","u6e80","u7121","u7533","u7981","u7a7a","uk","umbrella","unamused","underage","unlock","up","us","v","vertical_traffic_light","vhs","vibration_mode","video_camera","video_game","violin","virgo","volcano","vs","walking","waning_crescent_moon","waning_gibbous_moon","warning","watch","water_buffalo","watermelon","wave","wavy_dash","waxing_crescent_moon","waxing_gibbous_moon","wc","weary","wedding","whale","whale2","wheelchair","white_check_mark","white_circle","white_flower","white_large_square","white_medium_small_square","white_medium_square","white_small_square","white_square_button","wind_chime","wine_glass","wink","wolf","woman","womans_clothes","womans_hat","womens","worried","wrench","x","yellow_heart","yen","yum","zap","zero","zzz"];window.emojify=function(e,a){return-1===o.indexOf(a)?e:''+a+''}}(); 2 | -------------------------------------------------------------------------------- /docs/yard/js/app.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var localStorage = {}, sessionStorage = {}; 4 | try { localStorage = window.localStorage; } catch (e) { } 5 | try { sessionStorage = window.sessionStorage; } catch (e) { } 6 | 7 | function createSourceLinks() { 8 | $('.method_details_list .source_code'). 9 | before("[View source]"); 10 | $('.toggleSource').toggle(function() { 11 | $(this).parent().nextAll('.source_code').slideDown(100); 12 | $(this).text("Hide source"); 13 | }, 14 | function() { 15 | $(this).parent().nextAll('.source_code').slideUp(100); 16 | $(this).text("View source"); 17 | }); 18 | } 19 | 20 | function createDefineLinks() { 21 | var tHeight = 0; 22 | $('.defines').after(" more..."); 23 | $('.toggleDefines').toggle(function() { 24 | tHeight = $(this).parent().prev().height(); 25 | $(this).prev().css('display', 'inline'); 26 | $(this).parent().prev().height($(this).parent().height()); 27 | $(this).text("(less)"); 28 | }, 29 | function() { 30 | $(this).prev().hide(); 31 | $(this).parent().prev().height(tHeight); 32 | $(this).text("more..."); 33 | }); 34 | } 35 | 36 | function createFullTreeLinks() { 37 | var tHeight = 0; 38 | $('.inheritanceTree').toggle(function() { 39 | tHeight = $(this).parent().prev().height(); 40 | $(this).parent().toggleClass('showAll'); 41 | $(this).text("(hide)"); 42 | $(this).parent().prev().height($(this).parent().height()); 43 | }, 44 | function() { 45 | $(this).parent().toggleClass('showAll'); 46 | $(this).parent().prev().height(tHeight); 47 | $(this).text("show all"); 48 | }); 49 | } 50 | 51 | function searchFrameButtons() { 52 | $('.full_list_link').click(function() { 53 | toggleSearchFrame(this, $(this).attr('href')); 54 | return false; 55 | }); 56 | window.addEventListener('message', function(e) { 57 | if (e.data === 'navEscape') { 58 | $('#nav').slideUp(100); 59 | $('#search a').removeClass('active inactive'); 60 | $(window).focus(); 61 | } 62 | }); 63 | 64 | $(window).resize(function() { 65 | if ($('#search:visible').length === 0) { 66 | $('#nav').removeAttr('style'); 67 | $('#search a').removeClass('active inactive'); 68 | $(window).focus(); 69 | } 70 | }); 71 | } 72 | 73 | function toggleSearchFrame(id, link) { 74 | var frame = $('#nav'); 75 | $('#search a').removeClass('active').addClass('inactive'); 76 | if (frame.attr('src') === link && frame.css('display') !== "none") { 77 | frame.slideUp(100); 78 | $('#search a').removeClass('active inactive'); 79 | } 80 | else { 81 | $(id).addClass('active').removeClass('inactive'); 82 | if (frame.attr('src') !== link) frame.attr('src', link); 83 | frame.slideDown(100); 84 | } 85 | } 86 | 87 | function linkSummaries() { 88 | $('.summary_signature').click(function() { 89 | document.location = $(this).find('a').attr('href'); 90 | }); 91 | } 92 | 93 | function summaryToggle() { 94 | $('.summary_toggle').click(function(e) { 95 | e.preventDefault(); 96 | localStorage.summaryCollapsed = $(this).text(); 97 | $('.summary_toggle').each(function() { 98 | $(this).text($(this).text() == "collapse" ? "expand" : "collapse"); 99 | var next = $(this).parent().parent().nextAll('ul.summary').first(); 100 | if (next.hasClass('compact')) { 101 | next.toggle(); 102 | next.nextAll('ul.summary').first().toggle(); 103 | } 104 | else if (next.hasClass('summary')) { 105 | var list = $('"),this.cacheTree[r]=l}return i},ie.prototype.subSidebar=function(e){if(e){var t=this.router.getCurrentPath(),n=this.cacheTree,r=this.toc;r[0]&&r[0].ignoreAllSubs&&r.splice(0),r[0]&&1===r[0].level&&r.shift();for(var i=0;i=t||e.classList.contains("hidden")?$(y,"add","sticky"):$(y,"remove","sticky")}}function se(e,t,r,n){var i=[];null!=(t=v(t))&&(i=w(t,"a"));var a,o=decodeURI(e.toURL(e.getCurrentPath()));return i.sort(function(e,t){return t.href.length-e.href.length}).forEach(function(e){var t=e.getAttribute("href"),n=r?e.parentNode:e;0!==o.indexOf(t)||a?$(n,"remove","active"):(a=e,$(n,"add","active"))}),n&&(b.title=a?a.title||a.innerText+" - "+ae:ae),a}var le=function(){function r(e,t){for(var n=0;nthis.end&&e>=this.next}[this.direction]}},{key:"_defaultEase",value:function(e,t,n,r){return(e/=r/2)<1?n/2*e*e+t:-n/2*(--e*(e-2)-1)+t}}]),t}(),ue={},pe=!1,he=null,de=!0,ge=0;function fe(e){if(de){for(var t,n=v(".sidebar"),r=w(".anchor"),i=x(n,".sidebar-nav"),a=x(n,"li.active"),o=document.documentElement,s=(o&&o.scrollTop||document.body.scrollTop)-ge,l=0,c=r.length;ls){t||(t=u);break}t=u}if(t){var p=ue[me(decodeURIComponent(e),t.getAttribute("data-id"))];if(p&&p!==a&&(a&&a.classList.remove("active"),p.classList.add("active"),a=p,!pe&&y.classList.contains("sticky"))){var h=n.clientHeight,d=a.offsetTop+a.clientHeight+40,g=d-0=i.scrollTop&&d<=i.scrollTop+h?i.scrollTop:g?0:d-h;n.scrollTop=f}}}}function me(e,t){return e+"?id="+t}function ve(e,t){if(t){var n,r=x("#"+t);r&&(n=r,he&&he.stop(),de=!1,he=new ce({start:window.pageYOffset,end:n.getBoundingClientRect().top+window.pageYOffset,duration:500}).on("tick",function(e){return window.scrollTo(0,e)}).on("done",function(){de=!0,he=null}).begin());var i=ue[me(e,t)],a=x(v(".sidebar"),"li.active");a&&a.classList.remove("active"),i&&i.classList.add("active")}}var be=b.scrollingElement||b.documentElement;var ye={};function ke(e,i){var o=e.compiler,a=e.raw;void 0===a&&(a="");var t=e.fetch,n=ye[a];if(n){var r=n.slice();return r.links=n.links,i(r)}var s=o._marked,l=s.lexer(a),c=[],u=s.InlineLexer.rules.link,p=l.links;l.forEach(function(e,a){"paragraph"===e.type&&(e.text=e.text.replace(new RegExp(u.source,"g"),function(e,t,n,r){var i=o.compileEmbed(n,r);return i&&c.push({index:a,embed:i}),e}))});var h=0;!function(e,a){var t,n=e.embedTokens,o=e.compile,s=(e.fetch,0),l=1;if(!n.length)return a({});for(;t=n[s++];){var r=function(i){return function(e){var t;if(e)if("markdown"===i.embed.type)t=o.lexer(e);else if("code"===i.embed.type){if(i.embed.fragment){var n=i.embed.fragment,r=new RegExp("(?:###|\\/\\/\\/)\\s*\\["+n+"\\]([\\s\\S]*)(?:###|\\/\\/\\/)\\s*\\["+n+"\\]");e=((e.match(r)||[])[1]||"").trim()}t=o.lexer("```"+i.embed.lang+"\n"+e.replace(/`/g,"@DOCSIFY_QM@")+"\n```\n")}else"mermaid"===i.embed.type?(t=[{type:"html",text:'
\n'+e+"\n
"}]).links={}:(t=[{type:"html",text:e}]).links={};a({token:i,embedToken:t}),++l>=s&&a({})}}(t);t.embed.url?F(t.embed.url).then(r):r(t.embed.html)}}({compile:s,embedTokens:c,fetch:t},function(e){var t=e.embedToken,n=e.token;if(n){var r=n.index+h;d(p,t.links),l=l.slice(0,r).concat(t,l.slice(r+1)),h+=t.length-1}else ye[a]=l.concat(),l.links=ye[a].links=p,i(l)})}function xe(){var e=w(".markdown-section>script").filter(function(e){return!/template/.test(e.type)})[0];if(!e)return!1;var t=e.innerText.trim();if(!t)return!1;setTimeout(function(e){window.__EXECUTE_RESULT__=new Function(t)()},0)}function we(e,t,n){var r,i,a;return t="function"==typeof n?n(t):"string"==typeof n?(i=[],a=0,(r=n).replace(N,function(t,e,n){i.push(r.substring(a,n-1)),a=n+=t.length+1,i.push(function(e){return("00"+("string"==typeof z[t]?e[z[t]]():z[t](e))).slice(-t.length)})}),a!==r.length&&i.push(r.substring(a)),function(e){for(var t="",n=0,r=e||new Date;n'):""),t.coverpage&&(u+=(i=", 100%, 85%",'
\x3c!--cover--\x3e
')),t.logo){var h=/^data:image/.test(t.logo),d=/(?:http[s]?:)?\/\//.test(t.logo),g=/^\./.test(t.logo);h||d||g||(t.logo=K(e.router.getBasePath(),t.logo))}u+=(r='',(m?r+"
":"
"+r)+'
\x3c!--main--\x3e
'),e._renderTo(c,u,!0)}else e.rendered=!0;t.mergeNavbar&&m?p=x(".sidebar"):(l.classList.add("app-nav"),t.repo||l.classList.add("no-badge")),t.loadNavbar&&A(p,l),t.themeColor&&(b.head.appendChild(_("div",(o=t.themeColor,"")).firstElementChild),function(n){if(!(window.CSS&&window.CSS.supports&&window.CSS.supports("(--v:red)"))){var e=w("style:not(.inserted),link");[].forEach.call(e,function(e){if("STYLE"===e.nodeName)j(e,n);else if("LINK"===e.nodeName){var t=e.getAttribute("href");if(!/\.css$/.test(t))return;F(t).then(function(e){var t=_("style",e);k.appendChild(t),j(t,n)})}})}}(t.themeColor)),e._updateRender(),$(y,"ready")}var Ae={};var Ce=function(e){this.config=e};function Ee(e){var t=location.href.indexOf("#");location.replace(location.href.slice(0,0<=t?t:0)+"#"+e)}Ce.prototype.getBasePath=function(){return this.config.basePath},Ce.prototype.getFile=function(e,t){void 0===e&&(e=this.getCurrentPath());var n,r,i=this.config,a=this.getBasePath(),o="string"==typeof i.ext?i.ext:".md";return e=i.alias?function e(t,n,r){var i=Object.keys(n).filter(function(e){return(Ae[e]||(Ae[e]=new RegExp("^"+e+"$"))).test(t)&&t!==r})[0];return i?e(t.replace(Ae[i],n[i]),n,t):t}(e,i.alias):e,n=e,r=o,e=(e=new RegExp("\\.("+r.replace(/^\./,"")+"|html)$","g").test(n)?n:/\/$/g.test(n)?n+"README"+r:""+n+r)==="/README"+o&&i.homepage||e,e=X(e)?e:K(a,e),t&&(e=e.replace(new RegExp("^"+a),"")),e},Ce.prototype.onchange=function(e){void 0===e&&(e=p),e()},Ce.prototype.getCurrentPath=function(){},Ce.prototype.normalize=function(){},Ce.prototype.parse=function(){},Ce.prototype.toURL=function(e,t,n){var r=n&&"#"===e[0],i=this.parse(ee(e));if(i.query=d({},i.query,t),e=(e=i.path+G(i.query)).replace(/\.md(\?)|\.md$/,"$1"),r){var a=n.indexOf("?");e=(0([^<]*?)

$');if(i){if("color"===i[2])n.style.background=i[1]+(i[3]||"");else{var a=i[1];$(n,"add","has-mask"),X(i[1])||(a=K(this.router.getBasePath(),i[1])),n.style.backgroundImage="url("+a+")",n.style.backgroundSize="cover",n.style.backgroundPosition="center center"}r=r.replace(i[0],"")}this._renderTo(".cover-main",r),oe()}else $(n,"remove","show")},Ne._updateRender=function(){!function(e){var t=v(".app-name-link"),n=e.config.nameLink,r=e.route.path;if(t)if(c(e.config.nameLink))t.setAttribute("href",n);else if("object"==typeof n){var i=Object.keys(n).filter(function(e){return-1