text:
package com.zimbra.cs.dav.resource;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.dom4j.Element;
import org.json.JSONException;

import com.google.common.io.Closeables;
import com.zimbra.common.mailbox.ContactConstants;
import com.zimbra.common.mime.MimeConstants;
import com.zimbra.common.service.ServiceException;
import com.zimbra.common.util.ByteUtil;
import com.zimbra.common.util.ZimbraLog;
import com.zimbra.cs.account.Account;
import com.zimbra.cs.account.Provisioning;
import com.zimbra.cs.dav.DavContext;
import com.zimbra.cs.dav.DavElements;
import com.zimbra.cs.dav.DavException;
import com.zimbra.cs.dav.DavProtocol;
import com.zimbra.cs.dav.property.CardDavProperty;
import com.zimbra.cs.dav.property.ResourceProperty;
import com.zimbra.cs.index.ContactHit;
import com.zimbra.cs.index.SortBy;
import com.zimbra.cs.index.ZimbraHit;
import com.zimbra.cs.index.ZimbraQueryResults;
import com.zimbra.cs.mailbox.Contact;
import com.zimbra.cs.mailbox.ContactGroup;
import com.zimbra.cs.mailbox.ContactGroup.Member;
import com.zimbra.cs.mailbox.Folder;
import com.zimbra.cs.mailbox.MailItem;
import com.zimbra.cs.mailbox.Mailbox;
import com.zimbra.cs.mailbox.MailboxManager;
import com.zimbra.cs.service.FileUploadServlet;
import com.zimbra.cs.service.formatter.VCard;
import com.zimbra.cs.service.util.ItemId;

public class AddressObject extends MailItemResource {

    public static final String VCARD_EXTENSION = ".vcf";

    // for compatibility with Apple Address Book app.
    private static final String XABSKIND = "X-ADDRESSBOOKSERVER-KIND";
    private static final String XABSMEMBER = "X-ADDRESSBOOKSERVER-MEMBER";

    public AddressObject(DavContext ctxt, Contact item) throws ServiceException {
        super(ctxt, item);
        setProperty(DavElements.P_GETCONTENTTYPE, DavProtocol.VCARD_CONTENT_TYPE);

        // size is approximate.  it just has to be non-zero as the actual content
        // will be chunked to the client in GET response.
        setProperty(DavElements.P_GETCONTENTLENGTH, Integer.toString(item.getFields().size()));
    }

    @Override
    public boolean isCollection() {
        return false;
    }

    @Override
    public ResourceProperty getProperty(Element prop) {
        if (prop.getQName().equals(DavElements.CardDav.E_ADDRESS_DATA)) {
            return CardDavProperty.getAddressbookData(prop, this);
        }
        return super.getProperty(prop);
    }

    @Override
    public InputStream getContent(DavContext ctxt) throws DavException, IOException {
        try {
            return new ByteArrayInputStream(toVCard(ctxt).getBytes("UTF-8"));
        } catch (ServiceException e) {
            ZimbraLog.dav.warn("can't get content for Contact %d", mId, e);
        }
        return null;
    }

    private static void constructContactGroupFromAppleXProps(DavContext ctxt, Account ownerAccount, VCard vcard, Contact existingContact, int folderId) {
        Map<String, String> xprops = Contact.decodeXProps(vcard.fields.get(ContactConstants.A_vCardXProps));
        String kind = xprops.get(XABSKIND);
        String memberList = xprops.get(XABSMEMBER);
        if (kind != null && kind.compareTo("group") == 0) {
            ContactGroup contactGroup;
            try {
                if (existingContact == null) // create
                    contactGroup = ContactGroup.init();
                else { // modify
                    contactGroup = ContactGroup.init(existingContact, true);
                    // remove all the contacts of type CONTACT_REF that belong to the collection same as the group
                    ArrayList<Member> membersToRemove = new ArrayList<Member>();
                    for (Member member : contactGroup.getMembers()) {
                        if (Member.Type.CONTACT_REF.equals(member.getType())) {
                            ItemId itemId = new ItemId(member.getValue(), existingContact.getAccount().getId());
                            if (itemId.belongsTo(existingContact.getAccount())) {
                                // make sure member belongs to the same collection as the group.
                                Contact c = getContactByUID(ctxt, itemId.toString(), existingContact.getAccount(), folderId);
                                if (c != null)
                                    membersToRemove.add(member);
                            }
                        }
                    }
                    for (Member member : membersToRemove)
                        contactGroup.removeMember(member.getType(), member.getValue());
                }
                if (memberList != null) {
                    try {
                        String[] members = Contact.parseMultiValueAttr(memberList);
                        for (String uidStr : members) {
                            if (uidStr.startsWith("urn:uuid:"))
                                uidStr = uidStr.substring(9);
                            Contact c = getContactByUID(ctxt, uidStr, ownerAccount, folderId);
                            if (c != null) {
                                // add to the group as a CONTACT_REF
                                ItemId itemId = new ItemId(c);
                                contactGroup.addMember(Member.Type.CONTACT_REF, itemId.toString());
                            }
                        }
                    } catch (JSONException e) {
                        ZimbraLog.dav.debug("can't parse xprop %s", memberList, e);
                    }
                }

                vcard.fields.put(ContactConstants.A_type, ContactConstants.TYPE_GROUP);
                vcard.fields.put(ContactConstants.A_groupMember, contactGroup.encode());
                // remove the Apple x-props and preserve the rest.
                xprops.remove(XABSKIND);
                xprops.remove(XABSMEMBER);
                vcard.fields.put(ContactConstants.A_vCardXProps, Contact.encodeXProps(xprops));
            } catch (ServiceException e) {
                ZimbraLog.dav.debug("can't parse xprop %s", memberList, e);
            }
        }
    }

    private static void populateContactGroupAppleXProps(DavContext ctxt, Contact contact) {
        if (contact.isContactGroup() == false)
            return;
        ContactGroup contactGroup = null;
        try {
            contactGroup = ContactGroup.init(contact.get(ContactConstants.A_groupMember));
        } catch (ServiceException e) {
            ZimbraLog.dav.warn("can't get group members for Contact %d", contact.getId(), e);
        }
        // get the x-props first.
        Map<String, String> xprops = contact.getXProps();
        xprops.put(XABSKIND, "group");
        if (contactGroup != null) {
            ArrayList<String> memberList = new ArrayList<String>(contactGroup.getMembers().size());
            try {
                for (Member member : contactGroup.getMembers()) {
                    if (member.getType().equals(Member.Type.CONTACT_REF)) {
                        ItemId itemId = new ItemId(member.getValue(), contact.getAccount().getId());
                        if (itemId.belongsTo(contact.getAccount())) {
                            // make sure member belongs to the same collection as the group.
                            Contact c = getContactByUID(ctxt, itemId.toString(), contact.getAccount(), contact.getFolderId());
                            if (c != null)
                                memberList.add("urn:uuid:" + VCard.getUid(c));
                        }
                    }
                }
                xprops.put(XABSMEMBER, Contact.encodeMultiValueAttr(memberList.toArray(new String[0])));
            } catch (JSONException e) {
                ZimbraLog.dav.warn("can't create group members xprops for Contact %d", contact.getId(), e);
            } catch (ServiceException e) {
                ZimbraLog.dav.warn("can't create group members xprops for Contact %d", contact.getId(), e);
            }
        }
        contact.setXProps(xprops);
    }

    public String toVCard(DavContext ctxt) throws ServiceException, DavException {
        Contact contact = (Contact)getMailItem(ctxt);
        populateContactGroupAppleXProps(ctxt, contact);
        return VCard.formatContact(contact, null, true, false).formatted;
    }
    public String toVCard(DavContext ctxt, java.util.Collection<String> attrs) throws ServiceException, DavException {
        if (attrs == null || attrs.isEmpty())
            return toVCard(ctxt);
        Contact contact = (Contact)getMailItem(ctxt);
        populateContactGroupAppleXProps(ctxt, contact);
        return VCard.formatContact(contact, attrs, true).formatted;
    }

    public static DavResource create(DavContext ctxt, String name, Collection where) throws DavException, IOException {
        FileUploadServlet.Upload upload = ctxt.getUpload();
        String buf = new String(ByteUtil.getContent(upload.getInputStream(), (int)upload.getSize()), MimeConstants.P_CHARSET_UTF8);
        Mailbox mbox = null;
        DavResource res = null;
        try {
            String url = ctxt.getItem();
            if (url.endsWith(".vcf"))
                url = url.substring(0, url.length()-4);
            mbox = where.getMailbox(ctxt);
            for (VCard vcard : VCard.parseVCard(buf)) {
                if (vcard.fields.isEmpty())
                    continue;
                vcard.fields.put(ContactConstants.A_vCardURL, url);
                String uid = vcard.uid;
                Account ownerAccount = Provisioning.getInstance().getAccountById(where.mOwnerId);
                Contact c = null;
                // check for existing contact
                if (uid != null) {
                    vcard.fields.put(ContactConstants.A_vCardUID, uid);
                    res = UrlNamespace.getResourceAt(ctxt, ctxt.getUser(), ctxt.getPath());
                }
                if (res == null) {
                    String ifnonematch = ctxt.getRequest().getHeader(DavProtocol.HEADER_IF_NONE_MATCH);
                    if (ifnonematch == null)
                        throw new DavException("item does not exists", HttpServletResponse.SC_CONFLICT);
                    // Convert Apple contact group to Zimbra contact group.
                    constructContactGroupFromAppleXProps(ctxt, ownerAccount, vcard, null, where.getId());
                    c = mbox.createContact(ctxt.getOperationContext(), vcard.asParsedContact(), where.mId, null);
                    res = new AddressObject(ctxt, c);
                    res.mNewlyCreated = true;
                } else {
                    String etag = ctxt.getRequest().getHeader(DavProtocol.HEADER_IF_MATCH);
                    String itemEtag = res.getEtag();
                    if (etag != null && !etag.equals(itemEtag))
                        throw new DavException("item etag does not match", HttpServletResponse.SC_CONFLICT);
                    MailItemResource mir = (MailItemResource) res;
                    constructContactGroupFromAppleXProps(ctxt, ownerAccount, vcard, (Contact) mir.getMailItem(ctxt), where.getId());
                    vcard.merge((Contact) mir.getMailItem(ctxt));
                    mbox.modifyContact(ctxt.getOperationContext(), mir.getId(), vcard.asParsedContact());
                    res = UrlNamespace.getResourceAt(ctxt, ctxt.getUser(), ctxt.getPath());
                }
            }
        } catch (ServiceException e) {
            throw new DavException.InvalidData(DavElements.CardDav.E_VALID_ADDRESS_DATA, "cannot parse vcard");
        }
        if (res == null)
            throw new DavException.InvalidData(DavElements.CardDav.E_VALID_ADDRESS_DATA, "cannot parse vcard");
        return res;
    }

    public static AddressObject getAddressObjectByUID(DavContext ctxt, String uid, Account account, Folder f) throws ServiceException {
        Contact c = getContactByUID(ctxt, uid, account, (f != null) ? f.getId() : -1);
        if (c == null)
            return null;
        return new AddressObject(ctxt, c);
    }

