text:
package org.h2.test.db;

import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Random;
import java.util.StringTokenizer;
import java.util.UUID;
import org.h2.fulltext.FullText;
import org.h2.store.fs.FileUtils;
import org.h2.test.TestBase;
import org.h2.util.Task;

/**
 * Fulltext search tests.
 */
public class TestFullText extends TestBase {

    /**
     * The words used in this test.
     */
    static final String[] KNOWN_WORDS = { "skiing", "balance", "storage",
            "water", "train" };
    private static final String LUCENE_FULLTEXT_CLASS_NAME =
            "org.h2.fulltext.FullTextLucene";

    /**
     * Run just this test.
     *
     * @param a ignored
     */
    public static void main(String... a) throws Exception {
        TestBase.createCaller().init().test();
    }

    @Override
    public void test() throws Exception {
        testUuidPrimaryKey(false);
        testAutoAnalyze();
        testNativeFeatures();
        testTransaction(false);
        testCreateDropNative();
        testStreamLob();
        test(false, "VARCHAR");
        test(false, "CLOB");
        testPerformance(false);
        testReopen(false);
        testDropIndex(false);
        if (!config.reopen) {
            try {
                Class.forName(LUCENE_FULLTEXT_CLASS_NAME);
                testCreateDropLucene();
                testUuidPrimaryKey(true);
                testMultiThreaded(true);
                testMultiThreaded(false);
                testTransaction(true);
                test(true, "VARCHAR");
                test(true, "CLOB");
                testPerformance(true);
                testReopen(true);
                testDropIndex(true);
            } catch (ClassNotFoundException e) {
                println("Class not found, not tested: " + LUCENE_FULLTEXT_CLASS_NAME);
                // ok
            } catch (NoClassDefFoundError e) {
                println("Class not found, not tested: " + LUCENE_FULLTEXT_CLASS_NAME);
                // ok
            }
            FullText.closeAll();
        }
        deleteDb("fullText");
        deleteDb("fullTextReopen");
    }

    private static void close(Collection<Connection> list) throws SQLException {
        for (Connection conn : list) {
            conn.close();
        }
    }

    private Connection getConnection(String name, Collection<Connection> list)
            throws SQLException {
        Connection conn = getConnection(name);
        list.add(conn);
        return conn;
    }

    private void testAutoAnalyze() throws SQLException {
        deleteDb("fullTextNative");
        Connection conn;
        Statement stat;

        ArrayList<Connection> connList = new ArrayList<Connection>();

        conn = getConnection("fullTextNative", connList);
        stat = conn.createStatement();
        stat.execute("create alias if not exists ft_init " +
                "for \"org.h2.fulltext.FullText.init\"");
        stat.execute("call ft_init()");
        stat.execute("create table test(id int primary key, name varchar)");
        stat.execute("call ft_create_index('PUBLIC', 'TEST', 'NAME')");

        if (!config.memory) {
            conn.close();
        }

        conn = getConnection("fullTextNative", connList);
        stat = conn.createStatement();
        stat.execute("insert into test select x, 'x' from system_range(1, 3000)");
        close(connList);
    }

    private void testNativeFeatures() throws SQLException {
        deleteDb("fullTextNative");
        ArrayList<Connection> connList = new ArrayList<Connection>();
        Connection conn = getConnection("fullTextNative", connList);
        Statement stat = conn.createStatement();
        stat.execute("CREATE ALIAS IF NOT EXISTS FT_INIT " +
                "FOR \"org.h2.fulltext.FullText.init\"");
        stat.execute("CALL FT_INIT()");
        FullText.setIgnoreList(conn, "to,this");
        FullText.setWhitespaceChars(conn, " ,.-");
        stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)");
        stat.execute("INSERT INTO TEST VALUES(1, 'Welcome to this world, One_Word')");
        stat.execute("CALL FT_CREATE_INDEX('PUBLIC', 'TEST', NULL)");
        ResultSet rs;
        rs = stat.executeQuery("SELECT * FROM FT_SEARCH('Welcome', 0, 0)");
        assertTrue(rs.next());
        assertEquals("QUERY", rs.getMetaData().getColumnLabel(1));
        assertEquals("SCORE", rs.getMetaData().getColumnLabel(2));
        assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=1", rs.getString(1));
        assertEquals("1.0", rs.getString(2));
        rs = stat.executeQuery("SELECT * FROM FT_SEARCH_DATA('One', 0, 0)");
        assertFalse(rs.next());
        rs = stat.executeQuery("SELECT * FROM FT_SEARCH_DATA('One_Word', 0, 0)");
        assertTrue(rs.next());
        rs = stat.executeQuery("SELECT * FROM FT_SEARCH_DATA('Welcome', 0, 0)");
        assertTrue(rs.next());
        assertEquals("SCHEMA", rs.getMetaData().getColumnLabel(1));
        assertEquals("TABLE", rs.getMetaData().getColumnLabel(2));
        assertEquals("COLUMNS", rs.getMetaData().getColumnLabel(3));
        assertEquals("KEYS", rs.getMetaData().getColumnLabel(4));
        assertEquals("PUBLIC", rs.getString(1));
        assertEquals("TEST", rs.getString(2));
        assertEquals("(ID)", rs.getString(3));
        assertEquals("(1)", rs.getString(4));

        rs = stat.executeQuery("SELECT * FROM FT_SEARCH('this', 0, 0)");
        assertFalse(rs.next());

