text:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Leah Guthrie</title>
    <link>https://ltcguthrie.github.io/</link>
      <atom:link href="https://ltcguthrie.github.io/index.xml" rel="self" type="application/rss+xml" />
    <description>Leah Guthrie</description>
    <generator>Wowchemy (https://wowchemy.com)</generator><language>en-us</language><lastBuildDate>Sat, 01 Jun 2030 13:00:00 +0000</lastBuildDate>
    <image>
      <url>https://ltcguthrie.github.io/images/icon_hu0b7a4cb9992c9ac0e91bd28ffd38dd00_9727_512x512_fill_lanczos_center_2.png</url>
      <title>Leah Guthrie</title>
      <link>https://ltcguthrie.github.io/</link>
    </image>

    <item>
      <title>Example Talk</title>
      <link>https://ltcguthrie.github.io/talk/example-talk/</link>
      <pubDate>Sat, 01 Jun 2030 13:00:00 +0000</pubDate>
      <guid>https://ltcguthrie.github.io/talk/example-talk/</guid>
      <description>

    Click on the Slides button above to view the built-in slides feature.

Slides can be added in a few ways:

Create slides using Wowchemy&rsquo;s Slides feature and link using slides parameter in the front matter of the talk file

Upload an existing slide deck to static/ and link using url_slides parameter in the front matter of the talk file

Embed your slides (e.g. Google Slides) or presentation video on this page using shortcodes.

Further event details, including page elements such as image galleries, can be added to the body of this page.

</description>
    </item>

    <item>
      <title>Slides</title>
      <link>https://ltcguthrie.github.io/slides/example/</link>
      <pubDate>Tue, 05 Feb 2019 00:00:00 +0000</pubDate>
      <guid>https://ltcguthrie.github.io/slides/example/</guid>
      <description>
Create slides in Markdown with Wowchemy

Wowchemy | Documentation

Features

Efficiently write slides in Markdown

3-in-1: Create, Present, and Publish your slides

Supports speaker notes

Mobile friendly slides

Controls

Next: Right Arrow or Space

Previous: Left Arrow

Start: Home

Finish: End

Overview: Esc

Speaker notes: S

Fullscreen: F

Zoom: Alt + Click

PDF Export: E

Code Highlighting

Inline code: variable

Code block:

porridge = &quot;blueberry&quot;
if porridge == &quot;blueberry&quot;:
    print(&quot;Eating...&quot;)

Math

In-line math: $x + y = z$

Block math:

$$
f\left( x \right) = ;\frac{{2\left( {x + 4} \right)\left( {x - 4} \right)}}{{\left( {x + 4} \right)\left( {x + 1} \right)}}
$$

Fragments

Make content appear incrementally

{{% fragment %}} One {{% /fragment %}}
{{% fragment %}} **Two** {{% /fragment %}}
{{% fragment %}} Three {{% /fragment %}}

Press Space to play!

One

Two

Three

A fragment can accept two optional parameters:

class: use a custom style (requires definition in custom CSS)

weight: sets the order in which a fragment appears

Speaker Notes

Add speaker notes to your presentation

{{% speaker_note %}}
- Only the speaker can read these notes
- Press `S` key to view
{{% /speaker_note %}}

Press the S key to view the speaker notes!

Only the speaker can read these notes

Press S key to view

Themes

black: Black background, white text, blue links (default)

white: White background, black text, blue links

league: Gray background, white text, blue links

beige: Beige background, dark text, brown links

sky: Blue background, thin dark text, blue links

night: Black background, thick white text, orange links

serif: Cappuccino background, gray text, brown links

simple: White background, black text, blue links

solarized: Cream-colored background, dark green text, blue links

Custom Slide

Customize the slide style and background

{{&lt; slide background-image=&quot;/media/boards.jpg&quot; &gt;}}
{{&lt; slide background-color=&quot;#0000FF&quot; &gt;}}
{{&lt; slide class=&quot;my-style&quot; &gt;}}

Custom CSS Example

Let&rsquo;s make headers navy colored.

Create assets/css/reveal_custom.css with:

.reveal section h1,
.reveal section h2,
.reveal section h3 {
  color: navy;
}

Questions?

Ask

Documentation

</description>
    </item>

    <item>
      <title>Example Project</title>
      <link>https://ltcguthrie.github.io/project/example/</link>
      <pubDate>Wed, 27 Apr 2016 00:00:00 +0000</pubDate>
      <guid>https://ltcguthrie.github.io/project/example/</guid>
      <description>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis posuere tellus ac convallis placerat. Proin tincidunt magna sed ex sollicitudin condimentum. Sed ac faucibus dolor, scelerisque sollicitudin nisi. Cras purus urna, suscipit quis sapien eu, pulvinar tempor diam. Quisque risus orci, mollis id ante sit amet, gravida egestas nisl. Sed ac tempus magna. Proin in dui enim. Donec condimentum, sem id dapibus fringilla, tellus enim condimentum arcu, nec volutpat est felis vel metus. Vestibulum sit amet erat at nulla eleifend gravida.

Nullam vel molestie justo. Curabitur vitae efficitur leo. In hac habitasse platea dictumst. Sed pulvinar mauris dui, eget varius purus congue ac. Nulla euismod, lorem vel elementum dapibus, nunc justo porta mi, sed tempus est est vel tellus. Nam et enim eleifend, laoreet sem sit amet, elementum sem. Morbi ut leo congue, maximus velit ut, finibus arcu. In et libero cursus, rutrum risus non, molestie leo. Nullam congue quam et volutpat malesuada. Sed risus tortor, pulvinar et dictum nec, sodales non mi. Phasellus lacinia commodo laoreet. Nam mollis, erat in feugiat consectetur, purus eros egestas tellus, in auctor urna odio at nibh. Mauris imperdiet nisi ac magna convallis, at rhoncus ligula cursus.

Cras aliquam rhoncus ipsum, in hendrerit nunc mattis vitae. Duis vitae efficitur metus, ac tempus leo. Cras nec fringilla lacus. Quisque sit amet risus at ipsum pharetra commodo. Sed aliquam mauris at consequat eleifend. Praesent porta, augue sed viverra bibendum, neque ante euismod ante, in vehicula justo lorem ac eros. Suspendisse augue libero, venenatis eget tincidunt ut, malesuada at lorem. Donec vitae bibendum arcu. Aenean maximus nulla non pretium iaculis. Quisque imperdiet, nulla in pulvinar aliquet, velit quam ultrices quam, sit amet fringilla leo sem vel nunc. Mauris in lacinia lacus.

Suspendisse a tincidunt lacus. Curabitur at urna sagittis, dictum ante sit amet, euismod magna. Sed rutrum massa id tortor commodo, vitae elementum turpis tempus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean purus turpis, venenatis a ullamcorper nec, tincidunt et massa. Integer posuere quam rutrum arcu vehicula imperdiet. Mauris ullamcorper quam vitae purus congue, quis euismod magna eleifend. Vestibulum semper vel augue eget tincidunt. Fusce eget justo sodales, dapibus odio eu, ultrices lorem. Duis condimentum lorem id eros commodo, in facilisis mauris scelerisque. Morbi sed auctor leo. Nullam volutpat a lacus quis pharetra. Nulla congue rutrum magna a ornare.

Aliquam in turpis accumsan, malesuada nibh ut, hendrerit justo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Quisque sed erat nec justo posuere suscipit. Donec ut efficitur arcu, in malesuada neque. Nunc dignissim nisl massa, id vulputate nunc pretium nec. Quisque eget urna in risus suscipit ultricies. Pellentesque odio odio, tincidunt in eleifend sed, posuere a diam. Nam gravida nisl convallis semper elementum. Morbi vitae felis faucibus, vulputate orci placerat, aliquet nisi. Aliquam erat volutpat. Maecenas sagittis pulvinar purus, sed porta quam laoreet at.

</description>
    </item>

    <item>
      <title>Welcome to Wowchemy, the website builder for Hugo</title>
      <link>https://ltcguthrie.github.io/post/getting-started/</link>
      <pubDate>Wed, 20 Apr 2016 00:00:00 +0000</pubDate>
      <guid>https://ltcguthrie.github.io/post/getting-started/</guid>
      <description>
Overview

The Wowchemy website builder for Hugo, along with its starter templates, is designed for professional creators, educators, and teams/organizations - although it can be used to create any kind of site

The template can be modified and customised to suit your needs. It&rsquo;s a good platform for anyone looking to take control of their data and online identity whilst having the convenience to start off with a no-code solution (write in Markdown and customize with YAML parameters) and having flexibility to later add even deeper personalization with HTML and CSS

You can work with all your favourite tools and apps with hundreds of plugins and integrations to speed up your workflows, interact with your readers, and much more

    The template is mobile first with a responsive design to ensure that your site looks stunning on every device.

Get Started

👉 Create a new site

📚 Personalize your site

💬 Chat with the Wowchemy community or Hugo community

🐦 Twitter: @wowchemy @GeorgeCushen #MadeWithWowchemy

💡 Request a feature or report a bug for Wowchemy

⬆ Updating Wowchemy? View the Update Guide and Release Notes

Crowd-funded open-source software

To help us develop this template and software sustainably under the MIT license, we ask all individuals and businesses that use it to help support its ongoing maintenance and development via sponsorship.

❤ Click here to become a sponsor and help support Wowchemy&rsquo;s future ❤

As a token of appreciation for sponsoring, you can unlock these awesome rewards and extra features 🦄✨

Ecosystem

Wowchemy Admin: An admin tool to automatically import publications from BibTeX

Inspiration

Check out the latest demo of what you&rsquo;ll get in less than 10 minutes, or view the showcase of personal, project, and business sites.

Features

Page builder - Create anything with widgets and elements

Edit any type of content - Blog posts, publications, talks, slides, projects, and more!

Create content in Markdown, Jupyter, or RStudio

Plugin System - Fully customizable color and font themes

Display Code and Math - Code highlighting and LaTeX math supported

Integrations - Google Analytics, Disqus commenting, Maps, Contact Forms, and more!

Beautiful Site - Simple and refreshing one page design

Industry-Leading SEO - Help get your website found on search engines and social media

Media Galleries - Display your images and videos with captions in a customizable gallery

Mobile Friendly - Look amazing on every screen with a mobile friendly version of your site

Multi-language - 34+ language packs including English, 中文, and Português

Multi-user - Each author gets their own profile page

Privacy Pack - Assists with GDPR

Stand Out - Bring your site to life with animation, parallax backgrounds, and scroll effects

One-Click Deployment - No servers. No databases. Only files.

Themes

Wowchemy and its templates come with automatic day (light) and night (dark) mode built-in. Alternatively, visitors can choose their preferred mode - click the moon icon in the top right of the Demo to see it in action! Day/night mode can also be disabled by the site admin in params.toml.

Choose a stunning theme and font for your site. Themes are fully customizable.

License

Copyright 2016-present George Cushen.

Released under the MIT license.

</description>
    </item>

    <item>
      <title>An example conference paper</title>
      <link>https://ltcguthrie.github.io/publication/example/</link>
      <pubDate>Mon, 01 Jul 2013 00:00:00 +0000</pubDate>
      <guid>https://ltcguthrie.github.io/publication/example/</guid>
      <description>

    Click the Cite button above to demo the feature to enable visitors to import publication metadata into their reference management software.

    Create your slides in Markdown - click the Slides button to check out the example.

Supplementary notes can be added here, including code, math, and images.

</description>
    </item>

  </channel>
</rss>


text:
from configparser import ConfigParser

parser = ConfigParser()
parser.read('multisection.ini')

for candidate in ['wiki', 'bug_tracker', 'dvcs']:
    print('{:<12}: {}'.format(
        candidate, parser.has_section(candidate)))

redpajama_set_name: RedPajamaGithub


text:
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"

	"github.com/go-check/check"
)

const v2binary = "registry-v2"

type testRegistryV2 struct {
	cmd *exec.Cmd
	dir string
}

func newTestRegistryV2(c *check.C) (*testRegistryV2, error) {
	template := `version: 0.1
loglevel: debug
storage:
    filesystem:
        rootdirectory: %s
http:
    addr: %s`
	tmp, err := ioutil.TempDir("", "registry-test-")
	if err != nil {
		return nil, err
	}
	confPath := filepath.Join(tmp, "config.yaml")
	config, err := os.Create(confPath)
	if err != nil {
		return nil, err
	}
	if _, err := fmt.Fprintf(config, template, tmp, privateRegistryURL); err != nil {
		os.RemoveAll(tmp)
		return nil, err
	}

	cmd := exec.Command(v2binary, confPath)
	if err := cmd.Start(); err != nil {
		os.RemoveAll(tmp)
		if os.IsNotExist(err) {
			c.Skip(err.Error())
		}
		return nil, err
	}
	return &testRegistryV2{
		cmd: cmd,
		dir: tmp,
	}, nil
}

func (t *testRegistryV2) Ping() error {
	// We always ping through HTTP for our test registry.
	resp, err := http.Get(fmt.Sprintf("http://%s/v2/", privateRegistryURL))
	if err != nil {
		return err
	}
	if resp.StatusCode != 200 {
		return fmt.Errorf("registry ping replied with an unexpected status code %d", resp.StatusCode)
	}
	return nil
}

func (r *testRegistryV2) Close() {
	r.cmd.Process.Kill()
	os.RemoveAll(r.dir)
}


text:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">我的计划</string>
    <string name="todo_list">计划列表</string>
    <string name="finished_list">已完成列表</string>
    <string name="add_plan">添加计划</string>
    <string name="edit_plan">编辑计划</string>
    <string name="add">添加</string>
    <string name="cancel">取消</string>
    <string name="added">新计划已添加</string>
    <string name="add_failed">添加失败!</string>
    <string name="todo_item">待完成</string>
    <string name="finished_item">已完成</string>
    <string name="created_at">创建于</string>
    <string name="modify">修改</string>
    <string name="delete">删除</string>
    <string name="deleted">已删除</string>
    <string name="delete_failed">删除失败!</string>
    <string name="finished">已完成</string>
    <string name="finished_at">完成于</string>
</resources>


text:
import os
import subprocess
from pathlib import Path

import pytest
from django.conf import settings
from django.contrib.admin.utils import flatten
from django.core.management import call_command

from rdmo.accounts.utils import set_group_permissions

@pytest.fixture(scope='session')
def django_db_setup(django_db_setup, django_db_blocker):
    with django_db_blocker.unblock():
        fixtures = flatten([os.listdir(fixture_dir) for fixture_dir in settings.FIXTURE_DIRS])

        call_command('loaddata', *fixtures)
        set_group_permissions()

@pytest.fixture
def files():
    def setup():
        media_path = Path(__file__).parent / 'testing' / 'media'
        subprocess.check_call(['rsync', '-a', '--delete', media_path.as_posix().rstrip('/') + '/', settings.MEDIA_ROOT.rstrip('/') + '/'])

    setup()
    return setup


text:
title: Reporting Issues
menu:
  enterprise_1_0:
    weight: 10
    parent: Troubleshooting
---

When you have challenges with the InfluxEnterprise product, please contact support
using the email we provided at the time of the signup.
That will ensure your support tickets are routed directly to our private release
support team.

Please include the following in your email:

* the version of InfluxEnterprise, e.g. 1.0.2-c1.0.4
* the version of Telegraf or Kapacitor, if applicable
* what you expected to happen
* what did happen
* query output, logs, screenshots, and any other helpful diagnostic information
* the results of the `SHOW DIAGNOSTICS` and `SHOW STATS` queries


text:
var when           		= require('when');
var needle         		= require('@trayio/needle');
var _              		= require('lodash');

var { setParam, guid }	= require('../utils/mout');
var logger         		= require('../logger');
var globalize      	    = require('./globalize');
var validateInput      	= require('./validateRESTInput');

var validateExpects    	= require('./validateExpects');
var validateNotExpects	= require('./validateNotExpects');

//The format of the response should always be an object with headers and body
var formatResponse = require('./formatResponse');

var addMethodFunction	= require('./addMethodFunction');

module.exports = function (methodName, config, afterHeadersFunction) {

	var threadneedle = this;

	//If one-off SOAP mode, then perform addMethodSOAP instead
	if (_.isPlainObject(config) && ((_.isString(config.type) && config.type.toLowerCase() === 'soap') || config.soap)) {
		if (config.soap) {
			//eslint-disable-next-line no-console
			console.warn(methodName + ': `soap` flag has been deprecated. Use `type: \'SOAP\'` instead.');
		}
		config.globals = false;
		threadneedle[methodName] = require('./addMethodSOAP').call({ _globalOptions: { type: 'soap' } }, methodName, config);
		return;
	}

	// All methods should default to no timeout, maximising the chance
	// of success.
	needle.defaults({
		open_timeout: 0,
		read_timeout: 0
	});

	// Validate the input. Errors will be `throw`n if there's anything
	// wrong. Throwing is usually bad - but this is declarative, so will happen
	// on app startup;
	validateInput.call(this, methodName, config);

	// Create the method
	threadneedle[methodName] = function (params) {

		params = params || {};

		/*
	  Override - if a function is provided as config, then simply run it - don't run HTTP requests.
	  It should expect a promise returned by the function. Pass the context
	*/
		if (_.isFunction(config)) {
			logger.info(methodName+': Running method function.');
			return addMethodFunction(threadneedle, config, afterHeadersFunction, params);
		}

		return when.promise(function (resolve, reject) {

			//Handle afterHeader for resolving
			function afterHeadersResolve (body, result) {

				logger.info(methodName+': running `afterHeaders` hook');
				globalize.afterHeaders.call(threadneedle, config, null, body, params, result.response)

				.done(
					function (headers) {
						resolve(formatResponse(headers, body));
					},
					function (error) {
						reject(formatResponse({}, error));
					}
				);

			}

			//Handle afterHeader for rejecting
			function afterHeadersReject (error, payload, response) {

				logger.info(methodName+': running `afterHeaders` hook');
				globalize.afterHeaders.call(threadneedle, config, error, payload, params, response)

				.done(
					function (headers) {
						reject(formatResponse(headers, error));
					},
					function (err) {
						reject(formatResponse({}, err || error));
					}
				);

			}

			// Kick off that promise chain
			when()

			// Run a `before` if set on the params.
			.then(function () {
				logger.info('Running method `'+methodName+'` `before`.');
				return globalize.before.call(threadneedle, config, params);
			})

			// Set a bunch of local variables, formatted and templated
			.then(function (result) {
				params = result;

				logger.info(methodName+': substituting parameters');

				// Method, always lowercased
				var method = globalize.method.call(threadneedle, config, params);

				// Add a temp file parameter for file handling operations
				if (config.fileHandler === true) {
					params.temp_file = '/tmp/'+guid();
				}

				// The URL endpoint. Query parameters allowed from here.
				var url = globalize.baseUrl.call(threadneedle, config, params);
				// var url = globalize.call(threadneedle, config.globals, 'url', config, params);

				// Add query parameters intelligently, without conflicting from query parameters
				// already specified in the URL.
				var query = globalize.object.call(threadneedle, 'query', config, params);
				_.each(query, function (value, key) {
					if (_.isArray(value) && value.length > 0) {
						value = value.join(',');
					}
					if (!_.isUndefined(value) && !(_.isString(value) && value === '')) {
						url = setParam(url, key, value);
					}
				});

				// The request options, substituted
				var options = globalize.object.call(threadneedle, 'options', config, params);

				// Post/put/delete data
				var data;
				switch (method) {
					case 'get':
					case 'head':
						break;
					default:
						data = globalize.object.call(threadneedle, 'data', config, params);
				}

				return {
					url: url,
					data: data,
					options: options,
					method: method
				};
			})

			// Run the `beforeRequest`
			.then(function (request) {
				logger.info(methodName+': running `beforeRequest` hook');
				return globalize.beforeRequest.call(threadneedle, config, request, params);
			})

			// Run the actual request
			.then(function (request) {
				return when.promise(function (resolve, reject) {

					var handleResponse = function (err, res, body) {

						function handleReject (payload) {
							return reject({
								payload: payload,
								response: res
							});
						}

						if (err) {

							// Specifically handle socket hang ups nicely
							if (_.isError(err) && err.message === 'socket hang up') {
								return handleReject( {
									code: 'api_timeout',
									response: {},
									message: 'API call timeout. Looks like the API you\'re calling is having a wobble. Please try again later.'
								});
							} else {
								return handleReject(err);
							}

						} else {

							logger.info(methodName + ': got response', res.statusCode, JSON.stringify(body));

							var validationError;

							// Validate `expects`
							var expects = globalize.expects.call(threadneedle, config);
							validationError = validateExpects(res, expects);
							if (validationError) {
								return handleReject(validationError);
							}

							// Validate `notExpects`
							var notExpects = globalize.notExpects.call(threadneedle, config);
							validationError = validateNotExpects(res, notExpects);
							if (validationError) {
								return handleReject(validationError);
							}

							// We're valid!
							resolve({
								body: body,
								response: res
							});

						}
					};

					var method = request.method;

					// console.log(options);
					logger.info(methodName + ': running ' + method + ' request', request);

					// Run a different method for get to not include data
					switch (method) {
						case 'get':
						case 'head':
							needle[method](request.url, request.options, handleResponse);
							break;
						case 'options':
							needle.request('options', request.url, request.options, handleResponse);
							break;
						default:
							needle[method](request.url, request.data, request.options, handleResponse);
					}

				});
			})

			// Handle the after success and failure messages
			.done(
				function (result) {

					logger.info(methodName + ': running `afterSuccess` hook');
					globalize.afterSuccess.call(threadneedle, config, result.body, params, result.response)
					.done(
						function (body) { afterHeadersResolve(body, result); },
						function (error) { afterHeadersReject(error, result.body, result.response); }
					);

				},
				function (err) {

					var payload = (err.payload ? err.payload : err),
						response = (err.response ? err.response : {});

					function rejectAfterHeaders (error) {
						afterHeadersReject(error, payload, response);
					}

					logger.info(methodName + ': running `afterFailure` hook', err);
					globalize.afterFailure.call(threadneedle, config, payload, params, response)
					.done(rejectAfterHeaders, rejectAfterHeaders);

				}
			);

		});

	};

};


text:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>be.nijs.cinnamon</groupId>
    <artifactId>cinnamon</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

    <modules>
        <module>core</module>
        <module>database</module>
        <module>rest</module>
        <module>rest-test</module>
        <module>test-utils</module>
    </modules>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.2.5.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.36</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.unitils</groupId>
            <artifactId>unitils-inject</artifactId>
            <version>3.4.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.unitils</groupId>
            <artifactId>unitils-core</artifactId>
            <version>3.4.2</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

</project>


text:
<!---
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

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

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

# Apache Arrow

[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/arrow.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arrow)
[![License](http://img.shields.io/:license-Apache%202-blue.svg)](https://github.com/apache/arrow/blob/master/LICENSE.txt)
[![Twitter Follow](https://img.shields.io/twitter/follow/apachearrow.svg?style=social&label=Follow)](https://twitter.com/apachearrow)

## Powering In-Memory Analytics

Apache Arrow is a development platform for in-memory analytics. It contains a
set of technologies that enable big data systems to process and move data fast.

Major components of the project include:

 - [The Arrow Columnar In-Memory Format](https://github.com/apache/arrow/blob/master/docs/source/format/Columnar.rst):
   a standard and efficient in-memory representation of various datatypes, plain or nested
 - [The Arrow IPC Format](https://github.com/apache/arrow/blob/master/docs/source/format/Columnar.rst#serialization-and-interprocess-communication-ipc):
   an efficient serialization of the Arrow format and associated metadata,
   for communication between processes and heterogeneous environments
 - [The Arrow Flight RPC protocol](https://github.com/apache/arrow/tree/master/format/Flight.proto):
   based on the Arrow IPC format, a building block for remote services exchanging
   Arrow data with application-defined semantics (for example a storage server or a database)
 - [C++ libraries](https://github.com/apache/arrow/tree/master/cpp)
 - [C bindings using GLib](https://github.com/apache/arrow/tree/master/c_glib)
 - [C# .NET libraries](https://github.com/apache/arrow/tree/master/csharp)
 - [Gandiva](https://github.com/apache/arrow/tree/master/cpp/src/gandiva):
   an [LLVM](https://llvm.org)-based Arrow expression compiler, part of the C++ codebase
 - [Go libraries](https://github.com/apache/arrow/tree/master/go)
 - [Java libraries](https://github.com/apache/arrow/tree/master/java)
 - [JavaScript libraries](https://github.com/apache/arrow/tree/master/js)
 - [Plasma Object Store](https://github.com/apache/arrow/tree/master/cpp/src/plasma):
   a shared-memory blob store, part of the C++ codebase
 - [Python libraries](https://github.com/apache/arrow/tree/master/python)
 - [R libraries](https://github.com/apache/arrow/tree/master/r)
 - [Ruby libraries](https://github.com/apache/arrow/tree/master/ruby)
 - [Rust libraries](https://github.com/apache/arrow-rs)

Arrow is an [Apache Software Foundation](https://www.apache.org) project. Learn more at
[arrow.apache.org](https://arrow.apache.org).

## What's in the Arrow libraries?

The reference Arrow libraries contain many distinct software components:

- Columnar vector and table-like containers (similar to data frames) supporting
  flat or nested types
- Fast, language agnostic metadata messaging layer (using Google's Flatbuffers
  library)
- Reference-counted off-heap buffer memory management, for zero-copy memory
  sharing and handling memory-mapped files
- IO interfaces to local and remote filesystems
- Self-describing binary wire formats (streaming and batch/file-like) for
  remote procedure calls (RPC) and interprocess communication (IPC)
- Integration tests for verifying binary compatibility between the
  implementations (e.g. sending data from Java to C++)
- Conversions to and from other in-memory data structures
- Readers and writers for various widely-used file formats (such as Parquet, CSV)

## Implementation status

The official Arrow libraries in this repository are in different stages of
implementing the Arrow format and related features.  See our current
[feature matrix](https://github.com/apache/arrow/blob/master/docs/source/status.rst)
on git master.

## How to Contribute

Please read our latest [project contribution guide][5].

## Getting involved

Even if you do not plan to contribute to Apache Arrow itself or Arrow
integrations in other projects, we'd be happy to have you involved:

- Join the mailing list: send an email to
  [dev-subscribe@arrow.apache.org][1]. Share your ideas and use cases for the
  project.
- [Follow our activity on JIRA][3]
- [Learn the format][2]
- Contribute code to one of the reference implementations

[1]: mailto:dev-subscribe@arrow.apache.org
[2]: https://github.com/apache/arrow/tree/master/format
[3]: https://issues.apache.org/jira/browse/ARROW
[4]: https://github.com/apache/arrow
[5]: https://github.com/apache/arrow/blob/master/docs/source/developers/contributing.rst


text:
'use strict';

/*
The CoSE layout was written by Gerardo Huck.
https://www.linkedin.com/in/gerardohuck/

Based on the following article:
http://dl.acm.org/citation.cfm?id=1498047

Modifications tracked on Github.
*/

var util = require('../../util');
var math = require('../../math');
var Thread = require('../../thread');
var is = require('../../is');

var DEBUG;

/**
 * @brief :  default layout options
 */
var defaults = {
  // Called on `layoutready`
  ready               : function() {},

  // Called on `layoutstop`
  stop                : function() {},

  // Whether to animate while running the layout
  animate             : true,

  // The layout animates only after this many milliseconds
  // (prevents flashing on fast runs)
  animationThreshold  : 250,

  // Number of iterations between consecutive screen positions update
  // (0 -> only updated on the end)
  refresh             : 20,

  // Whether to fit the network view after when done
  fit                 : true,

  // Padding on fit
  padding             : 30,

  // Constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
  boundingBox         : undefined,

  // Extra spacing between components in non-compound graphs
  componentSpacing    : 100,

  // Node repulsion (non overlapping) multiplier
  nodeRepulsion       : function( node ){ return 400000; },

  // Node repulsion (overlapping) multiplier
  nodeOverlap         : 10,

  // Ideal edge (non nested) length
  idealEdgeLength     : function( edge ){ return 10; },

  // Divisor to compute edge forces
  edgeElasticity      : function( edge ){ return 100; },

  // Nesting factor (multiplier) to compute ideal edge length for nested edges
  nestingFactor       : 5,

  // Gravity force (constant)
  gravity             : 80,

  // Maximum number of iterations to perform
  numIter             : 1000,

  // Initial temperature (maximum node displacement)
  initialTemp         : 200,

  // Cooling factor (how the temperature is reduced between consecutive iterations
  coolingFactor       : 0.95,

  // Lower temperature threshold (below this point the layout will end)
  minTemp             : 1.0,

  // Whether to use threading to speed up the layout
  useMultitasking     : true
};

/**
 * @brief       : constructor
 * @arg options : object containing layout options
 */
function CoseLayout(options) {
  this.options = util.extend({}, defaults, options);

  this.options.layout = this;
}

/**
 * @brief : runs the layout
 */
CoseLayout.prototype.run = function() {
  var options = this.options;
  var cy      = options.cy;
  var layout  = this;
  var thread  = this.thread;

  if( !thread || thread.stopped() ){
    thread = this.thread = Thread({ disabled: !options.useMultitasking });
  }

  layout.stopped = false;

  layout.trigger({ type: 'layoutstart', layout: layout });

  // Set DEBUG - Global variable
  if (true === options.debug) {
    DEBUG = true;
  } else {
    DEBUG = false;
  }

  // Initialize layout info
  var layoutInfo = createLayoutInfo(cy, layout, options);

  // Show LayoutInfo contents if debugging
  if (DEBUG) {
    printLayoutInfo(layoutInfo);
  }

  // If required, randomize node positions
  // if (true === options.randomize) {
    randomizePositions(layoutInfo, cy);
  // }

  var startTime = Date.now();
  var refreshRequested = false;
  var refresh = function( rOpts ){
    rOpts = rOpts || {};

    if( refreshRequested && !rOpts.next ){
      return;
    }

    if( !rOpts.force && Date.now() - startTime < options.animationThreshold ){
      return;
    }

    refreshRequested = true;

    util.requestAnimationFrame(function(){
      refreshPositions(layoutInfo, cy, options);

      // Fit the graph if necessary
      if (true === options.fit) {
        cy.fit( options.padding );
      }

      refreshRequested = false;

      if( rOpts.next ){ rOpts.next(); }
    });
  };

  thread.on('message', function( e ){
    var layoutNodes = e.message;

    layoutInfo.layoutNodes = layoutNodes;
    refresh();
  });

  thread.pass({
    layoutInfo: layoutInfo,
    options: {
      animate: options.animate,
      refresh: options.refresh,
      componentSpacing: options.componentSpacing,
      nodeOverlap: options.nodeOverlap,
      nestingFactor: options.nestingFactor,
      gravity: options.gravity,
      numIter: options.numIter,
      initialTemp: options.initialTemp,
      coolingFactor: options.coolingFactor,
      minTemp: options.minTemp
    }
  }).run(function( pass ){
    var layoutInfo = pass.layoutInfo;
    var options = pass.options;
    var stopped = false;

    /**
     * @brief          : Performs one iteration of the physical simulation
     * @arg layoutInfo : LayoutInfo object already initialized
     * @arg cy         : Cytoscape object
     * @arg options    : Layout options
     */
    var step = function(layoutInfo, options, step) {
      // var s = "\n\n###############################";
      // s += "\nSTEP: " + step;
      // s += "\n###############################\n";
      // logDebug(s);

      // Calculate node repulsions
      calculateNodeForces(layoutInfo, options);
      // Calculate edge forces
      calculateEdgeForces(layoutInfo, options);
      // Calculate gravity forces
      calculateGravityForces(layoutInfo, options);
      // Propagate forces from parent to child
      propagateForces(layoutInfo, options);
      // Update positions based on calculated forces
      updatePositions(layoutInfo, options);
    };

    /**
     * @brief : Computes the node repulsion forces
     */
    var calculateNodeForces = function(layoutInfo, options) {
      // Go through each of the graphs in graphSet
      // Nodes only repel each other if they belong to the same graph
      // var s = 'calculateNodeForces';
      // logDebug(s);
      for (var i = 0; i < layoutInfo.graphSet.length; i ++) {
        var graph    = layoutInfo.graphSet[i];
        var numNodes = graph.length;

        // s = "Set: " + graph.toString();
        // logDebug(s);

        // Now get all the pairs of nodes
        // Only get each pair once, (A, B) = (B, A)
        for (var j = 0; j < numNodes; j++) {
          var node1 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]];

          for (var k = j + 1; k < numNodes; k++) {
            var node2 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[k]]];

            nodeRepulsion(node1, node2, layoutInfo, options);
          }
        }
      }
    };

    /**
     * @brief : Compute the node repulsion forces between a pair of nodes
     */
    var nodeRepulsion = function(node1, node2, layoutInfo, options) {
      // var s = "Node repulsion. Node1: " + node1.id + " Node2: " + node2.id;

      var cmptId1 = node1.cmptId;
      var cmptId2 = node2.cmptId;

      if( cmptId1 !== cmptId2 && !layoutInfo.isCompound ){ return; }

      // Get direction of line connecting both node centers
      var directionX = node2.positionX - node1.positionX;
      var directionY = node2.positionY - node1.positionY;
      // s += "\ndirectionX: " + directionX + ", directionY: " + directionY;

      // If both centers are the same, apply a random force
      if (0 === directionX && 0 === directionY) {
        // s += "\nNodes have the same position.";
        return; // TODO could be improved with random force
      }

      var overlap = nodesOverlap(node1, node2, directionX, directionY);

      if (overlap > 0) {
        // s += "\nNodes DO overlap.";
        // s += "\nOverlap: " + overlap;
        // If nodes overlap, repulsion force is proportional
        // to the overlap
        var force    = options.nodeOverlap * overlap;

        // Compute the module and components of the force vector
        var distance = Math.sqrt(directionX * directionX + directionY * directionY);
        // s += "\nDistance: " + distance;
        var forceX   = force * directionX / distance;
        var forceY   = force * directionY / distance;

      } else {
        // s += "\nNodes do NOT overlap.";
        // If there's no overlap, force is inversely proportional
        // to squared distance

        // Get clipping points for both nodes
        var point1 = findClippingPoint(node1, directionX, directionY);
        var point2 = findClippingPoint(node2, -1 * directionX, -1 * directionY);

        // Use clipping points to compute distance
        var distanceX   = point2.x - point1.x;
        var distanceY   = point2.y - point1.y;
        var distanceSqr = distanceX * distanceX + distanceY * distanceY;
        var distance    = Math.sqrt(distanceSqr);
        // s += "\nDistance: " + distance;

        // Compute the module and components of the force vector
        var force  = ( node1.nodeRepulsion + node2.nodeRepulsion ) / distanceSqr;
        var forceX = force * distanceX / distance;
        var forceY = force * distanceY / distance;
      }

      // Apply force
      if( !node1.isLocked ){
        node1.offsetX -= forceX;
        node1.offsetY -= forceY;
      }

      if( !node2.isLocked ){
        node2.offsetX += forceX;
        node2.offsetY += forceY;
      }

      // s += "\nForceX: " + forceX + " ForceY: " + forceY;
      // logDebug(s);

      return;
    };

    /**
     * @brief  : Determines whether two nodes overlap or not
     * @return : Amount of overlapping (0 => no overlap)
     */
    var nodesOverlap = function(node1, node2, dX, dY) {

      if (dX > 0) {
        var overlapX = node1.maxX - node2.minX;
      } else {
        var overlapX = node2.maxX - node1.minX;
      }

      if (dY > 0) {
        var overlapY = node1.maxY - node2.minY;
      } else {
        var overlapY = node2.maxY - node1.minY;
      }

      if (overlapX >= 0 && overlapY >= 0) {
        return Math.sqrt(overlapX * overlapX + overlapY * overlapY);
      } else {
        return 0;
      }
    };

    /**
     * @brief : Finds the point in which an edge (direction dX, dY) intersects
     *          the rectangular bounding box of it's source/target node
     */
    var findClippingPoint = function(node, dX, dY) {

      // Shorcuts
      var X = node.positionX;
      var Y = node.positionY;
      var H = node.height || 1;
      var W = node.width || 1;
      var dirSlope     = dY / dX;
      var nodeSlope    = H / W;

      // var s = 'Computing clipping point of node ' + node.id +
      //   " . Height:  " + H + ", Width: " + W +
      //   "\nDirection " + dX + ", " + dY;
      //
      // Compute intersection
      var res = {};
      do {
        // Case: Vertical direction (up)
        if (0 === dX && 0 < dY) {
          res.x = X;
          // s += "\nUp direction";
          res.y = Y + H / 2;
          break;
        }

        // Case: Vertical direction (down)
        if (0 === dX && 0 > dY) {
          res.x = X;
          res.y = Y + H / 2;
          // s += "\nDown direction";
          break;
        }

        // Case: Intersects the right border
        if (0 < dX &&
        -1 * nodeSlope <= dirSlope &&
        dirSlope <= nodeSlope) {
          res.x = X + W / 2;
          res.y = Y + (W * dY / 2 / dX);
          // s += "\nRightborder";
          break;
        }

        // Case: Intersects the left border
        if (0 > dX &&
        -1 * nodeSlope <= dirSlope &&
        dirSlope <= nodeSlope) {
          res.x = X - W / 2;
          res.y = Y - (W * dY / 2 / dX);
          // s += "\nLeftborder";
          break;
        }

        // Case: Intersects the top border
        if (0 < dY &&
        ( dirSlope <= -1 * nodeSlope ||
          dirSlope >= nodeSlope )) {
          res.x = X + (H * dX / 2 / dY);
          res.y = Y + H / 2;
          // s += "\nTop border";
          break;
        }

        // Case: Intersects the bottom border
        if (0 > dY &&
        ( dirSlope <= -1 * nodeSlope ||
          dirSlope >= nodeSlope )) {
          res.x = X - (H * dX / 2 / dY);
          res.y = Y - H / 2;
          // s += "\nBottom border";
          break;
        }

      } while (false);

      // s += "\nClipping point found at " + res.x + ", " + res.y;
      // logDebug(s);
      return res;
    };

    /**
     * @brief : Calculates all edge forces
     */
    var calculateEdgeForces = function(layoutInfo, options) {
      // Iterate over all edges
      for (var i = 0; i < layoutInfo.edgeSize; i++) {
        // Get edge, source & target nodes
        var edge     = layoutInfo.layoutEdges[i];
        var sourceIx = layoutInfo.idToIndex[edge.sourceId];
        var source   = layoutInfo.layoutNodes[sourceIx];
        var targetIx = layoutInfo.idToIndex[edge.targetId];
        var target   = layoutInfo.layoutNodes[targetIx];

        // Get direction of line connecting both node centers
        var directionX = target.positionX - source.positionX;
        var directionY = target.positionY - source.positionY;

        // If both centers are the same, do nothing.
        // A random force has already been applied as node repulsion
        if (0 === directionX && 0 === directionY) {
        return;
        }

        // Get clipping points for both nodes
        var point1 = findClippingPoint(source, directionX, directionY);
        var point2 = findClippingPoint(target, -1 * directionX, -1 * directionY);

        var lx = point2.x - point1.x;
        var ly = point2.y - point1.y;
        var l  = Math.sqrt(lx * lx + ly * ly);

        var force  = Math.pow(edge.idealLength - l, 2) / edge.elasticity;

        if (0 !== l) {
          var forceX = force * lx / l;
          var forceY = force * ly / l;
        } else {
          var forceX = 0;
          var forceY = 0;
        }

        // Add this force to target and source nodes
        if( !source.isLocked ){
          source.offsetX += forceX;
          source.offsetY += forceY;
        }

        if( !target.isLocked ){
          target.offsetX -= forceX;
          target.offsetY -= forceY;
        }

        // var s = 'Edge force between nodes ' + source.id + ' and ' + target.id;
        // s += "\nDistance: " + l + " Force: (" + forceX + ", " + forceY + ")";
        // logDebug(s);
      }
    };

    /**
     * @brief : Computes gravity forces for all nodes
     */
    var calculateGravityForces = function(layoutInfo, options) {
      var distThreshold = 1;

      // var s = 'calculateGravityForces';
      // logDebug(s);
      for (var i = 0; i < layoutInfo.graphSet.length; i ++) {
        var graph    = layoutInfo.graphSet[i];
        var numNodes = graph.length;

        // s = "Set: " + graph.toString();
        // logDebug(s);

        // Compute graph center
        if (0 === i) {
          var centerX   = layoutInfo.clientHeight / 2;
          var centerY   = layoutInfo.clientWidth  / 2;
        } else {
          // Get Parent node for this graph, and use its position as center
          var temp    = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[0]]];
          var parent  = layoutInfo.layoutNodes[layoutInfo.idToIndex[temp.parentId]];
          var centerX = parent.positionX;
          var centerY = parent.positionY;
        }
        // s = "Center found at: " + centerX + ", " + centerY;
        // logDebug(s);

        // Apply force to all nodes in graph
        for (var j = 0; j < numNodes; j++) {
          var node = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]];
          // s = "Node: " + node.id;

          if( node.isLocked ){ continue; }

          var dx = centerX - node.positionX;
          var dy = centerY - node.positionY;
          var d  = Math.sqrt(dx * dx + dy * dy);
          if (d > distThreshold) {
            var fx = options.gravity * dx / d;
            var fy = options.gravity * dy / d;
            node.offsetX += fx;
            node.offsetY += fy;
            // s += ": Applied force: " + fx + ", " + fy;
          } else {
            // s += ": skypped since it's too close to center";
          }
          // logDebug(s);
        }
      }
    };

    /**
     * @brief          : This function propagates the existing offsets from
     *                   parent nodes to its descendents.
     * @arg layoutInfo : layoutInfo Object
     * @arg cy         : cytoscape Object
     * @arg options    : Layout options
     */
    var propagateForces = function(layoutInfo, options) {
      // Inline implementation of a queue, used for traversing the graph in BFS order
      var queue = [];
      var start = 0;   // Points to the start the queue
      var end   = -1;  // Points to the end of the queue

      // logDebug('propagateForces');

      // Start by visiting the nodes in the root graph
      queue.push.apply(queue, layoutInfo.graphSet[0]);
      end += layoutInfo.graphSet[0].length;

      // Traverse the graph, level by level,
      while (start <= end) {
        // Get the node to visit and remove it from queue
        var nodeId    = queue[start++];
        var nodeIndex = layoutInfo.idToIndex[nodeId];
        var node      = layoutInfo.layoutNodes[nodeIndex];
        var children  = node.children;

        // We only need to process the node if it's compound
        if (0 < children.length && !node.isLocked) {
          var offX = node.offsetX;
          var offY = node.offsetY;

          // var s = "Propagating offset from parent node : " + node.id +
          //   ". OffsetX: " + offX + ". OffsetY: " + offY;
          // s += "\n Children: " + children.toString();
          // logDebug(s);

          for (var i = 0; i < children.length; i++) {
            var childNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[children[i]]];
            // Propagate offset
            childNode.offsetX += offX;
            childNode.offsetY += offY;
            // Add children to queue to be visited
            queue[++end] = children[i];
          }

          // Reset parent offsets
          node.offsetX = 0;
          node.offsetY = 0;
        }

      }
    };

    /**
     * @brief : Updates the layout model positions, based on
     *          the accumulated forces
     */
    var updatePositions = function(layoutInfo, options) {
      // var s = 'Updating positions';
      // logDebug(s);

      // Reset boundaries for compound nodes
      for (var i = 0; i < layoutInfo.nodeSize; i++) {
        var n = layoutInfo.layoutNodes[i];
        if (0 < n.children.length) {
          // logDebug("Resetting boundaries of compound node: " + n.id);
          n.maxX = undefined;
          n.minX = undefined;
          n.maxY = undefined;
          n.minY = undefined;
        }
      }

      for (var i = 0; i < layoutInfo.nodeSize; i++) {
        var n = layoutInfo.layoutNodes[i];
        if (0 < n.children.length || n.isLocked) {
          // No need to set compound or locked node position
          // logDebug("Skipping position update of node: " + n.id);
          continue;
        }
        // s = "Node: " + n.id + " Previous position: (" +
        // n.positionX + ", " + n.positionY + ").";

        // Limit displacement in order to improve stability
        var tempForce = limitForce(n.offsetX, n.offsetY, layoutInfo.temperature);
        n.positionX += tempForce.x;
        n.positionY += tempForce.y;
        n.offsetX = 0;
        n.offsetY = 0;
        n.minX    = n.positionX - n.width;
        n.maxX    = n.positionX + n.width;
        n.minY    = n.positionY - n.height;
        n.maxY    = n.positionY + n.height;
        // s += " New Position: (" + n.positionX + ", " + n.positionY + ").";
        // logDebug(s);

        // Update ancestry boudaries
        updateAncestryBoundaries(n, layoutInfo);
      }

      // Update size, position of compund nodes
      for (var i = 0; i < layoutInfo.nodeSize; i++) {
        var n = layoutInfo.layoutNodes[i];
        if ( 0 < n.children.length && !n.isLocked ) {
          n.positionX = (n.maxX + n.minX) / 2;
          n.positionY = (n.maxY + n.minY) / 2;
          n.width     = n.maxX - n.minX;
          n.height    = n.maxY - n.minY;
          // s = "Updating position, size of compound node " + n.id;
          // s += "\nPositionX: " + n.positionX + ", PositionY: " + n.positionY;
          // s += "\nWidth: " + n.width + ", Height: " + n.height;
          // logDebug(s);
        }
      }
    };

    /**
     * @brief : Limits a force (forceX, forceY) to be not
     *          greater (in modulo) than max.
     8          Preserves force direction.
     */
    var limitForce = function(forceX, forceY, max) {
      // var s = "Limiting force: (" + forceX + ", " + forceY + "). Max: " + max;
      var force = Math.sqrt(forceX * forceX + forceY * forceY);

      if (force > max) {
        var res = {
        x : max * forceX / force,
        y : max * forceY / force
        };

      } else {
        var res = {
        x : forceX,
        y : forceY
        };
      }

      // s += ".\nResult: (" + res.x + ", " + res.y + ")";
      // logDebug(s);

      return res;
    };

    /**
     * @brief : Function used for keeping track of compound node
     *          sizes, since they should bound all their subnodes.
     */
    var updateAncestryBoundaries = function(node, layoutInfo) {
      // var s = "Propagating new position/size of node " + node.id;
      var parentId = node.parentId;
      if (null == parentId) {
        // If there's no parent, we are done
        // s += ". No parent node.";
        // logDebug(s);
        return;
      }

      // Get Parent Node
      var p = layoutInfo.layoutNodes[layoutInfo.idToIndex[parentId]];
      var flag = false;

      // MaxX
      if (null == p.maxX || node.maxX + p.padRight > p.maxX) {
        p.maxX = node.maxX + p.padRight;
        flag = true;
        // s += "\nNew maxX for parent node " + p.id + ": " + p.maxX;
      }

      // MinX
      if (null == p.minX || node.minX - p.padLeft < p.minX) {
        p.minX = node.minX - p.padLeft;
        flag = true;
        // s += "\nNew minX for parent node " + p.id + ": " + p.minX;
      }

      // MaxY
      if (null == p.maxY || node.maxY + p.padBottom > p.maxY) {
        p.maxY = node.maxY + p.padBottom;
        flag = true;
        // s += "\nNew maxY for parent node " + p.id + ": " + p.maxY;
      }

      // MinY
      if (null == p.minY || node.minY - p.padTop < p.minY) {
        p.minY = node.minY - p.padTop;
        flag = true;
        // s += "\nNew minY for parent node " + p.id + ": " + p.minY;
      }

      // If updated boundaries, propagate changes upward
      if (flag) {
        // logDebug(s);
        return updateAncestryBoundaries(p, layoutInfo);
      }

      // s += ". No changes in boundaries/position of parent node " + p.id;
      // logDebug(s);
      return;
    };

    var separateComponents = function(layutInfo, options){
      var nodes = layoutInfo.layoutNodes;
      var components = [];

      for( var i = 0; i < nodes.length; i++ ){
        var node = nodes[i];
        var cid = node.cmptId;
        var component = components[ cid ] = components[ cid ] || [];

        component.push( node );
      }

      var totalA = 0;

      for( var i = 0; i < components.length; i++ ){
        var c = components[i];
        c.x1 = Infinity;
        c.x2 = -Infinity;
        c.y1 = Infinity;
        c.y2 = -Infinity;

        for( var j = 0; j < c.length; j++ ){
          var n = c[j];

          c.x1 = Math.min( c.x1, n.positionX - n.width/2 );
          c.x2 = Math.max( c.x2, n.positionX + n.width/2 );
          c.y1 = Math.min( c.y1, n.positionY - n.height/2 );
          c.y2 = Math.max( c.y2, n.positionY + n.height/2 );
        }

        c.w = c.x2 - c.x1;
        c.h = c.y2 - c.y1;

        totalA += c.w * c.h;
      }

      components.sort(function( c1, c2 ){
        return c2.w*c2.h - c1.w*c1.h;
      });

      var x = 0;
      var y = 0;
      var usedW = 0;
      var rowH = 0;
      var maxRowW = Math.sqrt( totalA ) * layoutInfo.clientWidth / layoutInfo.clientHeight;

      for( var i = 0; i < components.length; i++ ){
        var c = components[i];

        for( var j = 0; j < c.length; j++ ){
          var n = c[j];

          if( !n.isLocked ){
            n.positionX += x;
            n.positionY += y;
          }
        }

        x += c.w + options.componentSpacing;
        usedW += c.w + options.componentSpacing;
        rowH = Math.max( rowH, c.h );

        if( usedW > maxRowW ){
          y += rowH + options.componentSpacing;
          x = 0;
          usedW = 0;
          rowH = 0;
        }
      }
    };

    var mainLoop = function(i){
      if( stopped ){
        // logDebug("Layout manually stopped. Stopping computation in step " + i);
        return false;
      }

      // Do one step in the phisical simulation
      step(layoutInfo, options, i);

      // Update temperature
      layoutInfo.temperature = layoutInfo.temperature * options.coolingFactor;
      // logDebug("New temperature: " + layoutInfo.temperature);

      if (layoutInfo.temperature < options.minTemp) {
        // logDebug("Temperature drop below minimum threshold. Stopping computation in step " + i);
        return false;
      }

      return true;
    };

    var i = 0;
    var loopRet;

    do {
      var f = 0;

      while( f < options.refresh && i < options.numIter ){
        var loopRet = mainLoop(i);
        if( !loopRet ){ break; }

        f++;
        i++;
      }

      if( options.animate ){
        broadcast( layoutInfo.layoutNodes ); // jshint ignore:line
      }

    } while ( loopRet && i + 1 < options.numIter );

    separateComponents( layoutInfo, options );

    return layoutInfo;
  }).then(function( layoutInfoUpdated ){
    layoutInfo.layoutNodes = layoutInfoUpdated.layoutNodes; // get the positions

    thread.stop();
    done();
  });

  var done = function(){
    refresh({
      force: true,
      next: function(){
        // Layout has finished
        layout.one('layoutstop', options.stop);
        layout.trigger({ type: 'layoutstop', layout: layout });
      }
    });
  };

  return this; // chaining
};

/**
 * @brief : called on continuous layouts to stop them before they finish
 */
CoseLayout.prototype.stop = function(){
  this.stopped = true;

  if( this.thread ){
    this.thread.stop();
  }

  this.trigger('layoutstop');

  return this; // chaining
};

CoseLayout.prototype.destroy = function(){
  if( this.thread ){
    this.thread.stop();
  }

  return this; // chaining
};

/**
 * @brief     : Creates an object which is contains all the data
 *              used in the layout process
 * @arg cy    : cytoscape.js object
 * @return    : layoutInfo object initialized
 */
var createLayoutInfo = function(cy, layout, options) {
  // Shortcut
  var edges = options.eles.edges();
  var nodes = options.eles.nodes();

  var layoutInfo   = {
    isCompound   : cy.hasCompoundNodes(),
    layoutNodes  : [],
    idToIndex    : {},
    nodeSize     : nodes.size(),
    graphSet     : [],
    indexToGraph : [],
    layoutEdges  : [],
    edgeSize     : edges.size(),
    temperature  : options.initialTemp,
    clientWidth  : cy.width(),
    clientHeight : cy.width(),
    boundingBox  : math.makeBoundingBox( options.boundingBox ? options.boundingBox : {
                     x1: 0, y1: 0, w: cy.width(), h: cy.height()
                   } )
  };

  var components = options.eles.components();
  var id2cmptId = {};

  for( var i = 0; i < components.length; i++ ){
    var component = components[i];

    for( var j = 0; j < component.length; j++ ){
      var node = component[j];

      id2cmptId[ node.id() ] = i;
    }
  }

  // Iterate over all nodes, creating layout nodes
  for (var i = 0; i < layoutInfo.nodeSize; i++) {
    var n = nodes[i];
    var nbb = n.boundingBox();

    var tempNode        = {};
    tempNode.isLocked   = n.locked();
    tempNode.id         = n.data('id');
    tempNode.parentId   = n.data('parent');
    tempNode.cmptId     = id2cmptId[ n.id() ];
    tempNode.children   = [];
    tempNode.positionX  = n.position('x');
    tempNode.positionY  = n.position('y');
    tempNode.offsetX    = 0;
    tempNode.offsetY    = 0;
    tempNode.height     = nbb.w;
    tempNode.width      = nbb.h;
    tempNode.maxX       = tempNode.positionX + tempNode.width  / 2;
    tempNode.minX       = tempNode.positionX - tempNode.width  / 2;
    tempNode.maxY       = tempNode.positionY + tempNode.height / 2;
    tempNode.minY       = tempNode.positionY - tempNode.height / 2;
    tempNode.padLeft    = parseFloat( n.style('padding-left') );
    tempNode.padRight   = parseFloat( n.style('padding-right') );
    tempNode.padTop     = parseFloat( n.style('padding-top') );
    tempNode.padBottom  = parseFloat( n.style('padding-bottom') );

    // forces
    tempNode.nodeRepulsion = is.fn( options.nodeRepulsion ) ? options.nodeRepulsion.call( n, n ) : options.nodeRepulsion;

    // Add new node
    layoutInfo.layoutNodes.push(tempNode);
    // Add entry to id-index map
    layoutInfo.idToIndex[tempNode.id] = i;
  }

  // Inline implementation of a queue, used for traversing the graph in BFS order
  var queue = [];
  var start = 0;   // Points to the start the queue
  var end   = -1;  // Points to the end of the queue

  var tempGraph = [];

  // Second pass to add child information and
  // initialize queue for hierarchical traversal
  for (var i = 0; i < layoutInfo.nodeSize; i++) {
    var n = layoutInfo.layoutNodes[i];
    var p_id = n.parentId;
    // Check if node n has a parent node
    if (null != p_id) {
    // Add node Id to parent's list of children
    layoutInfo.layoutNodes[layoutInfo.idToIndex[p_id]].children.push(n.id);
    } else {
    // If a node doesn't have a parent, then it's in the root graph
    queue[++end] = n.id;
    tempGraph.push(n.id);
    }
  }

  // Add root graph to graphSet
  layoutInfo.graphSet.push(tempGraph);

  // Traverse the graph, level by level,
  while (start <= end) {
    // Get the node to visit and remove it from queue
    var node_id  = queue[start++];
    var node_ix  = layoutInfo.idToIndex[node_id];
    var node     = layoutInfo.layoutNodes[node_ix];
    var children = node.children;
    if (children.length > 0) {
    // Add children nodes as a new graph to graph set
    layoutInfo.graphSet.push(children);
    // Add children to que queue to be visited
    for (var i = 0; i < children.length; i++) {
      queue[++end] = children[i];
    }
    }
  }

  // Create indexToGraph map
  for (var i = 0; i < layoutInfo.graphSet.length; i++) {
    var graph = layoutInfo.graphSet[i];
    for (var j = 0; j < graph.length; j++) {
    var index = layoutInfo.idToIndex[graph[j]];
    layoutInfo.indexToGraph[index] = i;
    }
  }

  // Iterate over all edges, creating Layout Edges
  for (var i = 0; i < layoutInfo.edgeSize; i++) {
    var e = edges[i];
    var tempEdge = {};
    tempEdge.id       = e.data('id');
    tempEdge.sourceId = e.data('source');
    tempEdge.targetId = e.data('target');

    // Compute ideal length
    var idealLength = is.fn( options.idealEdgeLength ) ? options.idealEdgeLength.call( e, e ) : options.idealEdgeLength;
    var elasticity = is.fn( options.edgeElasticity ) ? options.edgeElasticity.call( e, e ) : options.edgeElasticity;

    // Check if it's an inter graph edge
    var sourceIx    = layoutInfo.idToIndex[tempEdge.sourceId];
    var targetIx    = layoutInfo.idToIndex[tempEdge.targetId];
    var sourceGraph = layoutInfo.indexToGraph[sourceIx];
    var targetGraph = layoutInfo.indexToGraph[targetIx];

    if (sourceGraph != targetGraph) {
      // Find lowest common graph ancestor
      var lca = findLCA(tempEdge.sourceId, tempEdge.targetId, layoutInfo);

      // Compute sum of node depths, relative to lca graph
      var lcaGraph = layoutInfo.graphSet[lca];
      var depth    = 0;

      // Source depth
      var tempNode = layoutInfo.layoutNodes[sourceIx];
      while ( -1 === lcaGraph.indexOf(tempNode.id) ) {
        tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]];
        depth++;
      }

      // Target depth
      tempNode = layoutInfo.layoutNodes[targetIx];
      while ( -1 === lcaGraph.indexOf(tempNode.id) ) {
        tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]];
        depth++;
      }

      // logDebug('LCA of nodes ' + tempEdge.sourceId + ' and ' + tempEdge.targetId +
        //  ". Index: " + lca + " Contents: " + lcaGraph.toString() +
        //  ". Depth: " + depth);

      // Update idealLength
      idealLength *= depth * options.nestingFactor;
    }

    tempEdge.idealLength = idealLength;
    tempEdge.elasticity = elasticity;

    layoutInfo.layoutEdges.push(tempEdge);
  }

  // Finally, return layoutInfo object
  return layoutInfo;
};

/**
 * @brief : This function finds the index of the lowest common
 *          graph ancestor between 2 nodes in the subtree
 *          (from the graph hierarchy induced tree) whose
 *          root is graphIx
 *
 * @arg node1: node1's ID
 * @arg node2: node2's ID
 * @arg layoutInfo: layoutInfo object
 *
 */
var findLCA = function(node1, node2, layoutInfo) {
  // Find their common ancester, starting from the root graph
  var res = findLCA_aux(node1, node2, 0, layoutInfo);
  if (2 > res.count) {
    // If aux function couldn't find the common ancester,
    // then it is the root graph
    return 0;
  } else {
    return res.graph;
  }
};

/**
 * @brief          : Auxiliary function used for LCA computation
 *
 * @arg node1      : node1's ID
 * @arg node2      : node2's ID
 * @arg graphIx    : subgraph index
 * @arg layoutInfo : layoutInfo object
 *
 * @return         : object of the form {count: X, graph: Y}, where:
 *                   X is the number of ancesters (max: 2) found in
 *                   graphIx (and it's subgraphs),
 *                   Y is the graph index of the lowest graph containing
 *                   all X nodes
 */
var findLCA_aux = function(node1, node2, graphIx, layoutInfo) {
  var graph = layoutInfo.graphSet[graphIx];
  // If both nodes belongs to graphIx
  if (-1 < graph.indexOf(node1) && -1 < graph.indexOf(node2)) {
    return {count:2, graph:graphIx};
  }

  // Make recursive calls for all subgraphs
  var c = 0;
  for (var i = 0; i < graph.length; i++) {
    var nodeId   = graph[i];
    var nodeIx   = layoutInfo.idToIndex[nodeId];
    var children = layoutInfo.layoutNodes[nodeIx].children;

    // If the node has no child, skip it
    if (0 === children.length) {
    continue;
    }

    var childGraphIx = layoutInfo.indexToGraph[layoutInfo.idToIndex[children[0]]];
    var result = findLCA_aux(node1, node2, childGraphIx, layoutInfo);
    if (0 === result.count) {
    // Neither node1 nor node2 are present in this subgraph
    continue;
    } else if (1 === result.count) {
    // One of (node1, node2) is present in this subgraph
    c++;
    if (2 === c) {
      // We've already found both nodes, no need to keep searching
      break;
    }
    } else {
    // Both nodes are present in this subgraph
    return result;
    }
  }

  return {count:c, graph:graphIx};
};

/**
 * @brief: printsLayoutInfo into js console
 *         Only used for debbuging
 */
var printLayoutInfo = function(layoutInfo) {
  /* jshint ignore:start */

  if (!DEBUG) {
    return;
  }
  console.debug("layoutNodes:");
  for (var i = 0; i < layoutInfo.nodeSize; i++) {
    var n = layoutInfo.layoutNodes[i];
    var s =
    "\nindex: "     + i +
    "\nId: "        + n.id +
    "\nChildren: "  + n.children.toString() +
    "\nparentId: "  + n.parentId  +
    "\npositionX: " + n.positionX +
    "\npositionY: " + n.positionY +
    "\nOffsetX: " + n.offsetX +
    "\nOffsetY: " + n.offsetY +
    "\npadLeft: " + n.padLeft +
    "\npadRight: " + n.padRight +
    "\npadTop: " + n.padTop +
    "\npadBottom: " + n.padBottom;

    console.debug(s);
  }

  console.debug('idToIndex');
  for (var i in layoutInfo.idToIndex) {
    console.debug("Id: " + i + "\nIndex: " + layoutInfo.idToIndex[i]);
  }

  console.debug('Graph Set');
  var set = layoutInfo.graphSet;
  for (var i = 0; i < set.length; i ++) {
    console.debug("Set : " + i + ": " + set[i].toString());
  }

  var s = 'IndexToGraph';
  for (var i = 0; i < layoutInfo.indexToGraph.length; i ++) {
    s += "\nIndex : " + i + " Graph: "+ layoutInfo.indexToGraph[i];
  }
  console.debug(s);

  s = 'Layout Edges';
  for (var i = 0; i < layoutInfo.layoutEdges.length; i++) {
    var e = layoutInfo.layoutEdges[i];
    s += "\nEdge Index: " + i + " ID: " + e.id +
    " SouceID: " + e.sourceId + " TargetId: " + e.targetId +
    " Ideal Length: " + e.idealLength;
  }
  console.debug(s);

  s =  "nodeSize: " + layoutInfo.nodeSize;
  s += "\nedgeSize: " + layoutInfo.edgeSize;
  s += "\ntemperature: " + layoutInfo.temperature;
  console.debug(s);

  return;
  /* jshint ignore:end */
};

/**
 * @brief : Randomizes the position of all nodes
 */
var randomizePositions = function(layoutInfo, cy) {
  var width     = layoutInfo.clientWidth;
  var height    = layoutInfo.clientHeight;

  for (var i = 0; i < layoutInfo.nodeSize; i++) {
    var n = layoutInfo.layoutNodes[i];

    // No need to randomize compound nodes or locked nodes
    if ( 0 === n.children.length && !n.isLocked ) {
      n.positionX = Math.random() * width;
      n.positionY = Math.random() * height;
    }
  }
};

/**
 * @brief          : Updates the positions of nodes in the network
 * @arg layoutInfo : LayoutInfo object
 * @arg cy         : Cytoscape object
 * @arg options    : Layout options
 */
var refreshPositions = function(layoutInfo, cy, options) {
  // var s = 'Refreshing positions';
  // logDebug(s);

  var layout = options.layout;
  var nodes = options.eles.nodes();
  var bb = layoutInfo.boundingBox;
  var coseBB = { x1: Infinity, x2: -Infinity, y1: Infinity, y2: -Infinity };

  if( options.boundingBox ){
    nodes.forEach(function( node ){
      var lnode = layoutInfo.layoutNodes[layoutInfo.idToIndex[node.data('id')]];

      coseBB.x1 = Math.min( coseBB.x1, lnode.positionX );
      coseBB.x2 = Math.max( coseBB.x2, lnode.positionX );

      coseBB.y1 = Math.min( coseBB.y1, lnode.positionY );
      coseBB.y2 = Math.max( coseBB.y2, lnode.positionY );
    });

    coseBB.w = coseBB.x2 - coseBB.x1;
    coseBB.h = coseBB.y2 - coseBB.y1;
  }

  nodes.positions(function(i, ele) {
    var lnode = layoutInfo.layoutNodes[layoutInfo.idToIndex[ele.data('id')]];
    // s = "Node: " + lnode.id + ". Refreshed position: (" +
    // lnode.positionX + ", " + lnode.positionY + ").";
    // logDebug(s);

    if( options.boundingBox ){ // then add extra bounding box constraint
      var pctX = (lnode.positionX - coseBB.x1) / coseBB.w;
      var pctY = (lnode.positionY - coseBB.y1) / coseBB.h;

      return {
        x: bb.x1 + pctX * bb.w,
        y: bb.y1 + pctY * bb.h
      };
    } else {
      return {
        x: lnode.positionX,
        y: lnode.positionY
      };
    }
  });

  // Trigger layoutReady only on first call
  if (true !== layoutInfo.ready) {
    // s = 'Triggering layoutready';
    // logDebug(s);
    layoutInfo.ready = true;
    layout.one('layoutready', options.ready);
    layout.trigger({ type: 'layoutready', layout: this });
  }
};

/**
 * @brief : Logs a debug message in JS console, if DEBUG is ON
 */
// var logDebug = function(text) {
//   if (DEBUG) {
//     console.debug(text);
//   }
// };

module.exports = CoseLayout;


text:
Evender is a events provider which gets  different events website.

### Usage

Note: Install Java 8.

1. Import project into any IDE.

2. Run **Server** (Evender runs on an embedded Jetty web server)

### TESTING

#### City based event search

```xml
 localhost:8080/city/ankara
```

#### Get all events

```xml
 localhost:8080/event
```

#### Get ZorluCenter event

```xml
 localhost:8080/zorluevent
```

### Resource Website

[Etkinliktakvimi](http://etkinliktakvimi.org/)

[ZorluCenter](http://www.zorlucenterpsm.com)

[Etkinlik](http://www.etkinlik.com.tr/)

### Fork it for new resource :)


text:
pub mod boot;
pub mod memory;
pub mod multiboot;


text:
import $ from 'jquery';

const attachToggleables = (form) => {
    form = $(form);
    let query = '[data-grav-field="toggleable"] input[type="checkbox"]';

    form.on('change', query, (event) => {
        let toggle = $(event.target);
        let enabled = toggle.is(':checked');
        let parent = toggle.closest('.form-field');
        let label = parent.find('label.toggleable');
        let fields = parent.find('.form-data');
        let inputs = fields.find('input, select, textarea, button');

        label.add(fields).css('opacity', enabled ? '' : 0.7);
        inputs.map((index, input) => {
            let isSelectize = input.selectize;
            input = $(input);

            if (isSelectize) {
                isSelectize[enabled ? 'enable' : 'disable']();
            } else {
                input.prop('disabled', !enabled);
            }
        });
    });

    form.find(query).trigger('change');
};

const attachDisabledFields = (form) => {
    form = $(form);
    let prefix = '.form-field-toggleable .form-data';
    let query = [];

    ['input', 'select', 'label[for]', 'textarea', '.selectize-control'].forEach((item) => {
        query.push(`${prefix} ${item}`);
    });

    form.on('mousedown', query.join(', '), (event) => {
        let input = $(event.target);
        let isFor = input.prop('for');
        let isSelectize = (input.hasClass('selectize-control') || input.parents('.selectize-control')).length;

        if (isFor) { input = $(`[id="${isFor}"]`); }
        if (isSelectize) { input = input.closest('.selectize-control').siblings('select[name]'); }

        if (!input.prop('disabled')) { return true; }

        let toggle = input.closest('.form-field').find('[data-grav-field="toggleable"] input[type="checkbox"]');
        toggle.trigger('click');
    });
};

/*
const submitUncheckedFields = (forms) => {
    forms = $(forms);
    let submitted = false;
    forms.each((index, form) => {
        form = $(form);
        form.on('submit', () => {
            // workaround for MS Edge, submitting multiple forms at the same time
            if (submitted) { return false; }

            let formId = form.attr('id');
            let unchecked = form.find('input[type="checkbox"]:not(:checked):not(:disabled)');
            let submit = form.find('[type="submit"]').add(`[form="${formId}"][type="submit"]`);

            if (!unchecked.length) { return true; }

            submit.addClass('pointer-events-disabled');
            unchecked.each((index, element) => {
                element = $(element);
                let name = element.prop('name');
                let fake = $(`<input type="hidden" name="${name}" value="0" />`);
                form.append(fake);
            });
            submitted = true;
            return true;
        });
    });
};
*/

$(document).ready(() => {
    const forms = $('form').filter((form) => $(form).find('[name="__form-name__"]'));
    if (!forms.length) { return; }

    forms.each((index, form) => {
        attachToggleables(form);
        attachDisabledFields(form);
        // submitUncheckedFields(form);
    });
});


text:
"""
    sphinx.domains
    ~~~~~~~~~~~~~~

    Support for domains, which are groupings of description directives
    and roles describing e.g. constructs of one programming language.

    :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
    :license: BSD, see LICENSE for details.
"""

import copy
from abc import ABC, abstractmethod
from typing import (TYPE_CHECKING, Any, Callable, Dict, Iterable, List, NamedTuple, Optional,
                    Tuple, Type, Union, cast)

from docutils import nodes
from docutils.nodes import Element, Node, system_message
from docutils.parsers.rst.states import Inliner

from sphinx.addnodes import pending_xref
from sphinx.errors import SphinxError
from sphinx.locale import _
from sphinx.roles import XRefRole
from sphinx.util.typing import RoleFunction

if TYPE_CHECKING:
    from sphinx.builders import Builder
    from sphinx.environment import BuildEnvironment

class ObjType:
    """
    An ObjType is the description for a type of object that a domain can
    document.  In the object_types attribute of Domain subclasses, object type
    names are mapped to instances of this class.

    Constructor arguments:

    - *lname*: localized name of the type (do not include domain name)
    - *roles*: all the roles that can refer to an object of this type
    - *attrs*: object attributes -- currently only "searchprio" is known,
      which defines the object's priority in the full-text search index,
      see :meth:`Domain.get_objects()`.
    """

    known_attrs = {
        'searchprio': 1,
    }

    def __init__(self, lname: str, *roles: Any, **attrs: Any) -> None:
        self.lname = lname
        self.roles: Tuple = roles
        self.attrs: Dict = self.known_attrs.copy()
        self.attrs.update(attrs)

class IndexEntry(NamedTuple):
    name: str
    subtype: int
    docname: str
    anchor: str
    extra: str
    qualifier: str
    descr: str

class Index(ABC):
    """
    An Index is the description for a domain-specific index.  To add an index to
    a domain, subclass Index, overriding the three name attributes:

    * `name` is an identifier used for generating file names.
      It is also used for a hyperlink target for the index. Therefore, users can
      refer the index page using ``ref`` role and a string which is combined
      domain name and ``name`` attribute (ex. ``:ref:`py-modindex```).
    * `localname` is the section title for the index.
    * `shortname` is a short name for the index, for use in the relation bar in
      HTML output.  Can be empty to disable entries in the relation bar.

    and providing a :meth:`generate()` method.  Then, add the index class to
    your domain's `indices` list.  Extensions can add indices to existing
    domains using :meth:`~sphinx.application.Sphinx.add_index_to_domain()`.

    .. versionchanged:: 3.0

       Index pages can be referred by domain name and index name via
       :rst:role:`ref` role.
    """

    name: str = None
    localname: str = None
    shortname: str = None

    def __init__(self, domain: "Domain") -> None:
        if self.name is None or self.localname is None:
            raise SphinxError('Index subclass %s has no valid name or localname'
                              % self.__class__.__name__)
        self.domain = domain

    @abstractmethod
    def generate(self, docnames: Iterable[str] = None
                 ) -> Tuple[List[Tuple[str, List[IndexEntry]]], bool]:
        """Get entries for the index.

        If ``docnames`` is given, restrict to entries referring to these
        docnames.

        The return value is a tuple of ``(content, collapse)``:

        ``collapse``
          A boolean that determines if sub-entries should start collapsed (for
          output formats that support collapsing sub-entries).

        ``content``:
          A sequence of ``(letter, entries)`` tuples, where ``letter`` is the
          "heading" for the given ``entries``, usually the starting letter, and
          ``entries`` is a sequence of single entries. Each entry is a sequence
          ``[name, subtype, docname, anchor, extra, qualifier, descr]``. The
          items in this sequence have the following meaning:

          ``name``
            The name of the index entry to be displayed.

          ``subtype``
            The sub-entry related type. One of:

            ``0``
              A normal entry.
            ``1``
              An entry with sub-entries.
            ``2``
              A sub-entry.

          ``docname``
            *docname* where the entry is located.

          ``anchor``
            Anchor for the entry within ``docname``

          ``extra``
            Extra info for the entry.

          ``qualifier``
            Qualifier for the description.

          ``descr``
            Description for the entry.

        Qualifier and description are not rendered for some output formats such
        as LaTeX.
        """
        raise NotImplementedError

class Domain:
    """
    A Domain is meant to be a group of "object" description directives for
    objects of a similar nature, and corresponding roles to create references to
    them.  Examples would be Python modules, classes, functions etc., elements
    of a templating language, Sphinx roles and directives, etc.

    Each domain has a separate storage for information about existing objects
    and how to reference them in `self.data`, which must be a dictionary.  It
    also must implement several functions that expose the object information in
    a uniform way to parts of Sphinx that allow the user to reference or search
    for objects in a domain-agnostic way.

    About `self.data`: since all object and cross-referencing information is
    stored on a BuildEnvironment instance, the `domain.data` object is also
    stored in the `env.domaindata` dict under the key `domain.name`.  Before the
    build process starts, every active domain is instantiated and given the
    environment object; the `domaindata` dict must then either be nonexistent or
    a dictionary whose 'version' key is equal to the domain class'
    :attr:`data_version` attribute.  Otherwise, `OSError` is raised and the
    pickled environment is discarded.
    """

    #: domain name: should be short, but unique
    name = ''
    #: domain label: longer, more descriptive (used in messages)
    label = ''
    #: type (usually directive) name -> ObjType instance
    object_types: Dict[str, ObjType] = {}
    #: directive name -> directive class
    directives: Dict[str, Any] = {}
    #: role name -> role callable
    roles: Dict[str, Union[RoleFunction, XRefRole]] = {}
    #: a list of Index subclasses
    indices: List[Type[Index]] = []
    #: role name -> a warning message if reference is missing
    dangling_warnings: Dict[str, str] = {}
    #: node_class -> (enum_node_type, title_getter)
    enumerable_nodes: Dict[Type[Node], Tuple[str, Callable]] = {}

    #: data value for a fresh environment
    initial_data: Dict = {}
    #: data value
    data: Dict
    #: data version, bump this when the format of `self.data` changes
    data_version = 0

    def __init__(self, env: "BuildEnvironment") -> None:
        self.env: BuildEnvironment = env
        self._role_cache: Dict[str, Callable] = {}
        self._directive_cache: Dict[str, Callable] = {}
        self._role2type: Dict[str, List[str]] = {}
        self._type2role: Dict[str, str] = {}

        # convert class variables to instance one (to enhance through API)
        self.object_types = dict(self.object_types)
        self.directives = dict(self.directives)
        self.roles = dict(self.roles)
        self.indices = list(self.indices)

        if self.name not in env.domaindata:
            assert isinstance(self.initial_data, dict)
            new_data = copy.deepcopy(self.initial_data)
            new_data['version'] = self.data_version
            self.data = env.domaindata[self.name] = new_data
        else:
            self.data = env.domaindata[self.name]
            if self.data['version'] != self.data_version:
                raise OSError('data of %r domain out of date' % self.label)
        for name, obj in self.object_types.items():
            for rolename in obj.roles:
                self._role2type.setdefault(rolename, []).append(name)
            self._type2role[name] = obj.roles[0] if obj.roles else ''
        self.objtypes_for_role: Callable[[str], List[str]] = self._role2type.get
        self.role_for_objtype: Callable[[str], str] = self._type2role.get

    def setup(self) -> None:
        """Set up domain object."""
        from sphinx.domains.std import StandardDomain

        # Add special hyperlink target for index pages (ex. py-modindex)
        std = cast(StandardDomain, self.env.get_domain('std'))
        for index in self.indices:
            if index.name and index.localname:
                docname = "%s-%s" % (self.name, index.name)
                std.note_hyperlink_target(docname, docname, '', index.localname)

    def add_object_type(self, name: str, objtype: ObjType) -> None:
        """Add an object type."""
        self.object_types[name] = objtype
        if objtype.roles:
            self._type2role[name] = objtype.roles[0]
        else:
            self._type2role[name] = ''

        for role in objtype.roles:
            self._role2type.setdefault(role, []).append(name)

    def role(self, name: str) -> Optional[RoleFunction]:
        """Return a role adapter function that always gives the registered
        role its full name ('domain:name') as the first argument.
        """
        if name in self._role_cache:
            return self._role_cache[name]
        if name not in self.roles:
            return None
        fullname = '%s:%s' % (self.name, name)

        def role_adapter(typ: str, rawtext: str, text: str, lineno: int,
                         inliner: Inliner, options: Dict = {}, content: List[str] = []
                         ) -> Tuple[List[Node], List[system_message]]:
            return self.roles[name](fullname, rawtext, text, lineno,
                                    inliner, options, content)
        self._role_cache[name] = role_adapter
        return role_adapter

    def directive(self, name: str) -> Optional[Callable]:
        """Return a directive adapter class that always gives the registered
        directive its full name ('domain:name') as ``self.name``.
        """
        if name in self._directive_cache:
            return self._directive_cache[name]
        if name not in self.directives:
            return None
        fullname = '%s:%s' % (self.name, name)
        BaseDirective = self.directives[name]

        class DirectiveAdapter(BaseDirective):  # type: ignore
            def run(self) -> List[Node]:
                self.name = fullname
                return super().run()
        self._directive_cache[name] = DirectiveAdapter
        return DirectiveAdapter

    # methods that should be overwritten

    def clear_doc(self, docname: str) -> None:
        """Remove traces of a document in the domain-specific inventories."""
        pass

    def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None:
        """Merge in data regarding *docnames* from a different domaindata
        inventory (coming from a subprocess in parallel builds).
        """
        raise NotImplementedError('merge_domaindata must be implemented in %s '
                                  'to be able to do parallel builds!' %
                                  self.__class__)

    def process_doc(self, env: "BuildEnvironment", docname: str,
                    document: nodes.document) -> None:
        """Process a document after it is read by the environment."""
        pass

    def check_consistency(self) -> None:
        """Do consistency checks (**experimental**)."""
        pass

    def process_field_xref(self, pnode: pending_xref) -> None:
        """Process a pending xref created in a doc field.
        For example, attach information about the current scope.
        """
        pass

    def resolve_xref(self, env: "BuildEnvironment", fromdocname: str, builder: "Builder",
                     typ: str, target: str, node: pending_xref, contnode: Element
                     ) -> Optional[Element]:
        """Resolve the pending_xref *node* with the given *typ* and *target*.

        This method should return a new node, to replace the xref node,
        containing the *contnode* which is the markup content of the
        cross-reference.

        If no resolution can be found, None can be returned; the xref node will
        then given to the :event:`missing-reference` event, and if that yields no
        resolution, replaced by *contnode*.

        The method can also raise :exc:`sphinx.environment.NoUri` to suppress
        the :event:`missing-reference` event being emitted.
        """
        pass

    def resolve_any_xref(self, env: "BuildEnvironment", fromdocname: str, builder: "Builder",
                         target: str, node: pending_xref, contnode: Element
                         ) -> List[Tuple[str, Element]]:
        """Resolve the pending_xref *node* with the given *target*.

        The reference comes from an "any" or similar role, which means that we
        don't know the type.  Otherwise, the arguments are the same as for
        :meth:`resolve_xref`.

        The method must return a list (potentially empty) of tuples
        ``('domain:role', newnode)``, where ``'domain:role'`` is the name of a
        role that could have created the same reference, e.g. ``'py:func'``.
        ``newnode`` is what :meth:`resolve_xref` would return.

        .. versionadded:: 1.3
        """
        raise NotImplementedError

    def get_objects(self) -> Iterable[Tuple[str, str, str, str, str, int]]:
        """Return an iterable of "object descriptions".

        Object descriptions are tuples with six items:

        ``name``
          Fully qualified name.

        ``dispname``
          Name to display when searching/linking.

        ``type``
          Object type, a key in ``self.object_types``.

        ``docname``
          The document where it is to be found.

        ``anchor``
          The anchor name for the object.

        ``priority``
          How "important" the object is (determines placement in search
          results). One of:

          ``1``
            Default priority (placed before full-text matches).
          ``0``
            Object is important (placed before default-priority objects).
          ``2``
            Object is unimportant (placed after full-text matches).
          ``-1``
            Object should not show up in search at all.
        """
        return []

    def get_type_name(self, type: ObjType, primary: bool = False) -> str:
        """Return full name for given ObjType."""
        if primary:
            return type.lname
        return _('%s %s') % (self.label, type.lname)

    def get_enumerable_node_type(self, node: Node) -> Optional[str]:
        """Get type of enumerable nodes (experimental)."""
        enum_node_type, _ = self.enumerable_nodes.get(node.__class__, (None, None))
        return enum_node_type

    def get_full_qualified_name(self, node: Element) -> Optional[str]:
        """Return full qualified name for given node."""
        return None


text:
package org.jetbrains.java.generate.element;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiJavaFile;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.search.GlobalSearchScope;

import java.util.List;

public class GenerationHelper {

  //used in generate equals/hashCode
  @SuppressWarnings("unused")
  public static String getUniqueLocalVarName(String base, List<Element> elements, JavaCodeStyleSettings settings) {
    base = settings.LOCAL_VARIABLE_NAME_PREFIX + base;
    String id = base;
    int index = 0;
    while (true) {
      if (index > 0) {
        id = base + index;
      }
      index++;
      boolean anyEqual = false;
      for (Element equalsField : elements) {
        if (id.equals(equalsField.getName())) {
          anyEqual = true;
          break;
        }
      }
      if (!anyEqual) break;
    }

    return id;
  }

  /**
   * To be used from generate templates
   */
  @SuppressWarnings("unused")
  public static String getClassNameWithOuters(ClassElement classElement, Project project) {
    String qualifiedName = classElement.getQualifiedName();
    PsiClass aClass = JavaPsiFacade.getInstance(project).findClass(qualifiedName, GlobalSearchScope.projectScope(project));
    if (aClass != null) {
      PsiFile containingFile = aClass.getContainingFile();
      if (containingFile instanceof PsiJavaFile) {
        String packageName = ((PsiJavaFile)containingFile).getPackageName();
        if (qualifiedName.startsWith(packageName)) {
          if (packageName.isEmpty()) return qualifiedName;
          return qualifiedName.substring(packageName.length() + 1);
        }
      }
    }
    return classElement.getName();
  }

  public static String getParamName(FieldElement fieldElement, Project project) {
    JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
    return codeStyleManager.propertyNameToVariableName(getPropertyName(fieldElement, project), VariableKind.PARAMETER);
  }

  public static String getPropertyName(FieldElement fieldElement, Project project) {
    final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
    final VariableKind variableKind = fieldElement.isModifierStatic() ? VariableKind.STATIC_FIELD : VariableKind.FIELD;
    final String propertyName = codeStyleManager.variableNameToPropertyName(fieldElement.getName(), variableKind);
    if (!fieldElement.isModifierStatic() && fieldElement.isBoolean()) {
      if (propertyName.startsWith("is") &&
          propertyName.length() > "is".length() &&
          Character.isUpperCase(propertyName.charAt("is".length()))) {
        return StringUtil.decapitalize(propertyName.substring("is".length()));
      }
    }
    return propertyName;
  }
}


text:
using System.ComponentModel;
using NUnit.Framework;
using Suigetsu.Core.Util;

namespace Suigetsu.Core.Tests.Util
{
    [TestFixture]
    public class EnumUtilsTests : AssertionHelper
    {
        //TODO: missing code
        //[Test]
        //public void EnumRepoTest()
        //{
        //    Expect(EnumUtils.GetRepo(null).Id, Empty);
        //}

        [Test]
        public void ValidateEnumTest()
        {
            Expect(() => EnumUtils.Validate(null), Throws.InstanceOf<InvalidEnumArgumentException>());
            Expect(() => EnumUtils.Validate(EnumUtils.DummyEnum.DummyEnumItem), Throws.Nothing);
        }
    }
}


text:
using Gu.Roslyn.Asserts;
using NUnit.Framework;
using SpatialAnalyzers;

namespace Spatial.Roslyn.Tests
{
    public class FixRay3DTests
    {
        // ReSharper disable once InconsistentNaming
        private static readonly ExpectedDiagnostic CS0618 = ExpectedDiagnostic.Create("CS0618");

        [Test]
        public void ReplaceLineTo()
        {
            var testCode = @"
namespace RoslynSandbox
{
    using MathNet.Spatial.Euclidean;

    class Foo
    {
        public Foo()
        {
            var p1 = new Point3D(1, 2, 0);
            var p2 = new Point3D(3, 4, 5);
            var u = new UnitVector3D(0, 1, 0);
            var ray = new Ray3D(p1, u);
            var answer = ray.LineTo(p2);
        }
    }
}";
            var fixedCode = @"
namespace RoslynSandbox
{
    using MathNet.Spatial.Euclidean;

    class Foo
    {
        public Foo()
        {
            var p1 = new Point3D(1, 2, 0);
            var p2 = new Point3D(3, 4, 5);
            var u = new UnitVector3D(0, 1, 0);
            var ray = new Ray3D(p1, u);
            var answer = ray.ShortestLineTo(p2);
        }
    }
}";
            RoslynAssert.CodeFix(new UpdateCodeFix(), CS0618, testCode, fixedCode);
        }
    }
}