    public static AddressObject getAddressObjectByUID(DavContext ctxt, String uid, Account account) throws ServiceException {
        return getAddressObjectByUID(ctxt, uid, account, null);
    }

    private static Contact getContactByUID(DavContext ctxt, String uid, Account account, int folderId) throws ServiceException {
        Contact item = null;
        Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(account);
        if (uid.endsWith(AddressObject.VCARD_EXTENSION))
            uid = uid.substring(0, uid.length() - AddressObject.VCARD_EXTENSION.length());
        if (uid.indexOf('%') > 0) {
            try {
                uid = URLDecoder.decode(uid, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                ZimbraLog.dav.warn("Can't decode UID %s", uid);
            }
        }
        int id = 0;
        int index = uid.indexOf(':');
        if (index > 0) {
            String accountId = uid.substring(0, index);
            try {
                if (accountId.equals(account.getId()))
                    id = Integer.parseInt(uid.substring(index+1));
            } catch (NumberFormatException e) {
            }
        }
        if (id > 0) {
            item = mbox.getContactById(ctxt.getOperationContext(), Integer.parseInt(uid.substring(index+1)));
        } else {
            ZimbraQueryResults zqr = null;
            StringBuilder query = new StringBuilder();
            query.append("#").append(ContactConstants.A_vCardUID).append(":");
            // escape the double quotes in uid and surround with double quotes
            query.append("\"").append(uid.replace("\"", "\\\"")).append("\"");
            query.append(" OR ").append("#").append(ContactConstants.A_vCardURL).append(":");
            query.append("\"").append(uid.replace("\"", "\\\"")).append("\"");
            ZimbraLog.dav.debug("query %s", query.toString());
            try {
                zqr = mbox.index.search(ctxt.getOperationContext(), query.toString(),
                        EnumSet.of(MailItem.Type.CONTACT), SortBy.NAME_ASC, 10);
                // There could be multiple contacts with the same UID from different collections.
                while (zqr.hasNext()) {
                    ZimbraHit hit = zqr.getNext();
                    if (hit instanceof ContactHit) {
                        item = ((ContactHit)hit).getContact();
                        if (folderId < 0)
                            break;
                        if (item.getFolderId() == folderId)
                            break;
                        item = null;
                    }
                }
            } catch (Exception e) {
                ZimbraLog.dav.error("can't search for: uid=%s", uid, e);
            } finally {
                Closeables.closeQuietly(zqr);
            }
        }

        if ((item != null) && (folderId >= 0) && (item.getFolderId() != folderId))
            item = null;

        return item;
    }
}


text: {% assign url = '/assets/static/' | append: include.file %}

redpajama_set_name: RedPajamaGithub


text:
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import importlib
import os

from kafkatest.version import get_version, KafkaVersion, TRUNK

"""This module serves a few purposes:

First, it gathers information about path layout in a single place, and second, it
makes the layout of the Kafka installation pluggable, so that users are not forced
to use the layout assumed in the KafkaPathResolver class.

To run system tests using your own path resolver, use for example:

ducktape <TEST_PATH> --globals '{"kafka-path-resolver": "my.path.resolver.CustomResolverClass"}'
"""

SCRATCH_ROOT = "/mnt"
KAFKA_INSTALL_ROOT = "/opt"
KAFKA_PATH_RESOLVER_KEY = "kafka-path-resolver"
KAFKA_PATH_RESOLVER = "kafkatest.directory_layout.kafka_path.KafkaSystemTestPathResolver"

# Variables for jar path resolution
CORE_JAR_NAME = "core"
CORE_LIBS_JAR_NAME = "core-libs"
CORE_DEPENDANT_TEST_LIBS_JAR_NAME = "core-dependant-testlibs"
TOOLS_JAR_NAME = "tools"
TOOLS_DEPENDANT_TEST_LIBS_JAR_NAME = "tools-dependant-libs"

JARS = {
    "trunk": {
        CORE_JAR_NAME: "core/build/*/*.jar",
        CORE_LIBS_JAR_NAME: "core/build/libs/*.jar",
        CORE_DEPENDANT_TEST_LIBS_JAR_NAME: "core/build/dependant-testlibs/*.jar",
        TOOLS_JAR_NAME: "tools/build/libs/kafka-tools*.jar",
        TOOLS_DEPENDANT_TEST_LIBS_JAR_NAME: "tools/build/dependant-libs*/*.jar"
    }
}

def create_path_resolver(context, project="kafka"):
    """Factory for generating a path resolver class

    This will first check for a fully qualified path resolver classname in context.globals.

    If present, construct a new instance, else default to KafkaSystemTestPathResolver
    """
    assert project is not None

    if KAFKA_PATH_RESOLVER_KEY in context.globals:
        resolver_fully_qualified_classname = context.globals[KAFKA_PATH_RESOLVER_KEY]
    else:
        resolver_fully_qualified_classname = KAFKA_PATH_RESOLVER

    # Using the fully qualified classname, import the resolver class
    (module_name, resolver_class_name) = resolver_fully_qualified_classname.rsplit('.', 1)
    cluster_mod = importlib.import_module(module_name)
    path_resolver_class = getattr(cluster_mod, resolver_class_name)
    path_resolver = path_resolver_class(context, project)

    return path_resolver

class KafkaPathResolverMixin(object):
    """Mixin to automatically provide pluggable path resolution functionality to any class using it.

    Keep life simple, and don't add a constructor to this class:
    Since use of a mixin entails multiple inheritence, it is *much* simpler to reason about the interaction of this
    class with subclasses if we don't have to worry about method resolution order, constructor signatures etc.
    """

    @property
    def path(self):
        if not hasattr(self, "_path"):
            setattr(self, "_path", create_path_resolver(self.context, "kafka"))
            if hasattr(self.context, "logger") and self.context.logger is not None:
                self.context.logger.debug("Using path resolver %s" % self._path.__class__.__name__)

        return self._path

class KafkaSystemTestPathResolver(object):
    """Path resolver for Kafka system tests which assumes the following layout:

        /opt/kafka-trunk        # Current version of kafka under test
        /opt/kafka-0.9.0.1      # Example of an older version of kafka installed from tarball
        /opt/kafka-<version>    # Other previous versions of kafka
        ...
    """
    def __init__(self, context, project="kafka"):
        self.context = context
        self.project = project

    def home(self, node_or_version=TRUNK):
        version = self._version(node_or_version)
        home_dir = self.project
        if version is not None:
            home_dir += "-%s" % str(version)

        return os.path.join(KAFKA_INSTALL_ROOT, home_dir)

    def bin(self, node_or_version=TRUNK):
        version = self._version(node_or_version)
        return os.path.join(self.home(version), "bin")

    def script(self, script_name, node_or_version=TRUNK):
        version = self._version(node_or_version)
        return os.path.join(self.bin(version), script_name)

    def jar(self, jar_name, node_or_version=TRUNK):
        version = self._version(node_or_version)
        return os.path.join(self.home(version), JARS[str(version)][jar_name])

    def scratch_space(self, service_instance):
        return os.path.join(SCRATCH_ROOT, service_instance.service_id)

    def _version(self, node_or_version):
        if isinstance(node_or_version, KafkaVersion):
            return node_or_version
        else:
            return get_version(node_or_version)


text:
require 'rubygems'
require 'tjplurker'
require 'tzinfo'
require 'zip'
require 'fileutils'

include TJP

#Get plurk username by user id.

def getUserName(tjp, userId)

	result = tjp.get_public_profile(userId)

	username =  result['user_info']['display_name']

	return username

end

#Get the consumer key and access key from setting file

settingFile = File.read('./setting.json')
setting = JSON.parse(settingFile)

consumerKey = setting['consumerKey']
consumerSecert = setting['consumerSecert']
accessKey = setting['accessKey']
accessSecret = setting['accessSecret']

#Get the start time and end time of today

timeZone = TZInfo::Timezone.get('Asia/Hong_Kong')

today = DateTime.now().strftime('%Y%m%d')
startTime = DateTime.new(DateTime.now.year, DateTime.now.month, DateTime.now.day, 0, 0, 0, 0)
startTimeMs = startTime.strftime('%Q')
endTime = DateTime.new(DateTime.now.year, DateTime.now.month, DateTime.now.day, 23, 59, 59, 59)
endTimeMs = endTime.strftime('%Q')

#Create output folder if not existed

FileUtils::mkdir_p './output'

#Start to get plurk which posted on today

tjp = TJPlurker.new(consumerKey, consumerSecert, accessKey, accessSecret)

user = ARGV.first

userId = get_uid(user).to_i

publicPlurks = tjp.api('/APP/Timeline/getPublicPlurks', user_id: userId, limit:50)['plurks']

publicPlurks.each do |publicPlurk|

	postedDate = timeZone.utc_to_local(DateTime.httpdate(publicPlurk['posted'])).strftime('%Y%m%d%H%M%S')
	postedDateMs = timeZone.utc_to_local(DateTime.httpdate(publicPlurk['posted'])).strftime('%Q')

	#If the plurk is posted on today, write the content and reponse to html flie

	if postedDateMs > startTimeMs and postedDateMs < endTimeMs

		outputFile = "#{postedDate}.html"

		outputFilePath = "./output/#{outputFile}"

		fileHtml = File.new(outputFilePath, 'w')
		fileHtml.puts '<meta charset="UTF-8">'

		username = getUserName(tjp, publicPlurk['owner_id'])

		content = publicPlurk['content']

		postedDate = timeZone.utc_to_local(DateTime.httpdate(publicPlurk['posted'])).strftime('%Y-%m-%d %H:%M')

		fileHtml.puts '發噗日期:' + postedDate  + '
'
		fileHtml.puts '發噗者:' + username  + '

'

		fileHtml.puts content
		fileHtml.puts '

'

		publicPlurkId = publicPlurk['plurk_id']

		responses = tjp.api('/APP/Responses/get', plurk_id: publicPlurkId)['responses']

		responses.each do |response|

			responser = getUserName(tjp, response['user_id'])
			responseContent = response['content']

			fileHtml.puts responser + ':' + '
'
			fileHtml.puts responseContent
			fileHtml.puts '

'
		end

		fileHtml.puts ''
		fileHtml.close

		#Zip all of the output file

		zipFileName = "./output/" + username + today + ".zip"

		Zip::File.open(zipFileName, Zip::File::CREATE) do |zipfile|
			zipfile.add(outputFile, outputFilePath)
		end

		File.delete(outputFilePath)