        if (!config.memory) {
            conn.close();
        }
        conn = getConnection("fullTextNative", connList);
        stat = conn.createStatement();
        conn.setAutoCommit(false);
        rs = stat.executeQuery("SELECT * FROM FT_SEARCH_DATA('Welcome', 0, 0)");
        assertTrue(rs.next());
        stat.execute("delete from test");
        rs = stat.executeQuery("SELECT * FROM FT_SEARCH_DATA('Welcome', 0, 0)");
        assertFalse(rs.next());
        conn.rollback();
        rs = stat.executeQuery("SELECT * FROM FT_SEARCH_DATA('Welcome', 0, 0)");
        assertTrue(rs.next());
        conn.setAutoCommit(true);
        close(connList);
    }

    private void testUuidPrimaryKey(boolean lucene) throws SQLException {
        deleteDb("fullText");
        Connection conn = getConnection("fullText");
        Statement stat = conn.createStatement();
        String prefix = lucene ? "FTL" : "FT";
        initFullText(stat, lucene);
        stat.execute("CREATE TABLE TEST(ID UUID PRIMARY KEY, NAME VARCHAR)");
        String id = UUID.randomUUID().toString();
        stat.execute("INSERT INTO TEST VALUES('" + id + "', 'Hello World')");
        stat.execute("CALL " + prefix + "_CREATE_INDEX('PUBLIC', 'TEST', 'NAME')");
        ResultSet rs = stat.executeQuery("SELECT * FROM " +
                prefix + "_SEARCH('Hello', 0, 0)");
        assertTrue(rs.next());
        stat.execute("UPDATE TEST SET NAME=NULL WHERE ID='" + id + "'");
        rs = stat.executeQuery("SELECT * FROM " +
                prefix + "_SEARCH('Hello', 0, 0)");
        assertFalse(rs.next());
        stat.execute("UPDATE TEST SET NAME='Good Bye' WHERE ID='" + id + "'");
        rs = stat.executeQuery("SELECT * FROM " +
                prefix + "_SEARCH('bye', 0, 0)");
        assertTrue(rs.next());
        FullText.dropAll(conn);
        conn.close();
        deleteDb("fullText");
    }

    private void testTransaction(boolean lucene) throws SQLException {
        String prefix = lucene ? "FTL" : "FT";
        deleteDb("fullTextTransaction");
        FileUtils.deleteRecursive(getBaseDir() + "/fullTextTransaction", false);
        ArrayList<Connection> connList = new ArrayList<Connection>();
        Connection conn = getConnection("fullTextTransaction", connList);
        Statement stat = conn.createStatement();
        initFullText(stat, lucene);
        stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)");
        stat.execute("INSERT INTO TEST VALUES(1, 'Hello World')");
        stat.execute("CALL " + prefix + "_CREATE_INDEX('PUBLIC', 'TEST', NULL)");
        ResultSet rs = stat.executeQuery("SELECT * FROM " +
                prefix + "_SEARCH('Hello', 0, 0)");
        assertTrue(rs.next());
        stat.execute("UPDATE TEST SET NAME=NULL WHERE ID=1");
        stat.execute("UPDATE TEST SET NAME='Hello World' WHERE ID=1");
        conn.setAutoCommit(false);
        stat.execute("insert into test values(2, 'Hello Moon!')");
        conn.rollback();
        if (!config.memory) {
            conn.close();
        }
        conn = getConnection("fullTextTransaction", connList);
        stat = conn.createStatement();
        rs = stat.executeQuery("SELECT * FROM " +
                prefix + "_SEARCH('Hello', 0, 0)");
        assertTrue(rs.next());
        rs = stat.executeQuery("SELECT * FROM " +
                prefix + "_SEARCH('Moon', 0, 0)");
        assertFalse(rs.next());
        FullText.dropAll(conn);
        close(connList);
        deleteDb("fullTextTransaction");
        FileUtils.deleteRecursive(getBaseDir() + "/fullTextTransaction", false);
    }

    private void testMultiThreaded(boolean lucene) throws Exception {
        final String prefix = lucene ? "FTL" : "FT";
        trace("Testing multithreaded " + prefix);
        deleteDb("fullText");
        ArrayList<Connection> connList = new ArrayList<Connection>();
        int len = 2;
        Task[] task = new Task[len];
        for (int i = 0; i < len; i++) {
            // final Connection conn =
            // getConnection("fullText;MULTI_THREADED=1;LOCK_TIMEOUT=10000");
            final Connection conn = getConnection("fullText", connList);
            Statement stat = conn.createStatement();
            initFullText(stat, lucene);
            initFullText(stat, lucene);
            final String tableName = "TEST" + i;
            stat.execute("CREATE TABLE " + tableName +
                    "(ID INT PRIMARY KEY, DATA VARCHAR)");
            stat.execute("CALL " + prefix +
                    "_CREATE_INDEX('PUBLIC', '" + tableName + "', NULL)");
            task[i] = new Task() {
                @Override
                public void call() throws SQLException {
                    trace("starting thread " + Thread.currentThread());
                    PreparedStatement prep = conn.prepareStatement(
                            "INSERT INTO " + tableName + " VALUES(?, ?)");
                    Statement stat = conn.createStatement();
                    Random random = new Random();
                    int x = 0;
                    while (!stop) {
                        trace("stop = " + stop + " for " + Thread.currentThread());
                        StringBuilder buff = new StringBuilder();
                        for (int j = 0; j < 1000; j++) {
                            buff.append(" ").append(random.nextInt(10000));
                            buff.append(" x").append(j);
                            buff.append(" ").append(KNOWN_WORDS[j % KNOWN_WORDS.length]);
                        }
                        prep.setInt(1, x);
                        prep.setString(2, buff.toString());
                        prep.execute();
                        x++;
                        for (String knownWord : KNOWN_WORDS) {
                            trace("searching for " + knownWord + " with " +
                                    Thread.currentThread());
                            ResultSet rs = stat.executeQuery("SELECT * FROM " +
                                    prefix + "_SEARCH('" + knownWord +
                                    "', 0, 0)");
                            assertTrue(rs.next());
                        }
                    }
                    trace("closing connection");
                    if (!config.memory) {
                        conn.close();
                    }
                    trace("completed thread " + Thread.currentThread());
                }
            };
        }
        for (Task t : task) {
            t.execute();
        }
        trace("sleeping");
        Thread.sleep(1000);

        trace("setting stop to true");
        for (Task t : task) {
            trace("joining " + t);
            t.get();
            trace("done joining " + t);
        }
        close(connList);
    }

    private void testStreamLob() throws SQLException {
        deleteDb("fullText");
        Connection conn = getConnection("fullText");
        Statement stat = conn.createStatement();
        stat.execute("CREATE ALIAS IF NOT EXISTS FT_INIT " +
                "FOR \"org.h2.fulltext.FullText.init\"");
        stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, DATA CLOB)");
        FullText.createIndex(conn, "PUBLIC", "TEST", null);
        conn.setAutoCommit(false);
        stat.execute("insert into test values(1, 'Hello Moon!')");
        conn.rollback();
        conn.setAutoCommit(true);
        stat.execute("insert into test values(0, 'Hello World!')");
        PreparedStatement prep = conn.prepareStatement(
                "insert into test values(1, ?)");
        final int length = 1024 * 1024;
        prep.setCharacterStream(1, new Reader() {
            int remaining = length;

            @Override
            public void close() {
                // ignore
            }

            @Override
            public int read(char[] buff, int off, int len) {
                if (remaining >= len) {
                    remaining -= len;
                    return len;
                }
                remaining = -1;
                return -1;
            }
        }, length);
        prep.execute();
        ResultSet rs = stat.executeQuery(
                "SELECT * FROM FT_SEARCH('World', 0, 0)");
        assertTrue(rs.next());
        rs = stat.executeQuery("SELECT * FROM FT_SEARCH('Moon', 0, 0)");
        assertFalse(rs.next());
        FullText.dropAll(conn);
        conn.close();
        deleteDb("fullText");
    }

    private void testCreateDropNative() throws SQLException {
        deleteDb("fullText");
        FileUtils.deleteRecursive(getBaseDir() + "/fullText", false);
        Connection conn = getConnection("fullText");
        Statement stat = conn.createStatement();
        stat.execute("CREATE ALIAS IF NOT EXISTS FT_INIT " +
                "FOR \"org.h2.fulltext.FullText.init\"");
        stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)");
        for (int i = 0; i < 10; i++) {
            FullText.createIndex(conn, "PUBLIC", "TEST", null);
            FullText.dropIndex(conn, "PUBLIC", "TEST");
        }
        conn.close();
        deleteDb("fullText");
        FileUtils.deleteRecursive(getBaseDir() + "/fullText", false);
    }

    private void testCreateDropLucene() throws SQLException, SecurityException,
            NoSuchMethodException, ClassNotFoundException,
            IllegalArgumentException, IllegalAccessException,
            InvocationTargetException {
        deleteDb("fullText");
        FileUtils.deleteRecursive(getBaseDir() + "/fullText", false);
        Connection conn = getConnection("fullText");
        Statement stat = conn.createStatement();
        initFullText(stat, true);
        stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)");
        Method createIndexMethod = Class.forName(
                LUCENE_FULLTEXT_CLASS_NAME).getMethod("createIndex",
                new Class[] { java.sql.Connection.class,
                        String.class, String.class, String.class });
        Method dropIndexMethod = Class.forName(
                LUCENE_FULLTEXT_CLASS_NAME).getMethod("dropIndex",
                new Class[] { java.sql.Connection.class,
                        String.class, String.class });
        for (int i = 0; i < 10; i++) {
            createIndexMethod.invoke(null, conn, "PUBLIC", "TEST", null);
            dropIndexMethod.invoke(null, conn, "PUBLIC", "TEST");
        }
        conn.close();
        deleteDb("fullText");
        FileUtils.deleteRecursive(getBaseDir() + "/fullText", false);
    }

    private void testReopen(boolean lucene) throws SQLException {
        if (config.memory) {
            return;
        }
        String prefix = lucene ? "FTL" : "FT";
        deleteDb("fullTextReopen");
        FileUtils.deleteRecursive(getBaseDir() + "/fullTextReopen", false);
        Connection conn = getConnection("fullTextReopen");
        Statement stat = conn.createStatement();
        initFullText(stat, lucene);
        stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)");
        stat.execute("INSERT INTO TEST VALUES(1, 'Hello World')");
        stat.execute("CALL " + prefix + "_CREATE_INDEX('PUBLIC', 'TEST', NULL)");
        stat.execute("UPDATE TEST SET NAME=NULL WHERE ID=1");
        stat.execute("UPDATE TEST SET NAME='Hello World' WHERE ID=1");
        conn.close();

        conn = getConnection("fullTextReopen");
        stat = conn.createStatement();
        ResultSet rs = stat.executeQuery("SELECT * FROM " +
                prefix + "_SEARCH('Hello', 0, 0)");
        assertTrue(rs.next());
        stat.executeQuery("SELECT * FROM " + prefix + "_SEARCH(NULL, 0, 0)");
        stat.execute("INSERT INTO TEST VALUES(2, NULL)");
        conn.close();

        FullText.closeAll();
        conn = getConnection("fullTextReopen");
        stat = conn.createStatement();
        stat.execute("INSERT INTO TEST VALUES(3, 'Hello')");
        conn.close();
        FileUtils.deleteRecursive(getBaseDir() + "/fullTextReopen", false);
    }

    private void testPerformance(boolean lucene) throws SQLException {
        deleteDb("fullText");
        FileUtils.deleteRecursive(getBaseDir() + "/fullText", false);
        Connection conn = getConnection("fullText");
        String prefix = lucene ? "FTL" : "FT";
        Statement stat = conn.createStatement();
        initFullText(stat, lucene);
        stat.execute("DROP TABLE IF EXISTS TEST");
        stat.execute(
                "CREATE TABLE TEST AS SELECT * FROM INFORMATION_SCHEMA.HELP");
        stat.execute("ALTER TABLE TEST ALTER COLUMN ID INT NOT NULL");
        stat.execute("CREATE PRIMARY KEY ON TEST(ID)");
        long time = System.currentTimeMillis();
        stat.execute("CALL " + prefix + "_CREATE_INDEX('PUBLIC', 'TEST', NULL)");
        println("create " + prefix + ": " + (System.currentTimeMillis() - time));
        PreparedStatement prep = conn.prepareStatement(
                "SELECT * FROM " + prefix + "_SEARCH(?, 0, 0)");
        time = System.currentTimeMillis();
        ResultSet rs = stat.executeQuery("SELECT TEXT FROM TEST");
        int count = 0;
        while (rs.next()) {
            String text = rs.getString(1);
            StringTokenizer tokenizer = new StringTokenizer(
                        text, " ()[].,;:-+*/!?=<>{}#@'\"~$_%&|");
            while (tokenizer.hasMoreTokens()) {
                String word = tokenizer.nextToken();
                if (word.length() < 10) {
                    continue;
                }
                prep.setString(1, word);
                ResultSet rs2 = prep.executeQuery();
                while (rs2.next()) {
                    rs2.getString(1);
                    count++;
                }
            }
        }
        println("search " + prefix + ": " +
                (System.currentTimeMillis() - time) + " count: " + count);
        stat.execute("CALL " + prefix + "_DROP_ALL()");
        conn.close();
    }

    private void test(boolean lucene, String dataType) throws SQLException {
        if (lucene && getBaseDir().indexOf(':') > 0) {
            return;
        }
        deleteDb("fullText");
        ArrayList<Connection> connList = new ArrayList<Connection>();
        Connection conn = getConnection("fullText", connList);
        String prefix = lucene ? "FTL_" : "FT_";
        Statement stat = conn.createStatement();
        String className = lucene ? "FullTextLucene" : "FullText";
        stat.execute("CREATE ALIAS IF NOT EXISTS " +
                prefix + "INIT FOR \"org.h2.fulltext." + className + ".init\"");
        stat.execute("CALL " + prefix + "INIT()");
        stat.execute("DROP TABLE IF EXISTS TEST");
        stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME " + dataType + ")");
        stat.execute("INSERT INTO TEST VALUES(1, 'Hello World')");
        stat.execute("CALL " + prefix + "CREATE_INDEX('PUBLIC', 'TEST', NULL)");
        ResultSet rs;
        rs = stat.executeQuery("SELECT * FROM " +
                prefix + "SEARCH('Hello', 0, 0)");
        rs.next();
        assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=1", rs.getString(1));
        assertFalse(rs.next());
        rs = stat.executeQuery("SELECT * FROM " +
                prefix + "SEARCH('Hallo', 0, 0)");
        assertFalse(rs.next());
        stat.execute("INSERT INTO TEST VALUES(2, 'Hallo Welt')");
        rs = stat.executeQuery("SELECT * FROM " +
                prefix + "SEARCH('Hello', 0, 0)");
        rs.next();
        assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=1", rs.getString(1));
        assertFalse(rs.next());
        rs = stat.executeQuery("SELECT * FROM " +
                prefix + "SEARCH('Hallo', 0, 0)");
        rs.next();
        assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=2", rs.getString(1));
        assertFalse(rs.next());

        stat.execute("CALL " + prefix + "REINDEX()");
        rs = stat.executeQuery("SELECT * FROM " +
                prefix + "SEARCH('Hello', 0, 0)");
        rs.next();
        assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=1", rs.getString(1));
        assertFalse(rs.next());
        rs = stat.executeQuery("SELECT * FROM " +
                prefix + "SEARCH('Hallo', 0, 0)");
        rs.next();
        assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=2", rs.getString(1));
        assertFalse(rs.next());

        stat.execute("INSERT INTO TEST VALUES(3, 'Hello World')");
        stat.execute("INSERT INTO TEST VALUES(4, 'Hello World')");
        stat.execute("INSERT INTO TEST VALUES(5, 'Hello World')");

        rs = stat.executeQuery("SELECT * FROM " +
                prefix + "SEARCH('World', 0, 0) ORDER BY QUERY");
        rs.next();
        assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=1", rs.getString(1));
        rs.next();
        assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=3", rs.getString(1));
        rs.next();
        assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=4", rs.getString(1));
        rs.next();
        assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=5", rs.getString(1));
        assertFalse(rs.next());

        rs = stat.executeQuery("SELECT * FROM " +
                prefix + "SEARCH('World', 1, 0)");
        rs.next();
        assertTrue(rs.getString(1).startsWith("\"PUBLIC\".\"TEST\" WHERE \"ID\"="));
        assertFalse(rs.next());

        rs = stat.executeQuery("SELECT * FROM " +
                prefix + "SEARCH('World', 0, 2) ORDER BY QUERY");
        rs.next();
        assertTrue(rs.getString(1).startsWith("\"PUBLIC\".\"TEST\" WHERE \"ID\"="));
        rs.next();
        assertTrue(rs.getString(1).startsWith("\"PUBLIC\".\"TEST\" WHERE \"ID\"="));
        assertFalse(rs.next());

        rs = stat.executeQuery("SELECT * FROM " +
                prefix + "SEARCH('World', 2, 1) ORDER BY QUERY");
        rs.next();
        assertTrue(rs.getString(1).startsWith("\"PUBLIC\".\"TEST\" WHERE \"ID\"="));
        rs.next();
        assertTrue(rs.getString(1).startsWith("\"PUBLIC\".\"TEST\" WHERE \"ID\"="));
        assertFalse(rs.next());

        rs = stat.executeQuery("SELECT * FROM " +
                prefix + "SEARCH('1', 0, 0)");
        rs.next();
        assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=1", rs.getString(1));
        assertFalse(rs.next());

        if (lucene) {
            rs = stat.executeQuery("SELECT * FROM " +
                    prefix + "SEARCH('NAME:Hallo', 0, 0)");
            rs.next();
            assertEquals("\"PUBLIC\".\"TEST\" WHERE \"ID\"=2", rs.getString(1));
            assertFalse(rs.next());
        }

        if (!config.memory) {
            conn.close();
        }

        conn = getConnection("fullText", connList);
        stat = conn.createStatement();
        stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('World', 0, 0)");

        stat.execute("CALL " + prefix + "DROP_ALL()");

        close(connList);
    }

    private void testDropIndex(boolean lucene) throws SQLException {
        if (config.memory) {
            return;
        }
        deleteDb("fullTextDropIndex");
        String prefix = lucene ? "FTL" : "FT";
        FileUtils.deleteRecursive(getBaseDir() + "/fullTextDropIndex", false);
        Connection conn = getConnection("fullTextDropIndex");
        Statement stat = conn.createStatement();
        initFullText(stat, lucene);
        stat.execute("CREATE TABLE TEST" +
                "(ID INT PRIMARY KEY, NAME1 VARCHAR, NAME2 VARCHAR)");
        stat.execute("INSERT INTO TEST VALUES" +
                "(1, 'Hello World', 'Hello Again')");
        stat.execute("CALL " + prefix +
                "_CREATE_INDEX('PUBLIC', 'TEST', 'NAME1')");
        stat.execute("UPDATE TEST SET NAME1=NULL WHERE ID=1");
        stat.execute("UPDATE TEST SET NAME1='Hello World' WHERE ID=1");
        stat.execute("CALL " + prefix +
                "_DROP_INDEX('PUBLIC', 'TEST')");
        stat.execute("CALL " + prefix +
                "_CREATE_INDEX('PUBLIC', 'TEST', 'NAME1, NAME2')");
        stat.execute("UPDATE TEST SET NAME2=NULL WHERE ID=1");
        stat.execute("UPDATE TEST SET NAME2='Hello World' WHERE ID=1");
        conn.close();

        conn.close();
        FileUtils.deleteRecursive(getBaseDir() + "/fullTextDropIndex", false);
    }

    private static void initFullText(Statement stat, boolean lucene)
            throws SQLException {
        String prefix = lucene ? "FTL" : "FT";
        String className = lucene ? "FullTextLucene" : "FullText";
        stat.execute("CREATE ALIAS IF NOT EXISTS " + prefix +
                "_INIT FOR \"org.h2.fulltext." + className + ".init\"");
        stat.execute("CALL " + prefix + "_INIT()");
    }
}


