text:
'use strict';
const compiler = require('../lib/kremling.js');
const fs = require('fs');

const source = fs.readFileSync(process.argv[2], 'utf8');
const compiled = compiler.compile(source);
console.log(compiled);

redpajama_set_name: RedPajamaGithub


text:
@interface ZYCTopicCell()
@property (weak, nonatomic) IBOutlet UIImageView *profileImageView;
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@property (weak, nonatomic) IBOutlet UILabel *createTimeLabel;

@property (weak, nonatomic) IBOutlet UIButton *dingButton;
@property (weak, nonatomic) IBOutlet UIButton *caiButton;
@property (weak, nonatomic) IBOutlet UIButton *shareButton;
@property (weak, nonatomic) IBOutlet UIButton *commentButton;
@property (weak, nonatomic) IBOutlet UIImageView *sinaVView;
@property (weak, nonatomic) IBOutlet UILabel *text_Label;

@property (weak, nonatomic) ZYCTopicPictureView *pictureView;
@end
@implementation ZYCTopicCell

- (ZYCTopicPictureView *)pictureView
{
    if (!_pictureView) {
        ZYCTopicPictureView *pictureView = [ZYCTopicPictureView pictureView];
        [self.contentView addSubview:pictureView];
        _pictureView = pictureView;
    }
    return _pictureView ;
}
- (void)awakeFromNib {
    [super awakeFromNib];
    UIImageView *bgView = [[UIImageView alloc]init];
    bgView.image = [UIImage imageNamed:@"mainCellBackground"];
    self.backgroundView = bgView;

}