	end
end


text:
/*!
 * Start Bootstrap - Business Frontpage HTML Template (http://startbootstrap.com)
 * Code licensed under the Apache License v2.0.
 * For details, see http://www.apache.org/licenses/LICENSE-2.0.
 */

html {
  position: relative;
  min-height: 100%;
}
body {
  /* Margin bottom by footer height */
  margin-bottom: 100px;
}
.footer {
  position: absolute;
  bottom: 0;
  width: 100%;
  /* Set the fixed height of the footer here */
  height: 60px;
  background-color: #003c71;
}
.footer > .container {
  padding-right: 15px;
  padding-left: 15px;
}
.container .text-muted {
  margin: 20px 0;
  color: #ffffff;
}

.top-buffer { margin-top:10px; }

/* Customize article */
#articleDetail blockquote {font-size: 14px; }
#articleDetail li {line-height: 2; }

/* Header Image Background - Change the URL below to your image path (example: ../images/background.jpg) */
.business-header {
    background: url('../images/goodorbad.jpg') center center no-repeat scroll;
    -webkit-background-size: cover;
    -moz-background-size: cover;
    background-size: cover;
    -o-background-size: cover;
    /* Margin top by footer height */
    margin-top: 50px;
}
.business-header-large {
    height: 400px;
}
.business-header-small {
    height: 110px;
}
.business-header-none {
    background: none;
    height: 50px;
}
.business-header-small h1{
    font-size: 2em;
}

/* Customize the text color and shadow color and to optimize text legibility. */

.tagline {
    text-shadow: 0 0 10px #000;
    color: #fff;
}

.img-center {
    margin: 0 auto;
}

/* Customize the navbar style. */
.navbar-custom {
    background-color:#0071c5;
    color:#ffffff;
    border-radius:0;
}
.navbar-custom .navbar-nav > li > a {
    color:#fff;
}
.navbar-custom .navbar-nav > li > a:hover, .nav > li > a:focus {
    text-decoration: none;
    background-color: #33aa33;
}
.navbar-custom .navbar-brand {
    color:#eeeeee;
}
.navbar-custom .navbar-toggle {
    background-color:#0071c5;
}
.navbar-custom .icon-bar {
    background-color:#ffffff;
}

/* toc Support H1~H3*/
/* sidebar */
.bs-docs-sidebar {
    padding-left: 20px;
    margin-top: 20px;
    margin-bottom: 20px;
}

/* all links */
/* H1 */
.bs-docs-sidebar .nav>li>a {
    color: #999;
    border-left: 2px solid transparent;
    padding: 4px 20px;
    font-size: 16px;
    font-weight: 400;
}
/* H2 */
.bs-docs-sidebar .nav .nav>li>a {
    padding-top: 1px;
    padding-bottom: 1px;
    padding-left: 40px;
    font-size: 14px;
}
/* H3 */
.bs-docs-sidebar .nav .nav .nav>li>a {
    padding-top: 1px;
    padding-bottom: 1px;
    padding-left: 60px;
    font-size: 12px;
}

/* active & hover links */
.bs-docs-sidebar .nav>.active>a,
.bs-docs-sidebar .nav>li>a:hover,
.bs-docs-sidebar .nav>li>a:focus {
    color: #563d7c;
    text-decoration: none;
    background-color: transparent;
    border-left-color: #563d7c;
}
/* H1 */
.bs-docs-sidebar .nav>.active>a,
.bs-docs-sidebar .nav>.active:hover>a,
.bs-docs-sidebar .nav>.active:focus>a {
    font-weight: 700;
}
/* H2 */
.bs-docs-sidebar .nav .nav>.active>a,
.bs-docs-sidebar .nav .nav>.active:hover>a,
.bs-docs-sidebar .nav .nav>.active:focus>a {
    font-weight: 600;
}
/* H3 */
.bs-docs-sidebar .nav .nav .nav>.active>a,
.bs-docs-sidebar .nav .nav .nav>.active:hover>a,
.bs-docs-sidebar .nav .nav .nav>.active:focus>a {
    font-weight: 500;
}

/* hide inactive nested list */
.bs-docs-sidebar .nav ul.nav {
    display: none;
}
/* show active nested list */
.bs-docs-sidebar .nav>.active>ul.nav {
    display: block;
}

/* loading */
.glyphicon-refresh-animate {
    -animation: spin .7s infinite linear;
    -webkit-animation: spin2 .7s infinite linear;
}

@-webkit-keyframes spin2 {
    from { -webkit-transform: rotate(0deg);}
    to { -webkit-transform: rotate(360deg);}
}

@keyframes spin {
    from { transform: scale(1) rotate(0deg);}
    to { transform: scale(1) rotate(360deg);}
}


text:
import {Record} from 'immutable';

const Paper = Record({
  title: '',
});

export default Paper;


text:
#include "foundation/algorithm/iconsistent.h"
#include "foundation/util/idicttypes.h"
#include "foundation/util/iarraytypes.h"

/* the consistent destructor */
void iconsistent_destructor(const struct imeta *meta, iptr o) {
    iconsistent *c = icast(iconsistent, o);
    irefdelete(c->circle);
    irefdelete(c->elems);
}

/* make a empty iconsistent */
iconsistent *iconsistentmake(size_t capacity, size_t replicas) {
    iconsistent *c = irefnew(iconsistent);
    c->numberofreplicas = replicas;
    c->circle = idictmake(capacity);
    c->elems = idictmake(capacity);
    return c;
}

/* the element-size in circle */
size_t iconsistentsize(const iconsistent *c) {
    return idictsize(c->elems);
}

/* make a replicas-key */
istring *_iconsistent_key_n(iconsistent *c, istring *ele, int index) {
    return istringformat("%V|@@[%i]", ele, index);
}

/* add ele to c in span: replicasspan with numberofreplicas */
void iconsistentadd(iconsistent *c, istring *ele) {
    istring *key;

    for (int i=0; i<c->numberofreplicas; ++i) {
        key = _iconsistent_key_n(c, ele, i);
        idictadd_u64_istring(c->circle, iconsistenthashof(c, key), ele);
        irefdelete(key);
    }
    idictadd_istring_ibool(c->elems, ele, iiok);
}

/* remove ele from c in span */
void iconsistentremove(iconsistent *c, istring *ele) {
    istring *key;

    for (int i=0; i<c->numberofreplicas; ++i) {
        key = _iconsistent_key_n(c, ele, i);
        idictremove_u64(c->circle, iconsistenthashof(c, key));
        irefdelete(key);
    }
    idictremove_istring(c->elems, ele);
}

int _iarray_range_search(iarray *elems, istring* key) {
    irangearray(elems, istring*,
                if (istringcompare(__value, key) == 0) {
                    return iiok;
                }
                );
    return iino;
}

/* set the circle to elems: remove all not in elems, add all in elems*/
/* iarray<istring*> */
void iconsistentset(iconsistent *c, iarray* elems) {
    const iarray * keys = idictkeys(c->elems);
    istring *skey;

    /* remove ele in members but not in elems */
    irangearray(keys, idictentry*,
                skey = ivarcast(&__value->key, istring*);
                if (!_iarray_range_search(elems, skey)) {
                    iconsistentremove(c, skey);
                }
                );

    /* add elems to members */
    irangearray(elems, istring*,
                if (!idicthas_istring(c->elems, __value)) {
                    iconsistentadd(c, __value);
                }
                );
}

/* the index of elem-key ==> hashcode */
static uint64_t _iconsistent_key(const iconsistent *c, int index) {
    const iarray* sortedkeys = idictkeys(c->circle);
    idictentry *entry = iarrayof(sortedkeys, idictentry*, index);
    return ivarcast(&entry->key, uint64_t);
}

/* the index of elem-key ==> skey */
static istring* _iconsistent_value(const iconsistent *c, int index) {
    const iarray* sortedkeys = idictkeys(c->circle);
    idictentry *entry = iarrayof(sortedkeys, idictentry*, index);
    return ivarcast(&entry->value, istring*);
}

/* closed ele for key */
istring* iconsistentindexingof(const iconsistent *c, istring *key) {
    if (idictsize(c->circle) == 0) {
        return NULL;
    }
    int index = iconsistentindexing(c, key);
    return _iconsistent_value(c, index);
}

/* closed index for key */
int iconsistentindexing(const iconsistent *c, istring *key) {
    ivar *keyvar = ivarmakeu64(iconsistenthashof(c, key));
    idictentry ventry = {.key=*keyvar};
    idictentry *entry = &ventry;
    const iarray* sortedkeys = idictkeys(c->circle);
    int index = iarraybinaryindexing(sortedkeys, 0, iarraylen(sortedkeys), &entry);
    iobjfree(keyvar);
    if (index >= iarraylen(sortedkeys)) {
        index = 0;
    }
    return index;
}

/* closest index for key then next n key will return */
iarray* iconsistentsearch(const iconsistent *c, istring *key, size_t n) {
    iarray* closest = iarraymakeiref(8);
    istring *skey;
    size_t ne = idictsize(c->elems);
    size_t nc = idictsize(c->circle);
    int start;
    int i;

    do {
        if (nc == 0) {
            break;
        }
        n = imin(n, ne);
        /* the first one */
        start = iconsistentindexing(c, key);
        skey = _iconsistent_value(c, start);
        iarrayadd(closest, &skey);
        if (iarraylen(closest) == n) {
            break;
        }

        /* the next left ones */
        for (i = start + 1; i != start; ++i) {
            if (i >= nc) {
                i = 0;
            }
            skey = _iconsistent_value(c, i);
            if (_iarray_range_search(closest, skey) == iino) {
                iarrayadd(closest, &skey);
            }
            if (iarraylen(closest) == n) {
                break;
            }
        }
        break;
    }while(0);

    /* no-indexing key */
    if (iarraylen(closest)==0) {
        irefdelete(closest);
    }
    return closest;
}

/* the hash-code-for key */
uint64_t iconsistenthashof(const iconsistent *c, istring *key) {
    return istringhashcode(key)%INT32_MAX;
}

/* the circle-size */
size_t iconsistentcount(const iconsistent *c) {
    return idictsize(c->circle);
}

/* the circle-hashcode at */
uint64_t iconsistentcodeat(const iconsistent *c, int index) {
    return _iconsistent_key(c, index);
}

/* the circle-value at */
istring *iconsistentvalueat(const iconsistent *c, int index) {
    return _iconsistent_value(c, index);
}


text:
package apfe.runtime;

/**
 * Check for sequence match and unconditionally backtrack.
 *
 * @author gburdell
 */
public class NotPredicate extends Predicate {
    public NotPredicate(Acceptor seq) {
        super(seq, false);
    }

    @Override
    public Acceptor create() {
        return new NotPredicate(m_seq.create());
    }
}


text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <meta name="description" content="Legion: map examples">
    <meta name="author" content="http://novasys.di.fct.unl.pt/~alinde/">

    <title>Legion: Map examples</title>

    <link href="./../../node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="./../../node_modules/bootstrap/dist/css/bootstrap-theme.min.css" rel="stylesheet">

            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
                    aria-expanded="false" aria-controls="navbar">
                Toggle navigation

            </button>
            Legion showcase

Back

Map examples

Legion Map Examples

This page contains examples of using the Legion framework.

Usage

    var legion = new Legion();
    legion.join();
    var objectStore = legion.getObjectStore();

    var map = objectStore.get("mapID", legion.Map);

    map.set(key, value);
    map.get(key);
    map.delete(key);

    console.log(map.asArray());          //Array of pairs
    console.log(map.keys());             //Array
    console.log(map.values());           //Array
    console.log(map.contains(element));  //Boolean
    console.log(map.size());             //Number

Example

Input

                            Key:
                            <input type="text" id="map_key" placeholder="key" value="key">
                            Value:
                            <input type="text" id="map_value" placeholder="value" value="value">