text:
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _noImportant = require('aphrodite/no-important');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var Indicator = function Indicator(_ref) {
  var active = _ref.active,
      slideId = _ref.slideId,
      setActiveSlide = _ref.setActiveSlide;
  return _react2['default'].createElement('li', {
    className: (0, _noImportant.css)(styles.indicator, active && styles.active),
    onClick: setActiveSlide,
    'data-slideId': slideId
  });
};

exports['default'] = Indicator;

var styles = _noImportant.StyleSheet.create({
  active: {
    width: 17,
    height: 17,
    margin: 0,
    backgroundColor: '#fff',
    marginLeft: 10,
    ':hover': {
      backgroundColor: '#fff'
    }
  },
  indicator: {
    margin: 1,
    textIndent: '-999px',
    cursor: 'pointer',
    backgroundColor: 'rgba(0,0,0,0)',
    border: '1px solid #fff',
    borderRadius: '10px',
    display: 'inline-block',
    width: 15,
    height: 15,
    marginLeft: 10,
    ':hover': {
      backgroundColor: 'rgba(202, 203, 217, 0.4)'
    }
  }
});
//# sourceMappingURL=Indicator.js.map

redpajama_set_name: RedPajamaGithub


text:
package net.cloudkit.enterprises;

/**
 * @author hongquanli <hongquanli@qq.com>
 * @version 1.0 2016/2/19 12:31
 */
public class RandomPassword {

    /**
     * Get rand keys
     *
     * @param length
     * @param isUpperCase
     * @param isLowerCase
     * @param isSpecialChar
     * @return
     */
    public static final String getRandKeys(int length, boolean isUpperCase, boolean isLowerCase, boolean isSpecialChar) {

        String result = "";

        String charTable = "0123456789";
        charTable = isUpperCase ? charTable += "ABCDEFGHJKLMNPQRSTUVWXYZ" : charTable;
        charTable = isLowerCase ? charTable += "abcdefghijkmnpqrstuvwxyz" : charTable;
        charTable = isSpecialChar ? charTable += "~!@#$%^&*()_-+=`;:\"'{[}]<,>.?/" : charTable;

        int len = charTable.length();
        boolean bDone = true;
        do {
            result = "";
            int count = 0;
            for (int i = 0; i < length; i++) {
                double dblR = Math.random() * len;
                int intR = (int) Math.floor(dblR);
                char c = charTable.charAt(intR);
                if (('0' <= c) && (c <= '9')) {
                    count++;
                }
                result += charTable.charAt(intR);
            }
            if (count >= 2) {
                bDone = false;
            }
        } while (bDone);
        return result;
    }

    public static void main(String[] args) {
        System.out.println(getRandKeys(8, true, true, true));
    }
}


text:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Net;
using System.Text;
using X.Core.Utility;

namespace X.Lpw.App
{
    public class Sdk
    {
        public delegate void OutLogHandler(string log);
        public static event OutLogHandler OutLog;

