text:
package com.madphysicist.tools.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;

/**
 * A utility class for manipulating system files and their names. This class can
 * not be instantiated.
 *
 * @author Joseph Fox-Rabinovitz
 * @version 1.0.0, 16 Nov 2013 - J. Fox-Rabinovitz - Created
 * @since 1.0
 */
public class FileUtilities
{
    /**
     * The approximate size of a disk block in bytes. This number is intended to
     * be nearly optimal for copying files across multiple platforms. It may be
     * advisable to compute this constant for each device being copied to if
     * such a method should become readily available.
     * <p>
     * This number is set as a reasonable upper bound on the block size across
     * most platforms. The idea being that it is better to read multiple blocks
     * into a single buffer than to have to perform multiple reads for a single
     * large block if the buffer is too small. Similar logic applies to writing
     * the buffer back to disk.
     *
     * @since 1.0.0
     */
    private static final int DISK_BLOCK = 8192;

    /**
     * A private constructor to prevent instantiation.
     *
     * @since 1.0.0
     */
    private FileUtilities() {}

    /**
     * Checks if the specified file exists. If it does not, the user is asked to
     * select a replacement from a file chooser dialog.
     *
     * @param filename the name of the file to check.
     * @param filter the filter to apply in the dialog if the file does not exist. May be {@code null}.
     * @return the original file if it exists, or the replacement file if another one had to be selected.
     * @throws FileNotFoundException if the user refuses to select a file, or selects a non-existent one.
     * @since 1.0.0
     */
    public static File promptFile(String filename, FileFilter filter) throws FileNotFoundException
    {
        return promptFile(filename, filter, null);
    }

    /**
     * Checks if the specified file exists. If it does not, the user is asked to
     * select a replacement from a file chooser dialog.
     *
     * @param filename the name of the file to check.
     * @param filter the filter to apply in the dialog if the file does not exist. May be {@code null}.
     * @param title the title to set fot the dialog if the file does not exist. May be {@code null}.
     * @return the original file if it exists, or the replacement file if another one had to be selected.
     * @throws FileNotFoundException if the user refuses to select a file, or selects a non-existent one.
     * @since 1.0.0
     */
    public static File promptFile(String filename, FileFilter filter, String title) throws FileNotFoundException
    {
        return promptFile((filename == null) ? null : new File(filename), filter, title);
    }

    /**
     * Checks if the specified file exists. If it does not, the user is asked to
     * select a replacement from a file chooser dialog.
     *
     * @param file the file to check.
     * @param filter the filter to apply in the dialog if the file does not exist. May be {@code null}.
     * @param title the title to set for the dialog if the file does not exist. May be {@code null}.
     * @return the original file if it exists, or the replacement file if another one had to be selected.
     * @throws FileNotFoundException if the user refuses to select a file, or selects a non-existent one.
     * @since 1.0.0
     */
    public static File promptFile(File file, FileFilter filter, String title) throws FileNotFoundException
    {
        if(file == null || !file.exists()) {
            File start = file.getParentFile();
            if(!start.exists()) {
                start = new File(".");
            }
            JFileChooser chooser = new JFileChooser(start);

            if(title != null) {
                chooser.setDialogTitle(title);
            }
            if(filter != null) {
                chooser.addChoosableFileFilter(filter);
            }
            chooser.setFileFilter(filter);
            chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
            chooser.setMultiSelectionEnabled(false);
            chooser.setAcceptAllFileFilterUsed(true);

            if(chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
                file = chooser.getSelectedFile();
            } else {
                file = null;
            }
            if(file == null || !file.exists()) {
                throw new FileNotFoundException((file == null) ? "" : file.getAbsolutePath());
            }
        }

        return file;
    }

    /**
     * Copies the contents of one stream to another. Useful for copying files or
     * resources. To copy files, use the {@link #copyFile(java.io.File,
     * java.io.File) copyFile()} method.
     *
     * @param from the stream from which to copy.
     * @param to the stream to copy to.
     * @throws IOException if an error occurrs while reading or writing the
     * streams.
     * @since 1.0.0
     */
    public static void copyStream(InputStream from, OutputStream to) throws IOException
    {
        byte[] buffer = new byte[DISK_BLOCK];
        int nRead;
        while((nRead = from.read(buffer)) != -1) {
            to.write(buffer, 0, nRead);
        }
    }

    /**
     * Copies the contents of one file to another.
     *
     * @param from the file from which to copy.
     * @param to the file to copy to.
     * @throws IOException if an error occurrs while reading or writing the
     * files.
     * @since 1.0.0
     */
    public static void copyFile(File from, File to) throws IOException
    {
        try (InputStream input = new FileInputStream(from);
             OutputStream output = new FileOutputStream(to)) {
            FileUtilities.copyStream(input, output);
        }
    }

    /**
     * Copies the contents of an arbitrary stream into a file. This is useful
     * for creating files from various types of resources.
     *
     * @param from the stream from which to copy.
     * @param to the file to copy to.
     * @throws IOException if an error occurrs while reading the stream or
     * writing to the file.
     * @since 1.0.0
     */
    public static void copyStreamToFile(InputStream from, File to) throws IOException
    {
        try (OutputStream output = new FileOutputStream(to)) {
            FileUtilities.copyStream(from, output);
        }
    }

    /**
     * Copies the contents of a file into an arbitrary stream. This can be
     * useful for sending files through various types of streams.
     *
     * @param from the file to copy.
     * @param to the stream to copy to.
     * @throws IOException if an error occurrs while reading the file or
     * writing to the stream.
     * @since 1.0.0
     */
    public static void copyFileToStream(File from, OutputStream to) throws IOException
    {
        try (InputStream input = new FileInputStream(from)) {
            FileUtilities.copyStream(input, to);
        }
    }
}


text:
package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"os"
	"os/signal"
	"runtime"
	"strconv"
	"strings"
	"time"

	"github.com/fatih/color"
	fastping "github.com/tatsushid/go-fastping"
)

var pingIP, pingIPfile, listenPort, pingLabel string
var flagExpandDNS, flagShowRTT, flagEnableWeb, flagNoColor, flagTimestamp bool
var width = "2"
var rowcounter, maxPingCount int
var interval int

var ipList, ipLabelList, inputHosts, inputLabels []string
var ipListMap map[string][]string
var pingStats map[string]stats

func init() {
	flag.BoolVar(&flagNoColor, "nocolor", false, "disable color output")
	flag.BoolVar(&flagEnableWeb, "web", false, "enable webserver")
	flag.BoolVar(&flagExpandDNS, "expand", false, "use all available ip's (ipv4/ipv6) of a hostname (multiple A, AAAA)")
	flag.BoolVar(&flagTimestamp, "timestamp", false, "enables timestamp instead of ping count")
	flag.StringVar(&listenPort, "port", "8887", "port the webserver listens on")
	flag.StringVar(&pingIP, "hosts", "", "ip addresses/hosts to ping, space seperated (e.g \"8.8.8.8 8.8.4.4 google.com 2a00:1450:400c:c07::66\")")
	flag.StringVar(&pingIPfile, "file", "", "ip addresses/hosts file to ping, space seperated (e.g \"8.8.8.8 8.8.4.4 google.com 2a00:1450:400c:c07::66\")")
	flag.StringVar(&pingLabel, "labels", "", "labels matching the hosts, must be the same amount of values as the hosts")
	flag.BoolVar(&flagShowRTT, "showrtt", false, "show roundtrip time in ms")
	flag.IntVar(&maxPingCount, "c", 99999, "packets to send")
	flag.IntVar(&interval, "i", 1000, "Ping interval in Milliseconds")
	flag.Parse()
	if flag.NFlag() == 0 {
		fmt.Println("usage: ")
		flag.PrintDefaults()
		os.Exit(2)
	}
	if flagShowRTT {
		width = "5"
	}
	if pingIP == "" {
		b, err := ioutil.ReadFile(pingIPfile)
		if err != nil || string(b) == "" {
			fmt.Println("Error: Hosts not found")
			flag.PrintDefaults()
			os.Exit(3)
		}
		pingIP = string(b)
	}
	inputHosts = strings.Fields(pingIP)
	if len(pingLabel) > 0 {
		inputLabels = strings.Fields(pingLabel)
		if len(inputHosts) != len(inputLabels) {
			fmt.Println("ERROR: The number of hosts vs the number of labels does not match. Usage:")
			flag.PrintDefaults()
			os.Exit(2)
		}
	}
	if flagNoColor {
		color.NoColor = true
	}
	if runtime.GOOS != "windows" {
		if os.Geteuid() != 0 {
			fmt.Println("Please start gomphs as root or use sudo!")
			fmt.Println("This is required for raw socket access.")
			os.Exit(1)
		}
	}
}

type milliDuration time.Duration

func (hd milliDuration) String() string {
	milliseconds := time.Duration(hd).Nanoseconds()
	milliseconds = milliseconds / 1000000
	if milliseconds > 1000 {
		return fmt.Sprintf(">1s")
	}
	return fmt.Sprintf("%"+width+"d", milliseconds)
}

func (hd milliDuration) Int() int {
	milliseconds := time.Duration(hd).Nanoseconds()
	milliseconds = milliseconds / 1000000
	return int(milliseconds)
}

type gomphs struct {
	latestEntry []byte
	IPList      []string
	IPListMap   map[string][]string
}

type stats struct {
	min   int
	max   int
	avg   int
	count int
	rtts  []int
}

func (g *gomphs) update(result map[string]string) {
	record := []string{time.Now().Format("2006/01/02 15:04:05")}
	for _, key := range g.IPList {
		for _, value := range g.IPListMap[key] {
			if result[value] != "" {
				res := strings.Replace(result[value], " ", "", -1)
				record = append(record, res)
			} else {
				record = append(record, "-10")
			}
		}
	}
	g.latestEntry, _ = json.Marshal(record)
}

func main() {
	printcounter := rowcounter
	ipListMap = make(map[string][]string)
	pingStats = make(map[string]stats)
	g := &gomphs{}

	if flagEnableWeb {
		listener, err := net.Listen("tcp", ":"+listenPort)
		if err != nil {
			log.Fatal(err)
		}
		go http.Serve(listener, nil)
		http.HandleFunc("/read.json", webReadJSONHandler(g))
		http.HandleFunc("/stream", webStreamHandler)
	}

	result := make(map[string]string)

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		for range c {
			printStat()
			os.Exit(0)
		}
	}()
	p := fastping.NewPinger()
	p.MaxRTT = time.Millisecond * time.Duration(interval)

	labelIndex := 0
	for _, host := range inputHosts {
		if flagExpandDNS {
			lookups, err := net.LookupIP(host)
			checkHostErr(host, err)
			ipList = append(ipList, host)
			hostLabelIndex := 1
			for _, ip := range lookups {
				ra := &net.IPAddr{IP: ip}
				p.AddIPAddr(ra)
				ipListMap[host] = append(ipListMap[host], ra.String())
				if len(inputLabels) > 0 {
					ipLabelList = append(ipLabelList, inputLabels[labelIndex]+"-"+strconv.Itoa(hostLabelIndex))
				}
				hostLabelIndex++
			}
		} else {
			ra, err := net.ResolveIPAddr("ip:icmp", host)
			checkHostErr(host, err)
			p.AddIPAddr(ra)
			ipList = append(ipList, ra.String())
			ipListMap[ra.String()] = append(ipListMap[ra.String()], ra.String())
			if len(inputLabels) > 0 {
				ipLabelList = append(ipLabelList, inputLabels[labelIndex])
			}
		}
		labelIndex++
	}
	for _, label := range ipLabelList {
		widthInt, _ := strconv.Atoi(width)
		if len(label) > widthInt {
			width = strconv.Itoa(len(label))
		}
	}
	g.IPList = ipList
	g.IPListMap = ipListMap
	p.OnRecv = func(addr *net.IPAddr, rtt time.Duration) {
		result[addr.String()] = milliDuration(rtt).String()
		stats := pingStats[addr.String()]
		if stats.count == 0 {
			stats.min = 100000
		}
		stats.rtts = append(stats.rtts, milliDuration(rtt).Int())
		pingStats[addr.String()] = stats
	}
	p.OnIdle = func() {
		if rowcounter%25 == 0 {
			if flagTimestamp {
				printHeader("25", ipLabelList)
			} else {
				printHeader("4", ipLabelList)
			}
			if rowcounter%10000 == 0 {
				printcounter = 0
			}
		}
		g.update(result)
		if flagTimestamp {
			t := time.Now()
			fmt.Printf("%24s", t.Format(time.RFC3339))
		} else {
			fmt.Printf("%04d", printcounter+1)
		}
		for _, key := range ipList {
			for _, value := range ipListMap[key] {
				fmt.Printf(" ")
				if result[value] != "" {
					color.Set(color.BgGreen, color.FgYellow, color.Bold)
					if flagShowRTT {
						fmt.Printf("%"+width+"s", result[value])
					} else {
						fmt.Printf("%"+width+"s", ".")
					}
					color.Unset()
				} else {
					stats := pingStats[value]
					stats.rtts = append(stats.rtts, -1)
					pingStats[value] = stats
					color.Set(color.BgRed, color.FgYellow, color.Bold)
					fmt.Printf("%"+width+"s", "!")
					color.Unset()
				}
			}
		}
		fmt.Println(" ")
		result = make(map[string]string)
		rowcounter++
		printcounter++
	}
	if flagExpandDNS {
		printFirstHeader(ipLabelList)
	}
	for {
		if rowcounter == maxPingCount {
			break
		}
		err := p.Run()
		if err != nil {
			log.Fatal(err)
		}
	}
	printStat()
}