                        Type
                        Set(key, value)
                        Delete(key)
                        Size

                        1

                            <button onclick="add_1()" id="add_1" type="button"
                                    class="btn btn-xs btn-success disabled">Set
                            </button>

                            <button onclick="remove_1()" id="remove_1" type="button"
                                    class="btn btn-xs btn-success disabled">Remove
                            </button>

                        2

                            <button onclick="add_2()" id="add_2" type="button"
                                    class="btn btn-xs btn-success disabled">Set
                            </button>

                            <button onclick="remove_2()" id="remove_2" type="button"
                                    class="btn btn-xs btn-success disabled">Remove
                            </button>

                        3

                            <button onclick="add_3()" id="add_3" type="button"
                                    class="btn btn-xs btn-success disabled">Set
                            </button>

                            <button onclick="remove_3()" id="remove_3" type="button"
                                    class="btn btn-xs btn-success disabled">Remove
                            </button>

Map 1 Elements

Map 2 Elements

Map 3 Elements


text:
if (typeof Map === "undefined") {
  Map = function() { this.clear(); };
  Map.prototype = {
    set: function(k, v) { this._[k] = v; return this; },
    get: function(k) { return this._[k]; },
    has: function(k) { return k in this._; },
    delete: function(k) { return k in this._ && delete this._[k]; },
    clear: function() { this._ = Object.create(null); },
    get size() { var n = 0; for (var k in this._) ++n; return n; },
    forEach: function(c) { for (var k in this._) c(this._[k], k, this); }
  };
}

if (typeof requestAnimationFrame === "undefined") {
  requestAnimationFrame = typeof window !== "undefined"
      && (window.msRequestAnimationFrame
      || window.mozRequestAnimationFrame
      || window.webkitRequestAnimationFrame
      || window.oRequestAnimationFrame)
      || function(callback) { return setTimeout(callback, 17); };
}

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    global.d3 = factory();
}(this, function () { 'use strict';

    function Lock() {
      this.active = null;
      this.pending = [];
    }

    Lock.prototype = {
      scheduled: function(id) {
        if (this.active && this.active.id === id) return true;
        var pending = this.pending, i = pending.length;
        while (--i >= 0) if (pending[i].id === id) return true;
        return false;
      }
    };

    function initialize(key, id) {
      return function() {
        var lock = this[key] || (this[key] = new Lock);
        if (lock.scheduled(id)) return;

      };
    }

    var maxId = 0;

    function Transition(root, depth, key, id) {
      this._root = root;
      this._depth = depth;
      this._key = key || "__transition__";
      this._id = id || ++maxId;
      this.each(initialize(this._key, this._id));
    }

    function linearIn(t) {
      return +t;
    }

    var k = 1 / (2 * Math.PI);

    var number = function(x, defaultValue) {
      return x == null || isNaN(x) ? defaultValue : +x;
    }

    function elasticInOut(a, p) {
      a = Math.max(1, number(a, 1)), p = number(p, .3) * 1.5 * k; // Note: treatment differs from Penner!
      var s = p * Math.asin(1 / a);
      return function(t) {
        return a * ((t = t * 2 - 1) < 0
            ? Math.pow(2, 10 * t) * Math.sin((s - t) / p)
            : Math.pow(2, -10 * t) * Math.sin((t - s) / p) + 2) / 2;
      };
    }

    function elasticOut(a, p) {
      a = Math.max(1, number(a, 1)), p = number(p, .3) * k;
      var s = p * Math.asin(1 / a);
      return function(t) {
        return a * Math.pow(2, -10 * t) * Math.sin((t - s) / p) + 1;
      };
    }

    function elasticIn(a, p) {
      a = Math.max(1, number(a, 1)), p = number(p, .3) * k;
      var s = p * Math.asin(1 / a);
      return function(t) {
        return a * Math.pow(2, 10 * --t) * Math.sin((s - t) / p);
      };
    }

    function backInOut(s) {
      return s = number(s, 1.70158) * 1.525, function(t) {
        return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2;
      };
    }

    function backOut(s) {
      return s = number(s, 1.70158), function(t) {
        return --t * t * ((s + 1) * t + s) + 1;
      };
    }

    function backIn(s) {
      return s = number(s, 1.70158), function(t) {
        return t * t * ((s + 1) * t - s);
      };
    }

    var b1 = 4 / 11,
        b2 = 6 / 11,
        b3 = 8 / 11,
        b4 = 3 / 4,
        b5 = 9 / 11,
        b6 = 10 / 11,
        b7 = 15 / 16,
        b8 = 21 / 22,
        b9 = 63 / 64,
        b0 = 1 / b1 / b1;

    function bounceOut(t) {
      return t < b1 ? b0 * t * t : t < b3 ? b0 * (t -= b2) * t + b4 : t < b6 ? b0 * (t -= b5) * t + b7 : b0 * (t -= b8) * t + b9;
    }

    function bounceInOut(t) {
      return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2;
    }

    function bounceIn(t) {
      return 1 - bounceOut(1 - t);
    }

    function circleInOut(t) {
      return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2;
    }

    function circleOut(t) {
      return Math.sqrt(1 - --t * t);
    }

    function circleIn(t) {
      return 1 - Math.sqrt(1 - t * t);
    }

    function expInOut(t) {
      return ((t *= 2) <= 1 ? Math.pow(2, 10 * t - 10) : 2 - Math.pow(2, 10 - 10 * t)) / 2;
    }

    function expOut(t) {
      return 1 - Math.pow(2, -10 * t);
    }

    function expIn(t) {
      return Math.pow(2, 10 * t - 10);
    }

    var pi = Math.PI,
        halfPi = pi / 2;

    function sinInOut(t) {
      return (1 - Math.cos(pi * t)) / 2;
    }

    function sinOut(t) {
      return Math.sin(t * halfPi);
    }

    function sinIn(t) {
      return 1 - Math.cos(t * halfPi);
    }

    function cubicInOut(t) {
      return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
    }

    function cubicOut(t) {
      return --t * t * t + 1;
    }

    function cubicIn(t) {
      return t * t * t;
    }

    function quadInOut(t) {
      return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2;
    }

    function quadOut(t) {
      return t * (2 - t);
    }

    function quadIn(t) {
      return t * t;
    }

    var standardEases = (new Map)
        .set("linear-in", linearIn)
        .set("linear-out", linearIn)
        .set("linear-in-out", linearIn)
        .set("quad-in", quadIn)
        .set("quad-out", quadOut)
        .set("quad-in-out", quadInOut)
        .set("cubic-in", cubicIn)
        .set("cubic-out", cubicOut)
        .set("cubic-in-out", cubicInOut)
        .set("poly-in", cubicIn)
        .set("poly-out", cubicOut)
        .set("poly-in-out", cubicInOut)
        .set("sin-in", sinIn)
        .set("sin-out", sinOut)
        .set("sin-in-out", sinInOut)
        .set("exp-in", expIn)
        .set("exp-out", expOut)
        .set("exp-in-out", expInOut)
        .set("circle-in", circleIn)
        .set("circle-out", circleOut)
        .set("circle-in-out", circleInOut)
        .set("bounce-in", bounceIn)
        .set("bounce-out", bounceOut)
        .set("bounce-in-out", bounceInOut)
        .set("back-in", backIn())
        .set("back-out", backOut())
        .set("back-in-out", backInOut())
        .set("elastic-in", elasticIn())
        .set("elastic-out", elasticOut())
        .set("elastic-in-out", elasticInOut());

    function polyInOut(e) {
      return e = number(e, 3), function(t) {
        return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2;
      };
    }

    function polyOut(e) {
      return e = number(e, 3), function(t) {
        return 1 - Math.pow(1 - t, e);
      };
    }

    function polyIn(e) {
      return e = number(e, 3), function(t) {
        return Math.pow(t, e);
      };
    }

    var customEases = (new Map)
        .set("poly-in", polyIn)
        .set("poly-out", polyOut)
        .set("poly-in-out", polyInOut)
        .set("back-in", backIn)
        .set("back-out", backOut)
        .set("back-in-out", backInOut)
        .set("elastic-in", elasticIn)
        .set("elastic-out", elasticOut)
        .set("elastic-in-out", elasticInOut);

    var ease = function(type, a, b) {
      var i = (type += "").indexOf("-");
      if (i < 0) type += "-in";
      return arguments.length > 1 && customEases.has(type)
          ? customEases.get(type)(a, b)
          : standardEases.get(type) || linearIn;
    }

    var transition_ease = function(type, a, b) {
      var e = typeof type === "function" ? type : ease(type, a, b);
      return this.each(function() {
        // TODO
      });
    }

    // When depth = 1, root = [Node, …].
    // When depth = 2, root = [[Node, …], …].
    // When depth = 3, root = [[[Node, …], …], …]. etc.
    // Note that [Node, …] and NodeList are used interchangeably; see arrayify.
    function Selection(root, depth) {
      this._root = root;
      this._depth = depth;
      this._enter = this._update = this._exit = null;
    }

    var _defaultView = function(node) {
      return node
          && ((node.ownerDocument && node.ownerDocument.defaultView) // node is a Node
              || (node.document && node) // node is a Window
              || node.defaultView); // node is a Document
    }

    function dispatchEvent(node, type, params) {
      var window = _defaultView(node),
          event = window.CustomEvent;

      if (event) {
        event = new event(type, params);
      } else {
        event = window.document.createEvent("Event");
        if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;
        else event.initEvent(type, false, false);
      }

      node.dispatchEvent(event);
    }

    var selection_dispatch = function(type, params) {

      function dispatchConstant() {
        return dispatchEvent(this, type, params);
      }

      function dispatchFunction() {
        return dispatchEvent(this, type, params.apply(this, arguments));
      }

      return this.each(typeof params === "function" ? dispatchFunction : dispatchConstant);
    }

    function noop() {}

    var requoteRe = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;

    var requote = function(string) {
      return string.replace(requoteRe, "\\$&");
    }

    function filterListenerOf(listener) {
      return function(event) {
        var related = event.relatedTarget;
        if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) {
          listener(event);
        }
      };
    }

    var event = null;

    function listenerOf(listener, ancestors, args) {
      return function(event1) {
        var i = ancestors.length, event0 = event; // Events can be reentrant (e.g., focus).
        while (--i >= 0) args[i << 1] = ancestors[i].__data__;
        event = event1;
        try {
          listener.apply(ancestors[0], args);
        } finally {
          event = event0;
        }
      };
    }

    var filterEvents = new Map;

    if (typeof document !== "undefined") {
      var _element = document.documentElement;
      if (!("onmouseenter" in _element)) {
        filterEvents.set("mouseenter", "mouseover").set("mouseleave", "mouseout");
      }
    }

    var selection_event = function(type, listener, capture) {
      var n = arguments.length,
          key = "__on" + type,
          filter,
          root = this._root;

      if (n < 2) return (n = this.node()[key]) && n._listener;

      if (n < 3) capture = false;
      if ((n = type.indexOf(".")) > 0) type = type.slice(0, n);
      if (filter = filterEvents.has(type)) type = filterEvents.get(type);

      function add() {
        var ancestor = root, i = arguments.length >> 1, ancestors = new Array(i);
        while (--i >= 0) ancestor = ancestor[arguments[(i << 1) + 1]], ancestors[i] = i ? ancestor._parent : ancestor;
        var l = listenerOf(listener, ancestors, arguments);
        if (filter) l = filterListenerOf(l);
        remove.call(this);
        this.addEventListener(type, this[key] = l, l._capture = capture);
        l._listener = listener;
      }

      function remove() {
        var l = this[key];
        if (l) {
          this.removeEventListener(type, l, l._capture);
          delete this[key];
        }
      }

      function removeAll() {
        var re = new RegExp("^__on([^.]+)" + requote(type) + "$"), match;
        for (var name in this) {
          if (match = name.match(re)) {
            var l = this[name];
            this.removeEventListener(match[1], l, l._capture);
            delete this[name];
          }
        }
      }

      return this.each(listener
          ? (n ? add : noop) // Attempt to add untyped listener is ignored.
          : (n ? remove : removeAll));
    }

    var selection_datum = function(value) {
      return arguments.length ? this.property("__data__", value) : this.node().__data__;
    }

    var selection_remove = function() {
      return this.each(function() {
        var parent = this.parentNode;
        if (parent) parent.removeChild(this);
      });
    }

    var selectorOf = function(selector) {
      return function() {
        return this.querySelector(selector);
      };
    }

    var namespaces = (new Map)
        .set("svg", "http://www.w3.org/2000/svg")
        .set("xhtml", "http://www.w3.org/1999/xhtml")
        .set("xlink", "http://www.w3.org/1999/xlink")
        .set("xml", "http://www.w3.org/XML/1998/namespace")
        .set("xmlns", "http://www.w3.org/2000/xmlns/");

    var namespace = function(name) {
      var i = name.indexOf(":"), prefix = name;
      if (i >= 0) prefix = name.slice(0, i), name = name.slice(i + 1);
      return namespaces.has(prefix) ? {space: namespaces.get(prefix), local: name} : name;
    }

    function creatorOf(name) {
      name = namespace(name);

      function creator() {
        var document = this.ownerDocument,
            uri = this.namespaceURI;
        return uri
            ? document.createElementNS(uri, name)
            : document.createElement(name);
      }

      function creatorNS() {
        return this.ownerDocument.createElementNS(name.space, name.local);
      }

      return name.local ? creatorNS : creator;
    }

    var selection_append = function(creator, selector) {
      if (typeof creator !== "function") creator = creatorOf(creator);

      function append() {
        return this.appendChild(creator.apply(this, arguments));
      }

      function insert() {
        return this.insertBefore(creator.apply(this, arguments), selector.apply(this, arguments) || null);
      }

      return this.select(arguments.length < 2
          ? append
          : (typeof selector !== "function" && (selector = selectorOf(selector)), insert));
    }

    var selection_html = function(value) {
      if (!arguments.length) return this.node().innerHTML;

      function setConstant() {
        this.innerHTML = value;
      }

      function setFunction() {
        var v = value.apply(this, arguments);
        this.innerHTML = v == null ? "" : v;
      }

      if (value == null) value = "";

      return this.each(typeof value === "function" ? setFunction : setConstant);
    }

    var selection_text = function(value) {
      if (!arguments.length) return this.node().textContent;

      function setConstant() {
        this.textContent = value;
      }

      function setFunction() {
        var v = value.apply(this, arguments);
        this.textContent = v == null ? "" : v;
      }

      if (value == null) value = "";

      return this.each(typeof value === "function" ? setFunction : setConstant);
    }

    function collapse(string) {
      return string.trim().replace(/\s+/g, " ");
    }

    function classerOf(name) {
      var re;
      return function(node, value) {
        if (c = node.classList) return value ? c.add(name) : c.remove(name);
        if (!re) re = new RegExp("(?:^|\\s+)" + requote(name) + "(?:\\s+|$)", "g");
        var c = node.getAttribute("class") || "";
        if (value) {
          re.lastIndex = 0;
          if (!re.test(c)) node.setAttribute("class", collapse(c + " " + name));
        } else {
          node.setAttribute("class", collapse(c.replace(re, " ")));
        }
      };
    }

    var selection_class = function(name, value) {
      name = (name + "").trim().split(/^|\s+/);
      var n = name.length;

      if (arguments.length < 2) {
        var node = this.node(), i = -1;
        if (value = node.classList) { // SVG elements may not support DOMTokenList!
          while (++i < n) if (!value.contains(name[i])) return false;
        } else {
          value = node.getAttribute("class");
          while (++i < n) if (!classedRe(name[i]).test(value)) return false;
        }
        return true;
      }

      name = name.map(classerOf);

      function setConstant() {
        var i = -1;
        while (++i < n) name[i](this, value);
      }

      function setFunction() {
        var i = -1, x = value.apply(this, arguments);
        while (++i < n) name[i](this, x);
      }

      return this.each(typeof value === "function" ? setFunction : setConstant);
    }

    var selection_property = function(name, value) {
      if (arguments.length < 2) return this.node()[name];

      function remove() {
        delete this[name];
      }

      function setConstant() {
        this[name] = value;
      }

      function setFunction() {
        var x = value.apply(this, arguments);
        if (x == null) delete this[name];
        else this[name] = x;
      }

      return this.each(value == null ? remove : typeof value === "function" ? setFunction : setConstant);
    }

    var selection_style = function(name, value, priority) {
      var n = arguments.length;

      if (n < 2) return _defaultView(n = this.node()).getComputedStyle(n, null).getPropertyValue(name);

      if (n < 3) priority = "";

      function remove() {
        this.style.removeProperty(name);
      }

      function setConstant() {
        this.style.setProperty(name, value, priority);
      }

      function setFunction() {
        var x = value.apply(this, arguments);
        if (x == null) this.style.removeProperty(name);
        else this.style.setProperty(name, x, priority);
      }

      return this.each(value == null ? remove : typeof value === "function" ? setFunction : setConstant);
    }

    var selection_attr = function(name, value) {
      name = namespace(name);

      if (arguments.length < 2) {
        var node = this.node();
        return name.local
            ? node.getAttributeNS(name.space, name.local)
            : node.getAttribute(name);
      }

      function remove() {
        this.removeAttribute(name);
      }

      function removeNS() {
        this.removeAttributeNS(name.space, name.local);
      }

      function setConstant() {
        this.setAttribute(name, value);
      }

      function setConstantNS() {
        this.setAttributeNS(name.space, name.local, value);
      }

      function setFunction() {
        var x = value.apply(this, arguments);
        if (x == null) this.removeAttribute(name);
        else this.setAttribute(name, x);
      }

      function setFunctionNS() {
        var x = value.apply(this, arguments);
        if (x == null) this.removeAttributeNS(name.space, name.local);
        else this.setAttributeNS(name.space, name.local, x);
      }

      return this.each(value == null
          ? (name.local ? removeNS : remove)
          : (typeof value === "function"
              ? (name.local ? setFunctionNS : setFunction)
              : (name.local ? setConstantNS : setConstant)));
    }

    var selection_each = function(callback) {
      var depth = this._depth,
          stack = new Array(depth);

      function visit(nodes, depth) {
        var i = -1,
            n = nodes.length,
            node;

        if (--depth) {
          var stack0 = depth * 2,
              stack1 = stack0 + 1;
          while (++i < n) {
            if (node = nodes[i]) {
              stack[stack0] = node._parent.__data__, stack[stack1] = i;
              visit(node, depth);
            }
          }
        }

        else {
          while (++i < n) {
            if (node = nodes[i]) {
              stack[0] = node.__data__, stack[1] = i;
              callback.apply(node, stack);
            }
          }
        }
      }

      visit(this._root, depth);
      return this;
    }

    var selection_empty = function() {
      return !this.node();
    }

    var selection_size = function() {
      var size = 0;
      this.each(function() { ++size; });
      return size;
    }

    function firstNode(nodes, depth) {
      var i = -1,
          n = nodes.length,
          node;

      if (--depth) {
        while (++i < n) {
          if (node = nodes[i]) {
            if (node = firstNode(node, depth)) {
              return node;
            }
          }
        }
      }

      else {
        while (++i < n) {
          if (node = nodes[i]) {
            return node;
          }
        }
      }
    }

    var selection_node = function() {
      return firstNode(this._root, this._depth);
    }

    var selection_nodes = function() {
      var nodes = new Array(this.size()), i = -1;
      this.each(function() { nodes[++i] = this; });
      return nodes;
    }

    var selection_call = function() {
      var callback = arguments[0];
      callback.apply(arguments[0] = this, arguments);
      return this;
    }

    function arrayifyNode(nodes, depth) {
      var i = -1,
          n = nodes.length,
          node;

      if (--depth) {
        while (++i < n) {
          if (node = nodes[i]) {
            nodes[i] = arrayifyNode(node, depth);
          }
        }
      }

      else if (!Array.isArray(nodes)) {
        var array = new Array(n);
        while (++i < n) array[i] = nodes[i];
        array._parent = nodes._parent;
        nodes = array;
      }

      return nodes;
    }

    // The leaf groups of the selection hierarchy are initially NodeList,
    // and then lazily converted to arrays when mutation is required.
    var arrayify = function(selection) {
      return selection._root = arrayifyNode(selection._root, selection._depth);
    }

    function ascending(a, b) {
      return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
    }

    var selection_sort = function(comparator) {
      if (!comparator) comparator = ascending;

      function compare(a, b) {
        return a && b ? comparator(a.__data__, b.__data__) : !a - !b;
      }

      function visit(nodes, depth) {
        if (--depth) {
          var i = -1,
              n = nodes.length,
              node;
          while (++i < n) {
            if (node = nodes[i]) {
              visit(node, depth);
            }
          }
        }

        else {
          nodes.sort(compare);
        }
      }

      visit(arrayify(this), this._depth);
      return this.order();
    }

    function orderNode(nodes, depth) {
      var i = nodes.length,
          node,
          next;

      if (--depth) {
        while (--i >= 0) {
          if (node = nodes[i]) {
            orderNode(node, depth);
          }
        }
      }

      else {
        next = nodes[--i];
        while (--i >= 0) {
          if (node = nodes[i]) {
            if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);
            next = node;
          }
        }
      }
    }

    var selection_order = function() {
      orderNode(this._root, this._depth);
      return this;
    }

    function emptyNode(nodes, depth) {
      var i = -1,
          n = nodes.length,
          node,
          empty = new Array(n);

      if (--depth) {
        while (++i < n) {
          if (node = nodes[i]) {
            empty[i] = emptyNode(node, depth);
          }
        }
      }

      empty._parent = nodes._parent;
      return empty;
    }

    var emptyOf = function(selection) {
      return new Selection(emptyNode(arrayify(selection), selection._depth), selection._depth);
    }

    // Lazily constructs the exit selection for this (update) selection.
    // Until this selection is joined to data, the exit selection will be empty.
    var selection_exit = function() {
      return this._exit || (this._exit = emptyOf(this));
    }

    // Lazily constructs the enter selection for this (update) selection.
    // Until this selection is joined to data, the enter selection will be empty.
    var selection_enter = function() {
      if (!this._enter) {
        this._enter = emptyOf(this);
        this._enter._update = this;
      }
      return this._enter;
    }

    function EnterNode(parent, datum) {
      this.ownerDocument = parent.ownerDocument;
      this.namespaceURI = parent.namespaceURI;
      this._next = null;
      this._parent = parent;
      this.__data__ = datum;
    }

    EnterNode.prototype = {
      appendChild: function(child) { return this._parent.insertBefore(child, this._next); },
      insertBefore: function(child, next) { return this._parent.insertBefore(child, next || this._next); }
    };

    function valueOf_(value) { // XXX https://github.com/rollup/rollup/issues/12
      return function() {
        return value;
      };
    }

    // The value may either be an array or a function that returns an array.
    // An optional key function may be specified to control how data is bound;
    // if no key function is specified, data is bound to nodes by index.
    // Or, if no arguments are specified, this method returns all bound data.
    var selection_data = function(value, key) {
      if (!value) {
        var data = new Array(this.size()), i = -1;
        this.each(function(d) { data[++i] = d; });
        return data;
      }

      var depth = this._depth - 1,
          stack = new Array(depth * 2),
          bind = key ? bindKey : bindIndex;

      if (typeof value !== "function") value = valueOf_(value);
      visit(this._root, this.enter()._root, this.exit()._root, depth);

      function visit(update, enter, exit, depth) {
        var i = -1,
            n,
            node;

        if (depth--) {
          var stack0 = depth * 2,
              stack1 = stack0 + 1;

          n = update.length;

          while (++i < n) {
            if (node = update[i]) {
              stack[stack0] = node._parent.__data__, stack[stack1] = i;
              visit(node, enter[i], exit[i], depth);
            }
          }
        }

        else {
          var j = 0,
              before;

          bind(update, enter, exit, value.apply(update._parent, stack));
          n = update.length;

          // Now connect the enter nodes to their following update node, such that
          // appendChild can insert the materialized enter node before this node,
          // rather than at the end of the parent node.
          while (++i < n) {
            if (before = enter[i]) {
              if (i >= j) j = i + 1;
              while (!(node = update[j]) && ++j < n);
              before._next = node || null;
            }
          }
        }
      }

      function bindIndex(update, enter, exit, data) {
        var i = 0,
            node,
            nodeLength = update.length,
            dataLength = data.length,
            minLength = Math.min(nodeLength, dataLength);

        // Clear the enter and exit arrays, and then initialize to the new length.
        enter.length = 0, enter.length = dataLength;
        exit.length = 0, exit.length = nodeLength;

        for (; i < minLength; ++i) {
          if (node = update[i]) {
            node.__data__ = data[i];
          } else {
            enter[i] = new EnterNode(update._parent, data[i]);
          }
        }

        // Note: we don't need to delete update[i] here because this loop only
        // runs when the data length is greater than the node length.
        for (; i < dataLength; ++i) {
          enter[i] = new EnterNode(update._parent, data[i]);
        }

        // Note: and, we don't need to delete update[i] here because immediately
        // following this loop we set the update length to data length.
        for (; i < nodeLength; ++i) {
          if (node = update[i]) {
            exit[i] = update[i];
          }
        }

        update.length = dataLength;
      }

      function bindKey(update, enter, exit, data) {
        var i,
            node,
            dataLength = data.length,
            nodeLength = update.length,
            nodeByKeyValue = new Map,
            keyStack = new Array(2).concat(stack),
            keyValues = new Array(nodeLength),
            keyValue;

        // Clear the enter and exit arrays, and then initialize to the new length.
        enter.length = 0, enter.length = dataLength;
        exit.length = 0, exit.length = nodeLength;

        // Compute the keys for each node.
        for (i = 0; i < nodeLength; ++i) {
          if (node = update[i]) {
            keyStack[0] = node.__data__, keyStack[1] = i;
            keyValues[i] = keyValue = key.apply(node, keyStack);

            // Is this a duplicate of a key we've previously seen?
            // If so, this node is moved to the exit selection.
            if (nodeByKeyValue.has(keyValue)) {
              exit[i] = node;
            }

            // Otherwise, record the mapping from key to node.
            else {
              nodeByKeyValue.set(keyValue, node);
            }
          }
        }

        // Now clear the update array and initialize to the new length.
        update.length = 0, update.length = dataLength;

        // Compute the keys for each datum.
        for (i = 0; i < dataLength; ++i) {
          keyStack[0] = data[i], keyStack[1] = i;
          keyValue = key.apply(update._parent, keyStack);

          // Is there a node associated with this key?
          // If not, this datum is added to the enter selection.
          if (!(node = nodeByKeyValue.get(keyValue))) {
            enter[i] = new EnterNode(update._parent, data[i]);
          }

          // Did we already bind a node using this key? (Or is a duplicate?)
          // If unique, the node and datum are joined in the update selection.
          // Otherwise, the datum is ignored, neither entering nor exiting.
          else if (node !== true) {
            update[i] = node;
            node.__data__ = data[i];
          }

          // Record that we consumed this key, either to enter or update.
          nodeByKeyValue.set(keyValue, true);
        }

        // Take any remaining nodes that were not bound to data,
        // and place them in the exit selection.
        for (i = 0; i < nodeLength; ++i) {
          if ((node = nodeByKeyValue.get(keyValues[i])) !== true) {
            exit[i] = node;
          }
        }
      }

      return this;
    }

    var filterOf = function(selector) {
      return function() {
        return this.matches(selector);
      };
    };

    if (typeof document !== "undefined") {
      var element = document.documentElement;
      if (!element.matches) {
        var vendorMatches = element.webkitMatchesSelector || element.msMatchesSelector || element.mozMatchesSelector || element.oMatchesSelector;
        filterOf = function(selector) { return function() { return vendorMatches.call(this, selector); }; };
      }
    }

    // The filter may either be a selector string (e.g., ".foo")
    // or a function that returns a boolean.
    var selection_filter = function(filter) {
      var depth = this._depth,
          stack = new Array(depth * 2);

      if (typeof filter !== "function") filter = filterOf(filter);

      function visit(nodes, depth) {
        var i = -1,
            n = nodes.length,
            node,
            subnodes;

        if (--depth) {
          var stack0 = depth * 2,
              stack1 = stack0 + 1;
          subnodes = new Array(n);
          while (++i < n) {
            if (node = nodes[i]) {
              stack[stack0] = node._parent.__data__, stack[stack1] = i;
              subnodes[i] = visit(node, depth);
            }
          }
        }

        // The filter operation does not preserve the original index,
        // so the resulting leaf groups are dense (not sparse).
        else {
          subnodes = [];
          while (++i < n) {
            if (node = nodes[i]) {
              stack[0] = node.__data__, stack[1] = i;
              if (filter.apply(node, stack)) {
                subnodes.push(node);
              }
            }
          }
        }

        subnodes._parent = nodes._parent;
        return subnodes;
      }

      return new Selection(visit(this._root, depth), depth);
    }

    function selectorAllOf(selector) {
      return function() {
        return this.querySelectorAll(selector);
      };
    }

    // The selector may either be a selector string (e.g., ".foo")
    // or a function that optionally returns an array of nodes to select.
    // This is the only operation that increases the depth of a selection.
    var selection_selectAll = function(selector) {
      var depth = this._depth,
          stack = new Array(depth * 2);

      if (typeof selector !== "function") selector = selectorAllOf(selector);

      function visit(nodes, depth) {
        var i = -1,
            n = nodes.length,
            node,
            subnode,
            subnodes = new Array(n);

        if (--depth) {
          var stack0 = depth * 2,
              stack1 = stack0 + 1;
          while (++i < n) {
            if (node = nodes[i]) {
              stack[stack0] = node._parent.__data__, stack[stack1] = i;
              subnodes[i] = visit(node, depth);
            }
          }
        }

        // Data is not propagated since there is a one-to-many mapping.
        // The parent of the new leaf group is the old node.
        else {
          while (++i < n) {
            if (node = nodes[i]) {
              stack[0] = node.__data__, stack[1] = i;
              subnodes[i] = subnode = selector.apply(node, stack);
              subnode._parent = node;
            }
          }
        }

        subnodes._parent = nodes._parent;
        return subnodes;
      }

      return new Selection(visit(this._root, depth), depth + 1);
    }

    // The selector may either be a selector string (e.g., ".foo")
    // or a function that optionally returns the node to select.
    var selection_select = function(selector) {
      var depth = this._depth,
          stack = new Array(depth * 2);

      if (typeof selector !== "function") selector = selectorOf(selector);

      function visit(nodes, update, depth) {
        var i = -1,
            n = nodes.length,
            node,
            subnode,
            subnodes = new Array(n);

        if (--depth) {
          var stack0 = depth * 2,
              stack1 = stack0 + 1;
          while (++i < n) {
            if (node = nodes[i]) {
              stack[stack0] = node._parent.__data__, stack[stack1] = i;
              subnodes[i] = visit(node, update && update[i], depth);
            }
          }
        }

        // The leaf group may be sparse if the selector returns a falsey value;
        // this preserves the index of nodes (unlike selection.filter).
        // Propagate data to the new node only if it is defined on the old.
        // If this is an enter selection, materialized nodes are moved to update.
        else {
          while (++i < n) {
            if (node = nodes[i]) {
              stack[0] = node.__data__, stack[1] = i;
              if (subnode = selector.apply(node, stack)) {
                if ("__data__" in node) subnode.__data__ = node.__data__;
                if (update) update[i] = subnode, delete nodes[i];
                subnodes[i] = subnode;
              }
            }
          }
        }

        subnodes._parent = nodes._parent;
        return subnodes;
      }

      return new Selection(visit(this._root, this._update && this._update._root, depth), depth);
    }

    Selection.prototype = selection.prototype = {
      select: selection_select,
      selectAll: selection_selectAll,
      filter: selection_filter,
      data: selection_data,
      enter: selection_enter,
      exit: selection_exit,
      order: selection_order,
      sort: selection_sort,
      call: selection_call,
      nodes: selection_nodes,
      node: selection_node,
      size: selection_size,
      empty: selection_empty,
      each: selection_each,
      attr: selection_attr,
      style: selection_style,
      property: selection_property,
      class: selection_class,
      classed: selection_class, // deprecated alias
      text: selection_text,
      html: selection_html,
      append: selection_append,
      insert: selection_append, // deprecated alias
      remove: selection_remove,
      datum: selection_datum,
      event: selection_event,
      on: selection_event, // deprecated alias
      dispatch: selection_dispatch
    };

    function selection() {
      return new Selection([document.documentElement], 1);
    }

    function transition() {
      return new Transition([document.documentElement], 1);
    }

    Transition.prototype = transition.prototype = {
      each: selection.prototype.each,
      ease: transition_ease
    };

    var selection_transition = function(name) {
      return new Transition(this._root, this._depth, name && ("__transition_ " + name + "_"));
    }

    selection.prototype.transition = selection_transition;

    var queueHead,
        queueTail,
        active, // the currently-executing timer
        frame, // is an animation frame pending?
        timeout, // is a timeout pending?
        timeoutTime = Infinity; // the time the timeout will fire

    function wake() {
      frame = timeout = 0, timeoutTime = Infinity;
      wakeAt(timerFlush());
    }

    function wakeAt(time) {
      if (frame) return; // Fastest wake already set.
      var delay = time - Date.now();
      if (delay > 24) {
        if (timeoutTime > time) { // Note: false if time is infinite.
          if (timeout) clearTimeout(timeout);
          timeout = setTimeout(wake, delay);
          timeoutTime = time;
        }
      } else {
        if (timeout) timeout = clearTimeout(timeout), timeoutTime = Infinity;
        frame = requestAnimationFrame(wake);
      }
    }

    function Timer(callback, time) {
      this.callback = callback;
      this.time = time;
      this.flush = false;
      this.next = null;
    }

    // The timer will continue to fire until callback returns true.
    function timer(callback, delay, time) {
      if (time == null) time = Date.now(); else time = +time;
      if (delay != null) time += +delay;

      // Add the callback to the tail of the queue.
      var timer = new Timer(callback, time);
      if (queueTail) queueTail.next = timer;
      else queueHead = timer;
      queueTail = timer;

      wakeAt(time);
    }

    // Replace the current timer. Only allowed within a timer callback.
    function timerReplace(callback, delay, time) {
      if (time == null) time = Date.now(); else time = +time;
      if (delay != null) time += +delay;
      active.callback = callback;
      active.time = time;
    }

    // Execute all eligible timers,
    // then flush completed timers to avoid concurrent queue modification.
    // Returns the time of the earliest active timer.
    function timerFlush(time) {
      if (time == null) time = Date.now(); else time = +time;
      var active0 = active;

      // Note: timerFlush can be re-entrant, so we must preserve the old active.
      active = queueHead;
      while (active) {
        if (time >= active.time) active.flush = active.callback(time - active.time, time);
        active = active.next;
      }
      active = active0;
      time = Infinity;

      // Note: invoking a timer callback can change the timer queue (due to a re-
      // entrant timerFlush or scheduling a new timer). Thus we must defer capturing
      // queueHead until after we've invoked all callbacks.
      var t0,
          t1 = queueHead;
      while (t1) {
        if (t1.flush) {
          t1 = t0 ? t0.next = t1.next : queueHead = t1.next;
        } else {
          if (t1.time < time) time = t1.time;
          t1 = (t0 = t1).next;
        }
      }
      queueTail = t0;
      return time;
    }

    var bug44083 = typeof navigator !== "undefined" && /WebKit/.test(navigator.userAgent) ? -1 : 0; // https://bugs.webkit.org/show_bug.cgi?id=44083

    var select = function(selector) {
      return new Selection([typeof selector === "string" ? document.querySelector(selector) : selector], 1);
    }

    var point = function(node, event) {
      var svg = node.ownerSVGElement || node;
      if (svg.createSVGPoint) {
        var point = svg.createSVGPoint();
        if (bug44083 < 0) {
          var window = defaultView(node);
          if (window.scrollX || window.scrollY) {
            svg = select(window.document.body).append("svg").style({position: "absolute", top: 0, left: 0, margin: 0, padding: 0, border: "none"}, "important");
            var ctm = svg.node().getScreenCTM();
            bug44083 = !(ctm.f || ctm.e);
            svg.remove();
          }
        }
        if (bug44083) point.x = event.pageX, point.y = event.pageY;
        else point.x = event.clientX, point.y = event.clientY;
        point = point.matrixTransform(node.getScreenCTM().inverse());
        return [point.x, point.y];
      }
      var rect = node.getBoundingClientRect();
      return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
    }

    var sourceEvent = function() {
      var current = event, source;
      while (source = current.sourceEvent) current = source;
      return current;
    }

    var touches = function(node, touches) {
      if (arguments.length < 2) touches = sourceEvent().touches;
      for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) {
        points[i] = point(node, touches[i]);
      }
      return points;
    }

    var touch = function(node, touches, identifier) {
      if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches;
      for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) {
        if ((touch = touches[i]).identifier === identifier) {
          return point(node, touch);
        }
      }
      return null;
    }

    var selectAll = function(selector) {
      return new Selection(typeof selector === "string" ? document.querySelectorAll(selector) : selector, 1);
    }

    var mouse = function(node, event) {
      if (arguments.length < 2) event = sourceEvent();
      if (event.changedTouches) event = event.changedTouches[0];
      return point(node, event);
    }

    var d3 = {
      get event() { return event; },
      mouse: mouse,
      namespace: namespace,
      namespaces: namespaces,
      requote: requote,
      select: select,
      selectAll: selectAll,
      selection: selection,
      touch: touch,
      touches: touches,
      timer: timer,
      timerReplace: timerReplace,
      timerFlush: timerFlush,
      transition: transition
    };

    return d3;

}));