        static string gateWay;//网关
        static int city_id = 0;
        static T doapi<T>(string api, object o) where T : Resp
        {
            return (T)doapi<T>(api, o, true);
        }
        static T doapi<T>(string api, object o, bool scr) where T : Resp
        {
            var wc = new WebClient();
            wc.Encoding = Encoding.UTF8;
            string json = "";
            var r = Activator.CreateInstance<T>();
            var post = Serialize.ToJson(o);
            try
            {
                var ps = o as Dictionary<string, string>;
                var url = api.StartsWith("http://") ? api : gateWay + api;
                if (ps == null) json = wc.UploadString(url, scr ? Secret.Rc4.Encrypt(post) : post);
                else
                {
                    var parms = new NameValueCollection();
                    foreach (var k in ps.Keys) { parms.Add(Secret.Rc4.Encrypt(k), Secret.Rc4.Encrypt(ps[k])); }
                    json = Encoding.UTF8.GetString(wc.UploadValues(url, parms));
                }
                if (string.IsNullOrEmpty(json)) throw new Exception("服务器返回空");
                OutLog?.Invoke("sdk@" + api + "\r\n->" + post + "\r\n->" + json);
            }
            catch (Exception ex)
            {
                var msg = ex.Message + "\r\n" + ex.StackTrace;
                if (ex is WebException) using (var sr = new System.IO.StreamReader(((WebException)ex).Response.GetResponseStream())) msg = sr.ReadToEnd();
                OutLog?.Invoke("sdk@" + api + "\r\n->" + post + "\r\n->" + msg);
                r.RMessage = ex.Message;
            }

            var rp = Serialize.FromJson<T>(json);
            if (rp != null) return rp;

            return r;
        }

        public static void Init()
        {
            gateWay = Rbt.cfg.GateWay;
            city_id = Rbt.cfg.City_Id;
        }

        /// <summary>
        /// 获取消息
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static MsgResp LoadMsg(List<string> names, string wxno, int stat)
        {
            return doapi<MsgResp>("/robot/regist/get", new { build_name = names, city_id = city_id + "", status = stat, weixin_id = wxno });
        }
        /// <summary>
        /// 提交报备
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public static SubmitResp Submit(object m, string uid)
        {
            return doapi<SubmitResp>("/robot/regist/submit", new { regist_user_id = uid, data = m, city_id = city_id });//new Dictionary<string, string>() { { "regist_id", uid + "" }, { "data", Serialize.ToJson(m) }, { "city_id", city_id + "" } });// new { regist_id = uid + "", data = m, city_id = city_id });
        }
        /// <summary>
        /// 设置转发状态
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static StatusResp SetStatus(int id, int stat)
        {
            return doapi<StatusResp>("/robot/regist/upstatus", new { regist_id = id + "", stat = stat });
        }
        /// <summary>
        /// 获取城市列表
        /// </summary>
        /// <returns></returns>
        public static CityResp LoadCity()
        {
            return doapi<CityResp>("http://ldgl.loupan.com:8092/ld/InitCity", null, false);
        }
    }

    public class StatusResp : Resp
    {
        public string url { get; set; }
    }
    public class SubmitResp : Resp
    {
        public Msg Data { get; set; }
    }

    public class MsgResp : Resp
    {
        public List<Msg> Data { get; set; }
        public page Page { get; set; }
    }

    public class page
    {
        public int RAllCnt { get; set; }
        public int RIndex { get; set; }
    }

    public class CityResp : Resp
    {
        public List<City> Data { get; set; }
        public page Page { get; set; }
    }

    public class City
    {
        public int id { get; set; }
        public string name { get; set; }
        public override string ToString()
        {
            return name;
        }
    }

    public class Msg
    {
        /// <summary>
        /// 城市id
        /// </summary>
        public int city_id { get; set; }
        /// <summary>
        /// 楼盘名
        /// </summary>
        public string build_name { get; set; }
        /// <summary>
        /// 消息内容
        /// </summary>
        public string data { get; set; }
        /// <summary>
        /// 二维码地址
        /// </summary>
        public string short_url { get; set; }
        /// <summary>
        /// 发送人
        /// </summary>
        public string regist_user_id { get; set; }
        /// <summary>
        /// 报备id
        /// </summary>
        public int regist_id { get; set; }
    }

    public class Resp
    {
        public string RCode { get; set; }
        public string RMessage { get; set; }
    }
}


text:
package com.mariten.kanatools;
import com.mariten.kanatools.KanaAppraiser;

import java.util.HashMap;
import java.util.Map;

/**
  * Provides easy, automatic string conversions often necessary when dealing with Japanese text
  *
  * Port of PHP's "mb_convert_kana" function for Java.
  * http://www.php.net/manual/en/function.mb-convert-kana.php
  */
public class KanaConverter
{
    // Conversion Operations Types
    //// Matched numeric values to originals in PHP's source code
    //// https://github.com/php/php-src/blob/a84e5dc37dc0ff8c313164d9db141d3d9f2b2730/ext/mbstring/mbstring.c#L3434
    public static final int OP_HAN_ASCII_TO_ZEN_ASCII      = 0x00000001;
    public static final int OP_HAN_LETTER_TO_ZEN_LETTER    = 0x00000002;
    public static final int OP_HAN_NUMBER_TO_ZEN_NUMBER    = 0x00000004;
    public static final int OP_HAN_SPACE_TO_ZEN_SPACE      = 0x00000008;
    public static final int OP_HAN_KATA_TO_ZEN_KATA        = 0x00000100;
    public static final int OP_HAN_KATA_TO_ZEN_HIRA        = 0x00000200;
    public static final int OP_KEEP_DIACRITIC_MARKS_APART  = 0x00100000;
    public static final int OP_ZEN_ASCII_TO_HAN_ASCII      = 0x00000010;
    public static final int OP_ZEN_LETTER_TO_HAN_LETTER    = 0x00000020;
    public static final int OP_ZEN_NUMBER_TO_HAN_NUMBER    = 0x00000040;
    public static final int OP_ZEN_SPACE_TO_HAN_SPACE      = 0x00000080;
    public static final int OP_ZEN_KATA_TO_HAN_KATA        = 0x00001000;
    public static final int OP_ZEN_HIRA_TO_HAN_KATA        = 0x00002000;
    public static final int OP_ZEN_HIRA_TO_ZEN_KATA        = 0x00010000;
    public static final int OP_ZEN_KATA_TO_ZEN_HIRA        = 0x00020000;

    //// Maintain backwards compatibility (based on mb_convert_kana's "$option" parameter from PHP)
    //// Details: http://php.net/manual/en/function.mb-convert-kana.php
    public static final Map<Character, Integer> LETTER_OP_CODE_LOOKUP;
    static {
        LETTER_OP_CODE_LOOKUP = new HashMap<Character, Integer>();
        LETTER_OP_CODE_LOOKUP.put('A', OP_HAN_ASCII_TO_ZEN_ASCII);
        LETTER_OP_CODE_LOOKUP.put('a', OP_ZEN_ASCII_TO_HAN_ASCII);
        LETTER_OP_CODE_LOOKUP.put('C', OP_ZEN_HIRA_TO_ZEN_KATA);
        LETTER_OP_CODE_LOOKUP.put('c', OP_ZEN_KATA_TO_ZEN_HIRA);
        LETTER_OP_CODE_LOOKUP.put('H', OP_HAN_KATA_TO_ZEN_HIRA);
        LETTER_OP_CODE_LOOKUP.put('h', OP_ZEN_HIRA_TO_HAN_KATA);
        LETTER_OP_CODE_LOOKUP.put('K', OP_HAN_KATA_TO_ZEN_KATA);
        LETTER_OP_CODE_LOOKUP.put('k', OP_ZEN_KATA_TO_HAN_KATA);
        LETTER_OP_CODE_LOOKUP.put('N', OP_HAN_NUMBER_TO_ZEN_NUMBER);
        LETTER_OP_CODE_LOOKUP.put('n', OP_ZEN_NUMBER_TO_HAN_NUMBER);
        LETTER_OP_CODE_LOOKUP.put('R', OP_HAN_LETTER_TO_ZEN_LETTER);
        LETTER_OP_CODE_LOOKUP.put('r', OP_ZEN_LETTER_TO_HAN_LETTER);
        LETTER_OP_CODE_LOOKUP.put('S', OP_HAN_SPACE_TO_ZEN_SPACE);
        LETTER_OP_CODE_LOOKUP.put('s', OP_ZEN_SPACE_TO_HAN_SPACE);
    }

