text:
<?php

/**
 * An interface for persisting datasets
 *
 * @package    DbUnit
 * @author     Mike Lively <m@digitalsandwich.com>
 * @copyright  2010 Mike Lively <m@digitalsandwich.com>
 * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
 * @version    Release: 1.0.1
 * @link       http://www.phpunit.de/
 * @since      Class available since Release 1.0.0
 */
interface PHPUnit_Extensions_Database_DataSet_IPersistable
{
    /**
     * Writes the given dataset
     *
     * The previous dataset will be overwritten.
     *
     * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
     */
    public function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset);
}


text:
#ifndef YR_RE_H
#define YR_RE_H

#include <ctype.h>

#include <yara/arena.h>
#include <yara/sizedstr.h>

#define RE_NODE_LITERAL             1
#define RE_NODE_MASKED_LITERAL      2
#define RE_NODE_ANY                 3
#define RE_NODE_CONCAT              4
#define RE_NODE_ALT                 5
#define RE_NODE_RANGE               6
#define RE_NODE_STAR                7
#define RE_NODE_PLUS                8
#define RE_NODE_CLASS               9
#define RE_NODE_WORD_CHAR           10
#define RE_NODE_NON_WORD_CHAR       11
#define RE_NODE_SPACE               12
#define RE_NODE_NON_SPACE           13
#define RE_NODE_DIGIT               14
#define RE_NODE_NON_DIGIT           15
#define RE_NODE_EMPTY               16
#define RE_NODE_ANCHOR_START        17
#define RE_NODE_ANCHOR_END          18
#define RE_NODE_WORD_BOUNDARY       19
#define RE_NODE_NON_WORD_BOUNDARY   20
#define RE_NODE_RANGE_ANY           21

#define RE_OPCODE_ANY                   0xA0
#define RE_OPCODE_ANY_EXCEPT_NEW_LINE   0xA1
#define RE_OPCODE_LITERAL               0xA2
#define RE_OPCODE_MASKED_LITERAL        0xA4
#define RE_OPCODE_CLASS                 0xA5
#define RE_OPCODE_WORD_CHAR             0xA7
#define RE_OPCODE_NON_WORD_CHAR         0xA8
#define RE_OPCODE_SPACE                 0xA9
#define RE_OPCODE_NON_SPACE             0xAA
#define RE_OPCODE_DIGIT                 0xAB
#define RE_OPCODE_NON_DIGIT             0xAC
#define RE_OPCODE_MATCH                 0xAD

#define RE_OPCODE_MATCH_AT_END          0xB0
#define RE_OPCODE_MATCH_AT_START        0xB1
#define RE_OPCODE_WORD_BOUNDARY         0xB2
#define RE_OPCODE_NON_WORD_BOUNDARY     0xB3
#define RE_OPCODE_REPEAT_ANY_GREEDY     0xB4
#define RE_OPCODE_REPEAT_ANY_UNGREEDY   0xB5

#define RE_OPCODE_SPLIT_A               0xC0
#define RE_OPCODE_SPLIT_B               0xC1
#define RE_OPCODE_JUMP                  0xC2
#define RE_OPCODE_REPEAT_START_GREEDY   0xC3
#define RE_OPCODE_REPEAT_END_GREEDY     0xC4
#define RE_OPCODE_REPEAT_START_UNGREEDY 0xC5
#define RE_OPCODE_REPEAT_END_UNGREEDY   0xC6

#define RE_FLAGS_FAST_REGEXP            0x02
#define RE_FLAGS_BACKWARDS              0x04
#define RE_FLAGS_EXHAUSTIVE             0x08
#define RE_FLAGS_WIDE                   0x10
#define RE_FLAGS_NO_CASE                0x20
#define RE_FLAGS_SCAN                   0x40
#define RE_FLAGS_DOT_ALL                0x80
#define RE_FLAGS_GREEDY                0x400
#define RE_FLAGS_UNGREEDY              0x800

typedef struct RE RE;
typedef struct RE_AST RE_AST;
typedef struct RE_NODE RE_NODE;
typedef struct RE_ERROR RE_ERROR;

typedef uint8_t RE_SPLIT_ID_TYPE;

struct RE_NODE
{
  int type;

  union {
    int value;
    int count;
    int start;
  };

  union {
    int mask;
    int end;
  };

  int greedy;

  uint8_t* class_vector;

  RE_NODE* left;
  RE_NODE* right;

  uint8_t* forward_code;
  uint8_t* backward_code;
};

struct RE_AST
{
  uint32_t flags;
  RE_NODE* root_node;
};

// Disable warning due to zero length array in Microsoft's compiler

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4200)
#endif

struct RE
{
  uint32_t flags;
  uint8_t code[0];
};

#ifdef _MSC_VER
#pragma warning(pop)
#endif

struct RE_ERROR
{
  char message[512];
};

typedef int RE_MATCH_CALLBACK_FUNC(
    uint8_t* match,
    int match_length,
    int flags,
    void* args);

int yr_re_ast_create(
    RE_AST** re_ast);

void yr_re_ast_destroy(
    RE_AST* re_ast);

void yr_re_ast_print(
    RE_AST* re_ast);

SIZED_STRING* yr_re_ast_extract_literal(
    RE_AST* re_ast);

int yr_re_ast_contains_dot_star(
    RE_AST* re_ast);

int yr_re_ast_split_at_chaining_point(
    RE_AST* re_ast,
    RE_AST** result_re_ast,
    RE_AST** remainder_re_ast,
    int32_t* min_gap,
    int32_t* max_gap);

int yr_re_ast_emit_code(
    RE_AST* re_ast,
    YR_ARENA* arena,
    int backwards_code);

RE_NODE* yr_re_node_create(
    int type,
    RE_NODE* left,
    RE_NODE* right);

void yr_re_node_destroy(
    RE_NODE* node);

int yr_re_exec(
    uint8_t* re_code,
    uint8_t* input,
    size_t input_forwards_size,
    size_t input_backwards_size,
    int flags,
    RE_MATCH_CALLBACK_FUNC callback,
    void* callback_args,
    int* matches);

int yr_re_fast_exec(
    uint8_t* code,
    uint8_t* input_data,
    size_t input_forwards_size,
    size_t input_backwards_size,
    int flags,
    RE_MATCH_CALLBACK_FUNC callback,
    void* callback_args,
    int* matches);

int yr_re_parse(
    const char* re_string,
    RE_AST** re_ast,
    RE_ERROR* error);

int yr_re_parse_hex(
    const char* hex_string,
    RE_AST** re_ast,
    RE_ERROR* error);

int yr_re_compile(
    const char* re_string,
    int flags,
    YR_ARENA* code_arena,
    RE** re,
    RE_ERROR* error);

int yr_re_match(
    RE* re,
    const char* target);

int yr_re_initialize(void);

int yr_re_finalize(void);

int yr_re_finalize_thread(void);

#endif

redpajama_set_name: RedPajamaGithub


text:
<?php

declare(strict_types=1);

namespace Phpcq\Runner\Report;

use Phpcq\PluginApi\Version10\Report\DiagnosticBuilderInterface;
use Phpcq\PluginApi\Version10\Report\FileDiagnosticBuilderInterface;
use Phpcq\PluginApi\Version10\Report\TaskReportInterface;
use Phpcq\Runner\Report\Buffer\DiagnosticBuffer;
use Phpcq\Runner\Report\Buffer\FileRangeBuffer;

/**
 * @psalm-type TDiagnosticSeverity = TaskReportInterface::SEVERITY_NONE
 * |TaskReportInterface::SEVERITY_INFO
 * |TaskReportInterface::SEVERITY_MARGINAL
 * |TaskReportInterface::SEVERITY_MINOR
 * |TaskReportInterface::SEVERITY_MAJOR
 * |TaskReportInterface::SEVERITY_FATAL
 */
final class DiagnosticBuilder implements DiagnosticBuilderInterface
{
    /**
     * @var string
     * @psalm-var TDiagnosticSeverity
     */
    private $severity;

    /** @var string */
    private $message;

    /** @var FileRangeBuffer[] */
    private $files = [];

    /** @var string|null */
    private $source;

    /** @var TaskReportInterface */
    private $parent;

    /**
     * @var callable
     * @psalm-var callable(DiagnosticBuffer, DiagnosticBuilder): void
     */
    private $callback;

    /** @var FileDiagnosticBuilder[] */
    private $pendingFiles = [];

    /** @var string|null */
    private $externalInfoUrl;

    /** @var string[] */
    private $classNames = [];

    /** @var string[] */
    private $categories = [];

    /**
     * @psalm-param callable(DiagnosticBuffer, DiagnosticBuilder): void $callback
     * @psalm-param TDiagnosticSeverity $severity
     */
    public function __construct(TaskReportInterface $parent, string $severity, string $message, callable $callback)
    {
        $this->severity = $severity;
        $this->message  = $message;
        $this->parent   = $parent;
        $this->callback = $callback;
    }

    public function forFile(string $file): FileDiagnosticBuilderInterface
    {
        // FIXME: if we would know the root dir, we could strip it here.
        $builder = new FileDiagnosticBuilder(
            $this,
            $file,
            /** @param FileRangeBuffer[] $rangeBuffers */
            function (array $rangeBuffers, FileDiagnosticBuilder $builder) {
                foreach ($rangeBuffers as $rangeBuffer) {
                    $this->files[] = $rangeBuffer;
                }
                unset($this->pendingFiles[spl_object_hash($builder)]);
            }
        );

        return $this->pendingFiles[spl_object_hash($builder)] = $builder;
    }