redpajama_set_name: RedPajamaGithub


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ColossalFramework.UI;
using UnityEngine;

namespace SkylinesMultiplayer
{
    public class Chat : UIPanel
    {
        private const int MaxChatMessageLimit = 5;
        private const int MaxChatMessageLength = 255;

        private Queue<string> m_messageLog = new Queue<string>(MaxChatMessageLimit);

        private bool m_usingChat;

        private UILabel m_chatLabel;
        private UITextField m_chatInputTextField;

        public override void Start()
        {
            UIView v = UIView.GetAView();

            m_chatLabel = this.AddUIComponent<UILabel>();
            m_chatLabel.text = "";
            m_chatLabel.anchor = UIAnchorStyle.Bottom | UIAnchorStyle.Left;
            m_chatLabel.pivot = UIPivotPoint.TopLeft;
            m_chatLabel.autoHeight = false;
            m_chatLabel.autoSize = false;
            m_chatLabel.textAlignment = UIHorizontalAlignment.Left;
            m_chatLabel.verticalAlignment = UIVerticalAlignment.Bottom;
            m_chatLabel.wordWrap = true;
            m_chatLabel.height = 250;
            m_chatLabel.width = 400;
            m_chatLabel.absolutePosition = new Vector3(50, v.fixedHeight - 320);

            m_chatInputTextField = CreateTextField();
            m_chatInputTextField.pivot = UIPivotPoint.TopLeft;
            m_chatInputTextField.absolutePosition = new Vector3(50, v.fixedHeight - 50);
            m_chatInputTextField.width = 250;
            m_chatInputTextField.maxLength = MaxChatMessageLength;
        }

        public override void Update()
        {
            if (PlayerInput.ChatKey.GetKeyDown())
            {
                m_usingChat = !m_usingChat;
                if (m_usingChat)
                {
                    m_chatInputTextField.Focus();
                    PlayerInput.DisableInput = true;
                }
                else
                {
                    SendChatMessage(m_chatInputTextField.text);
                    m_chatInputTextField.Cancel();  //Clears the textfield and remove focus from it
                    PlayerInput.DisableInput = false;
                }
            }

            if (m_usingChat)
            {
                m_chatInputTextField.Focus();
            }
        }

        void SendChatMessage(string msg)
        {
            //No point of sending if you have nothing to send
            if (msg.Length == 0)
                return;
            if (msg.Length > MaxChatMessageLength)
                msg.Remove(MaxChatMessageLength);
            string textToSend = MultiplayerManager.instance.MyNetworkPlayer.Name + ": " + msg;
            MessageSendChatMessage messageSendChat = new MessageSendChatMessage();
            messageSendChat.chatMessage = textToSend;
            MultiplayerManager.instance.SendNetworkMessage(messageSendChat, SendTo.All);
        }

        public void OnReceiveChatMessage(string msg)
        {
            if (m_messageLog.Count >= MaxChatMessageLimit)
                m_messageLog.Dequeue();
            m_messageLog.Enqueue(msg);
            RefreshChatText();
        }

        void RefreshChatText()
        {
            StringBuilder sb = new StringBuilder();
            foreach (string msg in m_messageLog)
            {
                sb.Append(msg + "\n");
            }
            m_chatLabel.text = sb.ToString();
        }

        private UITextField CreateTextField()
        {
            UITextField textField = this.AddUIComponent<UITextField>();

            textField.maxLength = 100;
            textField.enabled = true;
            textField.builtinKeyNavigation = true;
            textField.isInteractive = true;
            textField.readOnly = false;
            textField.submitOnFocusLost = true;

            textField.horizontalAlignment = UIHorizontalAlignment.Left;
            textField.selectionSprite = "EmptySprite";
            textField.selectionBackgroundColor = new Color32(0, 171, 234, 255);
            textField.normalBgSprite = "TextFieldPanel";
            textField.textColor = new Color32(174, 197, 211, 255);
            textField.disabledTextColor = new Color32(254, 254, 254, 255);
            textField.textScale = 1.3f;
            textField.opacity = 1;
            textField.color = new Color32(58, 88, 104, 255);
            textField.disabledColor = new Color32(254, 254, 254, 255);

            return textField;
        }
    }
}


text:
Brett Zamir

on 2010-12-27 05:50:40

@seingh: Yes, document.write() works all right (unless you are using XHTML served as application/xhtml+xml), but this function attempts to offer normal DOM construction (assuming well-formed XHTML) which can work in either environment.

seingh

on 2010-12-25 13:19:41

i think that echo() is only document.write() ...

Brett Zamir

on 2010-10-29 02:31:43

@EdorFaus: Good catch (and bad mistake on my part, mitigated a bit by the catch thankfully). Fixed in Git (along with some JSLint/coding standards fixes).

EdorFaus

on 2010-10-29 01:26:58

I think this code (lines 57-60) is not quite right:

if (!fc || !fc.documentElement ||
  fc.documentElement.localName !== 'parsererror' ||
  fc.documentElement.namespaceURI !== 'http://www.mozilla.org/newlayout/xml/parsererror.xml') {
  return fc.documentElement.firstChild;

Considering what's in the block, and the last two tests, shouldn't the or-s be and-s, and the two first tests be reversed, to avoid returning undefined? Like this:

if (fc && fc.documentElement &&
  fc.documentElement.localName !== 'parsererror' &&
  fc.documentElement.namespaceURI !== 'http://www.mozilla.org/newlayout/xml/parsererror.xml') {
  return fc.documentElement.firstChild;

Cue

on 2010-05-13 16:04:57

This throws an error in Firefox 3.6.3. Works fine in all other browsers.

stringToDOM(arg, d.body, ns_xhtml, "div").cloneNode is not a function

Brett Zamir

on 2009-05-30 10:22:22

JB, I adapted your idea as our last resort, since it may not work in an XML context. I also moved out the bulky code and added support for the common DOMParser or IE-specific parsing--for those who want full standards support, they can add the script referenced in the code to add DOM 3 Load and Save. The problem now though is that one must use the XHTML namespace since the script is giving a chance for the parsing to be done by DOMParser(), etc. for the sake of working with and in XML. We might make that code only execute if an ini is set, thus removing the need for a namespace.

JB

on 2009-05-29 05:18:31

Couldn't you just create a new node, innerHTML the code into it then move all of the children of the new node into body?

Brett Zamir

on 2009-04-30 03:21:04

@Eugene, thanks for the catch! Fixed in SVN. (p.s. We're hoping to catch such issues automatically in the future with JSLint)

Eugene Bulkin

on 2009-04-30 00:28:57

Lines 62 and 132 are missing semicolons after the bracket; as you are setting a var to a function, you must include them or when you pack the code it can trigger errors.

Kevin van Zonneveld

on 2009-01-25 13:41:24

@ Brett Zamir: Noted. I don't mind big comments. Relevant info should be here, and people should know how to use ctrl+f :)

Brett Zamir

on 2009-01-18 03:28:54

As far as output buffering, I plan to shortly discuss my thoughts on how this, as with other issues, can be solved without too much pain for maintenance with a global instead, but if not, being dependent on echo would be fine by me.

By the way, maybe the function could also test

if (document.body) {
    document.body.appendChild(stringToDOM(arg));
}
else {
    document.documentElement.appendChild(stringToDOM(arg));
}

to see if there IS a document.body, in case we are in an XML context (like XUL), and if not, append after the last element in the document.

As far as the speed, in my crude tests just now in JavaScript, there seems to be no difference in JavaScript between returning with null and not returning anything. But in PHP there is apparently a slight difference according to the FAQ linked from the PHP documentation: http://www.faqts.com/knowledge_base/view.phtml/aid/1/fid/40 , and the behavior of echo is not to return anything (while print returns 1), so I think there's no reason to return null specifically (takes a little more space in the already big function!) :)

As far as implementing the DOM functions, you're right, there is no place I know of, except serialize() if it handles DOM objects, and DOMDocument::saveXML, DOMDocument::loadXML . (speaking of the DOM in PHP (as in DOMDocument::validate), I'd LOVE to get XML validation in JS somehow).

But the note about the DOM functions was otherwise more just of an interesting aside (if you don't mind my overloading the comments here!).

Kevin van Zonneveld

on 2009-01-17 13:36:29

unfortunately, right now i cannot implement print as rhino already provides it. will have to change the testsuite later on.

out buffering is a great idea. we should first make all functions that print something rely on echo,
and have echo collect a buffer. i can see this working.

does that really effect the speed, yes?

notes removed.

I don't see yet where else we we should implement those dom functions. I have to say I don't work with that stuff on a daily basis.

Brett Zamir

on 2009-01-17 03:14:38

Sorry, if you did apply my changes for an independent version of print(), this should be changed to also apply the fix for stringToDOM():

    if (document.createDocumentFragment &amp;&amp; document.createTextNode &amp;&amp; document.appendChild) {
        stringToDOM(arg);
    }

to

    if (document.createDocumentFragment &amp;&amp; document.createTextNode &amp;&amp; document.appendChild) {
        document.body.appendChild(stringToDOM(arg));
    }

Brett Zamir

on 2009-01-17 03:11:03

One important thing first...The line

stringToDOM(arg);

needs to be changed to:

document.body.appendChild(stringToDOM(arg));

Now...print() would be the same with the following differences:

This line at the top:

var arg = '', argc = arguments.length, argv = arguments, i = 0;

can be entirely removed in print(). print() should also have &quot;arg&quot; added as an explicit function parameter (unless you want to merge the functions--see below).

To get the marginal speed difference with echo, you don't even need the line &quot;return null&quot; because functions always return undefined when not specified (which is probably a little closer to the PHP behavior if we get picky).

The for loop at the end can be replaced with the following shorter version if you are making an independent version for print():

    if (document.createDocumentFragment &amp;&amp; document.createTextNode &amp;&amp; document.appendChild) {
        stringToDOM(arg);
    } else if (document.write) {
        document.write(arg);
    }
    return 1;

Note that if you did decide to have print() call echo() and just let its single argument cycle through the for loop one time, you'd have to still:
1) avoid potential recursion by avoiding the print(arg) call (as I did above for a dedicated version of print())
2) return 1 instead of not returning anything

Also, you can remove the notes to this function now (and for print()).

By the way, I realized that the stringToDOM() function can be stripped down a tiny bit more by changing substr() references to slice() (same behavior with one argument)--and substring() calls could be changed to slice() in cases where the 2nd argument would never be negative, though that would be harder to gauge without going through the code.

After going through the stringToDOM() code a little more, besides the shortening just mentioned, I realized that a little bit more could be done, such as allow namespaces on elements and attributes when parsing to DOM. I'm not sure though when I may have time to get to it (have some deadlines now), but I hope to get to it eventually.

It would be cool if there could be some what we could specify where we wanted the echo to go (e.g., if we didn't want it in the body).  You know, I think we should be able to actually implement the PHP output buffer functions by configuring a parameter (as in the global php_js) which allowed the output from such functions to be captured and aggregated (until flushed/cleaned) and then output later or assigned to a variable!

As an extended aside, another great thing about the stringToDOM() and DOMToString() functions is that they could be combined to make a standards-compliant version of the DOM level 3 Load-and-Save module for serialization and parsing (currently not supported in Firefox and probably other browsers).

For example, using the skeleton code within the source at https://bugzilla.mozilla.org/attachment.cgi?id=333875 (for Mozilla bug https://bugzilla.mozilla.org/show_bug.cgi?id=155749 ), they could be used within the code for LSSerializer.prototype.writeToString and LSParser.prototype.parse .

Thus you could parse in any browser in a compliant fashion with something like this:

var lsInput = DOMImplementationLS.createLSInput().stringData = '&lt;myXml/&gt;';

var doc = DOMImplementationLS.createLSParser(1, null).parse(lsInput);

and serialize in any browser with something like this:

var ser = DOMImplementationLS.createLSSerializer();
var str = ser.writeToString(document);

Admittedly it might not be pretty, but it's standard (and can easily be wrapped as with the current Firefox and IE equivalents).

Kevin van Zonneveld

on 2009-01-16 23:11:51

@ der_simon &amp; Brett Zamir: First of all, Der Simon Thank you so much for coming to us and offering your great code to our project. It seems we can put it to good use.

My main concern was that for such a little function, it would be a lot of code. There's no room in PHP.JS for global dependencies so it would really have to be duplicated inside the functions. So a really bloated echo would be the result.

I'm okay with it now because:
- Brett you did a great job trimming it down the the essentials that are important to us.
- I have actually gotten some work done on the public compiler, which will enable people to optionally include echo in their package.

Never ceases to amaze me. The simplest functions sometimes need the biggest chunks of code ;)

Anyway, great effort both.

PS. Can we alias print to echo?

Brett Zamir

on 2009-01-15 23:18:43

Since Kevin stated it might be possible to use innerDOM, I took it upon myself to check with Der Simon to see if we could release under MIT.

Although it is still somewhat large for the average PHP-JS function, with a few superficial tweaks to the already terse code (such as removing a couple document.all blocks), and by just using one of his functions (the only one needed by echo), we can get something as relatively small as this:

function stringToDOM(q){
    var d=document;
    function r(a){
	return a.replace(/\r/g,' ').replace(/\n/g,' ');
    }
    function s(a){
	return a.replace(/&amp;amp;/g,'&amp;').replace(/&amp;gt;/g,'&gt;').replace(/&amp;lt;/g,'&lt;').replace(/&amp;nbsp;/g,' ').replace(/&amp;quot;/g,'&quot;');
    }
    function t(a){
	return a.replace(/ /g,'');
    }
    function u(a){
	var b,c,e,f,g,h,i;
	b=d.createDocumentFragment();
	c=a.indexOf(' ');
	if(c===-1){
	    b.appendChild(d.createElement(a.toLowerCase()))
	}
	else{
	    i=t(a.substring(0,c)).toLowerCase();
	    a=a.substr(c+1);
	    b.appendChild(d.createElement(i));
	    while(a.length){
		e=a.indexOf('=');
		if(e&gt;=0){
		    f=t(a.substring(0,e)).toLowerCase();
		    g=a.indexOf('&quot;');
		    a=a.substr(g+1);
		    g=a.indexOf('&quot;');
		    h=s(a.substring(0,g));
		    a=a.substr(g+2);
		    b.lastChild.setAttribute(f,h)
	      }else{
		  break
	      }
	  }
      }
      return b
  }
  function v(a,b,c){
      var e,f;
      e=b;
      c=c.toLowerCase();
      f=e.indexOf('&lt;/'+c+'&gt;');
      a=a.concat(e.substring(0,f));
      e=e.substr(f);
      while(a.indexOf('&lt;'+c)!=-1){
	  a=a.substr(a.indexOf('&lt;'+c));
	  a=a.substr(a.indexOf('&gt;')+1);
	  e=e.substr(e.indexOf('&gt;')+1);
	  f=e.indexOf('&lt;/'+c+'&gt;');
	  a=a.concat(e.substring(0,f));
	  e=e.substr(f)
      }
      return b.length-e.length
  }
  function w(a){
      var b,c,e,f,g,h,i,j,k,l,m,n,o,p,q;
      b=d.createDocumentFragment();
      while(a&amp;&amp;a.length){
	  c=a.indexOf('&lt;');
	  if(c===-1){
	      a=s(a);
	      b.appendChild(d.createTextNode(a));
	      a=null
	  }
	  else if(c){
	      q=s(a.substring(0,c));
	      b.appendChild(d.createTextNode(q));
	      a=a.substr(c)
	  }
	  else{
	      e=a.indexOf('&lt;!--');
	      if(!e){
		  f=a.indexOf('--&gt;');
		  g=a.substring(4,f);
		  g=s(g);
		  b.appendChild(d.createComment(g));
		  a=a.substr(f+3)
	      }
	      else{
		  h=a.indexOf('&gt;');
		  if(a.substring(h-1,h)==='/'){
		      i=a.indexOf('/&gt;');
		      j=a.substring(1,i);
		      b.appendChild(u(j));
		      a=a.substr(i+2)
		  }
		  else{
		      k=a.indexOf('&gt;');
		      l=a.substring(1,k);
		      m=d.createDocumentFragment();
		      m.appendChild(u(l));
		      a=a.substr(k+1);
		      n=a.substring(0,a.indexOf('&lt;/'));
		      a=a.substr(a.indexOf('&lt;/'));
		      if(n.indexOf('&lt;')!=-1){
			  o=m.lastChild.nodeName;
			  p=v(n,a,o);
			  n=n.concat(a.substring(0,p));
			  a=a.substr(p)
		      }
		      a=a.substr(a.indexOf('&gt;')+1);
		      m.lastChild.appendChild(w(n));
		      b.appendChild(m)
		  }
	      }
	  }
      }
      return b
  }
  return w(q)
}

I suggest incorporating his useful and standards-compliant method (and also adding print() too), if you were still open to it...

(Maybe it would be even more standards compliant if it checked for createElementNS support, but using the function in XUL still works ok for me)

der_simon

on 2009-01-15 20:44:37

Hi,

im the author of the innerDOM-Script and I'm happy that anyone really cares about my few lines of code. I'm way out of the programming business, so I can only partly partitiate.

What I couldn't see from my point is: Whould it help to contribiute the innerDOM-Script to your project or not? The php.js page says:

"There's no good place for a package like http://innerdom.sourceforge.net/"

So if it would be helpful I'm willing to contribute my code.

Regard from Germany

Der Simon

Kevin van Zonneveld

on 2008-11-14 00:58:19

@ Nate: I believe it would upset a lot of peope if we were to use innerHTML (considering &quot;echo is bad&quot;'s comments). innerDOM seems to be a solution, but we can't include it into php.js without changing php.js' nature. And to do that for only echo, would make inpracticle an understatement. We'll have to think some more on the innerDOM thing I guess: maybe we could ask it's author if we can just copy a portion of his code into this function directly. That would:
- work
- not change php.js' standalone-lyness
- make echo a big function ;)

Thank you very much for sharing your thoughts and code on this with us. For now, I've at least  comitted your changes.

Nate

on 2008-11-13 16:16:35

There are a few problems with this function.

1. There is a misspelling.  The code

            var txt = document.createTextNode(aarg);

Should read

            var txt = document.createTextNode(arg);

2. After

            docFragment.appendChild(txt);

you need the line

            document.body.appendChild(docFragment);

I tested it with Firefox, IE, Opera, and Chrome (via wine), and they all worked (on Linux).

3. Like Philip Peterson pointed out, createTextNode() converts HTML to text.  I still think that innerHTML() is better because it actually works (and it's fast).  Though it might not be practical for this project, you could use the innerDOM script from http://innerdom.sourceforge.net/ to achieve the same effect as innerHTML() and adhere to &quot;standards.&quot;

Kevin van Zonneveld

on 2008-11-03 11:08:12

@ Waldo Malqui Silva: Hi there! Good to have you back Waldo! I've changed all the _argos credits to Waldo Malqui Silva.

We track the 'unported' functions in SVN, which can also be viewed here:
http://trac.plutonia.nl/projects/phpjs/browser/trunk/_unported

Everytime we create a new function it's moved from ./_unported to ./functions

I'll be looking forward to seeing some of your excellent work again.  And your english i fine btw ;) ciao!

waldo malqui silva

on 2008-10-29 03:18:11

HI, Kevin I'm back from long tiime, I wanna know if is possible 2 things:

1.- Change mi nick (_argos) by my real name (Waldo Malqui Silva) :p
2.- If you have a TODO list of functions to port.

I'm happy to back and see more functions that in my last visit. I promise practice more my english :p

PD: I'm working in a customizable download for the project like mootools 1.11 (packages¿?) based on the PHP functions group :p

Kevin van Zonneveld

on 2008-10-20 18:24:08

@ Philip Peterson: I've fixed the first issue, we still have to work on the second one.

Philip Peterson

on 2008-10-18 03:15:22

Aggh, sorry to clog up the comments, but there's also another problem: using createTextNode and then appending it like that converts all the special characters (e.g. tags) to HTML entities, thus reducing the usability of HTML formatting in echo().

Philip Peterson

on 2008-10-18 03:07:05

Also, this is a very pressing issue.  In Firefox, at the line

document.appendChild(elmt);

the script breaks, because it should be (for Firefox at least)

body.appendChild(elmt);

Philip Peterson

on 2008-10-14 22:43:47

From Ronsguide.com:

var docFragment = document.createDocumentFragment();
var txt = document.createTextNode(&quot;my text node&quot;);
docFragment.appendChild(txt);

I guess probably something like that? (note that I am not &quot;echo is bad&quot;.)

Perhaps there should be an alias print() which would take one argument?  It may also be useful to handle \b things (I think php does this, but I'm not sure), which could be accomplished by inserting some text that appears nowhere else in the document (like [COD_92993] or something) and then modify the .innerHTML of the body by removing that [COD_92993] plus as many characters as there are \b's.

Kevin van Zonneveld

on 2008-04-17 12:45:03

@ echo is bad: I've never used that function, could you tell me:
- this is what the code Should look like?
- your name to include in the comment

echo is bad

on 2008-04-16 18:17:48

Using innerHTML on the BODY is very dangerous because you will break all references to HTMLElements that were done before !

I strongly recommend you to use document.createDocumentFragment.

Kevin van Zonneveld

on 2008-04-15 09:03:15

Probably because it's executing a document.write from outside the real document, don't you think?

Philip Peterson

on 2008-04-15 08:34:09

I think this function is breaking php.js tester x.x


text:
=encoding utf-8

=head1 NAME

ngx_mail_proxy_module - Module ngx_mail_proxy_module

=head1 Directives

=head2 proxy_buffer

B<syntax:> proxy_buffer I<I<C<size>>>

B<default:> I<4kE<verbar>8k>

B<context:> I<mail>

B<context:> I<server>

Sets the size of the buffer used for proxying.
By default, the buffer size is equal to one memory page.
Depending on a platform, it is either 4K or 8K.

=head2 proxy_pass_error_message

B<syntax:> proxy_pass_error_message I<C<on> E<verbar> C<off>>

B<default:> I<off>

B<context:> I<mail>

B<context:> I<server>

Indicates whether to pass the error message obtained during
the authentication on the backend to the client.

Usually, if the authentication in nginx is a success,
the backend cannot return an error.
If it nevertheless returns an error,
it means some internal error has occurred.
In such case the backend message can contain information
that should not be shown to the client.
However, responding with an error for the correct password
is a normal behavior for some POP3 servers.
For example, CommuniGatePro informs a user about
L<mailbox
overflow|http://www.stalker.com/CommuniGatePro/Alerts.html#Quota> or other events by periodically outputting the
L<authentication
error|http://www.stalker.com/CommuniGatePro/POP.html#Alerts>.
The directive should be enabled in this case.

=head2 proxy_timeout

B<syntax:> proxy_timeout I<I<C<timeout>>>

B<default:> I<24h>

B<context:> I<mail>

B<context:> I<server>

Sets the I<C<timeout>> between two successive
read or write operations on client or proxied server connections.
If no data is transmitted within this time, the connection is closed.

=head2 xclient

B<syntax:> xclient I<C<on> E<verbar> C<off>>

B<default:> I<on>

B<context:> I<mail>

B<context:> I<server>

Enables or disables the passing of the
L<XCLIENT|http://www.postfix.org/XCLIENT_README.html>
command with client parameters when connecting to the SMTP backend.

With C<XCLIENT>, the MTA is able to write client information
to the log and apply various limitations based on this data.

If C<XCLIENT> is enabled
then nginx passes the following commands when connecting to the backend:

=over

=item *

C<EHLO> with the
L<server name|ngx_mail_core_module>

=item *

C<
XCLIENT
>

=item *

C<EHLO> or C<HELO>,
as passed by the client

=back

If the name
L<found|ngx_mail_core_module>
by the client IP address points to the same address,
it is passed in the C<NAME> parameter
of the C<XCLIENT> command.
If the name could not be found, points to a different address,
or L<ngx_mail_core_module> is not specified,
the C<[UNAVAILABLE]> is passed
in the C<NAME> parameter.
If an error has occurred in the process of resolving,
the C<[TEMPUNAVAIL]> value is used.

If C<XCLIENT> is disabled
then nginx passes the C<EHLO> command with the
L<server name|ngx_mail_core_module>
when connecting to the backend if the client has passed
C<EHLO>,
or C<HELO> with the server name, otherwise.


text:
set -ex

# Docker Variables
NAME=vite_server
USER=thevite
DOCKER_NAME="${USER}/${NAME}"
TAG=${1:-latest}

cp build/libs/${NAME}-*.jar docker/${NAME}.jar
docker build docker/ -t ${DOCKER_NAME}:${TAG}
rm docker/${NAME}.jar


text:
package org.icepdf.core.pobjects.graphics.batik.ext.awt;

import java.awt.*;
import java.awt.geom.AffineTransform;

/**
 * This is the superclass for Paints which use a multiple color
 * gradient to fill in their raster.  It provides storage for variables and
 * enumerated values common to LinearGradientPaint and RadialGradientPaint.
 *
 * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
 * @author Vincent Hardy
 * @version $Id: MultipleGradientPaint.java,v 1.1 2008/09/30 20:44:16 patrickc Exp $
 */
public abstract class MultipleGradientPaint implements Paint {

    /**
     * Transparency.
     */
    protected int transparency;

    /**
     * Gradient keyframe values in the range 0 to 1.
     */
    protected float[] fractions;

    /**
     * Gradient colors.
     */
    protected Color[] colors;

    /**
     * Transform to apply to gradient.
     */
    protected AffineTransform gradientTransform;

    /**
     * The method to use when painting out of the gradient bounds.
     */
    protected CycleMethodEnum cycleMethod;

    /**
     * The colorSpace in which to perform the interpolation.
     */
    protected ColorSpaceEnum colorSpace;

    /**
     * Inner class to allow for typesafe enumerated ColorSpace values.
     */
    public static class ColorSpaceEnum {
    }

    /**
     * Inner class to allow for typesafe enumerated CycleMethod values.
     */
    public static class CycleMethodEnum {
    }

    /**
     * Indicates (if the gradient starts or ends inside the target region)
     * to use the terminal colors to fill the remaining area. (default)
     */
    public static final CycleMethodEnum NO_CYCLE = new CycleMethodEnum();

    /**
     * Indicates (if the gradient starts or ends inside the target region),
     * to cycle the gradient colors start-to-end, end-to-start to fill the
     * remaining area.
     */
    public static final CycleMethodEnum REFLECT = new CycleMethodEnum();

    /**
     * Indicates (if the gradient starts or ends inside the target region),
     * to cycle the gradient colors start-to-end, start-to-end to fill the
     * remaining area.
     */
    public static final CycleMethodEnum REPEAT = new CycleMethodEnum();

    /**
     * Indicates that the color interpolation should occur in sRGB space.
     * (default)
     */
    public static final ColorSpaceEnum SRGB = new ColorSpaceEnum();

    /**
     * Indicates that the color interpolation should occur in linearized
     * RGB space.
     */
    public static final ColorSpaceEnum LINEAR_RGB = new ColorSpaceEnum();

    /**
     * Superclass constructor, typical user should never have to call this.
     *
     * @param fractions         numbers ranging from 0.0 to 1.0 specifying the
     *                          distribution of colors along the gradient
     * @param colors            array of colors corresponding to each fractional value
     * @param cycleMethod       either NO_CYCLE, REFLECT, or REPEAT
     * @param colorSpace        which colorspace to use for interpolation,
     *                          either SRGB or LINEAR_RGB
     * @param gradientTransform transform to apply to the gradient
     * @throws NullPointerException     if arrays are null, or
     *                                  gradientTransform is null
     * @throws IllegalArgumentException if fractions.length != colors.length,
     *                                  or if colors is less than 2 in size, or if an enumerated value is bad.
     */
    public MultipleGradientPaint(float[] fractions,
                                 Color[] colors,
                                 CycleMethodEnum cycleMethod,
                                 ColorSpaceEnum colorSpace,
                                 AffineTransform gradientTransform) {

        if (fractions == null) {
            throw new IllegalArgumentException("Fractions array cannot be " +
                    "null");
        }

        if (colors == null) {
            throw new IllegalArgumentException("Colors array cannot be null");
        }

        if (fractions.length != colors.length) {
            throw new IllegalArgumentException("Colors and fractions must " +
                    "have equal size");
        }

        if (colors.length < 2) {
            throw new IllegalArgumentException("User must specify at least " +
                    "2 colors");
        }

        if ((colorSpace != LINEAR_RGB) &&
                (colorSpace != SRGB)) {
            throw new IllegalArgumentException("Invalid colorspace for " +
                    "interpolation.");
        }

        if ((cycleMethod != NO_CYCLE) &&
                (cycleMethod != REFLECT) &&
                (cycleMethod != REPEAT)) {
            throw new IllegalArgumentException("Invalid cycle method.");
        }

        if (gradientTransform == null) {
            throw new IllegalArgumentException("Gradient transform cannot be " +
                    "null.");
        }

        //copy the fractions array
        this.fractions = new float[fractions.length];
        System.arraycopy(fractions, 0, this.fractions, 0, fractions.length);

        //copy the colors array
        this.colors = new Color[colors.length];
        System.arraycopy(colors, 0, this.colors, 0, colors.length);

        //copy some flags
        this.colorSpace = colorSpace;
        this.cycleMethod = cycleMethod;

        //copy the gradient transform
        this.gradientTransform = (AffineTransform) gradientTransform.clone();

        // Process transparency
        boolean opaque = true;
        for (int i = 0; i < colors.length; i++) {
            opaque = opaque && (colors[i].getAlpha() == 0xff);
        }

        if (opaque) {
            transparency = OPAQUE;
        } else {
            transparency = TRANSLUCENT;
        }
    }

    /**
     * Returns a copy of the array of colors used by this gradient.
     *
     * @return a copy of the array of colors used by this gradient
     */
    public Color[] getColors() {
        Color[] colors = new Color[this.colors.length];
        System.arraycopy(this.colors, 0, colors, 0, this.colors.length);
        return colors;
    }

    /**
     * Returns a copy of the array of floats used by this gradient
     * to calculate color distribution.
     *
     * @return a copy of the array of floats used by this gradient to
     *         calculate color distribution
     */
    public float[] getFractions() {
        float[] fractions = new float[this.fractions.length];
        System.arraycopy(this.fractions, 0, fractions, 0, this.fractions.length);
        return fractions;
    }

    /**
     * Returns the transparency mode for this LinearGradientPaint.
     *
     * @return an integer value representing this LinearGradientPaint object's
     *         transparency mode.
     */
    public int getTransparency() {
        return transparency;
    }

    /**
     * Returns the enumerated type which specifies cycling behavior.
     *
     * @return the enumerated type which specifies cycling behavior
     */
    public CycleMethodEnum getCycleMethod() {
        return cycleMethod;
    }

    /**
     * Returns the enumerated type which specifies color space for
     * interpolation.
     *
     * @return the enumerated type which specifies color space for
     *         interpolation
     */
    public ColorSpaceEnum getColorSpace() {
        return colorSpace;
    }

    /**
     * Returns a copy of the transform applied to the gradient.
     *
     * @return a copy of the transform applied to the gradient.
     */
    public AffineTransform getTransform() {
        return (AffineTransform) gradientTransform.clone();
    }
}


text:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="co.polarr.demo.autoenhance">

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:requestLegacyExternalStorage="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".CameraActivity" />
        <activity android:name=".PhotoDemoActivity" />
    </application>

</manifest>


text:
'use strict';
/*jshint asi: true, browser: true */

var proxyquire =  require('browsyquire')(require)
  ;

test('\nreplacing a module with null to simulate a non found module', function (t) {

  var myPolyfill;
  var foober = proxyquire('../fixtures/replace-with-null', { './bar': null, './es-bar': {
    Polyfill: myPolyfill
  } });

  t.equal(myPolyfill, foober, 'returns the modified value')

  t.end()
})


text:
include_recipe 'munin-node'

yum_package 'munin'

# 設定する
template '/etc/munin/munin.conf' do
  mode     0644
  notifies :restart, 'service[munin-node]'
end

cookbook_file '/etc/httpd/conf.d/munin.conf' do
  mode 0644
end

file '/etc/munin/munin-htpasswd' do
  action :delete
end


text:
using System;
using Cake.Core;
using Cake.Core.IO;

namespace Cake.Common.Tools.DotNetCore.Run
{
    /// <summary>
    /// .NET Core project runner.
    /// </summary>
    public sealed class DotNetCoreRunner : DotNetCoreTool<DotNetCoreRunSettings>
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="DotNetCoreRunner" /> class.
        /// </summary>
        /// <param name="fileSystem">The file system.</param>
        /// <param name="environment">The environment.</param>
        /// <param name="processRunner">The process runner.</param>
        /// <param name="globber">The globber.</param>
        public DotNetCoreRunner(
            IFileSystem fileSystem,
            ICakeEnvironment environment,
            IProcessRunner processRunner,
            IGlobber globber)
            : base(fileSystem, environment, processRunner, globber)
        {
        }

        /// <summary>
        /// Runs the project using the specified path with arguments and settings.
        /// </summary>
        /// <param name="project">The target project path.</param>
        /// <param name="arguments">The arguments.</param>
        /// <param name="settings">The settings.</param>
        public void Run(string project, string arguments, DotNetCoreRunSettings settings)
        {
            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }

            Run(settings, GetArguments(project, arguments, settings));
        }

        private ProcessArgumentBuilder GetArguments(string project, string arguments, DotNetCoreRunSettings settings)
        {
            var builder = CreateArgumentBuilder(settings);

            builder.Append("run");

            // Specific path?
            if (project != null)
            {
                builder.Append("--project");
                builder.AppendQuoted(project);
            }

            // Framework
            if (!string.IsNullOrEmpty(settings.Framework))
            {
                builder.Append("--framework");
                builder.Append(settings.Framework);
            }

            // Configuration
            if (!string.IsNullOrEmpty(settings.Configuration))
            {
                builder.Append("--configuration");
                builder.Append(settings.Configuration);
            }

            if (!string.IsNullOrEmpty(arguments))
            {
                builder.Append("--");
                builder.AppendQuoted(arguments);
            }

            return builder;
        }
    }
}


text:
//
// Blackfriday Markdown Processor
// Available at http://github.com/russross/blackfriday
//
// Copyright © 2011 Russ Ross <russ@russross.com>.
// Distributed under the Simplified BSD License.
// See README.md for details.
//

//
// Functions to parse inline elements.
//

package blackfriday

import (
	"bytes"
	"regexp"
	"strconv"
)

var (
	urlRe    = `((https?|ftp):\/\/|\/)[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+`
	anchorRe = regexp.MustCompile(`^(<a\shref="` + urlRe + `"(\stitle="[^"<>]+")?\s?>` + urlRe + `<\/a>)`)

	// TODO: improve this regexp to catch all possible entities:
	htmlEntityRe = regexp.MustCompile(`&[a-z]{2,5};`)
)

// Functions to parse text within a block
// Each function returns the number of chars taken care of
// data is the complete block being rendered
// offset is the number of valid chars before the current cursor

func (p *Markdown) inline(currBlock *Node, data []byte) {
	// handlers might call us recursively: enforce a maximum depth
	if p.nesting >= p.maxNesting || len(data) == 0 {
		return
	}
	p.nesting++
	beg, end := 0, 0
	for end < len(data) {
		handler := p.inlineCallback[data[end]]
		if handler != nil {
			if consumed, node := handler(p, data, end); consumed == 0 {
				// No action from the callback.
				end++
			} else {
				// Copy inactive chars into the output.
				currBlock.AppendChild(text(data[beg:end]))
				if node != nil {
					currBlock.AppendChild(node)
				}
				// Skip past whatever the callback used.
				beg = end + consumed
				end = beg
			}
		} else {
			end++
		}
	}
	if beg < len(data) {
		if data[end-1] == '\n' {
			end--
		}
		currBlock.AppendChild(text(data[beg:end]))
	}
	p.nesting--
}

// single and double emphasis parsing
func emphasis(p *Markdown, data []byte, offset int) (int, *Node) {
	data = data[offset:]
	c := data[0]

	if len(data) > 2 && data[1] != c {
		// whitespace cannot follow an opening emphasis;
		// strikethrough only takes two characters '~~'
		if c == '~' || isspace(data[1]) {
			return 0, nil
		}
		ret, node := helperEmphasis(p, data[1:], c)
		if ret == 0 {
			return 0, nil
		}

		return ret + 1, node
	}

	if len(data) > 3 && data[1] == c && data[2] != c {
		if isspace(data[2]) {
			return 0, nil
		}
		ret, node := helperDoubleEmphasis(p, data[2:], c)
		if ret == 0 {
			return 0, nil
		}

		return ret + 2, node
	}

	if len(data) > 4 && data[1] == c && data[2] == c && data[3] != c {
		if c == '~' || isspace(data[3]) {
			return 0, nil
		}
		ret, node := helperTripleEmphasis(p, data, 3, c)
		if ret == 0 {
			return 0, nil
		}

		return ret + 3, node
	}

	return 0, nil
}

func codeSpan(p *Markdown, data []byte, offset int) (int, *Node) {
	data = data[offset:]

	nb := 0

	// count the number of backticks in the delimiter
	for nb < len(data) && data[nb] == '`' {
		nb++
	}

	// find the next delimiter
	i, end := 0, 0
	for end = nb; end < len(data) && i < nb; end++ {
		if data[end] == '`' {
			i++
		} else {
			i = 0
		}
	}

	// no matching delimiter?
	if i < nb && end >= len(data) {
		return 0, nil
	}

	// trim outside whitespace
	fBegin := nb
	for fBegin < end && data[fBegin] == ' ' {
		fBegin++
	}

	fEnd := end - nb
	for fEnd > fBegin && data[fEnd-1] == ' ' {
		fEnd--
	}

	// render the code span
	if fBegin != fEnd {
		code := NewNode(Code)
		code.Literal = data[fBegin:fEnd]
		return end, code
	}

	return end, nil
}

// newline preceded by two spaces becomes <br>
func maybeLineBreak(p *Markdown, data []byte, offset int) (int, *Node) {
	origOffset := offset
	for offset < len(data) && data[offset] == ' ' {
		offset++
	}

	if offset < len(data) && data[offset] == '\n' {
		if offset-origOffset >= 2 {
			return offset - origOffset + 1, NewNode(Hardbreak)
		}
		return offset - origOffset, nil
	}
	return 0, nil
}

// newline without two spaces works when HardLineBreak is enabled
func lineBreak(p *Markdown, data []byte, offset int) (int, *Node) {
	if p.extensions&HardLineBreak != 0 {
		return 1, NewNode(Hardbreak)
	}
	return 0, nil
}

type linkType int

const (
	linkNormal linkType = iota
	linkImg
	linkDeferredFootnote
	linkInlineFootnote
)

func isReferenceStyleLink(data []byte, pos int, t linkType) bool {
	if t == linkDeferredFootnote {
		return false
	}
	return pos < len(data)-1 && data[pos] == '[' && data[pos+1] != '^'
}

func maybeImage(p *Markdown, data []byte, offset int) (int, *Node) {
	if offset < len(data)-1 && data[offset+1] == '[' {
		return link(p, data, offset)
	}
	return 0, nil
}

func maybeInlineFootnote(p *Markdown, data []byte, offset int) (int, *Node) {
	if offset < len(data)-1 && data[offset+1] == '[' {
		return link(p, data, offset)
	}
	return 0, nil
}

// '[': parse a link or an image or a footnote
func link(p *Markdown, data []byte, offset int) (int, *Node) {
	// no links allowed inside regular links, footnote, and deferred footnotes
	if p.insideLink && (offset > 0 && data[offset-1] == '[' || len(data)-1 > offset && data[offset+1] == '^') {
		return 0, nil
	}

	var t linkType
	switch {
	// special case: ![^text] == deferred footnote (that follows something with
	// an exclamation point)
	case p.extensions&Footnotes != 0 && len(data)-1 > offset && data[offset+1] == '^':
		t = linkDeferredFootnote
	// ![alt] == image
	case offset >= 0 && data[offset] == '!':
		t = linkImg
		offset++
	// ^[text] == inline footnote
	// [^refId] == deferred footnote
	case p.extensions&Footnotes != 0:
		if offset >= 0 && data[offset] == '^' {
			t = linkInlineFootnote
			offset++
		} else if len(data)-1 > offset && data[offset+1] == '^' {
			t = linkDeferredFootnote
		}
	// [text] == regular link
	default:
		t = linkNormal
	}

	data = data[offset:]

	var (
		i                       = 1
		noteID                  int
		title, link, altContent []byte
		textHasNl               = false
	)

	if t == linkDeferredFootnote {
		i++
	}

	// look for the matching closing bracket
	for level := 1; level > 0 && i < len(data); i++ {
		switch {
		case data[i] == '\n':
			textHasNl = true

		case data[i-1] == '\\':
			continue

		case data[i] == '[':
			level++

		case data[i] == ']':
			level--
			if level <= 0 {
				i-- // compensate for extra i++ in for loop
			}
		}
	}

	if i >= len(data) {
		return 0, nil
	}

	txtE := i
	i++
	var footnoteNode *Node

	// skip any amount of whitespace or newline
	// (this is much more lax than original markdown syntax)
	for i < len(data) && isspace(data[i]) {
		i++
	}

	// inline style link
	switch {
	case i < len(data) && data[i] == '(':
		// skip initial whitespace
		i++

		for i < len(data) && isspace(data[i]) {
			i++
		}

		linkB := i

		// look for link end: ' " )
	findlinkend:
		for i < len(data) {
			switch {
			case data[i] == '\\':
				i += 2

			case data[i] == ')' || data[i] == '\'' || data[i] == '"':
				break findlinkend

			default:
				i++
			}
		}

		if i >= len(data) {
			return 0, nil
		}
		linkE := i

		// look for title end if present
		titleB, titleE := 0, 0
		if data[i] == '\'' || data[i] == '"' {
			i++
			titleB = i

		findtitleend:
			for i < len(data) {
				switch {
				case data[i] == '\\':
					i += 2

				case data[i] == ')':
					break findtitleend

				default:
					i++
				}
			}

			if i >= len(data) {
				return 0, nil
			}

			// skip whitespace after title
			titleE = i - 1
			for titleE > titleB && isspace(data[titleE]) {
				titleE--
			}

			// check for closing quote presence
			if data[titleE] != '\'' && data[titleE] != '"' {
				titleB, titleE = 0, 0
				linkE = i
			}
		}

		// remove whitespace at the end of the link
		for linkE > linkB && isspace(data[linkE-1]) {
			linkE--
		}

		// remove optional angle brackets around the link
		if data[linkB] == '<' {
			linkB++
		}
		if data[linkE-1] == '>' {
			linkE--
		}

		// build escaped link and title
		if linkE > linkB {
			link = data[linkB:linkE]
		}

		if titleE > titleB {
			title = data[titleB:titleE]
		}

		i++

	// reference style link
	case isReferenceStyleLink(data, i, t):
		var id []byte
		altContentConsidered := false

		// look for the id
		i++
		linkB := i
		for i < len(data) && data[i] != ']' {
			i++
		}
		if i >= len(data) {
			return 0, nil
		}
		linkE := i

		// find the reference
		if linkB == linkE {
			if textHasNl {
				var b bytes.Buffer

				for j := 1; j < txtE; j++ {
					switch {
					case data[j] != '\n':
						b.WriteByte(data[j])
					case data[j-1] != ' ':
						b.WriteByte(' ')
					}
				}

				id = b.Bytes()
			} else {
				id = data[1:txtE]
				altContentConsidered = true
			}
		} else {
			id = data[linkB:linkE]
		}

		// find the reference with matching id
		lr, ok := p.getRef(string(id))
		if !ok {
			return 0, nil
		}

		// keep link and title from reference
		link = lr.link
		title = lr.title
		if altContentConsidered {
			altContent = lr.text
		}
		i++

	// shortcut reference style link or reference or inline footnote
	default:
		var id []byte

		// craft the id
		if textHasNl {
			var b bytes.Buffer

			for j := 1; j < txtE; j++ {
				switch {
				case data[j] != '\n':
					b.WriteByte(data[j])
				case data[j-1] != ' ':
					b.WriteByte(' ')
				}
			}

			id = b.Bytes()
		} else {
			if t == linkDeferredFootnote {
				id = data[2:txtE] // get rid of the ^
			} else {
				id = data[1:txtE]
			}
		}

		footnoteNode = NewNode(Item)
		if t == linkInlineFootnote {
			// create a new reference
			noteID = len(p.notes) + 1

			var fragment []byte
			if len(id) > 0 {
				if len(id) < 16 {
					fragment = make([]byte, len(id))
				} else {
					fragment = make([]byte, 16)
				}
				copy(fragment, slugify(id))
			} else {
				fragment = append([]byte("footnote-"), []byte(strconv.Itoa(noteID))...)
			}

			ref := &reference{
				noteID:   noteID,
				hasBlock: false,
				link:     fragment,
				title:    id,
				footnote: footnoteNode,
			}

			p.notes = append(p.notes, ref)

			link = ref.link
			title = ref.title
		} else {
			// find the reference with matching id
			lr, ok := p.getRef(string(id))
			if !ok {
				return 0, nil
			}

			if t == linkDeferredFootnote {
				lr.noteID = len(p.notes) + 1
				lr.footnote = footnoteNode
				p.notes = append(p.notes, lr)
			}

			// keep link and title from reference
			link = lr.link
			// if inline footnote, title == footnote contents
			title = lr.title
			noteID = lr.noteID
		}

		// rewind the whitespace
		i = txtE + 1
	}

	var uLink []byte
	if t == linkNormal || t == linkImg {
		if len(link) > 0 {
			var uLinkBuf bytes.Buffer
			unescapeText(&uLinkBuf, link)
			uLink = uLinkBuf.Bytes()
		}

		// links need something to click on and somewhere to go
		if len(uLink) == 0 || (t == linkNormal && txtE <= 1) {
			return 0, nil
		}
	}

	// call the relevant rendering function
	var linkNode *Node
	switch t {
	case linkNormal:
		linkNode = NewNode(Link)
		linkNode.Destination = normalizeURI(uLink)
		linkNode.Title = title
		if len(altContent) > 0 {
			linkNode.AppendChild(text(altContent))
		} else {
			// links cannot contain other links, so turn off link parsing
			// temporarily and recurse
			insideLink := p.insideLink
			p.insideLink = true
			p.inline(linkNode, data[1:txtE])
			p.insideLink = insideLink
		}

	case linkImg:
		linkNode = NewNode(Image)
		linkNode.Destination = uLink
		linkNode.Title = title
		linkNode.AppendChild(text(data[1:txtE]))
		i++

	case linkInlineFootnote, linkDeferredFootnote:
		linkNode = NewNode(Link)
		linkNode.Destination = link
		linkNode.Title = title
		linkNode.NoteID = noteID
		linkNode.Footnote = footnoteNode
		if t == linkInlineFootnote {
			i++
		}

	default:
		return 0, nil
	}

	return i, linkNode
}

func (p *Markdown) inlineHTMLComment(data []byte) int {
	if len(data) < 5 {
		return 0
	}
	if data[0] != '<' || data[1] != '!' || data[2] != '-' || data[3] != '-' {
		return 0
	}
	i := 5
	// scan for an end-of-comment marker, across lines if necessary
	for i < len(data) && !(data[i-2] == '-' && data[i-1] == '-' && data[i] == '>') {
		i++
	}
	// no end-of-comment marker
	if i >= len(data) {
		return 0
	}
	return i + 1
}

func stripMailto(link []byte) []byte {
	if bytes.HasPrefix(link, []byte("mailto://")) {
		return link[9:]
	} else if bytes.HasPrefix(link, []byte("mailto:")) {
		return link[7:]
	} else {
		return link
	}
}

// autolinkType specifies a kind of autolink that gets detected.
type autolinkType int

// These are the possible flag values for the autolink renderer.
const (
	notAutolink autolinkType = iota
	normalAutolink
	emailAutolink
)

// '<' when tags or autolinks are allowed
func leftAngle(p *Markdown, data []byte, offset int) (int, *Node) {
	data = data[offset:]
	altype, end := tagLength(data)
	if size := p.inlineHTMLComment(data); size > 0 {
		end = size
	}
	if end > 2 {
		if altype != notAutolink {
			var uLink bytes.Buffer
			unescapeText(&uLink, data[1:end+1-2])
			if uLink.Len() > 0 {
				link := uLink.Bytes()
				node := NewNode(Link)
				node.Destination = link
				if altype == emailAutolink {
					node.Destination = append([]byte("mailto:"), link...)
				}
				node.AppendChild(text(stripMailto(link)))
				return end, node
			}
		} else {
			htmlTag := NewNode(HTMLSpan)
			htmlTag.Literal = data[:end]
			return end, htmlTag
		}
	}

	return end, nil
}

// '\\' backslash escape
var escapeChars = []byte("\\`*_{}[]()#+-.!:|&<>~")

func escape(p *Markdown, data []byte, offset int) (int, *Node) {
	data = data[offset:]

	if len(data) > 1 {
		if p.extensions&BackslashLineBreak != 0 && data[1] == '\n' {
			return 2, NewNode(Hardbreak)
		}
		if bytes.IndexByte(escapeChars, data[1]) < 0 {
			return 0, nil
		}

		return 2, text(data[1:2])
	}

	return 2, nil
}

func unescapeText(ob *bytes.Buffer, src []byte) {
	i := 0
	for i < len(src) {
		org := i
		for i < len(src) && src[i] != '\\' {
			i++
		}

		if i > org {
			ob.Write(src[org:i])
		}

		if i+1 >= len(src) {
			break
		}

		ob.WriteByte(src[i+1])
		i += 2
	}
}

// '&' escaped when it doesn't belong to an entity
// valid entities are assumed to be anything matching &#?[A-Za-z0-9]+;
func entity(p *Markdown, data []byte, offset int) (int, *Node) {
	data = data[offset:]

	end := 1

	if end < len(data) && data[end] == '#' {
		end++
	}

	for end < len(data) && isalnum(data[end]) {
		end++
	}

	if end < len(data) && data[end] == ';' {
		end++ // real entity
	} else {
		return 0, nil // lone '&'
	}

	ent := data[:end]
	// undo & escaping or it will be converted to &amp; by another
	// escaper in the renderer
	if bytes.Equal(ent, []byte("&")) {
		ent = []byte{'&'}
	}

	return end, text(ent)
}

func linkEndsWithEntity(data []byte, linkEnd int) bool {
	entityRanges := htmlEntityRe.FindAllIndex(data[:linkEnd], -1)
	return entityRanges != nil && entityRanges[len(entityRanges)-1][1] == linkEnd
}

// hasPrefixCaseInsensitive is a custom implementation of
//     strings.HasPrefix(strings.ToLower(s), prefix)
// we rolled our own because ToLower pulls in a huge machinery of lowercasing
// anything from Unicode and that's very slow. Since this func will only be
// used on ASCII protocol prefixes, we can take shortcuts.
func hasPrefixCaseInsensitive(s, prefix []byte) bool {
	if len(s) < len(prefix) {
		return false
	}
	delta := byte('a' - 'A')
	for i, b := range prefix {
		if b != s[i] && b != s[i]+delta {
			return false
		}
	}
	return true
}

var protocolPrefixes = [][]byte{
	[]byte("http://"),
	[]byte("https://"),
	[]byte("ftp://"),
	[]byte("file://"),
	[]byte("mailto:"),
}

const shortestPrefix = 6 // len("ftp://"), the shortest of the above

func maybeAutoLink(p *Markdown, data []byte, offset int) (int, *Node) {
	// quick check to rule out most false hits
	if p.insideLink || len(data) < offset+shortestPrefix {
		return 0, nil
	}
	for _, prefix := range protocolPrefixes {
		endOfHead := offset + 8 // 8 is the len() of the longest prefix
		if endOfHead > len(data) {
			endOfHead = len(data)
		}
		if hasPrefixCaseInsensitive(data[offset:endOfHead], prefix) {
			return autoLink(p, data, offset)
		}
	}
	return 0, nil
}

func autoLink(p *Markdown, data []byte, offset int) (int, *Node) {
	// Now a more expensive check to see if we're not inside an anchor element
	anchorStart := offset
	offsetFromAnchor := 0
	for anchorStart > 0 && data[anchorStart] != '<' {
		anchorStart--
		offsetFromAnchor++
	}

	anchorStr := anchorRe.Find(data[anchorStart:])
	if anchorStr != nil {
		anchorClose := NewNode(HTMLSpan)
		anchorClose.Literal = anchorStr[offsetFromAnchor:]
		return len(anchorStr) - offsetFromAnchor, anchorClose
	}

	// scan backward for a word boundary
	rewind := 0
	for offset-rewind > 0 && rewind <= 7 && isletter(data[offset-rewind-1]) {
		rewind++
	}
	if rewind > 6 { // longest supported protocol is "mailto" which has 6 letters
		return 0, nil
	}

	origData := data
	data = data[offset-rewind:]

	if !isSafeLink(data) {
		return 0, nil
	}

	linkEnd := 0
	for linkEnd < len(data) && !isEndOfLink(data[linkEnd]) {
		linkEnd++
	}

	// Skip punctuation at the end of the link
	if (data[linkEnd-1] == '.' || data[linkEnd-1] == ',') && data[linkEnd-2] != '\\' {
		linkEnd--
	}

	// But don't skip semicolon if it's a part of escaped entity:
	if data[linkEnd-1] == ';' && data[linkEnd-2] != '\\' && !linkEndsWithEntity(data, linkEnd) {
		linkEnd--
	}

	// See if the link finishes with a punctuation sign that can be closed.
	var copen byte
	switch data[linkEnd-1] {
	case '"':
		copen = '"'
	case '\'':
		copen = '\''
	case ')':
		copen = '('
	case ']':
		copen = '['
	case '}':
		copen = '{'
	default:
		copen = 0
	}

	if copen != 0 {
		bufEnd := offset - rewind + linkEnd - 2

		openDelim := 1

		/* Try to close the final punctuation sign in this same line;
		 * if we managed to close it outside of the URL, that means that it's
		 * not part of the URL. If it closes inside the URL, that means it
		 * is part of the URL.
		 *
		 * Examples:
		 *
		 *      foo http://www.pokemon.com/Pikachu_(Electric) bar
		 *              => http://www.pokemon.com/Pikachu_(Electric)
		 *
		 *      foo (http://www.pokemon.com/Pikachu_(Electric)) bar
		 *              => http://www.pokemon.com/Pikachu_(Electric)
		 *
		 *      foo http://www.pokemon.com/Pikachu_(Electric)) bar
		 *              => http://www.pokemon.com/Pikachu_(Electric))
		 *
		 *      (foo http://www.pokemon.com/Pikachu_(Electric)) bar
		 *              => foo http://www.pokemon.com/Pikachu_(Electric)
		 */

		for bufEnd >= 0 && origData[bufEnd] != '\n' && openDelim != 0 {
			if origData[bufEnd] == data[linkEnd-1] {
				openDelim++
			}

			if origData[bufEnd] == copen {
				openDelim--
			}

			bufEnd--
		}

		if openDelim == 0 {
			linkEnd--
		}
	}

	var uLink bytes.Buffer
	unescapeText(&uLink, data[:linkEnd])

	if uLink.Len() > 0 {
		node := NewNode(Link)
		node.Destination = uLink.Bytes()
		node.AppendChild(text(uLink.Bytes()))
		return linkEnd, node
	}

	return linkEnd, nil
}

func isEndOfLink(char byte) bool {
	return isspace(char) || char == '<'
}

var validUris = [][]byte{[]byte("http://"), []byte("https://"), []byte("ftp://"), []byte("mailto://")}
var validPaths = [][]byte{[]byte("/"), []byte("./"), []byte("../")}

func isSafeLink(link []byte) bool {
	for _, path := range validPaths {
		if len(link) >= len(path) && bytes.Equal(link[:len(path)], path) {
			if len(link) == len(path) {
				return true
			} else if isalnum(link[len(path)]) {
				return true
			}
		}
	}

	for _, prefix := range validUris {
		// TODO: handle unicode here
		// case-insensitive prefix test
		if len(link) > len(prefix) && bytes.Equal(bytes.ToLower(link[:len(prefix)]), prefix) && isalnum(link[len(prefix)]) {
			return true
		}
	}

	return false
}

// return the length of the given tag, or 0 is it's not valid
func tagLength(data []byte) (autolink autolinkType, end int) {
	var i, j int

	// a valid tag can't be shorter than 3 chars
	if len(data) < 3 {
		return notAutolink, 0
	}

	// begins with a '<' optionally followed by '/', followed by letter or number
	if data[0] != '<' {
		return notAutolink, 0
	}
	if data[1] == '/' {
		i = 2
	} else {
		i = 1
	}

	if !isalnum(data[i]) {
		return notAutolink, 0
	}

	// scheme test
	autolink = notAutolink

	// try to find the beginning of an URI
	for i < len(data) && (isalnum(data[i]) || data[i] == '.' || data[i] == '+' || data[i] == '-') {
		i++
	}

	if i > 1 && i < len(data) && data[i] == '@' {
		if j = isMailtoAutoLink(data[i:]); j != 0 {
			return emailAutolink, i + j
		}
	}

	if i > 2 && i < len(data) && data[i] == ':' {
		autolink = normalAutolink
		i++
	}

	// complete autolink test: no whitespace or ' or "
	switch {
	case i >= len(data):
		autolink = notAutolink
	case autolink != notAutolink:
		j = i

		for i < len(data) {
			if data[i] == '\\' {
				i += 2
			} else if data[i] == '>' || data[i] == '\'' || data[i] == '"' || isspace(data[i]) {
				break
			} else {
				i++
			}

		}

		if i >= len(data) {
			return autolink, 0
		}
		if i > j && data[i] == '>' {
			return autolink, i + 1
		}

		// one of the forbidden chars has been found
		autolink = notAutolink
	}
	i += bytes.IndexByte(data[i:], '>')
	if i < 0 {
		return autolink, 0
	}
	return autolink, i + 1
}

// look for the address part of a mail autolink and '>'
// this is less strict than the original markdown e-mail address matching
func isMailtoAutoLink(data []byte) int {
	nb := 0

	// address is assumed to be: [-@._a-zA-Z0-9]+ with exactly one '@'
	for i := 0; i < len(data); i++ {
		if isalnum(data[i]) {
			continue
		}

		switch data[i] {
		case '@':
			nb++

		case '-', '.', '_':
			break

		case '>':
			if nb == 1 {
				return i + 1
			}
			return 0
		default:
			return 0
		}
	}

	return 0
}

// look for the next emph char, skipping other constructs
func helperFindEmphChar(data []byte, c byte) int {
	i := 0

	for i < len(data) {
		for i < len(data) && data[i] != c && data[i] != '`' && data[i] != '[' {
			i++
		}
		if i >= len(data) {
			return 0
		}
		// do not count escaped chars
		if i != 0 && data[i-1] == '\\' {
			i++
			continue
		}
		if data[i] == c {
			return i
		}

		if data[i] == '`' {
			// skip a code span
			tmpI := 0
			i++
			for i < len(data) && data[i] != '`' {
				if tmpI == 0 && data[i] == c {
					tmpI = i
				}
				i++
			}
			if i >= len(data) {
				return tmpI
			}
			i++
		} else if data[i] == '[' {
			// skip a link
			tmpI := 0
			i++
			for i < len(data) && data[i] != ']' {
				if tmpI == 0 && data[i] == c {
					tmpI = i
				}
				i++
			}
			i++
			for i < len(data) && (data[i] == ' ' || data[i] == '\n') {
				i++
			}
			if i >= len(data) {
				return tmpI
			}
			if data[i] != '[' && data[i] != '(' { // not a link
				if tmpI > 0 {
					return tmpI
				}
				continue
			}
			cc := data[i]
			i++
			for i < len(data) && data[i] != cc {
				if tmpI == 0 && data[i] == c {
					return i
				}
				i++
			}
			if i >= len(data) {
				return tmpI
			}
			i++
		}
	}
	return 0
}

func helperEmphasis(p *Markdown, data []byte, c byte) (int, *Node) {
	i := 0

	// skip one symbol if coming from emph3
	if len(data) > 1 && data[0] == c && data[1] == c {
		i = 1
	}

	for i < len(data) {
		length := helperFindEmphChar(data[i:], c)
		if length == 0 {
			return 0, nil
		}
		i += length
		if i >= len(data) {
			return 0, nil
		}

		if i+1 < len(data) && data[i+1] == c {
			i++
			continue
		}

		if data[i] == c && !isspace(data[i-1]) {

			if p.extensions&NoIntraEmphasis != 0 {
				if !(i+1 == len(data) || isspace(data[i+1]) || ispunct(data[i+1])) {
					continue
				}
			}

			emph := NewNode(Emph)
			p.inline(emph, data[:i])
			return i + 1, emph
		}
	}

	return 0, nil
}

func helperDoubleEmphasis(p *Markdown, data []byte, c byte) (int, *Node) {
	i := 0

	for i < len(data) {
		length := helperFindEmphChar(data[i:], c)
		if length == 0 {
			return 0, nil
		}
		i += length

		if i+1 < len(data) && data[i] == c && data[i+1] == c && i > 0 && !isspace(data[i-1]) {
			nodeType := Strong
			if c == '~' {
				nodeType = Del
			}
			node := NewNode(nodeType)
			p.inline(node, data[:i])
			return i + 2, node
		}
		i++
	}
	return 0, nil
}

func helperTripleEmphasis(p *Markdown, data []byte, offset int, c byte) (int, *Node) {
	i := 0
	origData := data
	data = data[offset:]

	for i < len(data) {
		length := helperFindEmphChar(data[i:], c)
		if length == 0 {
			return 0, nil
		}
		i += length

		// skip whitespace preceded symbols
		if data[i] != c || isspace(data[i-1]) {
			continue
		}

		switch {
		case i+2 < len(data) && data[i+1] == c && data[i+2] == c:
			// triple symbol found
			strong := NewNode(Strong)
			em := NewNode(Emph)
			strong.AppendChild(em)
			p.inline(em, data[:i])
			return i + 3, strong
		case (i+1 < len(data) && data[i+1] == c):
			// double symbol found, hand over to emph1
			length, node := helperEmphasis(p, origData[offset-2:], c)
			if length == 0 {
				return 0, nil
			}
			return length - 2, node
		default:
			// single symbol found, hand over to emph2
			length, node := helperDoubleEmphasis(p, origData[offset-1:], c)
			if length == 0 {
				return 0, nil
			}
			return length - 1, node
		}
	}
	return 0, nil
}

func text(s []byte) *Node {
	node := NewNode(Text)
	node.Literal = s
	return node
}

func normalizeURI(s []byte) []byte {
	return s // TODO: implement
}


text:
using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.Regions;
using Microsoft.Practices.Unity;
using QBank.BasicAccountModule.Proxy;

namespace QBank.BasicAccountModule
{
    public class BasicAccountModule : IModule
    {
        private readonly IUnityContainer _container;
        private readonly IRegionManager _regionManager;

        public BasicAccountModule(IRegionManager regionManager, IUnityContainer container)
        {
            _regionManager = regionManager;
            _container = container;
        }

        #region IModule Members

        public void Initialize()
        {
            RegisterViews();
            RegisterViewModels();
            InjectScreensIntoRegions();
        }

        #endregion

        private void InjectScreensIntoRegions()
        {
            var view = _container.Resolve<CurrentBalanceView>();
            var mainView = _container.Resolve<WithdrawalView>();

            _regionManager.AddToRegion("TopRegion", view);
            _regionManager.AddToRegion("MainRegion", mainView);
        }

        private void RegisterViewModels()
        {
            _container.RegisterType<AccountServiceClient, AccountServiceClient>();
        }

        private void RegisterViews()
        {
            _container.RegisterType<CurrentBalanceView, CurrentBalanceView>();
            _container.RegisterType<CurrentBalanceViewModel, CurrentBalanceViewModel>();

            _container.RegisterType<WithdrawalView, WithdrawalView>();
            _container.RegisterType<WithdrawalViewModel, WithdrawalViewModel>();
        }
    }
}


text:
from django.conf.urls import patterns, url
from items import views

urlpatterns = patterns(
    '',
    url(r'^$', views.show_items, name='show'),
    url(r'update/$', views.update_items, name='update')
)


text:
package org.bouncycastle.crypto.ec;

import java.math.BigInteger;
import java.security.SecureRandom;

import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.math.ec.ECPoint;

/**
 * this transforms the original randomness used for an ElGamal encryption.
 */
public class ECNewRandomnessTransform
    implements ECPairFactorTransform
{
    private ECPublicKeyParameters key;
    private SecureRandom          random;

    private BigInteger            lastK;

    /**
     * initialise the underlying EC ElGamal engine.
     *
     * @param param the necessary EC key parameters.
     */
    public void init(
        CipherParameters    param)
    {
        if (param instanceof ParametersWithRandom)
        {
            ParametersWithRandom    p = (ParametersWithRandom)param;

            if (!(p.getParameters() instanceof ECPublicKeyParameters))
            {
                throw new IllegalArgumentException("ECPublicKeyParameters are required for new randomness transform.");
            }

            this.key = (ECPublicKeyParameters)p.getParameters();
            this.random = p.getRandom();
        }
        else
        {
            if (!(param instanceof ECPublicKeyParameters))
            {
                throw new IllegalArgumentException("ECPublicKeyParameters are required for new randomness transform.");
            }

            this.key = (ECPublicKeyParameters)param;
            this.random = new SecureRandom();
        }
    }

    /**
     * Transform an existing cipher test pair using the ElGamal algorithm. Note: it is assumed this
     * transform has been initialised with the same public key that was used to create the original
     * cipher text.
     *
     * @param cipherText the EC point to process.
     * @return returns a new ECPair representing the result of the process.
     */
    public ECPair transform(ECPair cipherText)
    {
        if (key == null)
        {
            throw new IllegalStateException("ECNewRandomnessTransform not initialised");
        }

        BigInteger             n = key.getParameters().getN();
        BigInteger             k = ECUtil.generateK(n, random);

        ECPoint  g = key.getParameters().getG();
        ECPoint  gamma = g.multiply(k);
        ECPoint  phi = key.getQ().multiply(k).add(cipherText.getY());

        lastK = k;

        return new ECPair(cipherText.getX().add(gamma).normalize(), phi.normalize());
    }

    /**
     * Return the last random value generated for a transform
     *
     * @return a BigInteger representing the last random value.
     */
    public BigInteger getTransformValue()
    {
        return lastK;
    }
}


text:
/*
 * HomeReducer
 *
 * The reducer takes care of our data. Using actions, we can change our
 * application state.
 * To add a new action, add it to the switch statement in the reducer function
 *
 * Example:
 * case YOUR_ACTION_CONSTANT:
 *   return state.set('yourStateVariable', true);
 */

import {
  LOAD_OCCUPATION_SUCCESS,
  CHANGE_QUERY,
  CHANGE_LIST_QUERY,
  LOAD_OCCUPATION_LIST_SUCCESS,
} from './constants';
import { fromJS } from 'immutable';

// The initial state of the App
const initialState = fromJS({
  query: '',
  occupations: [],
  error: false,
  occupationListQuery: '',
  occupationList: fromJS([]),
});

function addOccupationReducer(state = initialState, action) {
  switch (action.type) {
    case CHANGE_QUERY:
      return state
        .set('query', action.query);
    case CHANGE_LIST_QUERY:
      return state
        .set('occupationListQuery', action.occupationListQuery);
    case LOAD_OCCUPATION_SUCCESS:
      return state
        .set('occupations', action.occupations.splice(0, 10));
    case LOAD_OCCUPATION_LIST_SUCCESS:
      return state
        .set('occupationList', state.get('occupationList').clear())
        .updateIn(['occupationList'], (arr) => arr.push(...action.occupationList));
    default:
      return state;
  }
}

export default addOccupationReducer;


text:
from struct import *
from common import *
import sys

GNAMELEN_OFFSET = 0x30
ENAMELEN_OFFSET = 0x14
FNAMELEN_OFFSET = 0x10

def read_group(group_dump):
    group = {}
    glen, group['flag'], group['domain'], group['event group offset'], \
        group['event group length'], group['schema index'], \
        group['event count'] = unpack_from(">HxxIBxHHBB", group_dump)
    group['event indexes'] = unpack_from(">16H", group_dump[0x10:])
    group['name'], nlen = read_string(group_dump[GNAMELEN_OFFSET:])
    group['description'], dlen = read_string(group_dump[(GNAMELEN_OFFSET + nlen):])

    return glen, group

def read_formula(formula_dump):
    formula = {}
    tlen, formula['flag'], formula['Group'] = unpack_from(">HxxIH6x",
                                                          formula_dump)
    if formula['flag'] == 0x4:
        formula['Grouped'] = 'y'
    else:
        formula['Grouped'] = 'n'

    formula['Formula Name'], nlen = read_string(formula_dump[FNAMELEN_OFFSET:])
    formula['Formula Description'], dlen = read_string(formula_dump[(FNAMELEN_OFFSET + nlen):])
    formula['Formula'], flen = read_string(formula_dump[(FNAMELEN_OFFSET + nlen + dlen):])
    formula['Unit'], ulen = read_string(formula_dump[(FNAMELEN_OFFSET + nlen + dlen + flen):])

    return tlen, formula

def read_event(event_dump):
    event = {}
    elen, event['formula index'], event['domain'], event['record byte offset'], event['record length'], \
        event['counter offset'], event['flag'], event['primary group index'], \
        event['group count'] = unpack_from(">HHBxHHHIHH", event_dump)

    if event['formula index'] == 0xffff:
        event['formula index'] = "-1"

    event['name'], nlen = read_string(event_dump[ENAMELEN_OFFSET:])
    event['description'], dlen = read_string(event_dump[(ENAMELEN_OFFSET + nlen):])
    event['detailed description'], ddlen = read_string(event_dump[(ENAMELEN_OFFSET + nlen + dlen):])

    return elen, event

def read_groups(dump_file, page_offset, num_pages, num_count, group_type):
    f = open(dump_file, 'r')
    f.seek(page_offset * PAGE_SIZE, 0)
    dump = f.read(PAGE_SIZE * num_pages)

    if group_type == 'groups':
        read_fn = read_group
    elif group_type == 'events':
        read_fn = read_event
    elif group_type == 'formulae':
        read_fn = read_formula
    else:
        print "No such group"

    offset = 0
    groups = []
    for i in range(0, num_count):
        glen, group = read_fn(dump[offset:])
        offset += glen
        groups.append(group)

    f.close()

    return groups

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print "Require a lid file to read from"
        exit(1)

    lid_file = sys.argv[1]

    f = open(lid_file, 'r')
    dump = f.read(PAGE_SIZE)
    f.close()

    desc, length, version, build_date, schema_offset, schema_len, schema_len, \
    event_offset, event_len, event_count, group_offset, group_len, \
    group_count, formula_offset, formula_len, formula_count = unpack_from(">IIQ16s32xHHHxxHHHxxHHHxxHHHxx",
                                                                          dump)

    signature = struct.unpack('4s', struct.pack('>I', desc))[0]
    if signature != "24x7":
        print "Not a catalog file"
        exit(1)

    print "File Signature: %s\nLength: %d\nVersion: %lu\nBuild Date: %s" % (signature, length, version, build_date)

    write_to_csv('formulae.csv', read_groups(lid_file, formula_offset, formula_len, formula_count, 'formulae'))
    write_to_csv('events.csv', read_groups(lid_file, event_offset, event_len, event_count, 'events'))
    write_to_csv('groups.csv', read_groups(lid_file, group_offset, group_len, group_count, 'groups'))


text:
package algebra
package instances

import algebra.ring._

package object bigInt extends BigIntInstances

trait BigIntInstances extends cats.kernel.instances.BigIntInstances {
  implicit val bigIntAlgebra: BigIntAlgebra =
    new BigIntAlgebra
}

class BigIntAlgebra extends EuclideanRing[BigInt] with Serializable {

  val zero: BigInt = BigInt(0)
  val one: BigInt = BigInt(1)

  def plus(a: BigInt, b: BigInt): BigInt = a + b
  def negate(a: BigInt): BigInt = -a
  override def minus(a: BigInt, b: BigInt): BigInt = a - b

  def times(a: BigInt, b: BigInt): BigInt = a * b
  def quot(a: BigInt, b: BigInt) = a / b
  def mod(a: BigInt, b: BigInt) = a % b
  override def quotmod(a:BigInt, b:BigInt) = a /% b

  override def pow(a: BigInt, k: Int): BigInt = a pow k

  override def fromInt(n: Int): BigInt = BigInt(n)
  override def fromBigInt(n: BigInt): BigInt = n
}


text:
package org.xtuml.bp.core.ui;

import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;

import org.xtuml.bp.core.CorePlugin;
import org.xtuml.bp.core.Modeleventnotification_c;
import org.xtuml.bp.core.Ooaofooa;
import org.xtuml.bp.core.SystemModel_c;
import org.xtuml.bp.core.common.ModelRoot;
import org.xtuml.bp.core.common.NonRootModelElement;
import org.xtuml.bp.core.common.Transaction;
import org.xtuml.bp.core.common.TransactionManager;
import org.xtuml.bp.core.util.OoaofgraphicsUtil;

public abstract class CopyCutAction extends Action {

	public static final String GENERIC_PACKAGE_HEADER = "-- generics"; //$NON-NLS-1$

	protected int COPY_TYPE = 0;

	protected int CUT_TYPE = 1;

	private String transactioName;

	public CopyCutAction() {
		if (getActionType() == CUT_TYPE) {
			setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
					.getImageDescriptor(ISharedImages.IMG_TOOL_CUT));
			setText("Cut");
			setToolTipText("Cut the selected model elements.");
			transactioName = "Cut";
		} else if (getActionType() == COPY_TYPE) {
			setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
					.getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
			setText("Copy");
			setToolTipText("Copy the selected model elements.");
			transactioName = "Copy";
		}
	}

	public void run() {
		Clipboard cb = CorePlugin.getSystemClipboard();
		cb.clearContents();
		Object secondary = getSecondaryClipboardData();
		if(secondary != null && onlyIncludeSecondaryData()) {
			// this occurs when copy of element data is not
			// allowed, but image copy is
			cb.setContents(new Object[] { secondary },
					new Transfer[] { getSecondaryTransfer() });
			return;
		}
		TransactionManager manager = getTransactionManager();
		Transaction transaction = null;
		int old_val = 0;
		try {
			// only start a transaction for a cut, this allows for
			// restoration via undo
			if (getActionType() == CUT_TYPE) {
				transaction = manager
						.startTransaction(transactioName, new ModelRoot[] {
								Ooaofooa.getDefaultInstance(),
								(ModelRoot) OoaofgraphicsUtil.getGraphicsRoot(
										Ooaofooa.DEFAULT_WORKING_MODELSPACE,
										OoaofgraphicsUtil.getGraphicsClass()) });
				Ooaofooa.beginSaveOperation();
				// only respond to DELETE events
				old_val = Ooaofooa.Enablemodelchangelistenersfor(
						Ooaofooa.getDefaultInstance(), Modeleventnotification_c.DELTA_DELETE,
						Modeleventnotification_c.MODEL_ELEMENT_CHANGED);
			}
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			String streamContents = "";
			NonRootModelElement[] elements = getElementsToBeCopied(true);
			List<NonRootModelElement> elementList = Arrays.asList(elements);
			String packagingHeader = getPackagingHeaderFromElements(elementList);
			IRunnableWithProgress progress = CorePlugin
						.getStreamExportFactory()
						.create(out, elements, true, false);
			progress.run(new NullProgressMonitor());
			out.close();
			streamContents = new String(out.toByteArray());
			streamContents = streamContents.replaceFirst("\n", "\n" + packagingHeader + "\n");
			if(secondary == null) {
				cb.setContents(new Object[] { streamContents },
						new Transfer[] { TextTransfer.getInstance() });
			} else {
				cb.setContents(new Object[] { streamContents, secondary },
						new Transfer[] { TextTransfer.getInstance(), getSecondaryTransfer()});
			}
			postRun();
		} catch (Exception e) {
			if(getActionType() == CUT_TYPE) {
				if (transaction != null && manager != null
						&& manager.getActiveTransaction() == transaction) {
					manager.cancelTransaction(transaction, e);
					transaction = null;
				}
			}
			// log error
			CorePlugin.logError("Exception during cut/copy of selection.", e);
		} finally {
			if (transaction != null)
				manager.endTransaction(transaction);
			if(getActionType() == CUT_TYPE) {
				Ooaofooa.Enablemodelchangelistenersfor(Ooaofooa.getDefaultInstance(),
						old_val, old_val);
				Ooaofooa.endSaveOperation();
			}
		}
	}

	protected abstract Transfer getSecondaryTransfer();

	protected abstract Object getSecondaryClipboardData();

	protected abstract boolean onlyIncludeSecondaryData();

	private String getPackagingHeaderFromElements(List<NonRootModelElement> elements) {
		return GENERIC_PACKAGE_HEADER;
	}

	protected abstract TransactionManager getTransactionManager();

	protected abstract NonRootModelElement[] getElementsToBeCopied(boolean includeGraphics);

	protected abstract int getActionType();

	protected abstract void postRun();

}