text:
module Lucene
  module Store
    include_package "org.apache.lucene.store"

    # Biggie Smalls, Biggie Smalls, Biggie Smalls
    [
      Directory,
      FSDirectory,
      RAMDirectory
      ]
  end
end


text:
namespace rmclib {

// A cvar implementation that implements /much/ of the
// condition_variable_any interface and uses futexes.

// Requirements:
// wait can be viewed as three atomic parts
//  1. unlock and deschedule
//  2. wakeup
//  3. reacquire lock
//
// Executions of three parts of wait, notify_one, notify_all can be
// given a total order consistent with visible-to (XXX: union po??).
//
// I have not worked out all of the consequences of that, but one of
// the key ones is that if a wait.1 occurs in this order before a
// notify_one and there isn't any intervening (spurious) wakeup or
// another notify_one, it needs to wake that one up.
//
// It also means that if a notifying thread acquires the lock after a
// wait.1 and then notifies, that notify must come after the wait.1.
//
// A notify does /not/ need to "synchronize with" the waiter it wakes
// up, but the lock reacquisition will "synchronize with" the release
// in the notifier!

// XXX: *not* self-synchronizing on destruction with notify_all!
class condition_variable_futex {
private:
    Futex seq_;
    rmc::atomic<int> waiters_{0};