    public function fromSource(string $source): DiagnosticBuilderInterface
    {
        $this->source = $source;

        return $this;
    }

    public function withExternalInfoUrl(string $url): DiagnosticBuilderInterface
    {
        $this->externalInfoUrl = $url;

        return $this;
    }

    public function forClass(string $className): DiagnosticBuilderInterface
    {
        $this->classNames[$className] = $className;

        return $this;
    }

    public function withCategory(string $category): DiagnosticBuilderInterface
    {
        $this->categories[$category] = $category;

        return $this;
    }

    public function end(): TaskReportInterface
    {
        foreach ($this->pendingFiles as $pendingBuilder) {
            $pendingBuilder->end();
        }
        call_user_func(
            $this->callback,
            new DiagnosticBuffer(
                $this->severity,
                $this->message,
                $this->source,
                $this->files,
                $this->externalInfoUrl,
                array_values($this->classNames),
                array_values($this->categories)
            ),
            $this
        );

        return $this->parent;
    }
}


text:
class CreateQuestions < ActiveRecord::Migration
  def self.up
    create_table :questions do |t|
      t.string :title
      t.string :answer

      t.timestamps
    end
  end

  def self.down
    drop_table :questions
  end
end


text:
package org.wso2.siddhi.core.extension.holder;

import org.wso2.siddhi.core.config.SiddhiContext;
import org.wso2.siddhi.core.query.processor.transform.TransformProcessor;

public class TransformExtensionHolder extends AbstractExtensionHolder {
    private static TransformExtensionHolder instance;

    private TransformExtensionHolder(SiddhiContext siddhiContext) {
        super(TransformProcessor.class, siddhiContext);
    }

    public static TransformExtensionHolder getInstance(SiddhiContext siddhiContext) {
        if (instance == null) {
            instance = new TransformExtensionHolder(siddhiContext);
        }
        return instance;
    }
}


text:
// Copyright (c) 2013-present, febit.org. All Rights Reserved.
package org.febit.wit.exceptions;

import lombok.val;

import java.lang.reflect.Member;

/**
 * @author zqq90
 */
public class AmbiguousMethodException extends ScriptRuntimeException {

    public AmbiguousMethodException(String message) {
        super(message);
    }

    public <T extends Member> AmbiguousMethodException(T[] methods, Class<?>[] argTypes) {
        this(buildMessage(methods, argTypes));
    }

    protected static <T extends Member> String buildMessage(T[] methods, Class<?>[] argTypes) {
        val buf = new StringBuilder();
        buf.append("Ambiguous method for [");
        for (int i = 0; i < argTypes.length; i++) {
            if (i != 0) {
                buf.append(',');
            }
            buf.append(argTypes[i].getName());
        }
        buf.append("] with ");
        for (int i = 0; i < methods.length; i++) {
            if (i != 0) {
                buf.append(',');
            }
            buf.append(methods[i].toString());
        }
        return buf.toString();
    }

}


text:
package no.mesan.hipchatparse

import no.mesan.hipchatparse.roomlist.RoomlistParser.BuildRoomDb
import no.mesan.hipchatparse.roomlist.{RoomFilter, RoomlistParser, RoomlistDb}

import scala.concurrent.duration._
import scala.language.postfixOps

import akka.actor._
import akka.event.LoggingReceive

import no.mesan.hipchatparse.rooms.RoomDirReader.{RoomDiscovered, BuildRooms}
import no.mesan.hipchatparse.rooms._
import no.mesan.hipchatparse.users.UserParser.BuildUserDB
import no.mesan.hipchatparse.users.{UserParser, UserDb}

/** Main actor -- starts and ends the show. */
class HipChatParseMain extends Actor with Stash with ActorLogging {
  import HipChatParseMain.{Start, Stop, CheckIfDone}

  private val userDb= context.actorOf(UserDb.props(self), ActorNames.userDb)
  private val roomDb= context.actorOf(RoomlistDb.props(self), ActorNames.roomDb)
  private val userReader= context.actorOf(UserParser.props(self, userDb), ActorNames.userReader)
  private val writer= context.actorOf(RoomWriter.props(self), ActorNames.roomWriter)
  private val htmlFormatter= context.actorOf(HtmlRoomFormatter.props(self, writer))
  private val wikiFormatter= context.actorOf(WikiRoomFormatter.props(self, writer), ActorNames.roomFormatter)
  private val roomListParser= context.actorOf(RoomlistParser.props(self, roomDb), ActorNames.roomListParser)
  private val roomFilter= context.actorOf(RoomFilter.props(self, userDb, roomDb, List(wikiFormatter, htmlFormatter)), ActorNames.roomFilter)
  private val roomParser= context.actorOf(RoomParser.props(self, roomFilter), ActorNames.roomParser)
  private val roomFileReader= context.actorOf(RoomFileReader.props(self, roomParser), ActorNames.roomFileReader)
  private val roomDirReader= context.actorOf(RoomDirReader.props(self, roomFileReader), ActorNames.roomDirReader)
  // instantiated per room userFilter
  // instantiated per room messageFilter

  private var roomList = Set.empty[String]
  private var canExit = false // to avoid stopping before we have started (not likely)
  private var messagesWritten = 0

  override def receive: Receive = LoggingReceive{

    case Start(exportDir, resultDir) =>
      log.debug("Starting")
      context.setReceiveTimeout(5 seconds) // Break out if hanging
      writer ! ConfigValue(ActorNames.resultDir, resultDir)

      // Build DBs
      userReader ! BuildUserDB(exportDir + "/" + HipChatConfig.userFile)
      roomListParser ! BuildRoomDb(exportDir + "/" + HipChatConfig.roomFile)
      // The main pipe starts here
      roomDirReader ! BuildRooms(exportDir + "/" + HipChatConfig.roomDir)

    case RoomDiscovered(name) =>
      roomList = roomList + name

    case RoomDone(name, count) =>
      roomList = roomList - name
      messagesWritten  += count
      println(s"$name :: $count")
      self ! CheckIfDone

    case LastRoom =>
      canExit= true
      self ! CheckIfDone

    case CheckIfDone =>
      if (roomList.nonEmpty) log.debug(s"waiting for $roomList...")
      else if (canExit)  {
        htmlFormatter ! LastRoom
        context become finalizing
      }
      else log.debug("roomList is empty, but cannot exit")

    case TaskDone(task) =>
      log.debug(s"Trace: $task -- done")

    case ReceiveTimeout =>
      log.error(s"No action for too long -- terminated while waiting for $roomList")
      context.system.shutdown()
      println("boo")

    case Breakdown(err) =>
      log.error("FATAL: " + err)
      self ! Stop

    case Stop =>
      log.debug(s"Exiting, $messagesWritten messages written")
      context.system.shutdown()
  }

  var finalizing: Receive= LoggingReceive {
    case RoomDone(roomName, count) => // Final room
      unstashAll()
      self ! Stop
      context become receive // Read the stop message

    case ReceiveTimeout =>
      stash()
      unstashAll()
      context become receive // Reread the timeout message

    case _ => stash()
  }
}

object HipChatParseMain {
  /** Get running. */
  case class Start(baseDir: String, resultDir: String)

  /** Done! */
  case object Stop

  /** Check if last entry processed. */
  case object CheckIfDone

  /** "Constructor" */
  def props() = Props[HipChatParseMain]
}


text:
require 'heroics'

# Ruby HTTP client for the Heroku API.
module PlatformAPI
end

require 'platform-api/client'
require 'platform-api/version'


text:
class TestGLibUtils < Test::Unit::TestCase
  include GLibTestUtils

  def test_user_cache_dir
    only_glib_version(2, 6, 0)
    assert_kind_of(String, GLib.user_cache_dir)
  end

  def test_user_data_dir
    only_glib_version(2, 6, 0)
    assert_kind_of(String, GLib.user_data_dir)
  end

  def test_user_config_dir
    only_glib_version(2, 6, 0)
    assert_kind_of(String, GLib.user_config_dir)
  end

  def test_system_data_dirs
    only_glib_version(2, 6, 0)
    assert_kind_of(Array, GLib.system_data_dirs)
  end

  def test_system_config_dirs
    only_glib_version(2, 6, 0)
    assert_kind_of(Array, GLib.system_config_dirs)
  end

  def test_get_user_special_dir
    only_glib_version(2, 14, 0)
    assert_nothing_raised do
      GLib.get_user_special_dir(GLib::UserDirectory::DESKTOP)
    end
  end
end


text:
#import "NSPinyinString.h"

@interface NSPinyinString (AlternativesImpl)
+ (id)_correctionsForInputString:(id)arg1;
+ (id)_prefixesForInputString:(id)arg1;
+ (id)_alternativesForInputString:(id)arg1;
@end


text:
package edu.cs4730.jobservicejobworkitemdemo;

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.app.job.JobWorkItem;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.PersistableBundle;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;

/**
 * this demo shows how the workItem enqueue/dequeue works.  Note this API 26+
 * https://developer.android.com/reference/android/app/job/JobScheduler.html#enqueue(android.app.job.JobInfo,%20android.app.job.JobWorkItem)
 * https://developer.android.com/reference/android/app/job/JobParameters.html#dequeueWork()
 */

public class MainActivity extends AppCompatActivity {
    public static String id1 = "test_channel_01";