    //{{{ String convertKana(String, int, String)
    /**
      * Converts a string containing kana or other characters used in Japanese text input
      * according to one or more requested conversion methods.
      *
      * @param  original_string  Input string to perform conversion on
      * @param  conversion_ops   Flag-based integer indicating which type of conversions to perform
      * @param  chars_to_ignore  Each character in this string will be excluded from conversion
      * @return Content of "original_string" with specified conversions performed
      */
    public static String convertKana(String original_string, int conversion_ops, String chars_to_ignore)
    {
        // Don't perform conversions on empty string
        if(original_string.equals("")) {
            return "";
        }

        // Return original if no conversion requested
        if(conversion_ops <= 0) {
            return original_string;
        }

        boolean do_collapse_on_hankaku_diacritic = true;
        if((conversion_ops & OP_KEEP_DIACRITIC_MARKS_APART) != 0) {
            // Do not glue hankaku katakana diacritic symbols when converting to zenkaku.
            // Use with 'K' or 'H'
            do_collapse_on_hankaku_diacritic = false;
        }

        int char_count = original_string.length();
        StringBuffer new_string = new StringBuffer();
        int i = 0;
        while(i < char_count) {
            // Init char holders for this round
            char this_char = original_string.charAt(i);
            char current_char = this_char;
            char hankaku_diacritic_suffix = 0;
            char next_char = 0;
            if(i < (char_count - 1)) {
                next_char = original_string.charAt(i + 1);
            }

            // Skip all conversions if character is on the excluded chars list
            boolean is_ignore_char = isIgnoreChar(current_char, chars_to_ignore);
            if(is_ignore_char) {
                new_string.append(current_char);
                i++;
                continue;
            }

            // Order of conversion operations written to be similar to original PHP
            //// Source: https://github.com/php/php-src/blob/128eda843f7dff487fff529a384fee3c5494e0f6/ext/mbstring/libmbfl/filters/mbfilter_tl_jisx0201_jisx0208.c#L41
            if(0 != (conversion_ops & OP_HAN_ASCII_TO_ZEN_ASCII)) {
                current_char = convertHankakuAsciiToZenkakuAscii(current_char);
            }

            if(current_char == this_char
            && 0 != (conversion_ops & OP_HAN_LETTER_TO_ZEN_LETTER)) {
                current_char = convertHankakuLetterToZenkakuLetter(current_char);
            }

            if(current_char == this_char
            && 0 != (conversion_ops & OP_HAN_NUMBER_TO_ZEN_NUMBER)) {
                current_char = convertHankakuNumberToZenkakuNumber(current_char);
            }

            if(current_char == this_char
            && 0 != (conversion_ops & OP_HAN_SPACE_TO_ZEN_SPACE)) {
                current_char = convertHankakuSpaceToZenkakuSpace(current_char);
            }

            if(current_char == this_char
            && (0 != (conversion_ops & OP_HAN_KATA_TO_ZEN_KATA)
            ||  0 != (conversion_ops & OP_HAN_KATA_TO_ZEN_HIRA))) {
                char collapsed_char_for_check = current_char;
                boolean performed_hankaku_conversion = false;
                if(do_collapse_on_hankaku_diacritic) {
                    // Check if current character requires the collapsing of a diacritic mark
                    collapsed_char_for_check = convertDiacriticHankakuKanaToZenkaku(current_char, next_char);
                }

                if(collapsed_char_for_check != current_char) {
                    // Use collapsed result
                    current_char = collapsed_char_for_check;
                    performed_hankaku_conversion = true;

                    // Do not include next character in final result string because
                    // it is a hankaku-only diacritic mark that isn't needed after conversion to zenkaku
                    i++;
                }
                else {
                    // Use result from hankaku-kana unvoiced mapping
                    char converted_current_char = convertUnvoicedHankakuKanaToZenkaku(current_char);
                    if(converted_current_char != current_char) {
                        current_char = converted_current_char;
                        performed_hankaku_conversion = true;
                    }
                }

                if(performed_hankaku_conversion
                && 0 == (conversion_ops & OP_HAN_KATA_TO_ZEN_KATA)) {
                    // If request is not for katakana, perform additional kata->hira conversion
                    current_char = convertZenkakuKatakanaToZenkakuHiragana(current_char);
                }
            }

            if(current_char == this_char
            && 0 != (conversion_ops & OP_ZEN_ASCII_TO_HAN_ASCII)) {
                current_char = convertZenkakuAsciiToHankakuAscii(current_char);
            }

            if(current_char == this_char
            && 0 != (conversion_ops & OP_ZEN_LETTER_TO_HAN_LETTER)) {
                current_char = convertZenkakuLetterToHankakuLetter(current_char);
            }

            if(current_char == this_char
            && 0 != (conversion_ops & OP_ZEN_NUMBER_TO_HAN_NUMBER)) {
                current_char = convertZenkakuNumberToHankakuNumber(current_char);
            }

            if(current_char == this_char
            && 0 != (conversion_ops & OP_ZEN_SPACE_TO_HAN_SPACE)) {
                current_char = convertZenkakuSpaceToHankakuSpace(current_char);
            }

            if(current_char == this_char
            && 0 != (conversion_ops & OP_ZEN_KATA_TO_HAN_KATA)) {
                hankaku_diacritic_suffix = determineHankakuDiacriticSuffix(current_char);
                current_char = convertZenkakuKatakanaToHankakuKatakana(current_char);
            }

            // Check if current character is a zenkaku katakana character
            char full_katakana_to_hiragana_result = convertZenkakuKatakanaToZenkakuHiragana(current_char);

            // Do not enter this block if the current character is a zenkaku katakana character, no matter the flags
            // Protects against katakana characters being incorrectly converted by zen-hiragana to han-katakana logic
            if(current_char == this_char
            && full_katakana_to_hiragana_result == current_char
            && (0 != (conversion_ops & OP_ZEN_HIRA_TO_ZEN_KATA)
            ||  0 != (conversion_ops & OP_ZEN_HIRA_TO_HAN_KATA))) {
                // First convert from full hiragana to full katakana
                current_char = convertZenkakuHiraganaToZenkakuKatakana(current_char);

                if(0 != (conversion_ops & OP_ZEN_HIRA_TO_HAN_KATA)) {
                    // Proceed to convert to hankaku if requested (skip if zen-kata to han-kata conversion was already performed)
                    hankaku_diacritic_suffix = determineHankakuDiacriticSuffix(current_char);
                    current_char = convertZenkakuKatakanaToHankakuKatakana(current_char);
                }
            }

            if(current_char == this_char
            && 0 != (conversion_ops & OP_ZEN_KATA_TO_ZEN_HIRA)) {
                current_char = full_katakana_to_hiragana_result;
            }

            // Add converted character to output string buffer
            new_string.append(current_char);

            // Add hankaku diacritic mark if necessary (only for zen-to-han kana conversions)
            if(hankaku_diacritic_suffix == HANKAKU_VOICED_MARK
            || hankaku_diacritic_suffix == HANKAKU_ASPIRATED_MARK) {
                new_string.append(hankaku_diacritic_suffix);
            }

            // Proceed with loop
            i++;
        }

        return new_string.toString();
    }
    //}}}
    //{{{ String convertKana(String, int)
    /**
      * Converts a string containing kana or other characters used in Japanese text input
      * according to one or more requested conversion methods.
      *
      * @param  original_string  Input string to perform conversion on
      * @param  conversion_ops   Flag-based integer indicating which type of conversions to perform
      * @return Content of "original_string" with specified conversions performed
      */
    public static String convertKana(String original_string, int conversion_ops)
    {
        return convertKana(original_string, conversion_ops, "");
    }
    //}}}
    //{{{ String convertKana(String, String, String)
    /**
      * Converts a string containing kana or other characters used in Japanese text input
      * according to one or more requested conversion methods.
      *
      * @param  original_string         Input string to perform conversion on
      * @param  conversion_ops_string   PHP mb_convert_kana style string specifying desired conversions
      * @param  chars_to_ignore         Each character in this string will be excluded from conversion
      * @return Content of "original_string" with specified conversions performed
      */
    public static String convertKana(String original_string, String conversion_ops_string, String chars_to_ignore)
    {
        int conversion_ops = createOpsArrayFromString(conversion_ops_string);
        return convertKana(original_string, conversion_ops, chars_to_ignore);
    }
    //}}}
    //{{{ String convertKana(String, String)
    /**
      * Converts a string containing kana or other characters used in Japanese text input
      * according to one or more requested conversion methods.
      *
      * @param  original_string         Input string to perform conversion on
      * @param  conversion_ops_string   PHP mb_convert_kana style string specifying desired conversions
      * @return Content of "original_string" with specified conversions performed
      */
    public static String convertKana(String original_string, String conversion_ops_string)
    {
        return convertKana(original_string, conversion_ops_string, "");
    }
    //}}}

    //{{{ Hankaku Katakana related mappings
    // Diacritic constants
    public static final char HANKAKU_VOICED_MARK    = '゙';  // dakuten
    public static final char HANKAKU_ASPIRATED_MARK = '゚';  // handakuten