    rmc::atomic<int32_t> &rseq() {
        return reinterpret_cast<rmc::atomic<int32_t> &>(seq_.val);
    }

public:
    condition_variable_futex() {}
    condition_variable_futex(const condition_variable_futex&) = delete;
    condition_variable_futex& operator=(const condition_variable_futex&) =
        delete;

    // OK, I think we consider a wait.1 to cv-hb a notify iff the
    // inc_waiters is visible-to* chk_waiters.

    // This is a kind of weird implementation that admits spurious
    // wakeups but is very simple.
    template<class Lock>
    void wait(Lock &lock) {
        // read_seq needs to execute first so that we can't read the
        // signal from any notify that reads our inc_waiters
        XEDGE(read_seq, inc_waiters);
        // the inc_waiters must be visible-to the chk_waiters in a
        // notifier that // acquires this lock.
        //XEDGE(inc_waiters, unlock); // REDUNDANT

        // XXX: do we need an edge going into block???
        // It would be redundant, but...
        // I don't /think/ so, actually... Maybe from read_seq, but
        // in our RMW-futex model that is implied...

        // blocking needs to be done before dec_waiters and lock,
        // which could stop it from working
        //XEDGE(block, dec_waiters); // REDUNDANT
        //XEDGE(block, lock); // REDUNDANT

        int seq = L(read_seq, rseq());
        L(inc_waiters, waiters_.fetch_add(1));

        LS(unlock, lock.unlock());

        do {
            LS(block, seq_.wait(seq));
            // I think that we shouldn't need a constraint to this
            // next read because worst case we just loop around again
            // and fail from the futex again...
        } while (rseq() == seq);

        L(dec_waiters, waiters_.fetch_add(-1));

        LS(lock, lock.lock());
    }