text:
{% include '../head.html'%}
<link rel="stylesheet" href="/stylesheets/blog.css"/>

{% include '../navigator.html' %}

            {{document.content | raw}}

    <input id="flag" type="hidden" class="hidden" value="{{document.id}}"/>

        {% include '../comment.html'%}

{% include '../footer.html'%}


text: "Tree benchmarks"


text:
"""Functions for Sequential Halving."""

import math

import chex
import jax.numpy as jnp

def score_considered(considered_visit, gumbel, logits, normalized_qvalues,
                     visit_counts):
  """Returns a score usable for an argmax."""
  # We allow to visit a child, if it is the only considered child.
  low_logit = -1e9
  logits = logits - jnp.max(logits, keepdims=True, axis=-1)
  penalty = jnp.where(
      visit_counts == considered_visit,
      0, -jnp.inf)
  chex.assert_equal_shape([gumbel, logits, normalized_qvalues, penalty])
  return jnp.maximum(low_logit, gumbel + logits + normalized_qvalues) + penalty

def get_sequence_of_considered_visits(max_num_considered_actions,
                                      num_simulations):
  """Returns a sequence of visit counts considered by Sequential Halving.

  Sequential Halving is a "pure exploration" algorithm for bandits, introduced
  in "Almost Optimal Exploration in Multi-Armed Bandits":
  http://proceedings.mlr.press/v28/karnin13.pdf

  The visit counts allows to implement Sequential Halving by selecting the best
  action from the actions with the currently considered visit count.

  Args:
   max_num_considered_actions: The maximum number of considered actions.
     The `max_num_considered_actions` can be smaller than the number of
     actions.
   num_simulations: The total simulation budget.

  Returns:
    A tuple with visit counts. Length `num_simulations`.
  """
  if max_num_considered_actions <= 1:
    return tuple(range(num_simulations))
  log2max = int(math.ceil(math.log2(max_num_considered_actions)))
  sequence = []
  visits = [0] * max_num_considered_actions
  num_considered = max_num_considered_actions
  while len(sequence) < num_simulations:
    num_extra_visits = max(1, int(num_simulations / (log2max * num_considered)))
    for _ in range(num_extra_visits):
      sequence.extend(visits[:num_considered])
      for i in range(num_considered):
        visits[i] += 1
    # Halving the number of considered actions.
    num_considered = max(2, num_considered // 2)
  return tuple(sequence[:num_simulations])

def get_table_of_considered_visits(max_num_considered_actions, num_simulations):
  """Returns a table of sequences of visit counts.

  Args:
   max_num_considered_actions: The maximum number of considered actions.
     The `max_num_considered_actions` can be smaller than the number of
     actions.
   num_simulations: The total simulation budget.

  Returns:
    A tuple of sequences of visit counts.
    Shape [max_num_considered_actions + 1, num_simulations].
  """
  return tuple(
      get_sequence_of_considered_visits(m, num_simulations)
      for m in range(max_num_considered_actions + 1))


text:
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.chrome.browser.toolbar.bottom;

import static org.chromium.chrome.test.util.ToolbarTestUtils.BOTTOM_TOOLBAR;
import static org.chromium.chrome.test.util.ToolbarTestUtils.checkToolbarVisibility;

import android.support.test.filters.MediumTest;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.Restriction;
import org.chromium.chrome.browser.compositor.layouts.OverviewModeState;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.browser.toolbar.bottom.BottomToolbarVariationManager.Variations;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.chrome.test.util.browser.Features;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.ui.test.util.UiRestriction;

/**
 * Test bottom toolbar when start surface is enabled.
 */
@RunWith(ChromeJUnit4ClassRunner.class)
// clang-format off
@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
        "enable-features=" + ChromeFeatureList.START_SURFACE_ANDROID + "<Study",
        "force-fieldtrials=Study/Group",
        "force-fieldtrial-params=Study.Group:start_surface_variation/single"})