    protected static final Map<Character, Character> MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED;
    static {
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED = new HashMap<Character, Character>();
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('。', '。');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('「', '「');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('」', '」');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('、', '、');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('・', '・');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ヲ', 'ヲ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ァ', 'ァ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ィ', 'ィ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ゥ', 'ゥ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ェ', 'ェ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ォ', 'ォ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ャ', 'ャ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ュ', 'ュ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ョ', 'ョ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ッ', 'ッ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ー', 'ー');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ア', 'ア');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('イ', 'イ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ウ', 'ウ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('エ', 'エ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('オ', 'オ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('カ', 'カ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('キ', 'キ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ク', 'ク');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ケ', 'ケ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('コ', 'コ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('サ', 'サ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('シ', 'シ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ス', 'ス');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('セ', 'セ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ソ', 'ソ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('タ', 'タ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('チ', 'チ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ツ', 'ツ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('テ', 'テ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ト', 'ト');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ナ', 'ナ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ニ', 'ニ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ヌ', 'ヌ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ネ', 'ネ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ノ', 'ノ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ハ', 'ハ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ヒ', 'ヒ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('フ', 'フ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ヘ', 'ヘ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ホ', 'ホ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('マ', 'マ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ミ', 'ミ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ム', 'ム');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('メ', 'メ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('モ', 'モ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ヤ', 'ヤ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ユ', 'ユ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ヨ', 'ヨ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ラ', 'ラ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('リ', 'リ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ル', 'ル');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('レ', 'レ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ロ', 'ロ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ワ', 'ワ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('ン', 'ン');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('゙', '゛');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.put('゚', '゜');
    }

    protected static final Map<Character, Character> MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED;
    static {
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED = new HashMap<Character, Character>();
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('カ', 'ガ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('キ', 'ギ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('ク', 'グ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('ケ', 'ゲ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('コ', 'ゴ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('サ', 'ザ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('シ', 'ジ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('ス', 'ズ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('セ', 'ゼ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('ソ', 'ゾ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('タ', 'ダ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('チ', 'ヂ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('ツ', 'ヅ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('テ', 'デ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('ト', 'ド');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('ハ', 'バ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('ヒ', 'ビ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('フ', 'ブ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('ヘ', 'ベ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.put('ホ', 'ボ');
    }

    protected static final Map<Character, Character> MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_ASPIRATED;
    static {
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_ASPIRATED = new HashMap<Character, Character>();
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_ASPIRATED.put('ハ', 'パ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_ASPIRATED.put('ヒ', 'ピ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_ASPIRATED.put('フ', 'プ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_ASPIRATED.put('ヘ', 'ペ');
        MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_ASPIRATED.put('ホ', 'ポ');
    }

    protected static final Map<Character, Character> MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA;
    static {
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA = new HashMap<Character, Character>();
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('。', '。');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('「', '「');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('」', '」');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('、', '、');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('・', '・');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ァ', 'ァ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ィ', 'ィ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ゥ', 'ゥ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ェ', 'ェ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ォ', 'ォ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ャ', 'ャ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ュ', 'ュ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ョ', 'ョ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ッ', 'ッ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ー', 'ー');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ア', 'ア');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('イ', 'イ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ウ', 'ウ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ヴ', 'ウ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('エ', 'エ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('オ', 'オ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('カ', 'カ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ガ', 'カ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('キ', 'キ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ギ', 'キ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ク', 'ク');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('グ', 'ク');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ケ', 'ケ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ゲ', 'ケ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('コ', 'コ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ゴ', 'コ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('サ', 'サ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ザ', 'サ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('シ', 'シ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ジ', 'シ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ス', 'ス');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ズ', 'ス');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('セ', 'セ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ゼ', 'セ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ソ', 'ソ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ゾ', 'ソ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('タ', 'タ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ダ', 'タ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('チ', 'チ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ヂ', 'チ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ツ', 'ツ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ヅ', 'ツ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('テ', 'テ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('デ', 'テ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ト', 'ト');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ド', 'ト');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ナ', 'ナ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ニ', 'ニ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ヌ', 'ヌ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ネ', 'ネ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ノ', 'ノ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ハ', 'ハ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('バ', 'ハ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('パ', 'ハ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ヒ', 'ヒ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ビ', 'ヒ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ピ', 'ヒ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('フ', 'フ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ブ', 'フ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('プ', 'フ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ヘ', 'ヘ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ベ', 'ヘ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ペ', 'ヘ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ホ', 'ホ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ボ', 'ホ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ポ', 'ホ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('マ', 'マ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ミ', 'ミ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ム', 'ム');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('メ', 'メ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('モ', 'モ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ヤ', 'ヤ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ユ', 'ユ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ヨ', 'ヨ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ラ', 'ラ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('リ', 'リ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ル', 'ル');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('レ', 'レ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ロ', 'ロ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ワ', 'ワ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ヮ', 'ワ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ヰ', 'イ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ヱ', 'エ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ヲ', 'ヲ');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('ン', 'ン');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('゛', '゙');
        MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.put('゜', '゚');
    }

    protected static final Map<Character, Character> MAPPING_HANKAKU_DIACRITIC_SUFFIXES;
    static {
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES = new HashMap<Character, Character>();
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ヴ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ガ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ギ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('グ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ゲ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ゴ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ザ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ジ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ズ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ゼ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ゾ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ダ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ヂ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ヅ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('デ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ド', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('バ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ビ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ブ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ベ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ボ', HANKAKU_VOICED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('パ', HANKAKU_ASPIRATED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ピ', HANKAKU_ASPIRATED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('プ', HANKAKU_ASPIRATED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ペ', HANKAKU_ASPIRATED_MARK);
        MAPPING_HANKAKU_DIACRITIC_SUFFIXES.put('ポ', HANKAKU_ASPIRATED_MARK);
    }
    //}}}

    // Connect mapping of hiragana and katakana char codes
    public static final int OFFSET_ZENKAKU_HIRAGANA_TO_ZENKAKU_KATAKANA =
    (KanaAppraiser.ZENKAKU_KATAKANA_FIRST - KanaAppraiser.ZENKAKU_HIRAGANA_FIRST);

    // Connect mapping of regular ASCII characters to Zenkaku ASCII characters
    public static final int OFFSET_HANKAKU_ASCII_TO_ZENKAKU_ASCII =
    (KanaAppraiser.ZENKAKU_ASCII_FIRST - KanaAppraiser.HANKAKU_ASCII_FIRST);

    //{{{ char convertHankakuAsciiToZenkakuAscii(char)
    protected static char convertHankakuAsciiToZenkakuAscii(char target)
    {
        if(KanaAppraiser.isHankakuAscii(target)) {
            return (char)(target + OFFSET_HANKAKU_ASCII_TO_ZENKAKU_ASCII);
        } else if(target == KanaAppraiser.HANKAKU_SPACE) {
            return KanaAppraiser.ZENKAKU_SPACE;
        } else {
            return target;
        }
    }
    //}}}

    //{{{ char convertZenkakuAsciiToHankakuAscii(char)
    protected static char convertZenkakuAsciiToHankakuAscii(char target)
    {
        if(KanaAppraiser.isZenkakuAscii(target)) {
            return (char)(target - OFFSET_HANKAKU_ASCII_TO_ZENKAKU_ASCII);
        } else if(target == KanaAppraiser.ZENKAKU_SPACE) {
            return KanaAppraiser.HANKAKU_SPACE;
        } else {
            return target;
        }
    }
    //}}}

    //{{{ char convertZenkakuHiraganaToZenkakuKatakana(char)
    protected static char convertZenkakuHiraganaToZenkakuKatakana(char target)
    {
        if(KanaAppraiser.isZenkakuHiraganaWithKatakanaEquivalent(target)) {
            return (char)(target + OFFSET_ZENKAKU_HIRAGANA_TO_ZENKAKU_KATAKANA);
        } else {
            return target;
        }
    }
    //}}}

    //{{{ char convertZenkakuKatakanaToZenkakuHiragana(char)
    protected static char convertZenkakuKatakanaToZenkakuHiragana(char target)
    {
        if(KanaAppraiser.isZenkakuKatakanaWithHiraganaEquivalent(target)) {
            return (char)(target - OFFSET_ZENKAKU_HIRAGANA_TO_ZENKAKU_KATAKANA);
        } else {
            return target;
        }
    }
    //}}}

    //{{{ char convertUnvoicedHankakuKanaToZenkaku(char)
    protected static char convertUnvoicedHankakuKanaToZenkaku(char target)
    {
        if(MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.containsKey(target)) {
            // Return character from *unvoiced* han-to-zen mapping
            return MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_UNVOICED.get(target);
        }
        else {
            return target;
        }
    }
    //}}}

    //{{{ char convertDiacriticHankakuKanaToZenkaku(char)
    protected static char convertDiacriticHankakuKanaToZenkaku(char target, char diacritic_mark)
    {
        if(diacritic_mark == HANKAKU_VOICED_MARK
        && MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.containsKey(target)) {
            // Use character from *voiced* han-to-zen mapping
            return MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_VOICED.get(target);
        }

        if(diacritic_mark == HANKAKU_ASPIRATED_MARK
        && MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_ASPIRATED.containsKey(target)) {
            // Use character from *aspirated* han-to-zen mapping
            return MAPPING_HANKAKU_TO_ZENKAKU_KATAKANA_ASPIRATED.get(target);
        }

        // Not a voiced/aspirated hankaku katakana character, use original
        return target;
    }
    //}}}

    //{{{ char convertZenkakuKatakanaToHankakuKatakana(char)
    protected static char convertZenkakuKatakanaToHankakuKatakana(char target)
    {
        if(MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.containsKey(target)) {
            // Return character from mapped from zen-to-han
            return MAPPING_ZENKAKU_TO_HANKAKU_KATAKANA.get(target);
        } else {
            return target;
        }
    }
    //}}}

    //{{{ char determineHankakuDiacriticSuffix(char)
    protected static char determineHankakuDiacriticSuffix(char target)
    {
        if(MAPPING_HANKAKU_DIACRITIC_SUFFIXES.containsKey(target)) {
            return MAPPING_HANKAKU_DIACRITIC_SUFFIXES.get(target);
        } else {
            return 0;
        }
    }
    //}}}

    //{{{ char convertHankakuNumberToZenkakuNumber(char)
    protected static char convertHankakuNumberToZenkakuNumber(char target)
    {
        if(KanaAppraiser.isHankakuNumber(target)) {
            // Offset by difference in char-code position
            return (char)(target + OFFSET_HANKAKU_ASCII_TO_ZENKAKU_ASCII);
        } else {
            return target;
        }
    }
    //}}}

    //{{{ char convertZenkakuNumberToHankakuNumber(char)
    protected static char convertZenkakuNumberToHankakuNumber(char target)
    {
        if(KanaAppraiser.isZenkakuNumber(target)) {
            // Offset by difference in char-code position
            return (char)(target - OFFSET_HANKAKU_ASCII_TO_ZENKAKU_ASCII);
        } else {
            return target;
        }
    }
    //}}}

    //{{{ char convertHankakuLetterToZenkakuLetter(char)
    protected static char convertHankakuLetterToZenkakuLetter(char target)
    {
        if(KanaAppraiser.isHankakuLetter(target)) {
            return (char)(target + OFFSET_HANKAKU_ASCII_TO_ZENKAKU_ASCII);
        } else {
            return target;
        }
    }
    //}}}

    //{{{ char convertZenkakuLetterToHankakuLetter(char)
    protected static char convertZenkakuLetterToHankakuLetter(char target)
    {
        if(KanaAppraiser.isZenkakuLetter(target)) {
            return (char)(target - OFFSET_HANKAKU_ASCII_TO_ZENKAKU_ASCII);
        } else {
            return target;
        }
    }
    //}}}

    //{{{ char convertHankakuSpaceToZenkakuSpace(char)
    protected static char convertHankakuSpaceToZenkakuSpace(char target)
    {
        if(target == KanaAppraiser.HANKAKU_SPACE) {
            return KanaAppraiser.ZENKAKU_SPACE;
        } else {
            return target;
        }
    }
    //}}}

    //{{{ char convertZenkakuSpaceToHankakuSpace(char)
    protected static char convertZenkakuSpaceToHankakuSpace(char target)
    {
        if(target == KanaAppraiser.ZENKAKU_SPACE) {
            return KanaAppraiser.HANKAKU_SPACE;
        } else {
            return target;
        }
    }
    //}}}

    //{{{ boolean isIgnoreChar(char, String)
    protected static boolean isIgnoreChar(char char_to_check, String chars_to_ignore)
    {
        int ignore_char_count = chars_to_ignore.length();
        for(int i = 0; i < ignore_char_count; i++) {
            if(char_to_check == chars_to_ignore.charAt(i)) {
                // Matched
                return true;
            }
        }

        // No matches
        return false;
    }
    //}}}

    //{{{ int createOpsArrayFromString(String)
    private static int createOpsArrayFromString(String php_style_options_string)
    {
        int char_op_count = php_style_options_string.length();
        int conversion_op_flags = 0;
        for(int i = 0; i < char_op_count; i++) {
            char php_style_op_code = php_style_options_string.charAt(i);
            if(LETTER_OP_CODE_LOOKUP.containsKey(php_style_op_code)) {
                conversion_op_flags |= LETTER_OP_CODE_LOOKUP.get(php_style_op_code);
            }
        }
        return conversion_op_flags;
    }
    //}}}
}


text:
import React, { FormEvent, useState, useCallback, useEffect } from 'react';
import {
  TimeZone,
  isDateTime,
  TimeRange,
  DateTime,
  dateMath,
  dateTimeFormat,
  dateTimeParse,
  rangeUtil,
  RawTimeRange,
} from '@savantly/sprout-api';
import { TimePickerCalendar } from './TimePickerCalendar';
import { Field } from '../../Forms/Field';
import { Input } from '../../Input/Input';
import { Button } from '../../Button';

interface Props {
  isFullscreen: boolean;
  value: TimeRange;
  onApply: (range: TimeRange) => void;
  timeZone?: TimeZone;
  roundup?: boolean;
  isReversed?: boolean;
}

interface InputState {
  value: string;
  invalid: boolean;
}

const errorMessage = 'Please enter a past date or "now"';

export const TimeRangeForm: React.FC<Props> = props => {
  const { value, isFullscreen = false, timeZone, roundup } = props;

  const [from, setFrom] = useState<InputState>(valueToState(value.raw.from, false, timeZone));
  const [to, setTo] = useState<InputState>(valueToState(value.raw.to, true, timeZone));
  const [isOpen, setOpen] = useState(false);

  // Synchronize internal state with external value
  useEffect(() => {
    setFrom(valueToState(value.raw.from, false, timeZone));
    setTo(valueToState(value.raw.to, true, timeZone));
  }, [value.raw.from, value.raw.to, timeZone]);

  const onOpen = useCallback(
    (event: FormEvent<HTMLElement>) => {
      event.preventDefault();
      setOpen(true);
    },
    [setOpen]
  );

  const onFocus = useCallback(
    (event: FormEvent<HTMLElement>) => {
      if (!isFullscreen) {
        return;
      }
      onOpen(event);
    },
    [isFullscreen, onOpen]
  );

  const onApply = useCallback(
    (e: FormEvent<HTMLButtonElement>) => {
      e.preventDefault();
      if (to.invalid || from.invalid) {
        return;
      }

      const raw: RawTimeRange = { from: from.value, to: to.value };
      const timeRange = rangeUtil.convertRawToRange(raw, timeZone);

      props.onApply(timeRange);
    },
    [from, to, roundup, timeZone]
  );

  const onChange = useCallback(
    (from: DateTime, to: DateTime) => {
      setFrom(valueToState(from, false, timeZone));
      setTo(valueToState(to, true, timeZone));
    },
    [timeZone]
  );

  const icon = isFullscreen ? null : <Button icon="calendar-alt" variant="secondary" onClick={onOpen} />;

  return (
    <>
      <Field label="From" invalid={from.invalid} error={errorMessage}>
        <Input
          onClick={event => event.stopPropagation()}
          onFocus={onFocus}
          onChange={event => setFrom(eventToState(event, false, timeZone))}
          addonAfter={icon}
          aria-label="TimePicker from field"
          value={from.value}
        />
      </Field>
      <Field label="To" invalid={to.invalid} error={errorMessage}>
        <Input
          onClick={event => event.stopPropagation()}
          onFocus={onFocus}
          onChange={event => setTo(eventToState(event, true, timeZone))}
          addonAfter={icon}
          aria-label="TimePicker to field"
          value={to.value}
        />
      </Field>
      <Button aria-label="TimePicker submit button" onClick={onApply}>
        Apply time range
      </Button>

      <TimePickerCalendar
        isFullscreen={isFullscreen}
        isOpen={isOpen}
        from={dateTimeParse(from.value, { timeZone })}
        to={dateTimeParse(to.value, { timeZone })}
        onApply={onApply}
        onClose={() => setOpen(false)}
        onChange={onChange}
        timeZone={timeZone}
        isReversed={props.isReversed}
      />
    </>
  );
};

function eventToState(event: FormEvent<HTMLInputElement>, roundup?: boolean, timeZone?: TimeZone): InputState {
  return valueToState(event.currentTarget.value, roundup, timeZone);
}

function valueToState(raw: DateTime | string, roundup?: boolean, timeZone?: TimeZone): InputState {
  const value = valueAsString(raw, timeZone);
  const invalid = !isValid(value, roundup, timeZone);
  return { value, invalid };
}

function valueAsString(value: DateTime | string, timeZone?: TimeZone): string {
  if (isDateTime(value)) {
    return dateTimeFormat(value, { timeZone });
  }
  return value;
}

function isValid(value: string, roundUp?: boolean, timeZone?: TimeZone): boolean {
  if (isDateTime(value)) {
    return value.isValid();
  }

  if (dateMath.isMathString(value)) {
    return dateMath.isValid(value);
  }

  const parsed = dateTimeParse(value, { roundUp, timeZone });
  return parsed.isValid();
}


text:
.. _npm6001_ek_sample:

nPM6001 EK sample
#################

Overview
********

This sample is provided as an example to test the :ref:`npm6001_ek`. The sample
provides a shell interface that allows to test multiple functionalities offered
by the nPM6001 PMIC, including:

- GPIO
- Watchdog

Requirements
************

The shield needs to be wired to a host board supporting the Arduino connector.
Below you can find a wiring example for the nRF52840 DK:

.. figure:: nrf52840dk_wiring.jpg
   :alt: nRF52840DK + nPM6001-EK wiring example
   :align: center

   nRF52840DK + nPM6001-EK wiring example

Building and Running
********************

The sample is designed so that it can run on any platform. For example, when
building for the nRF52840 DK, the following command can be used:

.. zephyr-app-commands::
   :zephyr-app: samples/shields/npm6001_ek
   :board: nrf52840dk_nrf52840
   :goals: build
   :compact:

Note that this sample automatically sets ``SHIELD`` to ``npm6001_ek``. Once
flashed, you should boot into the shell interface. The ``npm6001`` command is
provided to test the PMIC. Below you can find details for each subcommand.

GPIO
====

The ``npm6001`` shell interface provides the ``gpio`` subcommand to test the
GPIO functionality offered by the PMIC. Below you can find some command
examples.

.. code-block:: bash

   # configure GPIO 0 as output
   npm6001 gpio configure -p 0 -d out
   # configure GPIO 0 as output (init high)
   npm6001 gpio configure -p 0 -d outh
   # configure GPIO 0 as output (init low)
   npm6001 gpio configure -p 0 -d outl
   # configure GPIO 0 as output with high-drive mode enabled
   npm6001 gpio configure -p 0 -d out --high-drive
   # configure GPIO 1 as input
   npm6001 gpio configure -p 1 -d input
   # configure GPIO 1 as input with pull-down enabled
   npm6001 gpio configure -p 1 -d input --pull-down
   # configure GPIO 1 as input with CMOS mode enabled
   npm6001 gpio configure -p 1 -d input --cmos

.. code-block:: bash

   # get GPIO 1 level
   npm6001 gpio get 1

.. code-block:: bash

   # set GPIO 0 high
   npm6001 gpio set 0 1
   # set GPIO 0 low
   npm6001 gpio set 0 0

.. code-block:: bash

   # toggle GPIO 0
   npm6001 gpio toggle 0

Watchdog
========

The ``npm6001`` shell interface provides the ``wdt`` subcommand to test the
Watchdog functionality offered by the PMIC. Below you can find some command
examples.

.. code-block:: bash

   # enable watchdog, timeout set to 8 seconds. Timeout will be rounded up to
   # the resolution of the watchdog, e.g. 10s -> 12s.
   npm6001 wdt enable 8000
   # disable watchdog
   npm6001 wdt disable
   # kick/feed watchdog
   npm6001 wdt kick

.. note::
   When the watchdog reset pin is connected to your board reset, you will see
   how Zephyr reboots after the watchdog timeout expires.


text:
require 'dm-core'

require 'dm-aggregates/aggregate_functions'
require 'dm-aggregates/collection'
require 'dm-aggregates/core_ext/symbol'
require 'dm-aggregates/model'
require 'dm-aggregates/query'
require 'dm-aggregates/repository'

module DataMapper
  module Aggregates
    def self.include_aggregate_api
      [ :Repository, :Model, :Collection, :Query ].each do |name|
        DataMapper.const_get(name).send(:include, const_get(name))
      end
      Adapters::AbstractAdapter.descendants.each do |adapter_class|
        Adapters.include_aggregate_api(DataMapper::Inflector.demodulize(adapter_class.name))
      end
    end
  end

  module Adapters

    def self.include_aggregate_api(const_name)
      require aggregate_extensions(const_name)
      if Aggregates.const_defined?(const_name)
        adapter = const_get(const_name)
        adapter.send(:include, aggregate_module(const_name))
      end
    rescue LoadError
      # Silently ignore the fact that no adapter extensions could be required
      # This means that the adapter in use doesn't support aggregates
    end

    def self.aggregate_module(const_name)
      Aggregates.const_get(const_name)
    end

    class << self
    private
      # @api private
      def aggregate_extensions(const_name)
        name = adapter_name(const_name)
        name = 'do' if name == 'dataobjects'
        "dm-aggregates/adapters/dm-#{name}-adapter"
      end
    end

    extendable do
      # @api private
      def const_added(const_name)
        include_aggregate_api(const_name)
        super
      end
    end
  end # module Adapters

  Aggregates.include_aggregate_api

end # module DataMapper


text:
package mainPackage;

import javafx.event.EventHandler;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;

public class FilledOval implements Brush {
	private int size=Brush.DEFAULT_SIZE;
	private Color color;
	private double x1, x2, y1, y2;

	public FilledOval(){

	}

	@Override
	public void draw() {
		Frame.gc.setStroke(this.color);
		Frame.gc.setFill(this.color);
		// TODO Auto-generated method stub
		Frame.canvas.setOnMousePressed(new EventHandler<MouseEvent>(){
			@Override
			public void handle(MouseEvent e){
				x1 = e.getX();
				y1 = e.getY();
			}
		});
		Frame.canvas.setOnMouseDragged(new EventHandler<MouseEvent>(){
			@Override
			public void handle(MouseEvent e){

			}
		});
		Frame.canvas.setOnMouseReleased(new EventHandler<MouseEvent>(){
			@Override
			public void handle(MouseEvent e){
				x2 = e.getX();
				y2 = e.getY();
				if (x1<x2&&y1<y2)
					Frame.gc.fillOval(x1, y1, Math.abs(x2-x1), Math.abs(y2-y1));
				else if (x2<x1&&y1<y2)
					Frame.gc.fillOval(x2, y1, Math.abs(x2-x1), Math.abs(y2-y1));
				else if (x2<x1&&y2<y1)
					Frame.gc.fillOval(x2, y2, Math.abs(x2-x1), Math.abs(y2-y1));
				else if (x1<x2&&y2<y1)
					Frame.gc.fillOval(x1, y2, Math.abs(x2-x1), Math.abs(y2-y1));
			}
		});

	}

	@Override
	public void setSize(int size) {
		// TODO Auto-generated method stub
		this.size=size;
	}

	@Override
	public void setColor(Color color) {
		// TODO Auto-generated method stub
		this.color=color;
	}

	@Override
	public Color getColor() {
		return this.color;

	}
}


text:
package controllers

import (
	"PhotosShare/models"
	"errors"
	"goappuser"
	"goappuser/database"
	"goappuser/middlewares"
	"log"
	"mime/multipart"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"strconv"

	"github.com/gorilla/mux"
)

func check(err error, next func()) {
	if err != nil {
		log.Println("error uploading file", err)
		next()
	}
}

//MediaController represent media management controller
type MediaController struct {
	DomainBase string
	db         dbm.DatabaseQuerier
}

//BasePath base path used for the routes of the controller
func (m *MediaController) BasePath() string {
	return "/api/media"
}

//GetName Name of the controller
func (m *MediaController) GetName() string {
	return "MediaController"
}

//LoadController Middleware of the controller
func (m *MediaController) LoadController(r *mux.Router, db dbm.DatabaseQuerier) {
	m.db = db
	sub := r.PathPrefix(m.BasePath()).Subrouter()
	sub.Handle("/updateDB", middlewares.NewMiddlewaresFunc(m.CreatesMediasFromDirectory)).Methods("GET")
	sub.Handle("/random", middlewares.NewMiddlewaresFunc(m.GetRandomMedia)).Methods("GET")
	sub.Handle("/{page}", middlewares.NewMiddlewaresFunc(m.GetMedias)).Methods("GET")
	sub.Handle("/", middlewares.NewMiddlewaresFunc(m.UploadPrivateImage)).Methods("POST")
	sub.Handle("/", middlewares.NewMiddlewaresFunc(m.GetMedias)).Methods("GET")
}

//CreatesMediasFromDirectory generate Media model in DB from file in  "./static/images/"
func (m *MediaController) CreatesMediasFromDirectory(w http.ResponseWriter, r *http.Request, next func()) {
	filePath := "./static/images/"
	url := "/images/"
	filepath.Walk(filePath, func(path string, f os.FileInfo, err error) error {
		media := model.Media{}
		m.db.GetOneModel(dbm.M{"Name": f.Name()}, media)
		if media != (model.Media{}) {
			log.Println(media)
			return nil
		}
		media = model.Media{
			Name:          f.Name(),
			Path:          filePath,
			ThumbnailPath: filePath + "/thumbnail",
			URL:           url,
			ThumbnailURL:  url + "/thumbnail",
		}
		m.db.InsertModel(media)
		return nil
	})
	app.JSONResp(w, struct{ Response string }{"Ok"})
}

//GetMedias used to retriev 20 medias from the database, the page must be add in parameter
func (m *MediaController) GetMedias(w http.ResponseWriter, r *http.Request, next func()) {
	vars := mux.Vars(r)
	if pagestr := vars["page"]; pagestr == "" {
		pagestr = "0"
	} else if pagestr == "random" {
		next()
	} else {
		if page, err := strconv.Atoi(pagestr); err == nil {
			medias := make([]model.Media, 0, 40)
			if mediasInterface, err := m.db.GetModels(nil, medias, 40, page*40); err == nil {
				medias := mediasInterface.([]model.Media)
				for index, element := range medias {
					medias[index].URL = m.DomainBase + element.URL
					medias[index].ThumbnailURL = m.DomainBase + element.ThumbnailURL
				}
				app.JSONResp(w, medias)
			} else {
				log.Println(err)
				next()
			}
		} else {
			log.Println(err)
			next()
		}
	}
}

//DownloadMedias get all files name to DownloadMedias
// It will search in ./static.images the files
// It will zip them
// Open a dialog box to download
func (m *MediaController) DownloadMedias(w http.ResponseWriter, r *http.Request, next func()) {
	//Open Dialog box
	w.Header().Set("Content-Disposition", "attachment; filename=WHATEVER_YOU_WANT")
	w.Header().Set("Content-Type", r.Header.Get("Content-Type"))
}

//GetRandomMedia return an image choosed randomly in the Database
func (m *MediaController) GetRandomMedia(w http.ResponseWriter, r *http.Request, next func()) {
	media := &model.Media{}
	if dbMongo, ok := m.db.(*dbm.MongoDatabaseSession); ok == true {
		err := dbMongo.GetRandomOneModel(media)
		media.URL = m.DomainBase + media.URL
		media.ThumbnailURL = m.DomainBase + media.ThumbnailURL
		if err != nil {
			log.Println(err)
			app.JSONResp(w, app.RequestError{"Error random Image", "error while retrieve a random image", 1})
		} else {
			app.JSONResp(w, media)
		}
	}
}

//UploadPrivateImage Upload image to the filesystem
func (m *MediaController) UploadPrivateImage(w http.ResponseWriter, r *http.Request, next func()) {
	files, err := m.handleUploads(r)
	if err != nil {
		log.Println("error handleUploads", err)
		app.JSONResp(w, app.RequestError{"Error Upload", "Didn't Upload", 0})
	} else {
		var genralMedia []interface{}
		for _, elem := range files {
			genralMedia = append(genralMedia, elem)
		}
		errorsInsert := m.db.InsertModel(genralMedia...)
		for err := range errorsInsert {
			log.Println(err)
		}
		app.JSONResp(w, files)
	}
}

func (m *MediaController) handleUpload(r *http.Request, p *multipart.Part) (*model.Media, error) {
	filenameDecoded, _ := url.QueryUnescape(p.FileName())
	return model.NewMedia(p, filenameDecoded, "./static/images", "/images")
}

func (m *MediaController) handleUploads(r *http.Request) ([]*model.Media, error) {
	var filesInfos []*model.Media
	mr, err := r.MultipartReader()
	if err != nil {
		log.Println("error Getting MultipartReader", err)
		return nil, errors.New("Cannot read Multipart")
	}
	part, err := mr.NextPart()
	for err == nil {
		if name := part.FormName(); name != "" {
			if part.FileName() != "" {
				if mediaInfos, err := m.handleUpload(r, part); err == nil {
					filesInfos = append(filesInfos, mediaInfos)
				} else {
					log.Println("error handle file ", part.FileName(), "-->", err)
				}
			}
		}
		part, err = mr.NextPart()
	}
	return filesInfos, nil
}

func (m *MediaController) handleMultiPartForm(r *http.Request, formFields []string) ([]*model.Media, error) {
	var filesInfos []*model.Media
	r.ParseMultipartForm(int64(len(formFields) * model.MaxFileSize))
	for _, formField := range formFields {
		file, handler, err := r.FormFile(formField)
		if err != nil {
			log.Println("FormFile error ", err)
			continue
		}
		defer file.Close()
		filenameDecoded, _ := url.QueryUnescape(handler.Filename)
		fi, errorMedia := model.NewMedia(file, filenameDecoded, "./static/images", "/images")
		if errorMedia != nil {
			continue
		}
		filesInfos = append(filesInfos, fi)
	}
	return filesInfos, nil
}