    void notify_one() {
        // The actual increment and wait needs to be xo after the
        // waiters check to make sure that waits that are cv-hb this
        // can't see the increment (and thus potentially miss the
        // signal)
        XEDGE(chk_waiters, signal);
        //XEDGE(chk_waiters, wake); // REDUNDANT
        // The updated seq value needs to be visible to anything we wake.
        // This is actually doubly redundant though if we are modeling
        // futexes as being RMWs to the futex location...
        //VEDGE(signal, wake); // REDUNDANT

        if (L(chk_waiters, waiters_) == 0) return;
        auto handle = seq_.getHandle();
        L(signal, rseq().fetch_add(1));
        LS(wake, Futex::wake(handle, 1));
    }

};

}

#endif


text:
'''
@author: Michael Vorotyntsev
@email: linkofwise@gmail.com
@github: unaxfromsibiria
'''

import asyncio
import functools
import logging
import inspect
import os
import re
import signal
import string
import tempfile
import weakref
import uuid

from contextlib import contextmanager
from datetime import datetime, timedelta
from random import SystemRandom

from . import action
from .common import Configuration
from .transport import Command, CommandTarget, ServerAction, AbstractTransport

_COMMAND_FILE_EXT = 'cmd'

def sleep_method(delay):
    return asyncio.sleep(delay)

class BaseDataStorage:

    _runtime_id = None
    _logger = None
    _actual_timeout = 60
    _rand = None

    def __init__(self, server):
        self._runtime_id = str(uuid.uuid4())
        self._logger = server.logger
        self.setup(**server._conf)
        self._active = True
        self._rand = SystemRandom()

    def get_old_time(self):
        return datetime.now() - timedelta(seconds=self._actual_timeout)

    def get_random_key(self):
        return '{}_{}'.format(
            datetime.now().strftime('%Y%m%d%H%M%S%f'),
            ''.join(self._rand.choice(
                string.ascii_lowercase) for _ in range(8)))

    def setup(self, **options):
        pass

    def clear(self):
        raise NotImplementedError()

    def remove_by_key(self, key):
        raise NotImplementedError()

    def find_lost_data(self):
        """
        find data from lost process
        """
        raise NotImplementedError()

    def put(self, data):
        raise NotImplementedError()

    def get(self, key):
        raise NotImplementedError()

    def stop(self):
        self._active = False

    @asyncio.coroutine
    def auto_clear_worker(self):
        iter_timeout = 5
        step_iter_count = self._actual_timeout / iter_timeout
        step_index = 0

        while self._active:
            step_index += 1
            yield from sleep_method(iter_timeout)
            if step_index < step_iter_count:
                continue

            step_index = 0
            self._logger.info('Run auto clear storage...')
            try:
                result = self.clear()
            except Exception as err:
                self._logger.error(err)
            else:
                if result:
                    self._logger.info(
                        'storage clear result: {}'.format(result))