    JobScheduler jobScheduler;
    JobInfo job;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        createChannel();
        //get the Job Scheduler
        jobScheduler = getSystemService(JobScheduler.class);
        //get the job we will be sending workitems too.
        job = getJobInfo();
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //let's create 3 fake work items and enqueue them.
                JobWorkItem item;
                Intent i;
                //first item
                i = new Intent();
                i.putExtra("Key1", "first item"); //fake data too.
                item = new JobWorkItem(i);
                jobScheduler.enqueue(job, item);
                //second item
                i = new Intent();
                i.putExtra("Key1", "Second item"); //fake data too.
                item = new JobWorkItem(i);
                jobScheduler.enqueue(job, item);
                //first item
                i = new Intent();
                i.putExtra("Key1", "Third item"); //fake data too.
                item = new JobWorkItem(i);
                jobScheduler.enqueue(job, item);

            }
        });
    }

    //This is a helper method to schedule the job.  It doesn't need to be declared here, but it
    //a good way to keep everything together.

    // schedule the start of the service every 10 - 30 seconds
    public JobInfo getJobInfo() {

        ComponentName serviceComponent = new ComponentName(getApplicationContext(), MyJobWorkService.class);
        JobInfo.Builder builder = new JobInfo.Builder(0, serviceComponent);
        builder.setMinimumLatency(10 * 1000); // wait at least
        builder.setOverrideDeadline(30 * 1000); // maximum delay
        //builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED); // require unmetered network
        //builder.setRequiresDeviceIdle(true); // device should be idle
        //builder.setRequiresCharging(false); // we don't care if the device is charging or not
        //builder.setRequiresBatteryNotLow(true);  //only when the batter is not low.  API 26+

        return builder.build();
    }

    /**
     * Create notificaiton channel required in  API 26+
     */
    private void createChannel() {

        NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationChannel mChannel = new NotificationChannel(id1,
                getString(R.string.channel_name),  //name of the channel
                NotificationManager.IMPORTANCE_LOW);   //importance level
        //important level: default is is high on the phone.  high is urgent on the phone.  low is medium, so none is low?
        // Configure the notification channel.
        mChannel.setDescription(getString(R.string.channel_description));
        mChannel.enableLights(true);
        // Sets the notification light color for notifications posted to this channel, if the device supports this feature.
        mChannel.setShowBadge(true);
        nm.createNotificationChannel(mChannel);

    }
}


text:
https://www.meetup.com/Go-Remote-Meetup/events/270632499/

Video recording: https://youtu.be/tTaFcZVqbbY


text:
package com.google.gerrit.server.plugins;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Ordering;
import com.google.common.io.ByteStreams;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.webui.JavaScriptPlugin;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

public class PluginUtil {
  public static List<Path> listPlugins(Path pluginsDir, String suffix) throws IOException {
    if (pluginsDir == null || !Files.exists(pluginsDir)) {
      return ImmutableList.of();
    }
    DirectoryStream.Filter<Path> filter =
        new DirectoryStream.Filter<Path>() {
          @Override
          public boolean accept(Path entry) throws IOException {
            String n = entry.getFileName().toString();
            boolean accept =
                !n.startsWith(".last_") && !n.startsWith(".next_") && Files.isRegularFile(entry);
            if (!Strings.isNullOrEmpty(suffix)) {
              accept &= n.endsWith(suffix);
            }
            return accept;
          }
        };
    try (DirectoryStream<Path> files = Files.newDirectoryStream(pluginsDir, filter)) {
      return Ordering.natural().sortedCopy(files);
    }
  }

  static List<Path> listPlugins(Path pluginsDir) throws IOException {
    return listPlugins(pluginsDir, null);
  }

  static Path asTemp(InputStream in, String prefix, String suffix, Path dir) throws IOException {
    Path tmp = Files.createTempFile(dir, prefix, suffix);
    boolean keep = false;
    try (OutputStream out = Files.newOutputStream(tmp)) {
      ByteStreams.copy(in, out);
      keep = true;
      return tmp;
    } finally {
      if (!keep) {
        Files.delete(tmp);
      }
    }
  }

  public static String nameOf(Path plugin) {
    return nameOf(plugin.getFileName().toString());
  }

  static String nameOf(String name) {
    if (name.endsWith(".disabled")) {
      name = name.substring(0, name.lastIndexOf('.'));
    }
    int ext = name.lastIndexOf('.');
    return 0 < ext ? name.substring(0, ext) : name;
  }

  static ClassLoader parentFor(Plugin.ApiType type) throws InvalidPluginException {
    switch (type) {
      case EXTENSION:
        return PluginName.class.getClassLoader();
      case PLUGIN:
        return PluginLoader.class.getClassLoader();
      case JS:
        return JavaScriptPlugin.class.getClassLoader();
      default:
        throw new InvalidPluginException("Unsupported ApiType " + type);
    }
  }
}


text:
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\User;
use App\Role;
use Validator;
use Session;
use Auth;
use Route;
use Sentinel;
use Activation;
use DB;
use Hash;
use Mail;
use Carbon\Carbon;