@Features.EnableFeatures({ChromeFeatureList.CHROME_DUET, ChromeFeatureList.START_SURFACE_ANDROID})
public class BottomToolbarWithStartSurfaceTest {
    //clang-format on
    @Rule
    public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();

    @Before
    public void setUp() {
        BottomToolbarVariationManager.setVariation(Variations.HOME_SEARCH_SHARE);

        // TODO(crbug.com/1051226): Test start activity with startMainActivityFromLauncher, so there
        // is no tab will be created, then the single start surface should be shown if it is
        // enabled.
        mActivityTestRule.startMainActivityOnBlankPage();
    }

    @Test
    @MediumTest
    public void testShowAndHideSingleSurface() {
        checkToolbarVisibility(BOTTOM_TOOLBAR, true);
        TestThreadUtils.runOnUiThreadBlocking(
                ()
                        -> mActivityTestRule.getActivity()
                                   .getStartSurface()
                                   .getController()
                                   .setOverviewState(OverviewModeState.SHOWING_HOMEPAGE));
        TestThreadUtils.runOnUiThreadBlocking(
                () -> mActivityTestRule.getActivity().getLayoutManager().showOverview(false));
        checkToolbarVisibility(BOTTOM_TOOLBAR, false);
        TestThreadUtils.runOnUiThreadBlocking(
                ()
                        -> mActivityTestRule.getActivity()
                                   .getStartSurface()
                                   .getController()
                                   .setOverviewState(OverviewModeState.SHOWING_TABSWITCHER));
        TestThreadUtils.runOnUiThreadBlocking(
                () -> mActivityTestRule.getActivity().getLayoutManager().showOverview(false));
        checkToolbarVisibility(BOTTOM_TOOLBAR, false);
        TestThreadUtils.runOnUiThreadBlocking(
                ()
                        -> mActivityTestRule.getActivity()
                                   .getStartSurface()
                                   .getController()
                                   .setOverviewState(OverviewModeState.NOT_SHOWN));
        TestThreadUtils.runOnUiThreadBlocking(
                () -> mActivityTestRule.getActivity().getLayoutManager().hideOverview(false));
        checkToolbarVisibility(BOTTOM_TOOLBAR, true);
    }
}