class TmpFileDataStorage(BaseDataStorage):
    """
    Default save server command into temp fs
    """
    tmp_dir = None
    _re_file = '(?P<datetime>\d{{14}})\d.+_\S{{8}}.{}'.format(_COMMAND_FILE_EXT)

    def setup(self, tmp_dir=None, **options):
        self.tmp_dir = tmp_dir or tempfile.gettempdir()
        actual_timeout = int(options.get('storage_actual_timeout') or 0)
        if actual_timeout > 0:
            self._actual_timeout = actual_timeout

        # check
        file_name = os.path.join(
            self.tmp_dir, '.check_{}'.format(self._runtime_id))
        try:
            self._logger.debug(
                '{} check file write {}'.format(self, file_name))
            with open(file_name, mode='w') as check_file:
                check_file.write('tmp')
            os.remove(file_name)
        except Exception as err:
            self._logger.error(err)
            raise

    def put(self, data):
        result = self.get_random_key()
        file_name = os.path.join(
            self.tmp_dir, '{}.{}'.format(result, _COMMAND_FILE_EXT))
        try:
            with open(file_name, mode='w') as tmp_file:
                tmp_file.write(data)
        except Exception as err:
            self._logger.error(err)
            result = None

        return result

    def remove_by_key(self, key):
        file_name = os.path.join(
            self.tmp_dir, '{}.{}'.format(key, _COMMAND_FILE_EXT))
        try:
            os.remove(file_name)
        except Exception as err:
            # auto clear do it
            self._logger.debug(err)
            pass

    def find_files(self, old=False):
        old_time = self.get_old_time()

        for _, _, files in os.walk(self.tmp_dir):
            for filename in files:
                find_date = re.search(self._re_file, filename)

                if find_date:
                    file_path = os.path.join(self.tmp_dir, filename)
                    target_file_date = datetime.strptime(
                        find_date.group('datetime'), '%Y%m%d%H%M%S')

                    if target_file_date < old_time and old:
                        yield (target_file_date, file_path)
                    elif not old:
                        yield (target_file_date, file_path)

    def clear(self):
        result = 0
        for __, old_file in self.find_files(old=True):
            os.remove(old_file)
            result += 1
        return result

    def find_lost_data(self):
        result = []
        for file_date, file_path in self.find_files():
            with open(file_path, encoding='utf-8') as cmd_file:
                data = cmd_file.read()
                if data:
                    result.append((file_date, data))
            os.remove(file_path)
        result.sort(key=lambda item: item[0], reverse=False)
        for __, file_path in result:
            yield file_path

class ConnectionClient(asyncio.Protocol):
    _transport = None
    _command_converter = {}
    _put_to_queue = None
    _logger_name = None

    def setup(self, server):
        self._put_to_queue = weakref.WeakMethod(server.command_queue.put_nowait)
        self._logger_name = server.logger.name

    def connection_made(self, transport):
        self._transport = transport

    def connection_lost(self, exc):
        pass

    def pause_writing(self):
        pass

    def resume_writing(self):
        pass

    def data_received(self, data):
        put_method = self._put_to_queue()
        if put_method:
            put_method(data.decode("utf-8"))
        else:
            logger = logging.getLogger(self._logger_name)
            logger.error('Connection received data for closed server!')

    def eof_received(self):
        pass

    def send_command(self, command, options):
        cls = command.__class__
        converter = self._command_converter.get(cls)
        if not converter:
            converter = command.get_convertor(options)
            self._command_converter[cls] = converter

        for command_data in converter.dump(command):
            data = command_data.encode()
            print(data)
            self._transport.write(data)

class ServerSatateChanger:

    def __init__(self, state_data):
        assert isinstance(state_data, dict)
        self.state_data = state_data

    @property
    def client_id(self):
        return self.state_data.get('client_id')

    @client_id.setter
    def client_id(self, client_id):
        self.state_data.update(new_client_id=client_id)

    def send_command(self, command):
        assert self.state_data.get('command') is None, 'One command for one accept!'
        self.state_data.update(command=command)

    def option(self, name):
        return self.state_data['conf'].get(name)

    def log_error(self, msg):
        self.state_data['error'].append(msg)

    def log_info(self, msg):
        self.state_data['info'].append(msg)

    def get_server_state_info(self):
        # TODO:
        return {}

    def set_server_wait_mode(self, on=True):
        # TODO:
        pass

class ServerStateManager:

    _server = None

    def __init__(self, server):
        assert isinstance(server, BaseServer)
        self._server = weakref.ref(server)

    @property
    def server(self):
        return self._server()

    @contextmanager
    def accept(self):
        server = self.server
        state_data = {
            'info': [],
            'error': [],
        }
        if server:
            state_data.update(
                client_id=server._client_id,
                conf=server._conf)

        try:
            yield ServerSatateChanger(state_data)
        except Exception as err:
            server = self.server
            if server:
                server.logger.error(err)
        else:
            server = self.server
            if server:
                # save server data
                new_client_id = state_data.get('new_client_id')
                if new_client_id:
                    server._client_id = new_client_id

                for msg in state_data['error']:
                    server.logger.error(msg)

                for msg in state_data['info']:
                    server.logger.info(msg)

                command = state_data.get('command')
                if command and command.target:
                    if server._client_id:
                        command.cid = server._client_id
                    server._send_command(command)

class BaseActionPool:

    _action_command_cls = None
    _command_cls = None
    _convertor = None
    _actions = None
    _send_command = None
    _server_manager = None

    def __init__(self, server):

        assert issubclass(self._action_command_cls, AbstractTransport)
        assert issubclass(self._command_cls, AbstractTransport)
        self._convertor = self._action_command_cls.get_convertor(server._conf)
        self._actions = {}
        self._local_data = {}
        self._server_manager = ServerStateManager(server)

        for __, action_cls in inspect.getmembers(action, inspect.isclass):
            if issubclass(action_cls, action.BaseAction):
                if action.BaseAction is action_cls:
                    continue

                new_action = action_cls()
                assert isinstance(new_action, action.BaseAction)
                new_action.setup()
                for target in new_action.targets:
                    if target in self._actions:
                        self._actions[target].append(new_action)
                    else:
                        self._actions[target] = [new_action]

        for target in self._actions:
            self._actions[target].sort(key=lambda item: item.top, reverse=True)

    def execute(self, action_command_data, restore=False):
        action_command = self._convertor.loads(action_command_data)
        actions = self._actions.get(action_command.target)
        with self._server_manager.accept() as manager:
            if actions:
                command = self.create_command()
                prev_context = None
                for action in actions:
                    if action.processing(
                            manager, action_command, self._local_data, prev_context, command):
                        break
                    else:
                        prev_context = action.context
            else:
                command = self.create_quit_command(
                    msg='Not implimented action for target: {}'.format(
                        action_command.target))

            manager.send_command(command)

    def create_command(self, **data):
        return self._command_cls(**data)

    def create_quit_command(self, msg='quit'):
        return self._command_cls(
            target=CommandTarget.Quit, data=msg)

class ActionPool(BaseActionPool):
    _action_command_cls = ServerAction
    _command_cls = Command

class BaseServer:

    _conf = None
    _loop = None
    _active = True
    _connected = False
    _client_tcp = None
    _need_close = False
    _client_id = None
    logger = None
    command_queue = None
    storage = action_pool = None

    _STD_ITER_DELAY = 1

    def __init__(self, conf):
        assert isinstance(conf, Configuration)
        assert conf.is_completed
        self._conf = conf
        self._active = False
        self.logger = conf.logger
        storage_cls = conf.get('storage_cls') or TmpFileDataStorage
        assert issubclass(storage_cls, BaseDataStorage)
        self.storage = storage_cls(self)

        action_pool_cls = conf.get('action_pool_cls') or ActionPool
        assert issubclass(action_pool_cls, BaseActionPool)
        self.action_pool = action_pool_cls(self)

    @property
    def active(self):
        return self._active

    def close_if_need(self):
        if self._need_close:
            if self.command_queue.empty():
                self._active = False
            else:
                self.logger.warn('Wait command queue cleaning..')
            self.storage.stop()

    @asyncio.coroutine
    def _node_connection(self):
        while not self._connected:
            try:
                self._client_tcp = yield from self._loop.create_connection(
                    ConnectionClient, self._conf.host, self._conf.port)
            except OSError:
                self.logger.info('try connection...')
                yield from self.sleep_method(self._conf.reconnect_delay)
            else:
                self._active = True
                self._connected = True

    def _close_signal_receiver(self, signame):
        self.logger.info('Close signal {}, wait out'.format(signame))
        self._need_close = True

    def _hello_server(self):
        command = self.action_pool.create_command(target=CommandTarget.Sigin)
        self._send_command(command)

    def _send_command(self, command):
        self._client_tcp[1].send_command(command, self._conf)

    def _create_workers(self):

        times = {
            'delay': self._STD_ITER_DELAY,
            'manager_delay': self._STD_ITER_DELAY / 2.0,
        }
        misc_flags = {
            'need_find_command': True,
        }
        self.logger.debug('times: {}'.format(times))

        @asyncio.coroutine
        def worker(index, server):
            while server.active:
                yield from sleep_method(times['delay'])
                # TODO: check call queue
                server.logger.info('todo {}'.format(index))

        @asyncio.coroutine
        def command_manager(server):

            def move_to_processing(server_command, storage_key=None, lost=False):
                try:
                    server.action_pool.execute(server_command, restore=lost)
                except Exception as err:
                    server.logger.error(err)
                finally:
                    if not lost:
                        server.storage.remove_by_key(storage_key)

            lost_commands = None
            if misc_flags.get('need_find_command') and server.active:
                misc_flags.update(need_find_command=False)
                try:
                    lost_commands = list(server.storage.find_lost_data())
                except Exception as err:
                    server.logger.error(err)
                else:
                    if lost_commands:
                        self.logger.warn(
                            'Has data of {} lost commands'.format(len(lost_commands)))

            while server.active:
                if lost_commands:
                    for command_data in lost_commands:
                        move_to_processing(command_data, lost=True)
                    lost_commands = None

                elif server.command_queue.empty():
                    yield from sleep_method(times['manager_delay'])
                else:
                    new_command_data = yield from server.command_queue.get()
                    storage_key = server.storage.put(new_command_data)
                    if storage_key is None:
                        # big fail, return command after delay
                        yield from sleep_method(times['delay'])
                        server.command_queue.put_nowait(new_command_data)
                        server.logger.warn(
                            'Return command to queue, some problem :(')
                    else:
                        move_to_processing(new_command_data, storage_key)

                server.close_if_need()

        workers = [
            asyncio.async(worker(w_index, self), loop=self._loop)
            for w_index in range(1, self._conf.worker_count + 1)
        ]
        for __ in range(self._conf.manage_worker_count):
            workers.append(asyncio.async(command_manager(self), loop=self._loop))

        workers.append(asyncio.async(self.storage.auto_clear_worker(), loop=self._loop))
        return workers

    def run(self):
        self.logger.info('Connect to {host}:{port}'.format(**self._conf))
        loop = asyncio.get_event_loop()
        self._loop = loop
        self._need_close = False
        self._client_tcp = None
        self._connected = False
        loop.run_until_complete(self._node_connection())

        for signame in ('SIGINT', 'SIGTERM'):
            signal_id = getattr(signal, signame)
            loop.add_signal_handler(
                signal_id,
                functools.partial(self._close_signal_receiver, signame))

        self.command_queue = asyncio.Queue(loop=loop)
        self._client_tcp[1].setup(self)
        self._hello_server()
        workers = self._create_workers()
        loop.run_until_complete(asyncio.wait(workers))
        loop.close()