- (void)setTopic:(ZYCTopic *)topic
{

    _topic = topic;
    [self.profileImageView sd_setImageWithURL:[NSURL URLWithString:topic.profile_image]placeholderImage:[UIImage imageNamed:@"defaultUserIcon"]];
    self.nameLabel.text = topic.name;
//    topic.sina_v = (int)arc4random_uniform(100)%2;
    self.sinaVView.hidden = !topic.isSina_v;

//    ZYCLog(@"%@",topic.create_time);

    self.createTimeLabel.text = topic.create_time;

    self.text_Label.text = topic.text;

    if (topic.type == ZYCTopicTypePicture) {
        self.pictureView.topic = topic;
        self.pictureView.frame = topic.pictureFrame;
    }

//    NSCalendar *calendar = [NSCalendar currentCalendar];

//    NSInteger year = [calendar component:NSCalendarUnitYear fromDate:now];

//    NSDateComponents *cmts = [calendar components:NSCalendarUnitDay|NSCalendarUnitMonth|NSCalendarUnitYear fromDate:now];

//    NSCalendarUnit unit = NSCalendarUnitDay|NSCalendarUnitMonth|NSCalendarUnitYear|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond;
//    NSDateComponents *comp = [now deltaFrom:create];

//    ZYCLog(@"%zd %zd %zd %zd %zd %zd ",comp.year,comp.month,comp.day,comp.hour,comp.minute,comp.second);
//    ZYCLog(@"%@",comp);

    [self setButtonTitle:_dingButton count:topic.ding placeholder:@"顶"];
    [self setButtonTitle:_caiButton count:topic.cai placeholder:@"踩"];
    [self setButtonTitle:_shareButton count:topic.repost placeholder:@"分享"];
    [self setButtonTitle:_commentButton count:topic.comment placeholder:@"评论"];

}
- (void)setButtonTitle:(UIButton *)button count:(NSInteger)count placeholder:(NSString *)placeholder
{
//    NSString *title = nil;
//
//    if (count == 0) {
//        title = placeholder;
//
//    } else if(count > 10000){
//        title = [NSString stringWithFormat:@"%.1f万",count/10000.0];
//    }else{
//        title = [NSString stringWithFormat:@"%zd",count];
//    }
//    [button setTitle:title forState:UIControlStateNormal];

    if(count > 10000){
        placeholder = [NSString stringWithFormat:@"%.1f万",count/10000.0];
    }else if(count > 0){
        placeholder = [NSString stringWithFormat:@"%zd",count];
    }
    [button setTitle:placeholder forState:UIControlStateNormal];
}
- (void)setFrame:(CGRect)frame
{

    frame.origin.x = ZYCTopicCellMargin;
    frame.size.width -= 2*ZYCTopicCellMargin;
    frame.size.height -= ZYCTopicCellMargin;
    frame.origin.y += ZYCTopicCellMargin;

    [super setFrame:frame];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

@end


text:
package integration

import (
	"testing"
	"time"

	kapi "k8s.io/kubernetes/pkg/api"
	kapierrors "k8s.io/kubernetes/pkg/api/errors"
	utilwait "k8s.io/kubernetes/pkg/util/wait"

	testutil "github.com/openshift/origin/test/util"
	testserver "github.com/openshift/origin/test/util/server"
)

func TestExtensionAPIServerConfigMap(t *testing.T) {
	testutil.RequireEtcd(t)
	defer testutil.DumpEtcdOnFailure(t)
	_, clusterAdminKubeConfig, err := testserver.StartTestMaster()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	clusterAdminKubeClient, err := testutil.GetClusterAdminKubeClient(clusterAdminKubeConfig)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	var configmap *kapi.ConfigMap
	err = utilwait.PollImmediate(50*time.Millisecond, 10*time.Second, func() (bool, error) {
		configmap, err = clusterAdminKubeClient.Core().ConfigMaps(kapi.NamespaceSystem).Get("extension-apiserver-authentication")
		if err == nil {
			return true, nil
		}
		if kapierrors.IsNotFound(err) {
			return false, nil
		}
		return false, err
	})
	if err != nil {
		t.Fatal(err)
	}
	if _, ok := configmap.Data["client-ca-file"]; !ok {
		t.Fatal("missing client-ca-file")
	}
}


text:
.. _aiohttp-built-with:

Built with aiohttp
==================

aiohttp is used to build useful libraries built on top of it,
and there's a page dedicated to list them: :ref:`aiohttp-3rd-party`.

There are also projects that leverage the power of aiohttp to
provide end-user tools, like command lines or software with
full user interfaces.

This page aims to list those projects. If you are using aiohttp
in your software and if it's playing a central role, you
can add it here in this list.

You can also add a **Built with aiohttp** link somewhere in your
project, pointing to `<https://github.com/aio-libs/aiohttp>`_.

* `Pulp <https://pulpproject.org>`_ Platform for managing repositories
  of software packages and making them available to consumers.
* `repo-peek <https://github.com/rahulunair/repo-peek>`_ CLI tool to open a remote repo locally quickly.
* `Molotov <http://molotov.readthedocs.io>`_ Load testing tool.
* `Arsenic <https://github.com/hde/arsenic>`_ Async WebDriver.
* `Home Assistant <https://home-assistant.io>`_ Home Automation Platform.
* `Backend.AI <https://backend.ai>`_ Code execution API service.
* `doh-proxy <https://github.com/facebookexperimental/doh-proxy>`_ DNS Over HTTPS Proxy.
* `Mariner <https://gitlab.com/radek-sprta/mariner>`_ Command-line torrent searcher.
* `DEEPaaS API <https://github.com/indigo-dc/DEEPaaS>`_ REST API for Machine learning, Deep learning and artificial intelligence applications.
* `BentoML <https://github.com/bentoml/BentoML>`_ Machine Learning model serving framework
* `salted <https://github.com/RuedigerVoigt/salted>`_ fast link check library (for HTML, Markdown, LaTeX, ...) with CLI


text:
"""
Copyright 2022 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

# [START sheets_append_values]
from __future__ import print_function

import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

def append_values(spreadsheet_id, range_name, value_input_option,
                  _values):
    """
    Creates the batch_update the user has access to.
    Load pre-authorized user credentials from the environment.
    TODO(developer) - See https://developers.google.com/identity
    for guides on implementing OAuth2 for the application.
        """
    creds, _ = google.auth.default()
    # pylint: disable=maybe-no-member
    try:
        service = build('sheets', 'v4', credentials=creds)

        values = [
            [
                # Cell values ...
            ],
            # Additional rows ...
        ]
        # [START_EXCLUDE silent]
        values = _values
        # [END_EXCLUDE]
        body = {
            'values': values
        }
        result = service.spreadsheets().values().append(
            spreadsheetId=spreadsheet_id, range=range_name,
            valueInputOption=value_input_option, body=body).execute()
        print(f"{(result.get('updates').get('updatedCells'))} cells appended.")
        return result

    except HttpError as error:
        print(f"An error occurred: {error}")
        return error

if __name__ == '__main__':
    # Pass: spreadsheet_id, range_name value_input_option and _values)
    append_values("1CM29gwKIzeXsAppeNwrc8lbYaVMmUclprLuLYuHog4k",
                  "A1:C2", "USER_ENTERED",
                  [
                      ['F', 'B'],
                      ['C', 'D']
                  ])
    # [END sheets_append_values]


text:
/**
 * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
 */

// DO NOT EDIT MANUALLY
package sbt.protocol.testing
/** Called if test completed with an error. */
final class EndTestGroupErrorEvent private (
  val name: String,
  val error: String) extends sbt.protocol.testing.TestMessage() with Serializable {

  override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match {
    case x: EndTestGroupErrorEvent => (this.name == x.name) && (this.error == x.error)
    case _ => false
  })
  override def hashCode: Int = {
    37 * (37 * (37 * (17 + "sbt.protocol.testing.EndTestGroupErrorEvent".##) + name.##) + error.##)
  }
  override def toString: String = {
    "EndTestGroupErrorEvent(" + name + ", " + error + ")"
  }
  private[this] def copy(name: String = name, error: String = error): EndTestGroupErrorEvent = {
    new EndTestGroupErrorEvent(name, error)
  }
  def withName(name: String): EndTestGroupErrorEvent = {
    copy(name = name)
  }
  def withError(error: String): EndTestGroupErrorEvent = {
    copy(error = error)
  }
}
object EndTestGroupErrorEvent {

  def apply(name: String, error: String): EndTestGroupErrorEvent = new EndTestGroupErrorEvent(name, error)
}


text:
import PropTypes from 'prop-types'
import React     from 'react'

export default class BreadcrumbItem extends React.Component {
	static defaultProps = {
		active: false,
		page  : false
	}

	static propTypes = {
		active  : PropTypes.bool,
		children: PropTypes.node,
		id      : PropTypes.string.isRequired,
		page    : PropTypes.bool
	}

	render () {
		const {active, children, id, page} = this.props

		let attributes = {}
		if (page) {
			attributes['aria-current'] = 'page'
		}

		return <li id={id} className={'breadcrumb-item ' + (active ? 'active ' : '')} {...attributes}>
			{children}
		</li >
	}
}


text:
import wx
import wx.lib.newevent
from parameters_panel_slicer import SlicerParameterPanel
from sas.sasgui.guiframe.utils import format_number
from sas.sasgui.guiframe.panel_base import PanelBase
from sas.sasgui.guiframe.events import (SlicerParameterEvent, EVT_SLICER_PARS,
                                        EVT_SLICER)

class SlicerPanel(wx.Panel, PanelBase):
    """
    Panel class to show the slicer parameters
    """
    # Internal name for the AUI manager
    window_name = "Slicer panel"
    # Title to appear on top of the window
    window_caption = "Slicer Panel"
    CENTER_PANE = False

    def __init__(self, parent, id=-1, type=None, base=None,
                 params=None, *args, **kwargs):
        wx.Panel.__init__(self, parent, id, *args, **kwargs)
        PanelBase.__init__(self)
        # Initialization of the class
        self.base = base
        if params is None:
            params = {}
        self.params = params
        self.parent = base.parent
        self.frame = None
        self.type = type
        self.listeners = []
        self.parameters = []
        self.bck = wx.GridBagSizer(5, 5)
        self.SetSizer(self.bck)
        if type is None and params is None:
            label = "Right-click on 2D plot for slicer options"
            title = wx.StaticText(self, -1, label, style=wx.ALIGN_LEFT)
            self.bck.Add(title, (0, 0), (1, 2),
                         flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL, border=15)
        else:
            self.set_slicer(type, params)
        # Bindings
        self.parent.Bind(EVT_SLICER, SlicerParameterPanel.on_evt_slicer)
        self.parent.Bind(EVT_SLICER_PARS, SlicerParameterPanel.on_param_change)

    def set_slicer(self, type, params):
        """
        Rebuild the panel
        """
        self.bck.Clear(True)
        self.type = type
        if type is None:
            label = "Right-click on 2D plot for slicer options"
            title = wx.StaticText(self, -1, label, style=wx.ALIGN_LEFT)
            self.bck.Add(title, (0, 0), (1, 2),
                         flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL, border=15)
        else:
            title_text = str(type) + "Parameters"
            title = wx.StaticText(self, -1, title_text,
                                  style=wx.ALIGN_LEFT)
            self.bck.Add(title, (0, 0), (1, 2),
                         flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL, border=15)
            n = 1
            self.parameters = []
            keys = params.keys()
            keys.sort()
            for item in keys:
                if not item.lower() in ["num_points", "avg", "avg_error", "sum",
                                        "sum_error"]:
                    n += 1
                    text = wx.StaticText(self, -1, item, style=wx.ALIGN_LEFT)
                    self.bck.Add(text, (n - 1, 0),
                                 flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL,
                                 border=15)
                    ctl = wx.TextCtrl(self, -1, size=(80, 20),
                                      style=wx.TE_PROCESS_ENTER)
                    hint_msg = "Modify the value of %s to change " % item
                    hint_msg += "the 2D slicer"
                    ctl.SetToolTipString(hint_msg)
                    ctl.SetValue(str(format_number(params[item])))
                    self.Bind(wx.EVT_TEXT_ENTER, self.on_text_enter)
                    ctl.Bind(wx.EVT_SET_FOCUS, self.on_set_focus)
                    ctl.Bind(wx.EVT_KILL_FOCUS, self.on_text_enter)
                    self.parameters.append([item, ctl])
                    self.bck.Add(ctl, (n - 1, 1), flag=wx.TOP | wx.BOTTOM,
                                 border=0)
            for item in keys:
                if item.lower() in ["num_points", "avg", "avg_error", "sum",
                                    "sum_error"]:
                    n += 1
                    text = wx.StaticText(self, -1, item + ": ",
                                         style=wx.ALIGN_LEFT)
                    self.bck.Add(text, (n - 1, 0),
                                 flag=wx.LEFT | wx.ALIGN_CENTER_VERTICAL,
                                 border=15)
                    ctl = wx.StaticText(self, -1,
                                        str(format_number(params[item])),
                                        style=wx.ALIGN_LEFT)
                    ctl.SetToolTipString("Result %s" % item)
                    self.bck.Add(ctl, (n - 1, 1), flag=wx.TOP | wx.BOTTOM,
                                 border=0)
        self.bck.Layout()
        self.Layout()
        p_sizer = self.parent.GetSizer()
        if p_sizer is not None:
            p_sizer.Layout()

    def on_set_focus(self, evt):
        """
        Highlight the txtcrtl
        """
        evt.Skip()
        # Get a handle to the TextCtrl
        widget = evt.GetEventObject()
        # Select the whole control, after this event resolves
        wx.CallAfter(widget.SetSelection, -1, -1)

    def on_text_enter(self, evt):
        """
        Parameters have changed
        """
        evt.Skip()
        params = {}
        has_error = False
        for item in self.parameters:
            try:
                params[item[0]] = float(item[1].GetValue())
                item[1].SetBackgroundColour(wx.SystemSettings_GetColour(
                    wx.SYS_COLOUR_WINDOW))
                item[1].Refresh()
            except:
                has_error = True
                item[1].SetBackgroundColour("pink")
                item[1].Refresh()
        if not has_error:
            # Post parameter event
            # base is guiframe is this case
            event = SlicerParameterEvent(type=self.type, params=params)
            wx.PostEvent(self.base, event)

    def on_close(self, event):
        """
        On Close Event
        """
        uid = self.uid
        self.parent.delete_panel(uid)
        self.frame.Destroy()


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title>selenium.webdriver.opera.webdriver — Selenium 2.0 documentation</title>

    <link rel="stylesheet" href="../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />

    <link rel="top" title="Selenium 2.0 documentation" href="../index.html" />

Navigation

          index

          modules |

Selenium 2.0 documentation »

selenium.webdriver.opera.webdriver¶

class <tt class="descclassname">selenium.webdriver.opera.webdriver.</tt><tt class="descname">WebDriver</tt><big>(</big>executable_path=None, port=0, desired_capabilities={'platform': 'ANY', 'browserName': 'opera', 'version': '', 'javascriptEnabled': True}<big>)</big>[source]¶

Controls the OperaDriver and allows you to drive the browser.

Creates a new instance of the Opera driver.

Starts the service and then creates new instance of Opera Driver.

<col class="field-name" />
<col class="field-body" />

Args :

executable_path - path to the executable. If the default is used it assumes the executable is in the
Environment Variable SELENIUM_SERVER_JAR

port - port you would like the service to run, if left as 0, a free port will be found.

desired_capabilities: Dictionary object with desired capabilities (Can be used to provide various Opera switches).

<tt class="descname">quit</tt><big>(</big><big>)</big>[source]¶

Closes the browser and shuts down the OperaDriver executable
that is started when starting the OperaDriver

This Page

Show Source

Quick search

    <form class="search" action="../search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>

    Enter search terms or a module, class or function name.

Navigation

          index

          modules |

Selenium 2.0 documentation »

        © Copyright 2011, plightbo, simon.m.stewart, hbchai, jrhuggins, et al..


text:
<?xml version="1.0"?>
<ruleset name="phpMyAdmin Standard">
  <!-- http://pear.php.net/manual/en/package.php.php-codesniffer.annotated-ruleset.php -->
  <description>phpMyAdmin custom coding standard</description>

  <rule ref="PEAR">
    <exclude name="PEAR.Commenting.FileComment" />
    <exclude name="PEAR.Commenting.ClassComment" />
    <exclude name="PEAR.Commenting.FunctionComment" />
    <exclude name="PEAR.Commenting.InlineComment" />
    <exclude name="Generic.Files.LineLength" />
  </rule>
  <rule ref="Generic.Metrics.NestingLevel" />
  <!-- There MUST NOT be trailing whitespace at the end of lines. -->
  <rule ref="Squiz.WhiteSpace.SuperfluousWhitespace" />
</ruleset>


text:
desc 'Manage products for a project'
long_desc %(
  The product[s] subcommand allows to manage your products by importing and exporting them as CSV.
)
command [:product, :products] do |c|

  c.arg_name 'key'
  c.flag [:p,:project], :desc => "Project key to use", :type => String

  c.desc 'List products'
  c.long_desc 'List the products (run in a configured code folder or provide the project key)'
  c.command [:list] do |list|
    list.action do |global_options,options,args|
      sphere.ensureLoggedIn
      Sphere::Products.new(nil, nil).list options, global_options
   end
  end

  c.desc 'Delete products'
  c.long_desc 'Delete all products in your prodject. Can not be undone'
  c.command [:delete] do |delete|
    delete.action do |global_options,options,args|
      sphere.ensureLoggedIn
      project_key = get_project_key options
      sphere_products = Sphere::Products.new project_key, global_options
      sphere_products.delete_all
    end
  end

  c.default_command :list

end


text:
export class NavigationItemMock implements Xrm.Controls.NavigationItem {
  private id: string;
  private standardElement: Xrm.Controls.UiStandardElement;
  private focusable: Xrm.Controls.UiFocusable;

  constructor(id: string, standardElement: Xrm.Controls.UiStandardElement, focusable: Xrm.Controls.UiFocusable) {
    this.id = id;
    this.standardElement = standardElement;
    this.focusable = focusable;
  }

  public setVisible(visible: boolean): void {
    return this.standardElement.setVisible(visible);
  }

  public getVisible(): boolean {
    return this.standardElement.getVisible();
  }

  public getLabel(): string {
    return this.standardElement.getLabel();
  }

  public setLabel(label: string): void {
    return this.standardElement.setLabel(label);
  }

  public setFocus(): void {
    return this.focusable.setFocus();
  }

  public getId(): string {
    return this.id;
  }
}


text:
import os, json, cloudant

from flask import Flask

app = Flask(__name__)

@app.route('/')
def Welcome():
    return app.send_static_file('index.html')

@app.route('/myapp')
def WelcomeToMyapp():
    vcap_config = os.environ.get('VCAP_SERVICES')
    decoded_config = json.loads(vcap_config)

    return 'Welcome to running flask and cloudant on Bluemix...' + decoded_config

@app.route('/createdb/<db>')
def create_db(db):
    try:
        vcap = json.loads(os.getenv("VCAP_SERVICES"))['cloudantNoSQLDB']

         cl_username = vcap[0]['credentials']['username']
         cl_password = vcap[0]['credentials']['password']

         url         = vcap[0]['credentials']['url']
         auth        = ( cl_username, cl_password )

    except:
        return 'uh oh... i think something went wrong...'

    requests.put( url + '/' + db, auth=auth )
    return 'Database %s created.' % db

@app.route('/api/people')
def GetPeople():
    list = [
        {'name': 'John', 'age': 28},
        {'name': 'Bill', 'val': 26}
    ]
    return jsonify(results=list)

@app.route('/api/people/<name>')
def SayHello(name):
    message = {
        'message': 'Hello ' + name
    }
    return jsonify(results=message)

port = os.getenv('PORT', '5000')
if __name__ == "__main__":
	app.run(host='0.0.0.0', port=int(port))


text:
layout: post
date: '2016-08-23'
title: "One Shoulder Pretty Maids 22555 Short Chiffon Bridesmaids Dress"
category: One Shoulder
tags: [One Shoulder]
---
### One Shoulder Pretty Maids 22555 Short Chiffon Bridesmaids Dress
Just **$214.99**
###

Buy it: [https://www.eudances.com/en/one-shoulder/2098-pretty-maids-22555-short-chiffon-bridesmaids-dress.html](https://www.eudances.com/en/one-shoulder/2098-pretty-maids-22555-short-chiffon-bridesmaids-dress.html)


text:
var argv = process.argv.slice(2)
  , path = require("path")
  , Runner = require("../lib/tap-runner")

  , nopt = require("nopt")

  , knownOpts =
    { cover: [path, false]
    , "cover-dir": path
    , stderr: Boolean
    , stdout: Boolean
    , diag: Boolean
    , version: Boolean
    , tap: Boolean
    , timeout: Number
    , gc: Boolean
    }

  , shorthands =
    // debugging 1: show stderr
    { d: ["--stderr"]
    // debugging 2: show stderr and tap
    , dd: ["--stderr", "--tap


text:
import React from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';

import SignOutButton from './SignOut';
import * as routes from '../constants/routes';

const Navigation = ({ authUser }) =>

    { authUser
        ? <NavigationAuth />
        : <NavigationNonAuth />
    }

const NavigationAuth = () =>

<Link to={routes.LANDING}>Landing</Link>

<Link to={routes.HOME}>Home</Link>

<Link to={routes.ACCOUNT}>Account</Link>

<Link to={routes.MAP1}>Valcia map</Link>

<Link to={routes.ADMINPAGE}>Admin</Link>

<SignOutButton />

const NavigationNonAuth = () =>

<Link to={routes.LANDING}>Info</Link>

    {/*
<Link to={routes.SIGN_IN}>Sign In</Link>
 */}

<Link to={routes.MAP1}>Valcia map</Link>

const mapStateToProps = (state) => ({
  authUser: state.sessionState.authUser,
});

export default connect(mapStateToProps)(Navigation);


text:
//
//  Geometry.cpp
//  JLIGameEngineTest
//
//  Created by James Folk on 11/22/14.
//  Copyright (c) 2014 James Folk. All rights reserved.
//

#include "Geometry.h"
#include "JLIFactoryTypes.h"
#include "World.h"
#include "LevelOfDetail.h"
#include "Material.h"
#include "ShaderProgram.h"
#include "MaterialProperty.h"
#include "GraphicsPlatform.h"
#include "Node.h"
#include "btTransform.h"

#include "Log.h"
#define TAG "Geometry.cpp"
#define FORMATSTRING "{\"njli::Geometry\":[]}"
#include "btPrint.h"
#include "JsonJLI.h"

#include "Image.h"
#define USE_OES

static const u32 MAX_SPRITES = NUMBER_OF_MESHES;

static const GLfloat IDENTITYMATRIX[] =
{
    1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1,
};

static const GLfloat COLOR_IDENTITYMATRIX[] =
{
    1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 0,
};

namespace njli
{
    f32 Geometry::s_PointSize = 1;
    f32 Geometry::s_LineWidth = 1;

    Geometry::Geometry():
    AbstractFactoryObject(this),
//    m_Name("MyGeometry"),
    m_Material(NULL),
    m_ShaderProgram(NULL),
    m_projectionMatrixUniform(-1),
//    m_modelViewMatrixUniform(-1),
    m_ModelviewTransform(NULL),
    m_ColorTransform(NULL),
    m_modelViewBufferID(-1),
    m_colorTransformBufferID(-1),
    m_InTransformAttrib(-1),
    m_InColorTransform(-1),
//    m_CurrentMeshCount(-1),
    m_verticesBufferID(-1),
    indexBufferID(-1),
    m_vertexArrayID(-1),
    m_InPositionAttrib(-1),
    m_InTexCoordAttrib(-1),
    m_InColorAttrib(-1),
    m_blendFuncSource(GL_SRC_ALPHA),
    m_blendFuncDestination(GL_ONE_MINUS_SRC_ALPHA),
    _opacityModifyRGB(false),
    m_enableBlend(true),
    m_enableDepthTest(true),
    m_enableStencilTest(false),
    m_TransformDirty(true),
    m_ColorTransformDirty(true),
//    m_StartCopyTransform(std::numeric_limits<u64>::max()),
    m_LoadGPU(false),
    m_setupOpacity_Material(NULL),
    m_setupOpacity_Image(NULL),
    m_setupOpacity(false),
    m_UnLoadGPU(false),
//    m_setupShader(false),
    m_bufferModified(true),
    m_vertexAttribChanged(false),
    m_MatrixBuffer(new float[16]),
    m_maxindice(0),
    m_RenderCategory(JLI_BIT_CATEGORY_NONE)
    {
        enableRenderObject();
    }

    Geometry::Geometry(const AbstractBuilder &builder):
    AbstractFactoryObject(this),
//    m_Name("MyGeometry"),
    m_Material(NULL),
    m_ShaderProgram(NULL),
    m_projectionMatrixUniform(-1),
//    m_modelViewMatrixUniform(-1),
    m_ModelviewTransform(NULL),
    m_ColorTransform(NULL),
    m_modelViewBufferID(-1),
    m_colorTransformBufferID(-1),
    m_InTransformAttrib(-1),
    m_InColorTransform(-1),
//    m_CurrentMeshCount(-1),
    m_verticesBufferID(-1),
    indexBufferID(-1),
    m_vertexArrayID(-1),
    m_InPositionAttrib(-1),
    m_InTexCoordAttrib(-1),
    m_InColorAttrib(-1),
    m_blendFuncSource(GL_SRC_ALPHA),
    m_blendFuncDestination(GL_ONE_MINUS_SRC_ALPHA),
    _opacityModifyRGB(false),
    m_enableBlend(true),
    m_enableDepthTest(true),
    m_enableStencilTest(false),
    m_TransformDirty(true),
    m_ColorTransformDirty(true),
//    m_StartCopyTransform(std::numeric_limits<u64>::max()),
    m_LoadGPU(false),
    m_setupOpacity_Material(NULL),
    m_setupOpacity_Image(NULL),
    m_setupOpacity(false),
    m_UnLoadGPU(false),
//    m_setupShader(false),
    m_bufferModified(true),
    m_vertexAttribChanged(false),
    m_MatrixBuffer(new float[16]),
    m_maxindice(0),
    m_RenderCategory(JLI_BIT_CATEGORY_NONE)
    {
        enableRenderObject();
    }

    Geometry::Geometry(const Geometry &copy):
    AbstractFactoryObject(this),
//    m_Name("MyGeometry"),
    m_Material(NULL),
    m_ShaderProgram(NULL),
    m_projectionMatrixUniform(-1),
//    m_modelViewMatrixUniform(-1),
    m_ModelviewTransform(NULL),
    m_ColorTransform(NULL),
    m_modelViewBufferID(-1),
    m_colorTransformBufferID(-1),
    m_InTransformAttrib(-1),
    m_InColorTransform(-1),
//    m_CurrentMeshCount(-1),
    m_verticesBufferID(-1),
    indexBufferID(-1),
    m_vertexArrayID(-1),
    m_InPositionAttrib(-1),
    m_InTexCoordAttrib(-1),
    m_InColorAttrib(-1),
    m_InOpacityAttrib(-1),
    m_InHiddenAttrib(-1),
    m_blendFuncSource(GL_SRC_ALPHA),
    m_blendFuncDestination(GL_ONE_MINUS_SRC_ALPHA),
    _opacityModifyRGB(false),
    m_enableBlend(true),
    m_enableDepthTest(true),
    m_enableStencilTest(false),
    m_TransformDirty(true),
    m_ColorTransformDirty(true),
//    m_StartCopyTransform(std::numeric_limits<u64>::max()),
    m_LoadGPU(false),
    m_setupOpacity_Material(NULL),
    m_setupOpacity_Image(NULL),
    m_setupOpacity(false),
    m_UnLoadGPU(false),
//    m_setupShader(false),
    m_bufferModified(true),
    m_vertexAttribChanged(false),
    m_MatrixBuffer(new float[16]),
    m_maxindice(0),
    m_RenderCategory(JLI_BIT_CATEGORY_NONE)
    {
        enableRenderObject();
    }

    Geometry::~Geometry()
    {
        delete [] m_MatrixBuffer; m_MatrixBuffer = NULL;

        unLoadGPU_Internal();
    }

    Geometry &Geometry::operator=(const Geometry &rhs)
    {
        if(this != &rhs)
        {

        }
        return *this;
    }

    s32	Geometry::calculateSerializeBufferSize() const
    {
        //TODO: calculateSerializeBufferSize
        return 0;
    }

    void Geometry::serialize(void* dataBuffer, btSerializer* serializer) const
    {
        //TODO: serialize
    }

    const char *Geometry::getClassName()const
    {
        return "Geometry";
    }

    s32 Geometry::getType()const
    {
        return Geometry::type();
    }

    Geometry::operator std::string() const
    {
        return njli::JsonJLI::parse(string_format("%s", FORMATSTRING));
    }

    Geometry *Geometry::create(u32 type)
    {
        SDL_assert(type == JLI_OBJECT_TYPE_Plane);

        return dynamic_cast<Geometry*>(World::getInstance()->getWorldFactory()->create(type));
    }

    void Geometry::destroy(Geometry *object)
    {
        if(object)
        {
            object->removeMaterial();
            object->removeShaderProgram();
            object->removeAllLevelOfDetails();

            World::getInstance()->getWorldFactory()->destroy(object);
        }
    }

    void Geometry::load(Geometry &object, lua_State *L, int index)
    {
        // Push another reference to the table on top of the stack (so we know
        // where it is, and this function can work for negative, positive and
        // pseudo indices
        lua_pushvalue(L, index);
        // stack now contains: -1 => table
        lua_pushnil(L);
        // stack now contains: -1 => nil; -2 => table
        while (lua_next(L, -2))
        {
            // stack now contains: -1 => value; -2 => key; -3 => table
            // copy the key so that lua_tostring does not modify the original
            lua_pushvalue(L, -2);
            // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table
            const char *key = lua_tostring(L, -1);
//            const char *value = lua_tostring(L, -2);
            if(lua_istable(L, -2))
            {
                Geometry::load(object, L, -2);
            }
            else
            {
                if(lua_isnumber(L, index))
                {
                    double number = lua_tonumber(L, index);
                    printf("%s => %f\n", key, number);
                }
                else if(lua_isstring(L, index))
                {
                    const char *v = lua_tostring(L, index);
                    printf("%s => %s\n", key, v);
                }
                else if(lua_isboolean(L, index))
                {
                    bool v = lua_toboolean(L, index);
                    printf("%s => %d\n", key, v);
                }
                else if(lua_isuserdata(L, index))
                {
//                    swig_lua_userdata *usr;
//                    swig_type_info *type;
//                    assert(lua_isuserdata(L,index));
//                    usr=(swig_lua_userdata*)lua_touserdata(L,index);  /* get data */
//                    type = usr->type;
//                    njli::AbstractFactoryObject *object = static_cast<njli::AbstractFactoryObject*>(usr->ptr);
//                    printf("%s => %d:%s\n", key, object->getType(), object->getClassName());

                }
            }
            // pop value + copy of key, leaving original key
            lua_pop(L, 2);
            // stack now contains: -1 => key; -2 => table
        }
        // stack now contains: -1 => table (when lua_next returns 0 it pops the key
        // but does not push anything.)
        // Pop table
        lua_pop(L, 1);
        // Stack is now the same as it was on entry to this function
    }

    u32 Geometry::type()
    {
        return JLI_OBJECT_TYPE_Geometry;
    }

    void Geometry::addLevelOfDetail(LevelOfDetail *lod)
    {
        SDL_assert(NULL != lod);

        std::vector<LevelOfDetail*>::const_iterator iter = std::find(m_LevelOfDetailList.begin(), m_LevelOfDetailList.end(), lod);

        if(iter == m_LevelOfDetailList.end())
        {
            std::vector<LevelOfDetail*>::iterator iter = std::find(m_LevelOfDetailList.begin(), m_LevelOfDetailList.end(), lod);

            if(iter != m_LevelOfDetailList.end())
                removeLevelOfDetail(lod);

            m_LevelOfDetailList.push_back(lod);

            addChild(lod);
        }
    }

    bool Geometry::removeLevelOfDetail(LevelOfDetail *lod)
    {SDL_assert(NULL != lod);

        std::vector<LevelOfDetail*>::iterator iter = std::find(m_LevelOfDetailList.begin(), m_LevelOfDetailList.end(), lod);

        if(iter != m_LevelOfDetailList.end())
        {
            removeChild(*iter);
            m_LevelOfDetailList.erase(iter);
            return true;
        }
        return false;
    }

    void Geometry::removeAllLevelOfDetails()
    {
        for(std::vector<LevelOfDetail*>::iterator iter = m_LevelOfDetailList.begin();
            iter != m_LevelOfDetailList.end();
            ++iter)
        {
            removeChild(*iter);
        }
        m_LevelOfDetailList.clear();
    }

    void Geometry::getLevelOfDetails(std::vector<LevelOfDetail*> &particleEmitters)const
    {
        for(std::vector<LevelOfDetail*>::const_iterator iter = m_LevelOfDetailList.begin();
            iter != m_LevelOfDetailList.end();
            ++iter)
        {
            if(getChildIndex(*iter) != -1)
                particleEmitters.push_back(*iter);
        }
    }

    LevelOfDetail *Geometry::getLevelOfDetail(const u32 index)
    {
        if (index < m_LevelOfDetailList.size())
        {
            s32 idx = getChildIndex(m_LevelOfDetailList.at(index));
            if(idx != -1)
                return dynamic_cast<LevelOfDetail*>(getChild(idx));
        }
        return NULL;
    }

    const LevelOfDetail *Geometry::getLevelOfDetail(const u32 index)const
    {
        if (index < m_LevelOfDetailList.size())
        {
            s32 idx = getChildIndex(m_LevelOfDetailList.at(index));
            if(idx != -1)
                return dynamic_cast<const LevelOfDetail*>(getChild(idx));
        }
        return NULL;
    }

    void Geometry::setMaterial(Material *material, Image *img)
    {
        SDL_assert(material != NULL);

        removeMaterial();

        m_Material = material;

        addChild(m_Material);

        if(img)
        {
            bool hasAlpha = img->getNumberOfComponents() == 4 || img->getNumberOfComponents() == 2;
            bool premultiplied = img->getNumberOfComponents() != 1 && hasAlpha;

            _opacityModifyRGB = false;
            if (m_blendFuncSource == GL_ONE && m_blendFuncDestination == GL_ONE_MINUS_SRC_ALPHA)
            {
                if (premultiplied)
                    _opacityModifyRGB = true;
                else {
                    m_blendFuncSource = GL_SRC_ALPHA;
                    m_blendFuncDestination = GL_ONE_MINUS_SRC_ALPHA;
                }
            }

            if(premultiplied)
                img->preMultiplyAlpha();
        }
    }

    void Geometry::removeMaterial()
    {
        if(getMaterial())
        {
            removeChild(getMaterial());
        }

        m_Material = NULL;
    }

    Material *Geometry::getMaterial()
    {
        s32 idx = getChildIndex(m_Material);
        if(idx != -1)
            return dynamic_cast<Material*>(getChild(idx));
        return NULL;
    }
    const Material *Geometry::getMaterial() const
    {
        s32 idx = getChildIndex(m_Material);
        if(idx != -1)
            return dynamic_cast<const Material*>(getChild(idx));
        return NULL;
    }

    void Geometry::setShaderProgram(ShaderProgram *shader)
    {
        SDL_assert(shader != NULL);

        removeShaderProgram();

        m_ShaderProgram = shader;

        addChild(m_ShaderProgram);

        setupShader();
    }

    void Geometry::removeShaderProgram()
    {
        ShaderProgram *shader = getShaderProgram();
        if(NULL != shader)
        {
            removeChild(shader);
        }

        m_ShaderProgram = NULL;
    }

    ShaderProgram *Geometry::getShaderProgram()
    {
        s32 idx = getChildIndex(m_ShaderProgram);
        if(idx != -1)
            return dynamic_cast<ShaderProgram*>(getChild(idx));
        return NULL;
    }

    const ShaderProgram *Geometry::getShaderProgram() const
    {
        s32 idx = getChildIndex(m_ShaderProgram);
        if(idx != -1)
            return dynamic_cast<const ShaderProgram*>(getChild(idx));
        return NULL;
    }

    u32 Geometry::getMaxMeshes()const
    {
        return MAX_SPRITES;
    }

    void Geometry::setBlendSource(s32 source)
    {
        m_blendFuncSource = source;
    }

    void Geometry::setBlendDestination(s32 dest)
    {
        m_blendFuncDestination = dest;
    }

    void Geometry::setupOpacity(Material *material, Image *img)
    {
        m_setupOpacity_Material = material;
        m_setupOpacity_Image = img;
        m_setupOpacity = true;
    }

    void Geometry::loadGPU()
    {
        m_LoadGPU = true;
    }

    void Geometry::unLoadGPU()
    {
        m_UnLoadGPU = true;
    }

    bool Geometry::isLoadedGPU()const
    {
        return (m_verticesBufferID != -1);
    }

    void Geometry::sort(const btVector3 &cameraOrigin)
    {
        quickSort(0, m_maxindice, cameraOrigin);
        m_maxindice = 0;
    }

    void Geometry::quickSort(signed long left, signed long right, const btVector3 &cameraOrigin)
    {
        SDL_assert(left >= 0 && left < getMaxMeshes());
        SDL_assert(right >= 0 && right < getMaxMeshes());

        signed long i = left, j = right;
        signed long pivot = (left + right) / 2;

        while (i <= j)
        {
            while (lessThan(i, pivot, cameraOrigin))
                ++i;
            while(greaterThan(j, pivot, cameraOrigin))
                --j;
            if (i <= j)
            {
                swapTransformData(i, j);
//                swapVertexData(i, j);

                ++i;
                --j;
            }
        }

        if (left < j)
            quickSort(left, j, cameraOrigin);
        if (i < right)
            quickSort(i, right, cameraOrigin);
    }

    void Geometry::swapTransformData(const size_t idx1, const size_t idx2)
    {
        btTransform temp(getTransform(idx1));
        setTransform(idx1, getTransform(idx2));
        setTransform(idx2, temp);

    }
    bool Geometry::lessThan(const size_t idx1, const size_t idx2, const btVector3 &cameraOrigin)
    {
        btVector3 object1(getTransform(idx1).getOrigin());
        btVector3 object2(getTransform(idx2).getOrigin());

        return cameraOrigin.distance2(object1) < cameraOrigin.distance2(object2);
    }

    bool Geometry::greaterThan(const size_t idx1, const size_t idx2, const btVector3 &cameraOrigin)
    {
        btVector3 object1(getTransform(idx1).getOrigin());
        btVector3 object2(getTransform(idx2).getOrigin());

        return cameraOrigin.distance2(object1) > cameraOrigin.distance2(object2);
    }

    void Geometry::setTransform(const u64 index, const btTransform &transform)
    {
        if (index < getMaxMeshes())
        {
            const GLuint STRIDE = 64;

            transform.getOpenGLMatrix(m_MatrixBuffer);

            m_TransformDirty = true;
            for (int currentVertex = 0; currentVertex < numberOfVertices(); currentVertex++)
            {
                u64 p = ((index * STRIDE) + (16 * currentVertex));
                int cmp = memcmp(m_ModelviewTransform + p,
                                 m_MatrixBuffer,
                                 sizeof(f32) * 16);

                if(0 != cmp)
                {
                    memcpy(m_ModelviewTransform + p, m_MatrixBuffer, sizeof(f32) * 16);
                    m_TransformDirty = true;
                }
            }
            m_maxindice = std::max<u64>(index, m_maxindice);
        }
    }

    btTransform Geometry::getTransform(const u64 index)
    {
        btTransform transform(btTransform::getIdentity());
        if (index < getMaxMeshes())
        {
            const GLuint STRIDE = 64;

            for (int currentVertex = 0; currentVertex < numberOfVertices(); currentVertex++)
            {
                u64 p = ((index * STRIDE) + (16 * currentVertex));
                memcpy(m_MatrixBuffer,
                       m_ModelviewTransform + p,
                       sizeof(f32) * 16);
            }

            transform.setFromOpenGLMatrix(m_MatrixBuffer);
        }
        return transform;
    }

    void Geometry::setColorTransform(const u64 index, const btTransform &transform)
    {
        if (index < getMaxMeshes())
        {
            const GLuint STRIDE = 64;

            transform.getOpenGLMatrix(m_MatrixBuffer);

            m_ColorTransformDirty = false;
            for (int currentVertex = 0; currentVertex < numberOfVertices(); currentVertex++)
            {
                u64 p = ((index * STRIDE) + (16 * currentVertex));

                int cmp = memcmp(m_ColorTransform + p,
                               m_MatrixBuffer,
                               sizeof(f32) * 16);

                if(0 != cmp)
                {
                    memcpy(m_ColorTransform + p,
                           m_MatrixBuffer,
                           sizeof(f32) * 16);
                    m_ColorTransformDirty = true;

                }

            }
        }
    }

    btTransform Geometry::getColorTransform(const u64 index)
    {
        btTransform transform(btTransform::getIdentity());
        if (index < getMaxMeshes())
        {
            const GLuint STRIDE = 64;

            for (int currentVertex = 0; currentVertex < numberOfVertices(); currentVertex++)
            {
                u64 p = ((index * STRIDE) + (16 * currentVertex));
                memcpy(m_MatrixBuffer,
                       m_ColorTransform + p,
                       sizeof(f32) * 16);
            }

            transform.setFromOpenGLMatrix(m_MatrixBuffer);
        }
        return transform;
    }

    void Geometry::getAabb(Node *node, btVector3& aabbMin,btVector3& aabbMax) const
    {
        aabbMin = btVector3(0,0,0);
        aabbMax = btVector3(0,0,0);
    }

    void Geometry::enableBlend(const bool enable)
    {
        m_enableBlend = enable;
    }

    void Geometry::enableDepthTest(const bool enable)
    {
        m_enableDepthTest = enable;
    }

    void Geometry::enableStencilTest(const bool enable)
    {
        m_enableStencilTest = enable;
    }

    void Geometry::hide(Camera* camera)
    {
        SDL_assert(camera);

        m_RenderCategory = (njliBitCategories)Off(m_RenderCategory, camera->getRenderCategory());
    }

    void Geometry::show(Camera * camera)
    {
        SDL_assert(camera);

        m_RenderCategory = (njliBitCategories)On(m_RenderCategory, camera->getRenderCategory());
    }

    bool Geometry::isHidden(Camera * camera) const
    {
        return !camera->hasRenderCategory(m_RenderCategory);
    }

    void Geometry::load()
    {
        unLoad();

        m_ModelviewTransform = new f32[MAX_SPRITES * numberOfVertices() * 16];
        memset(m_ModelviewTransform, 0, sizeof(f32) * MAX_SPRITES * numberOfVertices() * 16);

        m_TransformDirty = true;
//        m_StartCopyTransform = 0;

        for (int i = 0; i < MAX_SPRITES * numberOfVertices() * 16; i += 16)
        {
            memcpy(m_ModelviewTransform + i, IDENTITYMATRIX, sizeof(IDENTITYMATRIX));
        }

        m_ColorTransform = new f32[MAX_SPRITES * numberOfVertices() * 16];
        memset(m_ColorTransform, 0, sizeof(f32) * MAX_SPRITES * numberOfVertices() * 16);

        m_ColorTransformDirty = true;
        //        m_StartCopyTransform = 0;

        for (int i = 0; i < MAX_SPRITES * numberOfVertices() * 16; i += 16)
        {
            memcpy(m_ColorTransform + i, COLOR_IDENTITYMATRIX, sizeof(COLOR_IDENTITYMATRIX));
        }

        m_References.reset();
//        std::string ids = m_References.to_string();
//        SDL_LogVerbose(SDL_LOG_CATEGORY_TEST, "reset\t%s", ids.c_str());
    }
    void Geometry::unLoad()
    {
        if(m_ModelviewTransform)
            delete [] m_ModelviewTransform;
        m_ModelviewTransform=NULL;

        if(m_ColorTransform)
            delete [] m_ColorTransform;
        m_ColorTransform=NULL;
    }

    void Geometry::render(Camera *camera, s32 mode)
    {
#if (defined(DEBUG) || defined (_DEBUG)) && defined(__APPLE__)
        GLchar buffer[2048];
        sprintf(buffer, "%s, %s", getName(), camera->getName());
        glPushGroupMarkerEXT(0, buffer);
#endif
        Material *material = getMaterial();
        ShaderProgram *shader = getShaderProgram();

        if (m_UnLoadGPU)
            unLoadGPU_Internal();

        if (m_setupOpacity)
            setupOpacity_Internal(m_setupOpacity_Material, m_setupOpacity_Image);

        glLineWidth(s_LineWidth);

        if (m_LoadGPU)
            loadGPU_Internal();

//        if(m_setupShader)
//            setupShader_Internal();

        if (m_enableBlend)
        {
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            glBlendEquation(GL_FUNC_ADD);
        }
        else
        {
            glDisable(GL_BLEND);
        }

        if (m_enableDepthTest)
            glEnable(GL_DEPTH_TEST);
        else
            glDisable(GL_DEPTH_TEST);

        if (m_enableStencilTest)
            glEnable(GL_STENCIL_TEST);
        else
            glDisable(GL_STENCIL_TEST);

        if(!isLoadedGPU())
        {
            m_LoadGPU = true;
            loadGPU_Internal();
        }

        glBindVertexArray(m_vertexArrayID);

        if(NULL != shader)
        {
            if(shader->use())
            {
                if(NULL != material)
                    material->bind(shader);

                shader->setUniformValue("modelView", camera->getModelView());
                //        shader->setUniformValue("projection", camera->getProjection());

                //        glUniformMatrix4fv(m_modelViewMatrixUniform, 1, 0, camera->getModelViewMatrixArray());
                glUniformMatrix4fv(m_projectionMatrixUniform, 1, 0, camera->getProjectionMatrixArray());
                //        glUniform1i(u_opacityModifyRGB, _opacityModifyRGB);
                shader->setUniformValue("u_opacityModifyRGB", _opacityModifyRGB);
            }
        }

        bindTransform();
        bindColorTransform();

        if(isBufferModified())
        {
            glBindBuffer(GL_ARRAY_BUFFER, m_verticesBufferID);
            glBufferSubData(GL_ARRAY_BUFFER, 0, (GLsizeiptr)getArrayBufferSize(), getArrayBuffer());
            m_bufferModified = false;
//            printf("buffer");

            if (m_vertexAttribChanged)
            {
//

                glEnableVertexAttribArray(m_InPositionAttrib);
                glVertexAttribPointer(m_InPositionAttrib,
                                      3,
                                      GL_FLOAT,
                                      GL_FALSE,
                                      sizeof(TexturedColoredVertex),
                                      (const GLvoid*) offsetof(TexturedColoredVertex, vertex));

                glEnableVertexAttribArray(m_InTexCoordAttrib);
                glVertexAttribPointer(m_InTexCoordAttrib,
                                      2,
                                      GL_FLOAT,
                                      GL_FALSE,
                                      sizeof(TexturedColoredVertex),
                                      (const GLvoid*) offsetof(TexturedColoredVertex, texture));

                glEnableVertexAttribArray(m_InColorAttrib);
                glVertexAttribPointer(m_InColorAttrib,
                                      4,
                                      GL_FLOAT,
                                      GL_FALSE,
                                      sizeof(TexturedColoredVertex),
                                      (const GLvoid*) offsetof(TexturedColoredVertex, color));

                glEnableVertexAttribArray(m_InOpacityAttrib);
                glVertexAttribPointer(m_InOpacityAttrib,
                                      1,
                                      GL_FLOAT,
                                      GL_FALSE,
                                      sizeof(TexturedColoredVertex),
                                      (const GLvoid*)offsetof(TexturedColoredVertex, opacity));

                glEnableVertexAttribArray(m_InHiddenAttrib);
                glVertexAttribPointer(m_InHiddenAttrib,
                                      1,
                                      GL_FLOAT,
                                      GL_FALSE,
                                      sizeof(TexturedColoredVertex),
                                      (const GLvoid*)offsetof(TexturedColoredVertex, hidden));
            }

            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);

            glDrawElements(mode, static_cast<GLsizei>((getMaxMeshes()) * numberOfIndices()), GL_UNSIGNED_SHORT, (const GLvoid*)0);

            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
            glBindBuffer(GL_ARRAY_BUFFER, 0);
        }
        m_vertexAttribChanged = false;

        if(material)
            material->unBind();

        glDisable(GL_STENCIL_TEST);
        glDisable(GL_DEPTH_TEST);
        glDisable(GL_BLEND);

#if (defined(DEBUG) || defined (_DEBUG)) && defined(__APPLE__)
        glPopGroupMarkerEXT();
#endif
    }

//    void Geometry::setupShader()
//    {
//        m_setupShader = true;
//
//    }

    void Geometry::bindTransform()
    {
        if(m_TransformDirty)
        {
            const GLuint STRIDE = 64;

            glBindBuffer(GL_ARRAY_BUFFER, m_modelViewBufferID);

            GLsizei size = sizeof(GLfloat) * getMaxMeshes() * numberOfVertices() * 16;

            glBufferSubData(GL_ARRAY_BUFFER, 0, size, m_ModelviewTransform);

            if (m_vertexAttribChanged)
            {
                glEnableVertexAttribArray(m_InTransformAttrib + 0);
                glEnableVertexAttribArray(m_InTransformAttrib + 1);
                glEnableVertexAttribArray(m_InTransformAttrib + 2);
                glEnableVertexAttribArray(m_InTransformAttrib + 3);
                glVertexAttribPointer(m_InTransformAttrib + 0, 4, GL_FLOAT, 0, STRIDE, (GLvoid*)0);
                glVertexAttribPointer(m_InTransformAttrib + 1, 4, GL_FLOAT, 0, STRIDE, (GLvoid*)16);
                glVertexAttribPointer(m_InTransformAttrib + 2, 4, GL_FLOAT, 0, STRIDE, (GLvoid*)32);
                glVertexAttribPointer(m_InTransformAttrib + 3, 4, GL_FLOAT, 0, STRIDE, (GLvoid*)48);
            }

            glBindBuffer(GL_ARRAY_BUFFER, 0);

            m_TransformDirty = false;
        }
    }

    void Geometry::bindColorTransform()
    {
        if(m_ColorTransformDirty)
        {
            const GLuint STRIDE = 64;

            glBindBuffer(GL_ARRAY_BUFFER, m_colorTransformBufferID);

            GLsizei size = sizeof(GLfloat) * getMaxMeshes() * numberOfVertices() * 16;

            glBufferSubData(GL_ARRAY_BUFFER, 0, size, m_ColorTransform);

            if (m_vertexAttribChanged)
            {
                glEnableVertexAttribArray(m_InColorTransform + 0);
                glEnableVertexAttribArray(m_InColorTransform + 1);
                glEnableVertexAttribArray(m_InColorTransform + 2);
                glEnableVertexAttribArray(m_InColorTransform + 3);
                glVertexAttribPointer(m_InColorTransform + 0, 4, GL_FLOAT, 0, STRIDE, (GLvoid*)0);
                glVertexAttribPointer(m_InColorTransform + 1, 4, GL_FLOAT, 0, STRIDE, (GLvoid*)16);
                glVertexAttribPointer(m_InColorTransform + 2, 4, GL_FLOAT, 0, STRIDE, (GLvoid*)32);
                glVertexAttribPointer(m_InColorTransform + 3, 4, GL_FLOAT, 0, STRIDE, (GLvoid*)48);
            }

            glBindBuffer(GL_ARRAY_BUFFER, 0);

            m_ColorTransformDirty = false;

        }
    }

//    void Geometry::resetMeshCount()
//    {
//        m_CurrentMeshCount = -1;
//    }

    Node *Geometry::getParent()
    {
        return dynamic_cast<Node*>(AbstractDecorator::getParent());
    }

    const Node *Geometry::getParent()const
    {
        return dynamic_cast<const Node*>(AbstractDecorator::getParent());
    }

    void Geometry::addReference(Node *node)
    {
        for (s32 i = 0; i < m_References.size(); ++i)
        {
            if (!m_References[i])
            {
                m_References[i] = 1;

//                std::string ids = m_References.to_string();
//                SDL_LogVerbose(SDL_LOG_CATEGORY_TEST, "add\t%s", ids.c_str());

                node->setGeometryIndex(i);
                return;
            }
        }
    }
    void Geometry::removeReference(Node *node)
    {
        size_t index = node->getGeometryIndex();
        if(index < m_References.size())
        {
            m_References[index] = 0;

//            std::string ids = m_References.to_string();
//            SDL_LogVerbose(SDL_LOG_CATEGORY_TEST, "remove\t%s", ids.c_str());

            hideGeometry(node);
        }
    }

    void Geometry::enableBufferModified(bool modified)
    {
        m_bufferModified = modified;
    }

    bool Geometry::isBufferModified()const
    {
        return m_bufferModified;
    }

    void Geometry::setPointSize(const f32 s)
    {
        s_PointSize = s;
    }

    f32 Geometry::getPointSize()
    {
        return s_PointSize;
    }

    void Geometry::setLineWidth(const f32 s)
    {
        SDL_assert(s >= 0.0);
        s_LineWidth = s;
    }

    f32 Geometry::getLineWidth()
    {
        return s_LineWidth;
    }

    s32 Geometry::numberOfReferences()const
    {
        return m_References.size();
    }

    void Geometry::loadGPU_Internal()
    {
        SDL_assert(m_LoadGPU);

        SDL_assert(m_vertexArrayID == -1);

        glGenVertexArrays(1, &m_vertexArrayID);
        glBindVertexArray(m_vertexArrayID);
        {
            {
                SDL_assert(m_modelViewBufferID == -1);
                glGenBuffers(1, &m_modelViewBufferID);
                glBindBuffer(GL_ARRAY_BUFFER, m_modelViewBufferID);

                GLsizei size = sizeof(GLfloat) * getMaxMeshes() * numberOfVertices() * 16;
                glBufferData(GL_ARRAY_BUFFER, size, m_ModelviewTransform, GL_DYNAMIC_DRAW);
                glBindBuffer(GL_ARRAY_BUFFER, 0);
            }

            {
                SDL_assert(m_colorTransformBufferID == -1);
                glGenBuffers(1, &m_colorTransformBufferID);
                glBindBuffer(GL_ARRAY_BUFFER, m_colorTransformBufferID);

                GLsizei size = sizeof(GLfloat) * getMaxMeshes() * numberOfVertices() * 16;
                glBufferData(GL_ARRAY_BUFFER, size, m_ColorTransform, GL_DYNAMIC_DRAW);
                glBindBuffer(GL_ARRAY_BUFFER, 0);
            }

            {
                SDL_assert(m_verticesBufferID == -1);
                glGenBuffers(1, &m_verticesBufferID);
                glBindBuffer(GL_ARRAY_BUFFER, m_verticesBufferID);
                glBufferData(GL_ARRAY_BUFFER, (long)getArrayBufferSize(), getArrayBuffer(), GL_DYNAMIC_DRAW);
                glBindBuffer(GL_ARRAY_BUFFER, 0);
            }

            {
                SDL_assert(indexBufferID == -1);
                glGenBuffers(1, &indexBufferID);
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
                glBufferData(GL_ELEMENT_ARRAY_BUFFER, (long)getElementArrayBufferSize(), getElementArrayBuffer(), GL_STATIC_DRAW);
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
            }
        }

        glBindVertexArray(0);

        m_LoadGPU = false;
    }

    void Geometry::setupOpacity_Internal(Material *material, Image *img)
    {
        SDL_assert(m_setupOpacity);

        bool hasAlpha = img->getNumberOfComponents() == 4 || img->getNumberOfComponents() == 2;
        bool premultiplied = img->getNumberOfComponents() != 1 && hasAlpha;

        _opacityModifyRGB = false;
        if (m_blendFuncSource == GL_ONE && m_blendFuncDestination == GL_ONE_MINUS_SRC_ALPHA)
        {
            if (premultiplied)
                _opacityModifyRGB = true;
            else {
                m_blendFuncSource = GL_SRC_ALPHA;
                m_blendFuncDestination = GL_ONE_MINUS_SRC_ALPHA;
            }
        }

        if(premultiplied)
            img->preMultiplyAlpha();

        material->getDiffuse()->loadGPU(*img);

        m_setupOpacity = false;
    }

    void Geometry::unLoadGPU_Internal()
    {
        unLoadGPU();

        SDL_assert(m_UnLoadGPU);

        if(m_modelViewBufferID == -1)
        {
            glDeleteBuffers(1, &m_modelViewBufferID);
            m_modelViewBufferID = -1;
        }

        if(m_colorTransformBufferID == -1)
        {
            glDeleteBuffers(1, &m_colorTransformBufferID);
            m_colorTransformBufferID = -1;
        }

        if(indexBufferID == -1)
        {
            glDeleteBuffers(1, &indexBufferID);
            indexBufferID = -1;
        }

        if(m_verticesBufferID == -1)
        {
            glDeleteBuffers(1, &m_verticesBufferID);
            m_verticesBufferID = -1;
        }

        if(m_vertexArrayID == -1)
        {
            glDeleteVertexArrays(1, &m_vertexArrayID);

            m_vertexArrayID = -1;
        }

        m_UnLoadGPU = false;
    }

    void Geometry::setupShader()
    {
//        SDL_assert(m_setupShader);

        ShaderProgram *shader = getShaderProgram();

        SDL_assert(shader);

        if (!shader->isLinked())
        {
            if(!shader->link())
            {
                SDL_LogError(SDL_LOG_CATEGORY_TEST, "%s\n", shader->programLog());
//                SDL_LogError(SDL_LOG_CATEGORY_TEST, "Vertex log: %s\n", shader->vertexShaderLog());
//                SDL_LogError(SDL_LOG_CATEGORY_TEST, "Fragment log: %s\n", shader->fragmentShaderLog());
            }
        }
        if (shader->isLinked())
        {
            shader->use();
            // ... and add the attributes the shader needs for the vertex position, color and texture st information
            shader->bindAttribute("inPosition");
            shader->bindAttribute("inTexCoord");
            shader->bindAttribute("inColor");
            shader->bindAttribute("inOpacity");
            shader->bindAttribute("inHidden");

            shader->bindAttribute("inTransform");
            shader->bindAttribute("inColorTransform");

            // Setup the index pointers into the shader for our attributes
            m_InPositionAttrib = shader->getAttributeLocation("inPosition");
            m_InTexCoordAttrib = shader->getAttributeLocation("inTexCoord");
            m_InColorAttrib = shader->getAttributeLocation("inColor");
            m_InOpacityAttrib = shader->getAttributeLocation("inOpacity");
            m_InHiddenAttrib = shader->getAttributeLocation("inHidden");

            m_InTransformAttrib = shader->getAttributeLocation("inTransform");
            m_InColorTransform = shader->getAttributeLocation("inColorTransform");

            //        m_modelViewMatrixUniform = shader->getUniformLocation("modelView");
            m_projectionMatrixUniform = shader->getUniformLocation("projection");
            //        u_opacityModifyRGB = shader->getUniformLocation("u_opacityModifyRGB");
            //        u_pointSize = shader->getUniformLocation("u_pointSize");

            //        m_setupShader = false;
            m_vertexAttribChanged = true;
        }
    }
}


text:
namespace Ui {
class NewsPage;
}

class NewsPage : public QWidget
{
    Q_OBJECT

public:
    explicit NewsPage(QWidget *parent = 0);
    ~NewsPage();

private:
    Ui::NewsPage *ui;
    QWebView *webView;
};

#endif // NEWSDIALOG_H


text:
//-----------------------------------------------------------------------
// <copyright file="ProjectionTypeConfiguration.cs" company="Ticoplex">
//     Copyright (c) Ticoplex. All rights reserved.
// </copyright>
// <author>Luis Aguilar</author>
//-----------------------------------------------------------------------

namespace ExpressionFramework.Projections.Configuration
{
    using System;
    using System.Collections.Generic;

    /// <summary>
    /// Defines configuration properties containing information of the source types a projection type can be matched.
    /// </summary>
    /// <typeparam name="TProjection">The type of the projection.</typeparam>
    public class ProjectionTypeConfiguration<TProjection> : IProjectionTypeConfiguration
    {
        #region Fields

        /// <summary>
        /// The type of the configured projection.
        /// </summary>
        private readonly Type projectionType;

        /// <summary>
        /// A collection of projection sources configuration.
        /// </summary>
        private readonly IList<IProjectionSourceTypeConfiguration> sourcesConfigurations;

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ProjectionTypeConfiguration{TProjection}"/> class.
        /// </summary>
        public ProjectionTypeConfiguration()
        {
            this.projectionType = typeof(TProjection);
            this.sourcesConfigurations = new List<IProjectionSourceTypeConfiguration>();
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets the type of the configured projection.
        /// </summary>
        public Type ProjectionType
        {
            get { return this.projectionType; }
        }

        /// <summary>
        /// Gets a collection of projection sources configuration.
        /// </summary>
        public IList<IProjectionSourceTypeConfiguration> SourcesConfigurations
        {
            get { return this.sourcesConfigurations; }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Configures a projection source.
        /// </summary>
        /// <typeparam name="TSource">The type of the source.</typeparam>
        /// <param name="configurator">The delegate that configures the projection source.</param>
        /// <exception cref="System.ArgumentNullException">If the source configurator is null.</exception>
        public void ForSource<TSource>(Action<ProjectionSourceTypeConfiguration<TProjection, TSource>> configurator)
        {
            if (configurator == null)
            {
                throw new ArgumentNullException("configurator");
            }

            var sourceConfiguration = new ProjectionSourceTypeConfiguration<TProjection, TSource>();

            configurator(sourceConfiguration);

            this.SourcesConfigurations.Add(sourceConfiguration);
        }

        /// <summary>
        /// Gets an instance implementing the <see cref="IProjectionTypeDefinition"/> interface based on the
        /// current instance configuration values.
        /// </summary>
        /// <returns>The projection type definition.</returns>
        public IProjectionTypeDefinition GetDefinition()
        {
            var definition = new ProjectionTypeDefinition<TProjection>();

            foreach (var sourceConfiguration in this.SourcesConfigurations)
            {
                definition.Sources.Add(sourceConfiguration.SourceType, sourceConfiguration.GetDefinition());
            }

            return definition;
        }

        #endregion
    }
}


text:
<?php

namespace Acme\PortfolioBundle\DataFixtures\ORM;

use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;

use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

use Acme\PortfolioBundle\Entity\User;
use Acme\PortfolioBundle\Entity\Role;

class LoadUserData implements FixtureInterface
{
    /**
     * {@inheritDoc}
     */
    public function load(ObjectManager $manager)
    {
        $adminRole = new Role();
        $adminRole->setName('Admin Role')->setRole('ROLE_ADMIN');

        $manager->persist($adminRole);

        $user = new User();
        $user
            ->setUsername('admindb')
            ->setPassword(password_hash('admindb', PASSWORD_BCRYPT, array('cost' => 12)))
            ->addRole($adminRole)
        ;

        $manager->persist($user);
        $manager->flush();
    }
}


text:
Nazwa grupy

Ka¿da grupa musi mieæ unikaln± nazwê, która j± identyfikuje. Po utworzeniu
grupy tej nazwy nie mo¿na zmieniæ.


text:
package ar.com.javacuriosities.jsp.el.model;

public interface Person {
    String getName();

    void setName(String name);
}


text:
<!DOCTYPE html>

  <meta charset="utf-8">
  <meta name="generator" content="pandoc">
  <meta name="author" content="Rory Graves and Sam Halliday">
  <title>ENSIME</title>
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
  <link rel="stylesheet" href="http://lab.hakim.se/reveal-js//css/reveal.css">

  <link rel="stylesheet" href="http://lab.hakim.se/reveal-js//css/theme/sky.css" id="theme">
  <link rel="stylesheet" href="overrides.css"/>

ENSIME

Rory Graves and Sam Halliday

Video from Scala Days 2015

Introduction

Rory Graves @a_dev_musing

Wrote mobile games before it was cool

Dynamic networks before clusters were cool

Shows people around an old windmill at weekends

Martial artist who is a trained swordsman

Rory was writing mobile games when Nokia Snake was the height of technology, long before it was cool.

He was doing novel research on dynamic network protocols to replace TCP/IP, which was when a cluster was more likely to refer to a collection of peanuts than a collection of server computers.

He shows people around an old windmill in southern England at the weekends.

And he is a black belt in a martial art that I cannot pronounce, with the superpower of sword fighting.

So believe me, you really don't want to be waiting on your compiler with Rory around!

Sam Halliday @fommil

co-founded FHSST, 5mil Free textbooks in South Africa

co-founded a mathematics company

quantum mechanics, machine learning, etc

co-founded Neurofiction: brain scanners + fiction

netlib-java underpinning Apache Spark

most proud of getting to the Mun in Kerbal…

FreeHighSchoolScienceTexts No Evidence he ever got back from the Mun

Straw Poll

IntelliJ

ScalaIDE

Emacs

Other

TL;DR

it's not another IDE, it's about context

so people can use their favourite text editor

so it can be used programmatically for better tooling / analysis

Ensime is not really an IDE

Its a toolset for building IDEs and analysing code.

But…

It is time to build our own IDE!

Overview

Ensime in action

Architecture

Ecosystem - our community

Protocols - Shapeless marshalling magic

The Roadmap

The Future

Ensime in action.

Everything you ever wanted to know about Ensime

Protocol Design

Jerk and the power of Shapeless marshalling

Coming soon

The future

End with 'Demo Time!'

Demo

(set-frame-font "Inconsolata-24") (required 'command-log-mode t) (global-command-log-mode) (setq guide-key/guide-key-sequence nil)

sleep 2 ; recordmydesktop –no-sound –on-the-fly-encoding –no-frame -o ensime.ogv

Rough script, for a walkthrough:

start with scala-mode2 and show regex syntax highlighting.

turn on ensime and comment on the sbt deploy process.

wait for the funny and announce that we'll have a call for new funnies for the 1.0 release, with a prize for the best.

semantic highlighting kicks in and we can see that everything is correctly detected where regex failed. Until I started using ENSIME for Scala, I always thought the colour coding was a bit random, but now I use colour to help me understand code and I can get a feel for it based on whether its type heavy, data driven or lots of functions.

introduce and error by creating an instance of something that hasn't been imported. Show the error and then import a suggestion.

Then show the type, and inspect the type.

Come back to the code buffer and autocomplete a method and show the parameter autofill / tab jumping.

Generate / go to the corresponding test

Call out to sbt to run just that test file.

Back to the test file, open up a nearby test file and use it to jump to the implementation.

Pick a class in a third party library and jump to its source code.

Come back, ask for its documentation, view it in your browser. Isn't it a pity that nobody writes Scaladocs!

Ask for the documentation for something in the Java standard library, read it in the browser.

Rename a local variable or method with refactor.

Reformat the code with Scalariform.

Start a REPL, type some stuff.

Search for a class, show that it works with camel case.

<video width="1024" height="572" controls>
  <source src="videos/ensime-demo.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>

Architecture

This is an architectural overview of the internals of the ensime-server, which is bounded here by the dotted lines.

The text editor communicates with the server via SWANK, which is a bidirectional TCP/IP sockets protocol using S-Expressions as the language. This is really convenient for emacs. We'll talk about protocols later because we really don't see ENSIME as being an emacs only library.

The server runs locally, so it also has direct access to the files on the disc and can watch for changes without needing to be told about them. This is typically used for detecting changes in the compiled files rather than looking for changes in source code.

And when the server is started, it needs to be given a .ensime file which defines the project layout. This is typically generated by the build tool.

Inside the server, everything goes via the central Project class which effectively just delegates to the relevant sub-component. The two big parts are the Search Service and the Analyzer:

The Search Service indexes all the binaries related to the project, including third party jars. We use ASM to do the heavy lifting and we persist the results to H2 to enable various types of searches. We also build up an index in Lucene for advanced searching, such as camel case searching of a classname.

The Analyzer is our layer that sits on top of the Scala Presentation Compiler, which is an interactive version of the Scala Compiler but is supposed to be quicker because it shortcuts various stages in order to be responsive. This is the same backend that is used by the Scala IDE, but it is released as part of the official Scala Compiler jar.

We also have the ability to identify source code to binaries, e.g. to relate your third party source zip files to the jars that you're including. This lets us implement the "jump to source" functionality beyond the user's project files.

Documentation is hosted via a Spray HTTP server and viewed in a normal web browser.

A debug manager component allows interactive debugging sessions against a running JVM. It manages the state of the threads and allows stepping and inspection.

Then there is some stuff that lives on the cusp of what ensime should really do, like source formatting. You can issue a command to ENSIME and it'll format your sources, which works well if you don't have automatic formatting as part of your build.

We've had various discussions about where the "in/out" line should be and we decided that compilation is definitely on the other side of the line because that's what build tools are designed to do. But with the possibility of closer integration with the new sbt server, we will see the coupling with sbt, in particular, becoming stronger. But we're not limiting ourselves to one build tool because the reality is that a large number of corporate development environments are using legacy build systems and we want to support that.

Ecosystem

Projects

ENSIME isn't just one project. The server is a Scala project with separate branches to support the three active stable release versions of Scala. (Yes, people are still using Scala 2.9 in production systems).

The compiler API has been quite volatile across versions, so we are not able to offer a single source build. The server jars are published as snapshots to Sonatype, more about that in a few slides.

The emacs client is a completely separate project to the server. It has its own github repository and is published using the emacs package management system MELPA.

Build tool plugins also live in their own repositories. The functionality offered here is typically the ability to generate the .ensime file, although we might see more functionality in the future, for example, integration with the sbt server or automating the debugging launch process with build tool commands. The plugins are rarely updated, so they are published to Maven Central.

And we have a separate repository for creating our docker images, which is used by the build system. We have an official docker image that is used for each release branch and that has all our hard dependencies pre-loaded (i.e. JDK and sbt), this is published to Docker Hub.

Community

c.f. Benjamin Mako Hill's talk at LibrePlanet 2013

Benjamin Mako Hill gave a talk at LibrePlanet 2013 did an analysis of projects on github. He showed that the vast majority of projects have one contributor.

ENSIME is a really nice project to work on because it doesn't have a single owner. Aemon started the project way back in 2010, but myself, Rory and Eric have all been helping out over the last year.

We don't have a financial backer, so realistic the only way for ENSIME to survive and grow is to have a strong community.

Server Contributors

Author
+ lines
- lines

Aemon Cannon
62529
47989

Sam Halliday
17505
17565

Rory Graves
12080
10156

Eric Daniel
2958
1113

Eugene Burmako
413
151

Jason Fager
230
144

Marc Saegesser
160
324

Fabian
144
45

Alexander Pupeikis
126
20

Jacob Schlather
66
64

Matt Russell, John Sullivan, Daniel Spiewak, Radzisław Galler, Toshiyuki Takahashi, Alexander Baier, Peluko, Grégoire Neuville, Igor Shymko, Anatoly Fayngelerin, tbje, Tomás Senart, Mark Schaake, Marc Weber, Felix Geller, toshiyuki takahashi, sksamuel, pashky, William O'Hanley, Wilfred Springer, The Gitter Badger, Steve Jenson, Scalariform, RayRacine, Pawel Kopiczko, Mike O'Connor, Michael Terry, Jack Viers, Ivan Poliakov, Huw Giddens, Hubert Plociniczak, Habibullah Pagarkar, Evgeny Chukreev, Erik Osheim, Eric Sessoms, Deokhwan Kim, Dave Fayram, Bozhidar Batsov, Bas Kok, Alexandre Bertails, Alejandro Pedraza.

Our list of contributors is really quite large.

These are the authors who have contributed to the ensime-server repository. So there are quite a lot of people, and the vast majority of contributors jump in with a small bugfix or feature.

Emacs Contributors

Author
+ lines
- lines

Aemon Cannon
30959
15624

Eric Daniel
16095
15625

Sam Halliday
2098
4131

Radzisław Galler
1094
3183

Grégoire Neuville
302
143

Alexander Pupeikis
132
19

Toshiyuki Takahashi
69
62

Fabian
59
9

Alexander Baier
57
58

Robin Green, Łukasz Klich, Paul Sexton, Kirill Kulikov, Erik Assum, Marc Saegesser, ScottyB, Peluko, Eugene Burmako, Matt Russell, Daniel Spiewak, John Sullivan, Jason Fager, Igor Shymko, Anatoly Fayngelerin, tbje, Tyson Hamilton, Tomás Senart, MrBones118, Mark Schaake, Marc Weber, Marc A. Saegesser, Felix Geller, Alejandro Pedraza, toshiyuki takahashi, pdn, pashky, jules, hmgibson23, Wilfred Springer, Sviridov Alexander, Steve Jenson, Scalariform, Sacha Chua, Rory Graves, RayRacine, Mike O'Connor, Michael Terry, Jack Viers, Ivan Poliakov, Huw Giddens, Hubert Plociniczak, Howard Branch, Habibullah Pagarkar, Greg Pfeil, Evgeny Chukreev, Erik Osheim, Deokhwan Kim, Dave Fayram, Dave Aitken, Bozhidar Batsov, Ben Spencer, Bas Kok, Andre Silva, Alexandre Bertails.

It's a similar story with the ensime-emacs repository, but the list of names is quite different.

And note that Rory is way down the list. A little known fact is that he doesn't actually use Emacs at all!

Community Principles

Code of Conduct

good vibes

Lots of help for new contributors

ticket → general area of code

fast PR reviews and feedback

Pragmatic approach

everybody is a Scala dev

KISS: prefer failure / explanation, not complexity

Bounties!

failed experiment

Fundamentally, a good community has to be inclusive, share a common goal, and be fun. As admins we try to encourage that vibe with anyone who comes across us and we recently put in place a formal code of conduct. (Selfishly we heard that some people looking for a project to contribute to had said it was a deciding factor for them, so we put one in place… but obviously it's a good thing to have just in case.)

Typically when we get a bug report, or a feature request, we'll offer to help the reporter. If you raise a ticket, you can expect to get pointed at the general area in the code that needs improvement and any changes you make will be quickly reviewed. Often with an avalanche of additional suggestions! :-)

This approach obviously doesn't always work out, and some tickets might never get closed, but clearly it's working out pretty well because we get a *lot* of contributors sending one or two PRs and make an improvement.

We take a pragmatic approach to feature and bugfix prioritisation. It's not like we're developing a mass consumer website, or a specialist system with business users — everybody who uses ENSIME is a scala developer and should know how to interpret an exception in the logs. That's why we prefer simple solutions and clear error messages to putting in error handling.

As an example, we recently had a bug report about the server barfing when the config contained a dodgy source zip file. Well, we could write lots of complex code to detect and deal with various kinds of dodgy zipfiles… but we much prefer to throw an exception and then find out how to get the source file excluded in Ivy, and the upstream Nexus. It's all about doing the simple, often dumb, thing, because that's easier to maintain.

And we have bounties on a lot of tickets, about $1,000 worth. But nobody wants to claim them even when they close the ticket! What tends to happen is that if someone claims the bounty, they put it back on the project… but we are actually very happy for you to spend it on beer if you'd like! (That was actually the original plan)

Continuous Integration

Key to survival of ENSIME is ease of contribution, and the only way to manage that is by automating as much of the development process as possible.

We have a strong emphasis on testing (unit, integration, client tests), coverage, shippable docker images (soon to be replaced by drone).

Continuous Delivery

We can do this because of the suite of tests.

Green master builds are automatically deployed to sonatype snapshots repository, and we use sbt in the emacs client to do the deployment on the client machine and obtain the classpath. Every time the client updates, or the user types ensime-update the server deployment will be refreshed.

Protocol

Greenspun's tenth rule

"Any sufficiently complicated program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp."

Yes, ok, so we wrote a lisp interpreter. Actually, we wrote two, but one as emerged as the victor. But it is worth noting that…

"The class of sufficiently complicated programs includes Common Lisp."

— Robert Morris' corollary (Y-Combinator)

S-Expressions

Let's talk about lisp for a little bit, or more specifically, S-Expressions.

For the emacs users among you, this is second nature.

An S-Expression is either an atom - symbol, string, number, array, hashmap, etc - or a cons of two S-Expressions, using this parenthesis notation with a dot to separate the two parts.

(a . (b . (c . nil)))

(a b c) ;; list syntax

One of the most amazing things about S-Expressions, and lisp, is that data is code and code is data.

There is no real "list" data type, in the Scala sense, it's just any structure that ends with the symbol "nil".

Lists are so common in lisps that this special syntax is introduced.

(:keyA . (valueA . (:keyB . (valueB . nil))))

(:keyA valueA
 :keyB valueB) ;; data syntax with keywords

(:file "Foo.scala"
 :line 13)

;; complex map structure
((1 2 3) "Foo.scala"
 (:key value) 13)

And similarly, other collection types are defined by convention rather than with formal types.

Here we have "data syntax", using keywords - symbols that begin with a colon - which is really just a list of alternating keywords and values.

And here we have a complex map structure where the first key is a list of numbers and the second key is a data structure.

It's these "data syntax" structures that make up the majority of the ENSIME protocol, called SWANK.

SWANK

ENSIME derived from SWANK — easy for Emacs

vs JSON

JSON keys are String

JSON maps are unordered

S-Exp naturally encodes structure

neither has an official schema

A little bit of history. Back when Aemon started ENSIME, he was taking inspiration from an emacs mode called SLIME, which is a mode for common lisp. SLIME has an external server that runs a binary that natively understands common lisp, as opposed to emacs lisp, and reports back to emacs using the SWANK protocol. Hence, with all that infrastructure in place on the client side, it made sense to base the ENSIME protocol on the SWANK protocol.

But actually, S-Expressions are pretty amazing as a data format. There is the obvious benefit of fast lisp parsers in existence, but even some shortcomings of JSON can be addressed: JSON keys in a map must be String but in S-Expressions they can be arbitrarily complex, and JSON maps are unordered and you cannot be guaranteed that your parser - or the other side - will preserve map ordering — but S-Expressions are fundamentally ordered.

It's also possible to encode complex structures into S-Expressions, which again can save time… red/black trees and so on are the obvious example.

But as a potential downside - although some may see it as a positive - there is no official schema for either.

case class TypeAtPointReq(
  file: File,
  range: OffsetRange
) extends RpcTypeRequest

case class BasicTypeInfo(
  name: String,
  typeId: Int,
  declAs: DeclaredAs,
  fullName: String,
  typeArgs: Iterable[TypeInfo],
  members: Iterable[EntityInfo],
  pos: Option[SourcePosition],
  outerTypeId: Option[Int]
) extends TypeInfo

Let's take an example of what SWANK actually looks like. Here we have some random case classes that are part of the ENSIME protocol.

(:swank-rpc
 (swank:type-at-point
  "<...>/org/ensime/indexer/SearchService.scala"
  1858)
 7)

(:return
 (:ok
   (:arrow-type nil
    :name "String"
    :type-id 7
    :decl-as class
    :full-name "java.lang.String"
    :type-args nil
    :members nil
    :pos (:type line
          :file "<...>/java/lang/String.java"
          :line 134)
    :outer-type-id nil))
 7)

And this is what they look like when they are converted into SWANK.

You can see that the client queries with a number for their request, and the server includes that number in the response.

S-Express

inspired by spray-json

but with shapeless magic for Product

helps automate addition of endpoints

makes it easier to contribute features!

but backwards compatibility is limiting

So how do we do generate our SWANK? Where does our S-Expression parser live?

It's actually a completely independent project within the ENSIME codebase called S-Express and you can use it in your own applications. As a tip of the hat to Emacs, it is licensed under the LGPL rather than the Apache License that the rest of ENSIME uses.

The codebase is heavily inspired by spray-json but we use shapeless to reduce boilerplate. In the future we are going to be using shapeless even more heavily — the first cut of S-Express was written before shapeless was up to the task of full serialisation but now it has certainly caught up.

We don't just use shapeless because it's a cool thing to do, most importantly, automatic derivation of messages should make it a lot easier for people to contribute to ENSIME itself — which is entirely in keeping with our goal of increasing ENSIME's chances of survival.

Unfortunately, we're currently using heavily customised marshalling rules to match the organically grown legacy format, but when we move onto version 2.0 of the protocol (as Rory will discuss) we can dramatically reduce the amount of code and rely more and more on automatic derivation.

JSON

Why JSON?

Most editors don't know how to speak Lisp!

If you build it, they will come.

JERK

We don't want to be an Emacs only thing. There is lots of interest from people using other editors and, from a purely selfish point of view, I see those users as potential future contributors.

Therefore we have an active pull request in review which adds a JSON protocol to ENSIME, and we went crazy with shapeless. To implement this, we wrote an automatic deriver for entire families of sealed traits and case classes, with as much customisation as anybody would care to shake a stick at.

And we're calling the protocol JERK, because we're hilarious like that.

Shapeless

HList ⇔ case class

Coproduct ⇔ sealed trait

The way the deriver works is a whole talk in itself, so I'm going to gloss over most of the details — but I'd be delighted to talk about it if you have any questions over the break or drinks tonight.

To give a crash course in shapeless, what it provides us is the ability to go between a case class and its generic form — an HList. You can think of an HList as being a List where the type of every element is encoded in the type of the list. Therefore a list with 4 elements has 4 types in it.

And shapeless provides the generic form for a sealed family, with Coproduct looking a lot like HList but only one of the elements in actually there for any given instance. I like to about it as an HList of Options where exactly one element is defined.

  implicit def familyFormat[T](
    implicit
    gen: LabelledGeneric[T],
    sg: WrappedRootJsonFormat[T, gen.Repr],
    tpe: Typeable[T]
  ): RootJsonFormat[T] = new RootJsonFormat[T] {
    if (log.isTraceEnabled)
      log.trace(s"creating ${tpe.describe}")

    def read(j: JsValue): T = gen.from(sg.value.read(j))
    def write(t: T): JsObject = sg.value.write(gen.to(t))
  }

Now, this code doesn't actually compile due to some compiler constraints that I'll explain in the next slide, but it is instructive as the "entry point" into the spray-json-shapeless layer.

Basically we define an implicit provider of RootJsonFormat[T] for your T. For your T, if it's a sealed trait or case class, shapeless will automatically create a LabelledGeneric[T] for us, which allows us to convert into the generic form - an HList or Coproduct.

We also ask shapeless for the Typeable[T], which simply allows us to print out some debugging information without having to use the reflection API.

And we ask for an implicit WrappedRootJsonFormat[T, gen.Repr], then all we need to do is to write an implementation of a marshaller for HList and Coproduct — which has type gen.Repr — and that is actually a lot simpler than it sounds but you'll have to go and read the code to see how we did it.

All we do in read/write is convert to/from the generic representation and call its read/write implementation.

But the compiler doesn't like two things here:

you can't refer to a type as gen.Repr

the order of evaluation of the implicits is a bit funny and sometimes the compiler will try to create this before it creates the WrappedRootJsonFormat.

Hipster Aux

  implicit def familyFormat[T, Repr](
    implicit
    gen: LabelledGeneric.Aux[T, Repr],
    sg: Lazy[WrappedRootJsonFormat[T, Repr]],
    tpe: Typeable[T]
  ): RootJsonFormat[T] = new RootJsonFormat[T] {
    if (log.isTraceEnabled)
      log.trace(s"creating ${tpe.describe}")

    def read(j: JsValue): T = gen.from(sg.value.read(j))
    def write(t: T): JsObject = sg.value.write(gen.to(t))
  }

So we have to introduce some hacks.

The first one is known as the Hipster.Aux. Some say that Travis Brown was once called a Hipster Aux as a slur, but he wore it as a badge of honour. Others say that it was an auto-corrector gone mad, who can say the intentions of justy-tylor.

If you see any shapeless code you'll quickly come across these .Aux types. The reason for their existence is to workaround the compiler limitation that we must declare all the types that we use in the parameter list. So we add an additional free type and then use it in the subsequent code. The LabelledGeneric.Aux places a constraint on Repr and the whole implicit will only trigger when Repr really is the HList or Coproduct for T.

The other hack is to use the Lazy type wrapper around the WrappedRootJsonFormat which is a bit magical but hints to the compiler to try harder at constructing the parameter.

  sealed trait SimpleTrait
  case class Foo(s: String) extends SimpleTrait
  case class Bar() extends SimpleTrait
  case object Baz extends SimpleTrait

  Foo("foo").toJson // {"type":"Foo","s":"foo"}
  Bar().toJson      // {"type":"Bar"}
  Baz.toJson        // {"type":"Baz"}

Even if you're not interested in the implementation details, you will be interested in the results. You can define a sealed trait and case class/object family like this

And without writing any marshalling code, you can convert to/from JSON automatically, with all the marshallers being calculated at compile time so it's super fast — almost on par with manually written marshallers.

Compile Times

Yeah, but it takes a long time to compile. Which we know is potentially life threatening :-/

We have 50 case classes for our incoming sealed family and it can take 10 minutes to compile this one marshaller. We have a workaround, but it involves a big performance hit to runtime.

So now I'm going to hand over to Rory who has more to say about compiler performance, which is not only relevant for us as ENSIME developers but as ENSIME users — since we fundamentally rely on the compiler for our analysis.

Roadmap

Performance

Mention Miles/YourKit? show performance stats? - probably don't have time Capture how many objects are created in a single call? Mention possibility of talk?

Ensime is a shim over the presentation compiler

Profiling shows compiler performance is poor in places.

e.g. scala.reflect.internal.Constants.safeToString generates 100s of temporary objects to create a single result string.

Performance is my next primary target

1.0 Stable

Stability! Some users don't like the snapshot approach, typically because of corporate proxies, and the possibility of regression. In reality, we've been extremely good at not releasing regressions but it would be nice to cut a stable so that we can be more experimental.

Separate stable and bleeding edge releases.

Freedom to break compatibility

JSON/WebSockets — Standard transport layers are A Good Thing™

http://doc.akka.io/docs/akka-stream-and-http-experimental/

https://github.com/smootoo/simple-spray-websockets/

2.0 Simplifications / Java

Dropping support for legacy versions: no more scala-2.9 backport and no more Java 6 support. Better version of Lucene, better filesystem monitoring.

Code quality, we want to make it even easier to add new endpoints to the protocol so we're going to focus on redesigning the protocol (S-Exp and JSON) to simplify it.

Java support… fear of The Big Java Project looming round the corner that we keep being threatened to be put on by management.

Whats next?

Simplification

Core

Protocol

design for enhancement

Going reactive

Reverse lookup / Find Implementations

Java Support - Enjime

scalac is getting Typed Trees. That's amazing for ENSIME because it means the presentation compiler could potentially turn into a data structure. It also allows for new debugging paradigms, where branches of the trees can be tracked instead of lines of code.

Also sbt-server is stabilising and we could interface with it to get better feedback from the actual compiler (not the initial stage presentation compiler) and various other project-level events.

The future

More editors

Sublime

Atom

vi The editor of the beast

Your editor here

Atom Demo

Viktor Hedefalk

Incoming fire!

TASTY

Scala.Meta

sbt-remote-control

ENSIME as a toolkit

Could enable lots of new build tools: integrate with scoverage for dead code removal, add return types to public methods (speeds up the compile and makes the code easier to read).

Of course, much of this would be available under a "hint" framework to the editors. Similar in concept to IDE's hints, but scriptable.

Still a work in progress

A user level API over the compiler

Analysis

Tooling

Dead code finding and cleanup

Refactoring / Hints

Ensime-IDE

IDEs tend to be monolithic - single system - text editors on steroids.

A fundamentally different model

IDEs tend to be monolithic

and tied to a legacy model (Java)

How?

We are at a nexus - lets change software development the world is changing, development environments hold back fast development (especially in kickstarter style team-building distributed environments).

ScalaJS - Shapeless JSON marshalling on both sides - some kind of voodoo

Components:

Web based front end - Atom/ScalaJS

Shared marshalling code (JERK/Shapeless)

Ensime based Server (Docker deployed)

Nodes to to tasked (sbt-remote/ Docker)

Compile

Repl

Testing

Debugging

Coverage

Shiny new things

How long does it take to get a project started. Instant setup - first day blues

Isolated dev - project contained in Docker Remote working - local rendering - remote heavy lifting. Scalable platform - compile nodes, test nodes, exec nodes, clusters

Project separation

Remotely hosted development

Remote working

Scalable

spin up an entire farm

Collaboration

Shared config/setup Shared environment - dual cursors multiple screens Video conference with duel control

Instant setup

Setup time - insta-project

training setup time

onboarding

Instant Collaboration

Pairing

Other possibilities

Scala Playground

4scala

Crowdsourcing

Final thoughts

Final thoughts

Ensime:

is a community project

opens up a bunch of interesting possibilities.

Questions?

Come join the party!

https://github.com/ensime/ensime-server


text:
import {setUsername, setRoom, setAllRooms, messageReceived} from './core.js';
import {Map} from 'immutable';
export default function(state = Map(), action) {
  switch (action.type) {
    case 'SET_STATE':
      return state.merge(state, action.state);
    case 'USERNAME':
      return setUsername(state, action.username);
    case 'ROOM':
      return setRoom(state, action.room);
    case 'MESSAGE_RECEIVED':
      return messageReceived(state, action.username, action.message)
    default:
      return state;
  }
}


text:
import { Color, useTheme } from "palette"
import { requireNativeComponent } from "react-native"

interface Props {
  /** The color of the dots (default: Artsy gray-medium) */
  color?: Color
}

export const DottedLine: React.FC<Props> = (props) => {
  const { color } = useTheme()

  return <NativeDottedLine style={{ height: 2 }} color={color(props.color ?? "black30")} />
}

const NativeDottedLine: React.ComponentClass<any> = requireNativeComponent("ARDottedLine")