class UserController extends Controller
{
    public function __construct()
    {
      //$this->middleware('auth')->except('orders');
      // $this->middleware('auth');
    }
    protected function validator(Request $request,$id='')
    {
        return Validator::make($request->all(), [
            'first_name' => 'required|min:2|max:35|string',
            'last_name' => 'required|min:2|max:35|string',
            'email' => Sentinel::inRole('Admin')?'required|email|min:3|max:50|string':(Sentinel::check()?'required|email|min:3|max:50|string|unique:users,email,'.$id:'required|email|min:3|max:50|unique:users|string'),
            'password' => 'min:6|max:50|confirmed',
            //'gender' => 'required',
            'role' => 'required',
        ]);
    }
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request){
         $type = $request->type;
         $users= User::all();
         if ($type) {
          $role = Sentinel::findRoleBySlug( $type);
          $users = $role->users()->get();

         }

        return View('backEnd.users.index', compact('users'));
    }
    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create(Request $request){

        $roles = Role::get()->pluck('name', 'id');
        return View('backEnd.users.create',compact('roles'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request){

        if ($this->validator($request,Sentinel::getUser()->id)->fails()) {

                return redirect()->back()
                        ->withErrors($this->validator($request))
                        ->withInput();
        }
         //create user
         $user = Sentinel::register($request->all());
         //activate user
         $activation = Activation::create($user);
         $activation = Activation::complete($user, $activation->code);
         //add role
         $user->roles()->sync([$request->role]);

        Session::flash('message', 'Success! User is created successfully.');
        Session::flash('status', 'success');

        return redirect()->route('user.index');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show(Request $request,$id)
    {
         $user = User::findOrFail($id);
         $type = $user->roles()->first();
         if ($request->is('api/*')) {
            $user= User::where('id',$id)->with('activations','roles')->get();
            return response()->json(compact('user'));
        }
        return View('backEnd.users.show', compact('user','type'));
    }
    public function accountFrontEnd(Request $request,$id)
    {
        $user=Sentinel::getUser();
         if ($user->inRole('admin')) {
           $user = User::findOrFail($id);
           return view('frontend.userAcount',compact('user'));
         }

        return view('frontend.userAcount',compact('user'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit(Request $request, $id)
    {
        $user = User::find($id);
        $roles = Role::get()->pluck('name', 'id');
        return View('backEnd.users.edit', compact('user', 'roles'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {

        $update_user = Validator::make($request->all(), [
            'first_name' => 'min:2|max:35|string',
            'last_name' => 'min:2|max:35|string',
            'email' => Sentinel::inRole('Admin')?'required|email|min:3|max:50|string':(Sentinel::check()?'required|email|min:3|max:50|string|unique:users,email,'.$id:'required|email|min:3|max:50|unique:users|string'),
        ]);

        if ($update_user->fails()) {
            return redirect()->back()
                        ->withErrors($update_user)
                        ->withInput();
        }

        $user = User::find($id);
        if ($user) {

              if($request->first_name){
              $user->first_name=$request->first_name;
              }
              if($request->last_name){
              $user->last_name=$request->last_name;
              }
              if($request->email){
              $user->email=$request->email;
              }
              if($request->new_password && $request->new_password_confirmation ){
                if ($request->new_password == $request->new_password_confirmation ){
                     $user->password=bcrypt($request->new_password);
                 }else{
                   Session::flash('message', 'Your old password is incorrect.');
                   Session::flash('status', 'error');
                  return redirect()->back()->withErrors(['old_password', 'your old password is incorrect']);
                 }
              }
              $user->update();
            if ($request->role) {
              $user->roles()->sync([$request->role]);
            }
            Session::flash('message', 'Success! User is updated successfully.');
            Session::flash('status', 'success');

        }

      return redirect()->back();
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(Request $request,$id)
    {
        $user = User::findOrFail($id);
        $user->delete();

        Session::flash('message', 'Success! User is deleted successfully.');
        Session::flash('status', 'success');

        return redirect()->route('user.index');
    }

    public function permissions($id)
    {
        $user = Sentinel::findById($id);
        $routes = Route::getRoutes();

        //Api Route
        // $api = app('api.router');
        // /** @var $api \Dingo\Api\Routing\Router */
        // $routeCollector = $api->getRoutes(config('api.version'));
        // /** @var $routeCollector \FastRoute\RouteCollector */
        // $api_route = $routeCollector->getRoutes();

        $actions = [];
        foreach ($routes as $route) {
            if ($route->getName() != "" && !substr_count($route->getName(), 'payment')) {
                $actions[] = $route->getName();
            }
        }

        //remove store option
        $input = preg_quote("store", '~');
        $var = preg_grep('~' . $input . '~', $actions);
        $actions = array_values(array_diff($actions, $var));

        //remove update option
        $input = preg_quote("update", '~');
        $var = preg_grep('~' . $input . '~', $actions);
        $actions = array_values(array_diff($actions, $var));

        //Api all names
        // foreach ($api_route as $route) {
        //     if ($route->getName() != "" && !substr_count($route->getName(), 'payment')) {
        //         $actions[] = $route->getName();
        //     }
        // }

        $var = [];
        $i = 0;
        foreach ($actions as $action) {

            $input = preg_quote(explode('.', $action )[0].".", '~');
            $var[$i] = preg_grep('~' . $input . '~', $actions);
            $actions = array_values(array_diff($actions, $var[$i]));
            $i += 1;
        }

        $actions = array_filter($var);
        // dd (array_filter($actions));

        return View('backEnd.users.permissions', compact('user', 'actions'));
    }

    public function save($id, Request $request)
    {
        //return $request->permissions;
        $user = Sentinel::findById($id);
        $user->permissions = [];
        if($request->permissions){
            foreach ($request->permissions as $permission) {
                if(explode('.', $permission)[1] == 'create'){
                    $user->addPermission($permission);
                    $user->addPermission(explode('.', $permission)[0].".store");
                }
                else if(explode('.', $permission)[1] == 'edit'){
                    $user->addPermission($permission);
                    $user->addPermission(explode('.', $permission)[0].".update");
                }
                else{
                    $user->addPermission($permission);
                }
            }
        }

        $user->save();

        Session::flash('message', 'Success! Permissions are stored successfully.');
        Session::flash('status', 'success');

        return redirect()->route('user.index');
    }

    public function activate(Request $request,$id)
    {
        $user = Sentinel::findById($id);

        $activation = Activation::completed($user);

        if($activation){
            Session::flash('message', 'Warning! The user is already activated.');
            Session::flash('status', 'warning');

            return redirect('user');
        }
        $activation = Activation::create($user);
        $activation = Activation::complete($user, $activation->code);

        Session::flash('message', 'Success! The user is activated successfully.');
        Session::flash('status', 'success');

        $role = $user->roles()->first()->name;

        return redirect()->route('user.index');
    }

    public function deactivate(Request $request,$id){

        $user = Sentinel::findById($id);
        Activation::remove($user);

        Session::flash('message', 'Success! The user is deactivated successfully.');
        Session::flash('status', 'success');

        return redirect()->route('user.index');
    }
    public function ajax_all(Request $request){
        if ($request->action=='delete') {
           foreach ($request->all_id as $id) {
             $user = User::findOrFail($id);
             if ($user->deleted_at == null){$user->delete();}
            }
            Session::flash('message', 'Success! Users are deleted successfully.');
            Session::flash('status', 'success');
            return response()->json(['success' => true, 'status' => 'Sucesfully Deleted']);
        }
        if ($request->action=='deactivate') {
           foreach ($request->all_id as $id) {
             $user = User::findOrFail($id);
             $activation = Activation::completed($user);
             if ($activation){Activation::remove($user);}
            }
            Session::flash('message', 'Success! Users are deactivate successfully.');
            Session::flash('status', 'success');
            return response()->json(['success' => true, 'status' => 'Sucesfully deactivate']);
        }
        if ($request->action=='activate') {
           foreach ($request->all_id as $id) {
             $user = User::findOrFail($id);
             $activation = Activation::completed($user);
             if ($activation==''){
                $activation = Activation::create($user);
                $activation = Activation::complete($user, $activation->code);
                }
            }
            Session::flash('message', 'Success! Users are Activated successfully.');
            Session::flash('status', 'success');
            return response()->json(['success' => true, 'status' => 'Sucesfully Activated']);
        }
    }

}


text:
namespace Cake.Common.Tools.InspectCode
{
    /// <summary>
    /// Represents Resharper's settings layers.
    /// </summary>
    public enum SettingsLayer
    {
        /// <summary>
        /// SettingsLayer: <c>GlobalAll</c>.
        /// </summary>
        GlobalAll = 1,

        /// <summary>
        /// SettingsLayer: <c>GlobalPerProduct</c>.
        /// </summary>
        GlobalPerProduct = 2,

        /// <summary>
        /// SettingsLayer: <c>SolutionShared</c>. This layer is saved in <c>%SolutionName%.sln.DotSettings</c>
        /// </summary>
        SolutionShared = 3,

        /// <summary>
        /// SettingsLayer: <c>SolutionPersonal</c>. This layer is saved in <c>%SolutionName%.sln.DotSettings.user</c>.
        /// </summary>
        SolutionPersonal = 4,

        /// <summary>
        /// SettingsLayer: <c>ProjectShared</c>. This layer is saved in <c>%ProjectName%.csproj.DotSettings</c>.
        /// </summary>
        ProjectShared = 5,

        /// <summary>
        /// SettingsLayer: <c>ProjectPersonal</c>. This layer is saved in <c>%ProjectName%.csproj.DotSettings.user</c>.
        /// </summary>
        ProjectPersonal = 6
    }
}


text:
<?php

namespace Zend\Code\Generator\Exception;

use Zend\Code\Exception\ExceptionInterface as Exception;

interface ExceptionInterface extends Exception
{}


text:
<?php namespace App\Http\Controllers;

use App\Http\Requests;
use App\Http\Controllers\Controller;

use Illuminate\Http\Request;

use App\Charm;
use App\CharmType;
use App\ExaltedType;
use App\Ability;
use App\Http\Requests\NewCharmRequest;
use App\Http\Requests\ChangeCharmRequest;
use App\Http\Requests\ChangeCharmLinksRequest;

class CharmsController extends Controller {

	/**
	 * Display a listing of the resource.
	 *
	 * @return Response
	 */
	public function index()
	{
		$charms = Charm::sortedByExaltedTypeSubTypeAndAbility()
			->with('exaltedType')
			->with('exaltedType.subTypes')
			->with('ability')
			->with('charmType')
			->get();
		return view('charms/list')
			->with('currentExaltedType', null)
			->with('currentExaltedSubType', null)
			->with('currentAbility', null)
			->with('charms', $charms);
	}

	/**
	 * Show the form for creating a new resource.
	 *
	 * @return Response
	 */
	public function createCharm()
	{
		return view('charms/create')
			->with('charm', new Charm())
			->with('exaltedTypes', ExaltedType::get())
			->with('abilities', Ability::get())
			->with('charmTypes', CharmType::get());
	}

	/**
	 * Store a newly created resource in storage.
	 *
	 * @return Response
	 */
	public function storeCharm(NewCharmRequest $request)
	{

		//Save the item
		$charm = new Charm();
		$charm->url = $request->url;
		$charm->name = $request->name;
		$charm->description_simple = $request->description_simple;
		$charm->description_complex = $request->description_complex;
		$charm->cost_simple = $request->cost_simple;
		$charm->cost_complex = $request->cost_complex;
		$charm->duration_simple = $request->duration_simple;
		$charm->duration_complex = $request->duration_complex;
		$charm->exalted_type_id = $request->exalted_type_id;
		$charm->charm_type_id = $request->charm_type_id;
		$charm->ability_id = $request->ability_id;
		$charm->minimum_ability = $request->minimum_ability;
		$charm->minimum_essence = $request->minimum_essence;
		$charm->save();

		//Set a flash message and then redirect
		return redirect('/content/charms/'.$charm->url.'/edit/links')
			->with('message-success', 'New Charm "'.$charm->name.'" created!');

	}

	/**
	 * Show the page for viewing the specified resource.
	 *
	 * @param  string  $charm
	 * @return Response
	 */
	public function showCharm($charm_url)
	{

		//Find the item
		$charm = Charm::where('url', '=', $charm_url)->first();
		if($charm == null)
		{
			return redirect('/content/charms')->with('message-error', 'Charm "'.$charm_url.'"" not found!');
		}

		//Display the item
		return view('charms/show')
			->with('charm', $charm);

	}

	/**
	 * Show the form for editing the specified resource.
	 *
	 * @param  string  $charm
	 * @return Response
	 */
	public function editCharm($charm_url)
	{

		//Find the item
		$charm = Charm::where('url', '=', $charm_url)->first();
		if($charm == null)
		{
			return redirect('/content/charms')->with('message-error', 'Charm "'.$charm_url.'"" not found!');
		}

		//Display the item
		return view('charms/edit')
			->with('charm', $charm)
			->with('exaltedTypes', ExaltedType::get())
			->with('abilities', Ability::get())
			->with('charmTypes', CharmType::get());

	}

	/**
	 * Show the form for editing the specified resource.
	 *
	 * @param  string  $charm
	 * @return Response
	 */
	public function editCharmLinks($charm_url)
	{

		//Find the item
		$charm = Charm::where('url', '=', $charm_url)->first();
		if($charm == null)
		{
			return redirect('/content/charms')->with('message-error', 'Charm "'.$charm_url.'"" not found!');
		}

		//Get the requiredCharms
		$requiredCharms = Charm::sortedByExaltedTypeSubTypeAndAbility()
			->with('exaltedType')
			->with('exaltedType.subTypes')
			->with('ability')
			->with('charmType')
			->where('exalted_charms.id', '<>', $charm->id)
			->where('exalted_charms.ability_id', '=', $charm->ability_id)
			->where('exalted_charms.exalted_type_id', '=', $charm->exalted_type_id)
			->get();

		//Display the item
		return view('charms/edit-links')
			->with('charm', $charm)
			->with('requiredCharms', $requiredCharms);

	}

	/**
	 * Update the specified resource in storage.
	 *
	 * @param  string  $charm
	 * @return Response
	 */
	public function updateCharm(ChangeCharmRequest $request, $charm_url)
	{

		//Find the item
		$charm = Charm::where('url', '=', $charm_url)->first();
		if($charm == null)
		{
			return redirect('/content/charms')->with('message-error', 'Charm "'.$charm_url.'"" not found!');
		}

		//Save the item
		$charm->url = $request->url;
		$charm->name = $request->name;
		$charm->description_simple = $request->description_simple;
		$charm->description_complex = $request->description_complex;
		$charm->cost_simple = $request->cost_simple;
		$charm->cost_complex = $request->cost_complex;
		$charm->duration_simple = $request->duration_simple;
		$charm->duration_complex = $request->duration_complex;
		$charm->exalted_type_id = $request->exalted_type_id;
		$charm->charm_type_id = $request->charm_type_id;
		$charm->ability_id = $request->ability_id;
		$charm->minimum_ability = $request->minimum_ability;
		$charm->minimum_essence = $request->minimum_essence;
		$charm->save();

		//Set a flash message and then redirect
		return redirect('/content/charms/'.$charm->url.'/edit/links')
			->with('message-success', 'Charm "'.$charm->name.'" saved!');

	}

	/**
	 * Update the specified resource in storage.
	 *
	 * @param  string  $charm
	 * @return Response
	 */
	public function updateCharmLinks(ChangeCharmLinksRequest $request, $charm)
	{

		//Find the item
		$charm = Charm::where('url', '=', $charm)->first();
		if($charm == null)
		{
			return redirect('/content/charms')->with('message-error', 'Charm "'.$charm.'"" not found!');
		}

		//Save the bindings to the requirements
		if(is_array($request->input('requiredCharm')))
		{
			$charm->requiredCharms()->sync($request->input('requiredCharm'));
		}

		//Redirect to the page of the Charm
		return redirect('/content/charms/'.$charm->url)->with('message-success', 'Charm requirements for "'.$charm->name.'"" saved!');

	}

}


text:
package schema

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/xeipuuv/gojsonschema"
)

func TestFileSpecSchema(t *testing.T) {
	// Load File Spec schema
	schema, err := ioutil.ReadFile("filespec-schema.json")
	assert.NoError(t, err)
	schemaLoader := gojsonschema.NewBytesLoader(schema)

	// Validate all specs in ../testdata/filespecs against the filespec-schema.json
	assert.NoError(t,
		filepath.Walk(filepath.Join("..", "testdata", "filespecs"), func(path string, info os.FileInfo, err error) error {
			assert.NoError(t, err)
			if info.IsDir() {
				return nil
			}

			specFileContent, err := ioutil.ReadFile(path)
			assert.NoError(t, err)
			documentLoader := gojsonschema.NewBytesLoader(specFileContent)
			result, err := gojsonschema.Validate(schemaLoader, documentLoader)
			assert.NoError(t, err)
			assert.True(t, result.Valid(), result.Errors())
			return nil
		}))
}


text:
<?php

declare(strict_types = 1);

include_once "img/InfoField.php";

/**
 * Created by The Ranger (ranger@risk.ee) on 2016-11-18
 *
 */
class UIImage {

	private static $file;
	private static $next;
	private static $previous;
	private static $exifParser;

	public function __construct(File $file, ExifParser $exifParser) {
		self::$file = $file;
		self::$exifParser = $exifParser;

		$entries = $file->getFolder()->getContents();
		foreach ($entries as $key => $value) {
			if ($value->getPath() != $file->getPath()) continue;

			if ($key > 0) self::$previous = $entries[$key - 1];
			if ($key < count($entries) - 1) self::$next = $entries[$key + 1];
		}
	}

	public static function PrintNextImageURL() {
		if (!isset(self::$next)) return ;
		print self::$next->getURL();
	}

	public static function hasNextImage(): bool {
		return isset(self::$next);
	}

	public static function PrintPreviousImageURL() {
		if (!isset(self::$previous)) return;
		print self::$previous->getURL();
	}

	public static function hasPreviousImage(): bool {
		return isset(self::$previous);
	}

	public static function PrintImageURL() {
		print self::$file->getURL();
	}

	public static function PrintTitle() {
		print self::$exifParser->getTitle();
	}

	public static function HasTitle(): bool {
		return !empty(self::$exifParser->getTitle());
	}

	public static function HasExif(): bool {
		return self::$exifParser->hasExif();
	}

	public static function PrintExif() {
		$exifInfo = self::$exifParser->getData();
		if (empty($exifInfo)) return;

		print '
';

		foreach ($exifInfo as $key => $value) {
			if (empty($value)) continue;

			switch ($key) {
				case InfoField::MAKE:
					print '
Manufacturer	';
					break;

				case InfoField::MODEL:
					print '
Model	';
					break;

				case InfoField::EXPOSURE:
					print '
Exposure time	';
					break;

				case InfoField::APERTURE:
					print '
Aperture	';
					break;

				case InfoField::ISO:
					print '
ISO Speed	';
					break;

				case InfoField::SHOT_TIME:
					print '
Date Taken	';
					break;

				default:
					continue 2;
			}

			print ''.$value.'
';
		}

		print '
';
	}
}


text:
package com.thoughtworks.go.plugin.access.pluggabletask;

import com.thoughtworks.go.plugin.api.config.PluginPreference;
import com.thoughtworks.go.plugin.api.task.Task;
import com.thoughtworks.go.plugin.api.task.TaskConfig;
import com.thoughtworks.go.plugin.api.task.TaskView;

public class TaskPreference implements PluginPreference {
    private TaskConfig taskConfig;
    private TaskView taskView;

    public TaskPreference(Task task) {
        this.taskConfig = task.config();
        this.taskView = task.view();
    }

    public TaskConfig getConfig() {
        return taskConfig;
    }

    public TaskView getView() {
        return taskView;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        TaskPreference that = (TaskPreference) o;

        if (!taskConfig.equals(that.taskConfig)) return false;
        if (!taskView.equals(that.taskView)) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = taskConfig.hashCode();
        result = 31 * result + taskView.hashCode();
        return result;
    }
}


text:
<?php declare(strict_types=1);

namespace Darvin\ImageBundle\Command\Imagine\Cache;

use Darvin\ImageBundle\Entity\Image\AbstractImage;
use Darvin\ImageBundle\Imagine\Cache\Warmer\ImagineCacheWarmerInterface;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

/**
 * Warm Imagine cache command
 */
class WarmCommand extends Command
{
    /**
     * @var \Doctrine\ORM\EntityManager
     */
    private $em;

    /**
     * @var \Darvin\ImageBundle\Imagine\Cache\Warmer\ImagineCacheWarmerInterface
     */
    private $imagineCacheWarmer;

    /**
     * @var int
     */
    private $chunkSize;

    /**
     * @param \Doctrine\ORM\EntityManager                                          $em                 Entity manager
     * @param \Darvin\ImageBundle\Imagine\Cache\Warmer\ImagineCacheWarmerInterface $imagineCacheWarmer Imagine cache warmer
     * @param int                                                                  $chunkSize          Chunk size
     */
    public function __construct(EntityManager $em, ImagineCacheWarmerInterface $imagineCacheWarmer, int $chunkSize)
    {
        parent::__construct();

        $this->em = $em;
        $this->imagineCacheWarmer = $imagineCacheWarmer;
        $this->chunkSize = $chunkSize;
    }

    /**
     * {@inheritDoc}
     */
    protected function configure(): void
    {
        $this
            ->setName('darvin:image:cache:warm')
            ->setDescription('Generates Imagine cache for all images.');
    }

    /**
     * {@inheritDoc}
     */
    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);

        $qb = $this->em->getRepository(AbstractImage::class)->createQueryBuilder('o');

        $countQb = clone $qb;
        $count = (int)$countQb->select($countQb->expr()->count('o'))->getQuery()->getSingleScalarResult();

        if (0 === $count) {
            $io->comment('No images found, exiting.');

            return 0;
        }

        $io->progressStart($count);

        $iterator = $qb->getQuery()->iterate();

        while ($iterator->next()) {
            $row = $iterator->current();
            /** @var \Darvin\ImageBundle\Entity\Image\AbstractImage $image */
            $image = reset($row);

            try {
                $this->imagineCacheWarmer->warmImageCache($image);
            } catch (\Exception $ex) {
                $io->warning($ex->getMessage());
            }

            $io->progressAdvance();
            $io->write(' '.$image->getFilename());

            if ($iterator->key() > 0 && 0 === $iterator->key() % $this->chunkSize) {
                $this->em->clear();
            }
        }

        $io->progressFinish();

        return 0;
    }
}


text:
import java.util.*;
public class Q281A{
    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);
        String s = sc.next();
        System.out.println(s.substring(0,1).toUpperCase()+s.substring(1));
    }
}


text:
package fr.univnantes.termsuite.model;

public enum CompoundType {
	NATIVE("nat"), NEOCLASSICAL("neo"), UNSET("unset");
	private String shortName;
	private CompoundType(String shortName) {
		this.shortName = shortName;
	}
	public String getShortName() {
		return shortName;
	}
	@Override
	public String toString() {
		return getShortName();
	}
	public static CompoundType fromName(String name) {
		for(CompoundType t:values())
			if(t.name().equals(name))
				return t;
		throw new IllegalArgumentException("Unknown compound type: " + name);
	}

	public static CompoundType fromShortName(String shortName) {
		for(CompoundType t:values())
			if(t.getShortName().equals(shortName))
				return t;

		throw new IllegalArgumentException("Unknown compound type: " + shortName);
	}
}


text:
namespace Kore {
	namespace Graphics5 {
		class IndexBuffer;
	}

	class IndexBuffer5Impl {
	protected:
	public:
		IndexBuffer5Impl(int count);
		void unset();

		int* data;
		int myCount;
		uint bufferId;

		VkBuffer buf;
		VkDeviceMemory mem;
		VkMemoryAllocateInfo mem_alloc;

	public:
		static Graphics5::IndexBuffer* current;
	};
}


text:
namespace keyczar {
namespace base {
namespace string_escape {

// Similar to the wide version, but for narrow strings.  It will not use
// \uXXXX unicode escape sequences.  It will pass non-7bit characters directly
// into the string unencoded, allowing the browser to interpret the encoding.
// The outputted literal, when interpreted by the browser, could result in a
// javascript string of a different length than the input |str|.
void JavascriptDoubleQuote(const std::string& str,
                           bool put_in_quotes,
                           std::string* dst);

}  // namespace string_escape
}  // namespace base
}  // namespace keyczar

#endif  // KEYCZAR_BASE_STRING_ESCAPE_H_


text:
export default {
  caption: 'Редактирование ассоциации',
  'description-caption': 'Описание связи',
  'description-placeholder': 'Введите описание связи',
  'start-role-caption': 'Имя роли у мастера',
  'start-role-placeholder': 'Введите имя роли у мастера',
  'start-role-publish-name-caption': 'Имя публикации роли мастера',
  'start-role-publish-name-placeholder': 'Введите имя публикации роли мастера',
  'start-multiplicity-caption': 'Множественность у мастера',
  'start-multiplicity-placeholder': 'Введите множественность у мастера',
  'end-role-access-modifier-caption': 'Модификатор доступа мастерового свойства',
  'start-role-stored-caption': 'Связь с мастером является хранимой',
  'end-role-caption': 'Имя роли у основного класса',
  'end-role-placeholder': 'Введите имя роли у основного класса',
  'end-role-publish-name-caption': 'Имя публикации роли у основного класса',
  'end-role-publish-name-placeholder': 'Введите имя публикации роли у основного класса',
  'end-multiplicity-caption': 'Множественность у основного класса',
  'end-multiplicity-placeholder': 'Введите множественность у основного класса',
  'auto-generate-type-usage-caption': 'Автогенерируемый TypeUsage',
  'type-usage-caption': 'TypeUsage',
  'type-usage-placeholder': 'Введите TypeUsage',
  'storage-caption': 'Имя связи в базе данных',
  'storage-placeholder': 'Введите имя связи в базе данных',
  'auto-store-master-disabled-caption': 'Автосохранение мастера запрещено',
};


text:
\section{Performance Testing Environment} % (fold)
\label{sec:performance_testing_environment}
To test the framework and applications, we use the following machine specification:
\begin{itemize}
  \item Processor: 2.3 GHz Intel Core i7 (1 processor, 4 cores)
  \item Memory: 8GB 1600 MHz DDR3. 256KB L2 cache per core; 6 MB L3 cache
  \item Graphics: NVIDIA GeForce GT 650M 1024 MB
  \item OS: Mac OS X 10.9.3
  \item Google Chrome version: 35.0.1916.153 (Official Build 274914)
  \item V8 version: 3.25.28.18
  \item Blink version: 537.36 (@175075)
  \item PPAPI version: 34
\end{itemize}

We use Benchmark JS \cite{benchmarkjs} to easily and accurately measure the amount of time taken to run JavaScript code. Benchmark JS uses high-resolution timers (microsecond precision) and automatically runs the function we wish to test enough times so that it returns statistically significant results.
% section performance_testing_environment (end)

\section{Application Performance Evaluation} % (fold)
\label{sec:application_performance_evaluation}
\subsection{Bullet Physics Performance} % (fold)
\label{sub:bullet_physics_performance}
The simplest way to measure how well the physics engine performs using Native Calls RPC is to analyse the frames per second (FPS) for a range of scenes of varying complexity. We identify what the biggest impact to the FPS is by measuring how long it takes to make a request and get a response for each frame rendered. We also measure how long it takes to perform the actual simulation step. Finally, we compare these measurements with the original implementation, which was implemented using Native Client Acceleration Modules and tweaked for performance using ArrayBuffers.

\subsubsection{Setup} % (fold)
\label{ssub:bullet_performance_setup}
To test the implementation, we use seven physics scenes. A screenshot of each scene is shown in Figure \ref{fig:bullet_screenshots}. Apart from the Jenga scenes, each scene starts with all the objects falling from the sky and crashing on the ground.

We measure three things - the frame rate, the simulation time, and the round trip time. To measure the frame rate, we simply add to a total of frames requested. A frame is requested by the browser automatically in order to achieve a frame rate of 60 frames per second. This is done using the \lstinline{window.requestAnimationFrame} API, which conveniently takes the computation time for rendering and processing the frame into account. This is why the frame rate drops when the round trip time and simulation time increases. We measure the total simulation time inside the C++ application by taking time stamps between and after the simulation step and calculating the difference. We send it back with the results every time we do the simulation. Finally, we calculate the round trip time by taking timestamps before and after the RPC call and taking a difference. We average all this data over a period of one second and send it to be plotted.

For each second, the average time per frame is calculated. This is the inverse of frames per second, and we call this period the \emph{frame time}. During that time, a RPC request is made and a response is received. We call the period between making a request and receiving a response the \emph{RPC time}. We calculate these times and average them for each second for a period of 20 seconds - the \emph{elapsed time}. Figure \ref{fig:frame-time-vis} shows a visualisation of this terminology.

The graph is plotted in real time in the browser, but we make sure not to use the same \lstinline{window} object - as this will impact JavaScript performance and give us skewed results. Instead, we send the data to be plotted in a different window - which in Chrome corresponds to a different process. HighCharts was chosen to quickly and easily create the realtime graph with very little configuration.

The actual implementation of the RPC library for the physics simulation is discussed in the qualitative evaluation section \ref{sub:implementation_bullet_evaluation} on page \pageref{sub:implementation_bullet_evaluation}.

\begin{figure}
    \centering
    \includegraphics[width=0.7\textwidth]{FrameTimeVisualisation.pdf}
    \caption{A graphical representation showing the times measured.}
    \label{fig:frame-time-vis}
\end{figure}

\begin{figure}
        \centering
        \begin{subfigure}[b]{0.45\textwidth}
                \includegraphics[width=\textwidth]{jenga_10.png}
                \caption{Jenga 10}
                \label{fig:screenshot_jenga_10}
        \end{subfigure}%
        ~ %add desired spacing between images, e. g. ~, \quad, \qquad, \hfill etc.
          %(or a blank line to force the subfigure onto a new line)
        \begin{subfigure}[b]{0.45\textwidth}
                \includegraphics[width=\textwidth]{jenga_20.png}
                \caption{Jenga 20}
                \label{fig:screenshot_jenga_20}
        \end{subfigure}
        ~ %add desired spacing between images, e. g. ~, \quad, \qquad, \hfill etc.
          %(or a blank line to force the subfigure onto a new line)
        \begin{subfigure}[b]{0.45\textwidth}
                \includegraphics[width=\textwidth]{random_shapes.png}
                \caption{Random Shapes}
                \label{fig:random_shapes}
        \end{subfigure}
        ~ %add desired spacing between images, e. g. ~, \quad, \qquad, \hfill etc.
          %(or a blank line to force the subfigure onto a new line)
        \begin{subfigure}[b]{0.45\textwidth}
                \includegraphics[width=\textwidth]{cubes_250.png}
                \caption{250 Cubes}
                \label{fig:cubes_250}
        \end{subfigure}
        \begin{subfigure}[b]{0.45\textwidth}
                \includegraphics[width=\textwidth]{cylinders_500.png}
                \caption{500 Cylinders}
                \label{fig:cylinders_500}
        \end{subfigure}%
        ~ %add desired spacing between images, e. g. ~, \quad, \qquad, \hfill etc.
          %(or a blank line to force the subfigure onto a new line)
        \begin{subfigure}[b]{0.45\textwidth}
                \includegraphics[width=\textwidth]{cubes_1000.png}
                \caption{1000 Cubes}
                \label{fig:cubes_1000}
        \end{subfigure}
        ~ %add desired spacing between images, e. g. ~, \quad, \qquad, \hfill etc.
          %(or a blank line to force the subfigure onto a new line)
        \begin{subfigure}[b]{0.45\textwidth}
                \includegraphics[width=\textwidth]{cubes_2000.png}
                \caption{2000 Cubes}
                \label{fig:cubes_2000}
        \end{subfigure}
        \caption{The bullet physics scenes used in the benchmark}\label{fig:bullet_screenshots}
\end{figure}

% subsubsection bullet_performance_setup (end)

\subsubsection{Results and comparison} % (fold)
\label{ssub:results_bullet_physics_performance}

\begin{table}[h]
    \begin{subtable}[h]{\textwidth}
        \centering
\begin{tabular}{l|lll|lll|lll|lll}
\multirow{3}{*}{Scene} & \multicolumn{9}{l|}{Time / ms}                                                          & \multicolumn{3}{l|}{\multirow{2}{*}{FPS}} \\ \cline{2-10}
                       & \multicolumn{3}{l|}{Frame} & \multicolumn{3}{l|}{RPC} & \multicolumn{3}{l|}{Simulation} & \multicolumn{3}{l|}{}                     \\ \cline{2-13}
                       & $\mu$     & Max     & Min     & $\mu$     & Max    & Min    & $\mu$       & Max       & Min      & $\mu$          & Max          & Min          \\ \hline
A                      & 17       & 18     & 16     & 17       & 18    & 16    & 0.11       & 0.13     & 0.10    & 60            & 61          & 55          \\
B                      & 17       & 18     & 16     & 17       & 18    & 16    & 0.35       & 2.93     & 0.08    & 60            & 61          & 56          \\
C                      & 17       & 17     & 16     & 17       & 17    & 16    & 0.45       & 0.90     & 0.23    & 60            & 61          & 59          \\
D                      & 17       & 21     & 16     & 17       & 21    & 16    & 0.67       & 1.80     & 0.20    & 59            & 61          & 48          \\
E                      & 21       & 23     & 17     & 21       & 24    & 17    & 2.46       & 5.73     & 1.08    & 49            & 58          & 44          \\
F                      & 39       & 45     & 17     & 38       & 43    & 17    & 10.80      & 14.56    & 0.11    & 25            & 60          & 22          \\
G                      & 72       & 91     & 34     & 73       & 91    & 34    & 23.73      & 41.08    & 0.91    & 14            & 29          & 11
\end{tabular}
        \caption{Using Native Calls}
    \end{subtable}
    ~
    \begin{subtable}[h]{\textwidth}
        \centering
\begin{tabular}{l|lll|lll|lll|lll}
\multirow{3}{*}{Scene} & \multicolumn{9}{l|}{Time / ms}                                                          & \multicolumn{3}{l|}{\multirow{2}{*}{FPS}} \\ \cline{2-10}
                       & \multicolumn{3}{l|}{Frame} & \multicolumn{3}{l|}{RPC} & \multicolumn{3}{l|}{Simulation} & \multicolumn{3}{l|}{}                     \\ \cline{2-13}
                       & $\mu$     & Max     & Min     & $\mu$     & Max    & Min    & $\mu$       & Max       & Min      & $\mu$          & Max          & Min          \\ \hline
A                      & 17       & 18     & 16     & 17       & 18    & 16    & 0.13       & 0.14     & 0.12    & 60            & 61          & 55          \\
B                      & 17       & 18     & 16     & 17       & 18    & 16    & 0.38       & 3.37     & 0.10    & 60            & 61          & 57          \\
C                      & 17       & 17     & 16     & 17       & 20    & 16    & 0.60       & 0.93     & 0.27    & 60            & 61          & 59          \\
D                      & 17       & 19     & 16     & 17       & 20    & 17    & 1.14       & 1.87     & 0.22    & 60            & 61          & 52          \\
E                      & 17       & 18     & 16     & 17       & 26    & 16    & 2.64       & 5.82     & 0.97    & 60            & 61          & 55          \\
F                      & 19       & 21     & 17     & 19       & 24    & 17    & 12.06      & 15.49    & 1.09    & 53            & 59          & 48          \\
G                      & 35       & 40     & 17     & 35       & 42    & 18    & 30.77      & 37.93    & 8.86    & 29            & 58          & 25
\end{tabular}
        \caption{Using NaClAM}
    \end{subtable}
\caption{Time measurements for the bullet physics demo, using different implementations}
\label{table:bullet_performance}
\end{table}

Table \ref{table:bullet_performance} shows the results of the measurements taken during the simulation every second, over a duration of 20 seconds. Figure \ref{fig:bullet_screenshots} shows which scene corresponds to which capital letter (for example, scene `E' is referring to the simulation of 500 cylinders).

Because the simulation is affected by time, the table shows the range of values taken for each measurement.

We can see that scenes A, B, C, D, and E have roughly similar results for both implementations. Scenes F and G show some more interesting results. Figures \ref{fig:bullet_graph_cyl500}, \ref{fig:bullet_graph_cube1000}, and \ref{fig:bullet_graph_cube2000} show some plots showing how the simulation time and frame time change per second for scenes E, F and G respectively, using the Native Calls and NaClAM implementations.

\begin{figure}
        \centering
        \begin{subfigure}[b]{\textwidth}
                \includegraphics[width=\textwidth]{bulletdata_cylinder500_nc.pdf}
                % \caption{Using Native Calls}
                \label{fig:bulletdata_cylinder500_nc}
        \end{subfigure}%
        \\
        \begin{subfigure}[b]{\textwidth}
                \includegraphics[width=\textwidth]{bulletdata_cylinder500_naclam.pdf}
                % \caption{Using NaClAM}
                \label{fig:bulletdata_cylinder500_naclam}
        \end{subfigure}
        \caption{The mean processing times per second over a period of 20 seconds, for Scene E: 500 cylinders. The two graphs show the results using the same scene but different implementations.}
        \label{fig:bullet_graph_cyl500}
\end{figure}

\begin{figure}
        \centering
        \begin{subfigure}[b]{\textwidth}
                \includegraphics[width=\textwidth]{bulletdata_cube1000_nc.pdf}
                % \caption{Random Shapes}
                % \label{fig:random_shapes}
        \end{subfigure}
        \\
        \begin{subfigure}[b]{\textwidth}
                \includegraphics[width=\textwidth]{bulletdata_cube1000_naclam.pdf}
                % \caption{250 Cubes}
                % \label{fig:cubes_250}
        \end{subfigure}
        \caption{The mean processing times per second over a period of 20 seconds, for Scene F: 1000 cubes.}
        \label{fig:bullet_graph_cube1000}
\end{figure}

\begin{figure}
        \centering
        \begin{subfigure}[b]{\textwidth}
                \includegraphics[width=\textwidth]{bulletdata_cube2000_nc.pdf}
                % \caption{500 Cylinders}
                % \label{fig:cylinders_500}
        \end{subfigure}%
        \\
        \begin{subfigure}[b]{\textwidth}
                \includegraphics[width=\textwidth]{bulletdata_cube2000_naclam.pdf}
                % \caption{1000 Cubes}
                % \label{fig:cubes_1000}
        \end{subfigure}
        \caption{The mean processing times per second over a period of 20 seconds, for Scene G: 2000 cubes.}
        \label{fig:bullet_graph_cube2000}
\end{figure}

% subsubsection results_bullet_physics_performance (end)

\subsubsection{Analysis} % (fold)
\label{ssub:bullet_physics_performanceanalysis}
From the graphs and tables, we can obviously see how the performance impact of our framework gets higher and higher with more and more objects being sent. We can see how for large scenes such as 2000 cubes, the Native Calls implementation performs almost two times worse than the NaClAM implementation. However for smaller scenes, the two implementations have very similar performance.

From the graphs we can see how the Native Calls framework contributes to the performance impact. For example, in Figure \ref{fig:bullet_graph_cube2000}, the large space between the physics simulation time line and the RPC round trip time line is an indication that the framework is doing most of the processing in the RPC call, not the simulation. When we compare this to the NaClAM version in the same figure, it is clear that most of the processing happens in the physics simulation.

The most likely reason for these two observations is that the data marshalling on the C++ Native Calls RPC framework implementation negatively impacts the performance. In our implementation, the data is processed in O(n) time in order to convert the received \lstinline{pp::VarArray} array of objects into a \lstinline{std::vector} of \lstinline{struct}s. In section \ref{sec:performance_evaluation} (page \pageref{sec:performance_evaluation}), we find that converting WebIDL dictionaries is also quite slow, compared to converting an array of numbers. When we compare this to the NaClAM implementation, we can see that the NaClAM version has almost O(1) time, since the data is only being read and is shared between the module and JavaScript. This is explained in section \ref{sec:naclam} on page \pageref{sec:naclam}.

% subsubsection bullet_physics_performanceanalysis (end)

% subsection bullet_physics_performance (end)

\subsection{Oniguruma Regular Expressions Performance} % (fold)
\label{sub:oniguruma_regular_expressions_performance}
To get an insight of the performance of the oniguruma library for Native Client using Native Calls, we shall count the number of regular expression matches. We compare this to running the engine in Node JS server natively, and then using WebSockets to get functionality in the browser.

\subsubsection{Setup} % (fold)
\label{ssub:onig_performance_setup}
Again, the actual implementation of the library is discussed later on in the evaluation, in section \ref{sub:implementation_oniguruma_evaluation} on page \pageref{sub:implementation_oniguruma_evaluation}. In this section, we discuss how we measure the time it took to find all matches.

For the benchmark, we searched a large code base. We took part of the jQuery implementation in JavaScript and stored it in a string. We then performed regular expression searches on that string. The search string was 3467 characters. We split it into lines. For each line, we found all instances of \lstinline{"this"}, \lstinline{"var"}, \lstinline{"selector"}, and \lstinline{"window"} using regular expressions. In total, there was 237 matches, and each implementation gave the correct output. However, we measured the amount of time it took to find all these matches.

For the browser implementations (Native Calls and web sockets), we measure it using BenchmarkJS, to get an accurate running time, and a relative error margin. Using BenchmarkJS, we measured the time it took from initiating a request to receiving a response. BenchmarkJS performed the tests hundreds of times to get an accurate running time.

For the server implementation (using node.js natively on the server), we simply timed and performed all the searches 1000 times and got the mean of the running time.
% subsubsection onig_performance_setup (end)

\subsubsection{Results and comparison} % (fold)
\label{ssub:onig_results_and_comparison}
Table \ref{table:onig_time_taken} shows the results of running the benchmark application using Native Calls RPC and node-oniguruma.

\begin{table}[h]
\centering
\begin{tabular}{l|l}
\textbf{Method}                 & \textbf{Time Taken / s} \\ \hline
Native Calls                    &  0.709 $\pm$0.47\%  \\
node-oniguruma with web sockets &  0.375 $\pm$0.32\%  \\
node-oniguruma (native)         &  0.045
\end{tabular}
\caption{A comparison of the time taken to find all matches of a regular expression using different implementations}
\label{table:onig_time_taken}
\end{table}

% subsubsection onig_results_and_comparison (end)

\subsubsection{Analysis} % (fold)
\label{ssub:onig_analysis}
We can see that the node-oniguruma version performs much better. This is due to a number of reasons:
\begin{itemize}
  \item The node-oniguruma implementation is \emph{native}, in the sense that it uses JavaScript types directly. No marshalling nor transfer happens.
  \item The node.js V8 engine usually performs better than V8 in Chrome, as it is optimised for server side performance.
  \item The web socket implementation has a very simple runtime on both client and server sides. No error checking, type checking, etc. happens.
  \item Strings are the slowest primitive types to marshal, send and de-marshal in Native Calls. See section \ref{sec:performance_evaluation} for details.
\end{itemize}
% subsubsection onig_analysis (end)

% subsection oniguruma_regular_expressions_performance (end)
% section application_performance_evaluation (end)

\section{Framework Performance Evaluation} % (fold)
\label{sec:performance_evaluation}
We used the IDL file shown in Listing \ref{code_webidl_benchmarks} to test transfer and processing performance of individual operations:

\lstset{language=WebIDL,caption={WebIDL file used for benchmarking},label=code_webidl_benchmarks}
\begin{code}
dictionary dict {
  DOMString str;
  double d;
  boolean b;
};

dictionary nestedDict {
  DOMString topStr;
  double topD;
  boolean topB;
  dict nested;
};

interface Benchmark{
  long bench_long(long v);
  double bench_double(double v);
  DOMString bench_DOMString(DOMString v);
  dict bench_dict(dict v);
  nestedDict bench_nestedDict(nestedDict v);

  sequence<long> bench_seq_long(sequence<long> v);
  sequence<double> bench_seq_double(sequence<double> v);
  sequence<DOMString> bench_seq_DOMString(sequence<DOMString> v);
  sequence<dict> bench_seq_dict(sequence<dict> v);
  sequence<nestedDict> bench_seq_nestedDict(sequence<nestedDict> v);
};
\end{code}

We will use the generated RPC library to test the framework's performance. We will do this by making RPC calls and measuring how long it takes.

\subsection{Round trip performance}\label{round-trip-performance}

We measure the number of round trips performed in one second (round trips per second, RT/s).

One round trip corresponds to a full remote procedure call, starting from JavaScript, reaching the target function, returning from the function, and going back to the JavaScript. This is illustrated in Figure \ref{fig:rpc_roundtrip}.

\begin{figure}
    \centering
    \includegraphics[width=1\textwidth]{RoundTrip.pdf}
    \caption{A depiction of the round trip time from JavaScript to C++}
    \label{fig:rpc_roundtrip}
\end{figure}

\begin{table}[h]
\centering
\begin{tabular}{l|lll}
\textbf{Type}       & \textbf{Mean RT/s} & \textbf{Uncertainty} & \textbf{Number of runs} \\ \hline
\textbf{long}       & 418                & $\pm$1.79\%              & 56                      \\
\textbf{double}     & 423                & $\pm$2.08\%              & 48                      \\
\textbf{DOMString}  & 420                & $\pm$1.25\%              & 43                      \\
\textbf{dict}       & 415                & $\pm$2.39\%              & 44                      \\
\textbf{nestedDict} & 385                & $\pm$1.29\%              & 47
\end{tabular}
\caption{Round trip performance of sending a single parameter}
\label{table:roundtrip_single_param}
\end{table}

\begin{table}[h]
\centering
\begin{tabular}{l|lllll}
\multirow{2}{*}{\textbf{Array Length}} & \multicolumn{5}{l}{\textbf{Round trips per second}}                                        \\
                                       & \textbf{long} & \textbf{double} & \textbf{DOMString} & \textbf{dict} & \textbf{nestedDict} \\ \hline
\textbf{10}                            & 403               & 403                 & 378                    & 317               & 244                     \\
\textbf{45}                            & 379               & 384                 & 309                    & 182               & 112                     \\
\textbf{100}                           & 354               & 347                 & 234                    & 110               & 60.07                   \\
\textbf{450}                           & 237               & 235                 & 102                    & 32.82             & 15.83                   \\
\textbf{1000}                          & 163               & 160                 & 55.41                  & 15.39             & 7.43                    \\
\textbf{4500}                          & 49.39             & 48.93               & 14.60                  & 3.62              & 1.68                    \\
\textbf{10000}                         & 24.68             & 24.50               & 6.62                   & 1.62              & 0.75                    \\
\textbf{45000}                         & 5.99              & 5.98                & 1.28                   & 0.33              & 0.15
\end{tabular}
\caption{Round trip performance for arrays of different lengths and types}
\label{table:roundtrip_array}
\end{table}

Tables \ref{table:roundtrip_array} and \ref{table:roundtrip_single_param} show the number of round trips performed in a second for RPC calls with a single parameter and different array lengths. To compare these times, Figure \ref{fig:arraylength-time-plot} shows a column chart visualisation of the data.

\begin{figure}
    \centering
    \includegraphics[width=1\textwidth]{arraylength-time-plot.pdf}
    \caption{The round trip time for arrays of different lengths and types}
    \label{fig:arraylength-time-plot}
\end{figure}

\begin{figure}
    \centering
    \includegraphics[width=1\textwidth]{arraylength-time-cpp-plot.pdf}
    \caption{The C++ library time for arrays of different lengths and types}
    \label{fig:arraylength-time-cpp-plot}
\end{figure}

\subsection{C++ Library Time}\label{c-library-time}

We measure the number of microseconds taken to handle a RPC call. This is the time it takes to detect it is an RPC call, extract parameters, convert them, find the method, call it, pack the result, and post the message back to JS.

The results are measured and averaged for the same runs that were performed above. Tables \ref{table:cpp_lib_time_single_param} and \ref{table:cpp_lib_time_arrays} show the results, and Figure \ref{fig:arraylength-time-cpp-plot} shows a visualisation of the data.

\begin{table}[h]
\centering
\begin{tabular}{l|ll}
\textbf{Type}       & \textbf{Mean lib time/$\mu$s} & \textbf{Uncertainty (1 sd)} \\ \hline
\textbf{long}       & 106                       & 18                          \\
\textbf{double}     & 104                       & 17                          \\
\textbf{DOMString}  & 104                       & 18                          \\
\textbf{dict}       & 136                       & 23                          \\
\textbf{nestedDict} & 180                       & 28
\end{tabular}
\caption{Mean C++ library time for sending and receiving single parameters of different types}
\label{table:cpp_lib_time_single_param}
\end{table}

\begin{table}[h]
\centering
\begin{tabular}{l|lllll}
\multirow{2}{*}{\textbf{Array Length}} & \multicolumn{5}{l}{\textbf{Time / $\mu$s}}                                                                             \\
                                       & \textbf{long} & \textbf{double} & \textbf{DOMSTring} & \textbf{dict} & \textbf{nestedDict} \\ \hline
\textbf{10}                            & 125                & 126                  & 197                     & 453                & 861                      \\
\textbf{45}                            & 169                & 163                  & 484                     & 1513               & 3273                     \\
\textbf{100}                           & 243                & 246                  & 906                     & 3445               & 7010                     \\
\textbf{450}                           & 705                & 704                  & 3735                    & 13629              & 28198                    \\
\textbf{1000}                          & 1276               & 1355                 & 7607                    & 29582              & 63494                    \\
\textbf{4500}                          & 5548               & 5564                 & 30485                   & 132122             & 292828                   \\
\textbf{10000}                         & 11283              & 11376                & 68444                   & 301438             & 632956                   \\
\textbf{45000}                         & 50532              & 50843                & 359134                  & 1418792            & 3242286                  \\
\textbf{100000}                        & 104087             & 114020               & 799743                  & 3319250            & 7347985
\end{tabular}
\caption{Mean C++ library time for sending and receiving arrays of different lengths and types}
\label{table:cpp_lib_time_arrays}
\end{table}

\subsection{JS Library performance}\label{js-library-performance}

The JS library performance \textbf{without} client-side type validation has also been measured, however its performance impact is negligible. The slowest benchmark was found to take approx 3 microseconds (269,253 ops/sec $\pm$  1.90\%).

\subsection{Analysis}\label{analysis}

From the data, we can see that for small types, the most contributing factor to performance is the browser (e.g.~event system, etc.) and PPAPI libraries (how PPAPI implements postMessage). For example, sending a single long type takes 2392.34 microseconds (.002 seconds), but our library only spends 105.5 microseconds processing the call (less than 5\% of the time).

For large and complicated data, the impact of using the library becomes higher and higher. For example, sending 45000 nested objects (which are actually quite simple) has a total round-trip time of 6.67s, and a whole 3.24 seconds of this is spent in our library (i.e.~half the time).

The most likely reason for this is that the C++ library takes O(n) time to process the data in order to marshal it, by converting it from a \lstinline{pp::VarArray} into a \lstinline{std::vector}.

We also notice that the DOMString and Dictionary types are the slowest to marshal and de-marshal. One reason for this could be that number types have a standard representation so perhaps the PPAPI was able to improve how they are transferred, whilst the string types and dictionary types would need marshalling even by the PPAPI. One obvious reason for why the dictionary types take longer to marshal is that they contain multiple types, each type is individually marshalled. So sending a dictionary with multiple keys and values is almost equivalent to sending multiple values separately.

% section performance_evaluation (end)