Business Name by Anders stanly
Summary:
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the .
Upload Video and Photo:
Company Portfolio
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining
Director's BIO
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining
Proposal
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.


DryadTree
Manages the tree structure, contexts for nodes, utilities to walk the tree, collect commands and call command middleware.
Constructor Summary
| Public Constructor | ||
| public |
constructor(rootDryad: Dryad, getClass: Function) |
Member Summary
| Public Members | ||
| public |
contexts: * |
|
| public |
dryads: * |
|
| public |
getClass: * |
|
| public |
root: * |
|
| public |
rootContext: * |
|
| public |
tree: * |
Method Summary
| Public Methods | ||
| public |
collectCommands(methodName: String, node: Dryad): Object Collect a tree of command objects from each node for a given method. |
|
| public |
getDebugState(): * Get a representation of current state of the tree. |
|
| public |
makeCommandTree(nodeId: *, command: *): * Construct a command tree for a single commandObject to be executed with a single node's context. This is for runtime execution of commands, called from streams and async processes initiated during Dryad's .add() |
|
| public |
updateContext(dryadId: String, update: Object): * Update the context for a node. |
|
| public |
Depth first traversal of the Dryad tree |
Public Constructors
Public Members
public contexts: * source
public dryads: * source
public getClass: * source
public root: * source
public rootContext: * source
public tree: * source
Public Methods
public collectCommands(methodName: String, node: Dryad): Object source
Collect a tree of command objects from each node for a given method. eg. 'add' 'remove' 'prepareForAdd'
public getDebugState(): * source
Get a representation of current state of the tree. Contains add|remove|prepared and may hold errors.
Return:
| * |
public makeCommandTree(nodeId: *, command: *): * source
Construct a command tree for a single commandObject to be executed with a single node's context.
This is for runtime execution of commands, called from streams and async processes initiated during Dryad's .add()
Params:
| Name | Type | Attribute | Description |
| nodeId | * | ||
| command | * |
Return:
| * |
public updateContext(dryadId: String, update: Object): * source
Update the context for a node.
Return:
| * |


Home
Search
Profile
Watchlist
What type of content do you want to search for?
Movies
TV Shows
What genre of content do you want to search for?
Action
Adventure
Comedy
Thriller
Mystery
Sci-Fi
Cancel
Apply


[§527‑8] Capacity of transferor. The capacity required to execute or revoke a transfer on death deed is the same as the capacity required to execute a will. [L 2011, c 173, pt of §1]


VIP Cool stays
Where Travelmaker VIP members are staying and saving
South Beach Hotel
Miami Soho Beach House
3,457
from $430/night
Tropical Hotel
Indonesia Mystic Palace
2,490
from $150/night
Dubai Oriental Hotel
3,523
from $400/night
California Dreamin
4,685
from $180/night
Thailand hotel
3,422
from $550/night
Cambodia Tropical Resort
Home Rentals Near You
We think you'd enjoy these homes for a quick trip out of town.
Rentals in New York City
634 rentalsRentals in Houston
359 rentalsRentals in Chicago
289 rentalsRentals in Los Angeles
451 rentalsRentals in Phoenix
227 rentalsRentals in Philadelphia
358 rentalsMore to explore
Why Fall Is the Perfect Time to Visit Our National Parks
A Guide to Last-Minute Road Trips You Can Do Right Now
All the Ways We're Celebrating Hispanic Heritage Month
Destinations travelers love
Yellowstone National Park, WY
Punta Cana, Dominican Republic
Maui, HI
Orlando, FL
Sedona, AZ
Cancun, Mexico
New York City, NY
Las Vegas, NV
Get more of what you've been missing.
Introducing Travelmaker VIP. Endless travel savings, one simple membership.


--- layout: post title: Some thoughts on developing my first Confluence plugin date: 2010-01-25 13:42:04.000000000 +00:00 type: post published: true status: publish categories: - Uncategorised - web tags: - analytics - atlassian - confluence - google analytics - java - plugin - wiki meta: _syntaxhighlighter_encoded: '1' _topsy_cache_timestamp: '1299691618' _topsy_long_url: /2010/01/25/some-thoughts-on-developing-my-first-confluence-plugin topsy_short_url: http://bit.ly/8X5OVK _edit_last: '1' tmac_last_id: '618797401055178752' _encloseme: '1' _pingme: '1' author: David Simpson excerpt_separator: ---
I recently started building Confluence plugins. The first one being my Google Analytics plugin for Confluence. This post outlines my "journey" into Confluence plugin development. It documents a beginner's pitfalls when developing with the Atlassian Plugin SDK. Hopefully others can learn from, or at least laugh at my mistakes.
Where I was starting from:
I tried to setup a development environment for plugin development using Atlassian's documentation a little before the beta release of version 3 of the Atlassian Plugin SDK. It was a pain. This was no fault of the documentation — it was really just to do with my schedules and available time to experiment.
The problem was two-fold:
I was well aware of point 1 and the pain it was likely to cause. Point 2 seemed to be the old chestnut - install and configure the exact correct versions of the software you need in the correct sequence, then start.
Wait. I don't know what that means, see point 1. Yes, I've got maven installed on my MacBook! Woo! Let's go. Hang on, it's not the correct version. Where do I get that from?
In many ways, it reminded me of my initial experience of building and installing Apache 1.x on Solaris SPARC boxes back in the day:
cd /path/to/apache/source; make; make install;
Oh. Wrong version of make. Where do I get that from? Hmmm.
Install correct version of make. Damn, make needs the correct version of gcc. Where do I get that from?
And so on. Moving further and further away from the problem you're trying to solve.
So, I stopped there. No shiny Confluence plugins for me. I've got plenty of other things to do anyway thank you very much.
Then Atlassian released the Plugin SDK beta and all this nastiness was removed. Everything you need to build an Atlassian plugin was bundled in one place. Refreshing. All commands have been wrapped and so are prefixed with atlas-
to prevent conflict with whatever else you've got installed.
For the impatient, this really drives down the barriers to entry for plugin development.
Following the documentation for installing the Plugin SDK was a piece of cake. It just worked.
~/.profile
and add:
PATH=$PATH:.
PATH=$PATH:$HOME/
PATH=$PATH:$HOME/bin
PATH=$PATH:$HOME/atlassian-plugin-sdk/atlassian-plugin-sdk-3.0-beta3
PATH=$PATH:$HOME/atlassian-plugin-sdk/atlassian-plugin-sdk-3.0-beta3/bin
export PATH
Starting out to build your Atlassian plugin is documented here. It's a fairly straightforward set of instructions.
You start by doing something like this:
mkdir ~/projects/davidsimpson.me/
mkdir ~/projects/davidsimpson.me/confluence
cd ~/projects/davidsimpson.me/confluence
atlas-create-confluence-plugin
...
...
...
When prompted
Define value for groupId: : me.davdsimpson.confluence.plugins
Define value for artifactId: : googleanalytics
Define value for version: 1.0-SNAPSHOT: :
Define value for package: me.davdsimpson.confluence.plugins: :
Confirm properties configuration:
groupId: me.davdsimpson.confluence.plugins
artifactId: googleanalytics
version: 1.0-SNAPSHOT
package: me.davdsimpson.confluence.plugins
Then type...
cd googleanalytics
atlas-run
...and sit back. If maven doesn't fall over for lack of memory at this point, you're laughing. Go away, have a beer or two. This may take some time.
On your return, maven will hopefully have finished dragging all manner of nonsense from Australia and installed a working copy of Confluence, together with an empty plugin onto your computer. Nice. Next, write some code.
I like to run before I can walk. It seems like much more fun to attempt something that's harder. You do fall over a lot more often though. So rather than some kind of silly little hello world or equivalent plugin, my first plugin was an integration of Google Analytics with Confluence using the Google Analytics API to fetch data from Google. It requires some additional JARs from Google.
Google doesn't have a public maven repository to my knowledge and I'd no idea how to get these JARs added into maven. Luckily, people had already written about parts of this, so I put 2 and 2 together.
Add Google Analytics JARs to maven:
atlas-mvn install:install-file -DgroupId=com.google.gdata \
-DartifactId=gdata-core \
-Dversion=1.0 \
-Dpackaging=jar \
-Dfile=/path/to/gdata-core-1.0.jar \
-DgeneratePom=true
atlas-mvn install:install-file -DgroupId=com.google.gdata \
-DartifactId=gdata-analytics \
-Dversion=2.0 \
-Dpackaging=jar \
-Dfile=/path/to/gdata-analytics-2.0.jar \
-DgeneratePom=true
atlas-mvn install:install-file -DgroupId=com.google.collect \
-DartifactId=google-collect \
-Dversion=1.0 \
-Dpackaging=jar \
-Dfile=/path/to/google-collect-1.0-rc3.jar
Edit the Project Object Model (POM) to add the dependencies
Edit the pom:
Add this bit to the end of the dependencies node:
<!--
It's not all straightforward. Here's some of the annoyances that I came across.
I needed more memory for maven. Not really a problem - append to ~/.profile
:
export MAVEN_OPTS=-Xmx512m
atlas-run
I noticed this on running atlas-run
- it probably shouldn't be there:
Of course, someone has already blogged about it — Red Leopard — and it's easily fixed by editing the POM to add the correct encoding.
3.0.2
3.0
<!-- Fix for MacRoman warnings on build -->
UTF-8
UTF-8
Now, we have no nasty warnings.
I love the Macro Browser in Confluence. It's a nice step forward in the evolution of the UI. So as a result, I wanted my macro to have a shiny icon in the macro browser.  Looking at the comments on the documentation page, several other people have had a whole load of fun getting their pretty icon to show up too.
[caption id="attachment_521" align="alignnone" width="440" caption="The macro browser icon: What we"][/caption]
Could I get the Macro Browser to show my plugin's icon. No. I followed the documentation. It did not work. I looked again. This time I really paid attention.  Was I just being stupid? (Probably.) I ignored this for a while — maybe it would be better after a night's sleep.
Everything seemed to work a whole lot better when I dropped the beta and moved to version 3.0.2 of the Plugin SDK.
Note: I had to update my ~/.profile
to point to the new version of the SDK and update the references to maven in Intelli-J at this point.
I also followed a different tack on getting the macro browser icon to work
atlassian-plugin.xml
and paste into your macro's own atlassian-plugin.xml
atlassian-plugin.xml
and put it in the correct place in the directory structureI'm not entirely sure whether it was the copy and paste approach that helped or moving away from the beta. It works now, so I'm not going to loose sleep on why.
My plugin needed to store Google account credentials and display a list of Google Analytics sites, so you can choose the correct profile. How do you do that? Hmmm. Go back to the documentation. It wasn't nearly detailed enough for my liking, so time to vent a little.
Again, it seemed the best way to learn was to find a plugin that has a similar kind of configuration to that you're hoping for and start appropriating the code.
This is a good idea. Period. Did I have a clue how to do it for Confluence? Of course not.
Again, the community helped out. Atlassian partners at Adaptavist, Comala Technology and Customware have written about this:
Browsing around the Atlassian public subversion repository was also a help. I've got to say that I'm an easy convert to testing. It just makes sense.
Update (2010-05-04): A nice feature of the SDK is running or testing your plugin against different versions of the product. This is straightforward:
# Integration tests for different versions
atlas-integration-test -v 3.0
atlas-integration-test -v 3.1
atlas-integration-test -v 3.2
# Run different versions of Confluence
atlas-run -v 3.0
atlas-run -v 3.1
atlas-run -v 3.2
After a good deal of stumbling around, it turns out that I can write a Confluence plugin after all. Everything started working a lot better after I updated from the beta version, but that could just be coincidence. The documentation could be a little better to help the uninitiated but it was equally my fault for not learning to walk first. There is a lot of good information, but it is spread over a few different spaces.
My next step was to get the plugin added to Atlassian Plugin Exchange. It took a little while to get this done — maybe that's best saved for a follow up post. The plugin is now available on Atlassian Plugin Exchange. I hope other people get some use out of it.


-
messageDone()
-
called after attempting to send message wether successful or not.
- Source:
-
messageError()
-
called on xhr failiure when sending message, and before messageDone
- Source:
-
messageStart()
-
called at start of xhr request to send message
- Source:
-
messageSuccess()
-
called after message is successfully delivered, and before messageDone
- Source:
-
networkError()
-
called on event of network error. Either you have no internet
connection, or Lobsterrr is probably down. This can be used for
backup form handler.
- Source:
-
tokenError()
-
called when Lobsterr cannot aquire a token
- Source:


1. 环境
准备三台机器，ip如下:
| 节点 | ip |
|---|---|
| node1 | <IP_ADDRESS> |
| node2 | <IP_ADDRESS> |
| node3 | <IP_ADDRESS> |
2. kafak安装配置
2.1 zookeeper 安装配置
kafka依赖zookeeper，所以在运行kafka之前先安装配置好并启动zookeeper。
生产环境的zookeeper一般是集群，这里为了简化，使用单机，配置在<IP_ADDRESS>节点上。
3. kafka 安装配置（单机）
wget http://<IP_ADDRESS>/www/lib/kafka_2.12-<IP_ADDRESS>.tgz
tar -zxvf kafka_2.12-<IP_ADDRESS>.tgz
mv kafka_2.12-<IP_ADDRESS> kafka
kafak的配置文件kafak/configure/server.properties
现在只要配置来两个配置项就ok
listeners=PLAINTEXT://<IP_ADDRESS>:9092
zookeeper.connect=<IP_ADDRESS>:2181
其他配置项保持默认就可以了，配置好的配置文件如下
# 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.
# see kafka.server.KafkaConfig for additional details and defaults
############################# Server Basics #############################
# The id of the broker. This must be set to a unique integer for each broker.
broker.id=0
# Switch to enable topic deletion or not, default value is false
#delete.topic.enable=true
############################# Socket Server Settings #############################
# The address the socket server listens on. It will get the value returned from
# java.net.InetAddress.getCanonicalHostName() if not configured.
# FORMAT:
# listeners = listener_name://host_name:port
# EXAMPLE:
# listeners = PLAINTEXT://your.host.name:9092
listeners=PLAINTEXT://<IP_ADDRESS>:9092
# Hostname and port the broker will advertise to producers and consumers. If not set,
# it uses the value for "listeners" if configured. Otherwise, it will use the value
# returned from java.net.InetAddress.getCanonicalHostName().
#advertised.listeners=PLAINTEXT://your.host.name:9092
# Maps listener names to security protocols, the default is for them to be the same. See the config documentation for more details
#listener.security.protocol.map=PLAINTEXT:PLAINTEXT,SSL:SSL,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_SSL:SASL_SSL
# The number of threads handling network requests
num.network.threads=3
# The number of threads doing disk I/O
num.io.threads=8
# The send buffer (SO_SNDBUF) used by the socket server
socket.send.buffer.bytes=102400
# The receive buffer (SO_RCVBUF) used by the socket server
socket.receive.buffer.bytes=102400
# The maximum size of a request that the socket server will accept (protection against OOM)
socket.request.max.bytes=104857600
############################# Log Basics #############################
# A comma seperated list of directories under which to store log files
log.dirs=/tmp/kafka-logs
# The default number of log partitions per topic. More partitions allow greater
# parallelism for consumption, but this will also result in more files across
# the brokers.
num.partitions=1
# The number of threads per data directory to be used for log recovery at startup and flushing at shutdown.
# This value is recommended to be increased for installations with data dirs located in RAID array.
num.recovery.threads.per.data.dir=1
############################# Log Flush Policy #############################
# Messages are immediately written to the filesystem but by default we only fsync() to sync
# the OS cache lazily. The following configurations control the flush of data to disk.
# There are a few important trade-offs here:
# 1. Durability: Unflushed data may be lost if you are not using replication.
# 2. Latency: Very large flush intervals may lead to latency spikes when the flush does occur as there will be a lot of data to flush.
# 3. Throughput: The flush is generally the most expensive operation, and a small flush interval may lead to exceessive seeks.
# The settings below allow one to configure the flush policy to flush data after a period of time or
# every N messages (or both). This can be done globally and overridden on a per-topic basis.
# The number of messages to accept before forcing a flush of data to disk
#log.flush.interval.messages=10000
# The maximum amount of time a message can sit in a log before we force a flush
#log.flush.interval.ms=1000
############################# Log Retention Policy #############################
# The following configurations control the disposal of log segments. The policy can
# be set to delete segments after a period of time, or after a given size has accumulated.
# A segment will be deleted whenever *either* of these criteria are met. Deletion always happens
# from the end of the log.
# The minimum age of a log file to be eligible for deletion due to age
log.retention.hours=168
# A size-based retention policy for logs. Segments are pruned from the log as long as the remaining
# segments don't drop below log.retention.bytes. Functions independently of log.retention.hours.
#log.retention.bytes=1073741824
# The maximum size of a log segment file. When this size is reached a new log segment will be created.
log.segment.bytes=1073741824
# The interval at which log segments are checked to see if they can be deleted according
# to the retention policies
log.retention.check.interval.ms=300000
############################# Zookeeper #############################
# Zookeeper connection string (see zookeeper docs for details).
# This is a comma separated host:port pairs, each corresponding to a zk
# server. e.g. "<IP_ADDRESS>:3000,<IP_ADDRESS>:3001,<IP_ADDRESS>:3002".
# You can also append an optional chroot string to the urls to specify the
# root directory for all kafka znodes.
zookeeper.connect=<IP_ADDRESS>:2181
# Timeout in ms for connecting to zookeeper
zookeeper.connection.timeout.ms=6000
启动kafka服务
bin/kafka-server-start.sh config/server.properties
创建topic
[root@centos kafka]# bin/kafka-topics.sh --create --zookeeper <IP_ADDRESS>:2181 --replication-factor 1 --partitions 1 --topic my_topic_1
WARNING: Due to limitations in metric names, topics with a period ('.') or underscore ('_') could collide. To avoid issues it is best to use either, but not both.
Created topic "my_topic_1".
查看创建的topic
[root@centos kafka]# bin/kafka-topics.sh --list --zookeeper <IP_ADDRESS>:2181
__consumer_offsets
my_topic_1
[root@centos kafka]#
启动消费者
[root@centos kafka]# bin/kafka-console-consumer.sh --bootstrap-server <IP_ADDRESS>:9092 --topic my_topic_1 --from-beginning
启动生产者
bin/kafka-console-producer.sh --broker-list <IP_ADDRESS>:9092 --topic my_topic_1
4. kafka 集群
broker划分
| broker | broker.id | 节点 | ip |
|---|---|---|---|
| broker0 | 0 | node1 | <IP_ADDRESS> |
| broker1 | 1 | node2 | <IP_ADDRESS> |
| broker2 | 2 | node3 | <IP_ADDRESS> |
集群配置和简单，只要在各个broker上配置好如上单机版的配置，在此基础上分配好broker.id即可，broker.id是每一个broker的表示，同一集群不可重复。


| ${value}% Chance to Fumble attacks over ${duration} Second(s) | min: 15.0% Chance to Fumble attacks over min: 5.0 Second(s) |
| ${value}% Slowed over ${duration} Second(s) | min: 10.0% Slowed over min: 5.0 Second(s) |
| ${value}% reduced Offensive Ability over ${duration} Second(s) | min: 10.0% reduced Offensive Ability over min: 5.0 Second(s) |
| +${value}% Total Damage | -10 |
| MaxLevel | 1 |
| UltimateLevel | 1 |


Filtering Security Roles by Role Group
How to filter the security roles displayed in the Security Roles module. You can choose to view all roles, global roles or roles belonging to a role group . Note: One or more role groups must already exist to enable the filter drop down list.
- Navigate to Admin > Security Roles - OR - Go to a Security Roles module.
- At Filter By Role Group, select one of the following options from the drop down list:
- < All Roles >: Displays all roles including both roles within and not within a role group.
- < Global Roles >: Displays all roles that do not belong to a role group. The default global roles are Administrators, Registered Users, Subscribers and Translator (en-US)
- [Role Group Name]: Select the name of a role group to view each of the roles within that Role Group. For example, the below image displays a Staff role group.
Filtering by Role Group


| 1 | /* =========================================================== | |
| 2 | * JFreeChart : a free chart library for the Java(tm) platform | |
| 3 | * =========================================================== | |
| 4 | * | |
| 5 | * (C) Copyright 2000-2009, by Object Refinery Limited and Contributors. | |
| 6 | * | |
| 7 | * Project Info: http://www.jfree.org/jfreechart/index.html | |
| 8 | * | |
| 9 | * This library is free software; you can redistribute it and/or modify it | |
| 10 | * under the terms of the GNU Lesser General Public License as published by | |
| 11 | * the Free Software Foundation; either version 2.1 of the License, or | |
| 12 | * (at your option) any later version. | |
| 13 | * | |
| 14 | * This library is distributed in the hope that it will be useful, but | |
| 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
| 16 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | |
| 17 | * License for more details. | |
| 18 | * | |
| 19 | * You should have received a copy of the GNU Lesser General Public | |
| 20 | * License along with this library; if not, write to the Free Software | |
| 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, | |
| 22 | * USA. | |
| 23 | * | |
| 24 | * [Java is a trademark or registered trademark of Sun Microsystems, Inc. | |
| 25 | * in the United States and other countries.] | |
| 26 | * | |
| 27 | * -------------------- | |
| 28 | * ScatterRenderer.java | |
| 29 | * -------------------- | |
| 30 | * (C) Copyright 2007-2009, by Object Refinery Limited and Contributors. | |
| 31 | * | |
| 32 | * Original Author: David Gilbert (for Object Refinery Limited); | |
| 33 | * Contributor(s): David Forslund; | |
| 34 | * Peter Kolb (patches 2497611, 2791407); | |
| 35 | * | |
| 36 | * Changes | |
| 37 | * ------- | |
| 38 | * 08-Oct-2007 : Version 1, based on patch 1780779 by David Forslund (DG); | |
| 39 | * 11-Oct-2007 : Renamed ScatterRenderer (DG); | |
| 40 | * 17-Jun-2008 : Apply legend shape, font and paint attributes (DG); | |
| 41 | * 14-Jan-2009 : Added support for seriesVisible flags (PK); | |
| 42 | * 16-May-2009 : Patch 2791407 - findRangeBounds() override (PK); | |
| 43 | * | |
| 44 | */ | |
| 45 | ||
| 46 | package org.jfree.chart.renderer.category; | |
| 47 | ||
| 48 | import java.awt.Graphics2D; | |
| 49 | import java.awt.Paint; | |
| 50 | import java.awt.Shape; | |
| 51 | import java.awt.Stroke; | |
| 52 | import java.awt.geom.Line2D; | |
| 53 | import java.awt.geom.Rectangle2D; | |
| 54 | import java.io.IOException; | |
| 55 | import java.io.ObjectInputStream; | |
| 56 | import java.io.ObjectOutputStream; | |
| 57 | import java.io.Serializable; | |
| 58 | import java.util.List; | |
| 59 | ||
| 60 | import org.jfree.chart.LegendItem; | |
| 61 | import org.jfree.chart.axis.CategoryAxis; | |
| 62 | import org.jfree.chart.axis.ValueAxis; | |
| 63 | import org.jfree.chart.event.RendererChangeEvent; | |
| 64 | import org.jfree.chart.plot.CategoryPlot; | |
| 65 | import org.jfree.chart.plot.PlotOrientation; | |
| 66 | import org.jfree.chart.util.BooleanList; | |
| 67 | import org.jfree.chart.util.ObjectUtilities; | |
| 68 | import org.jfree.chart.util.PublicCloneable; | |
| 69 | import org.jfree.chart.util.ShapeUtilities; | |
| 70 | import org.jfree.data.Range; | |
| 71 | import org.jfree.data.category.CategoryDataset; | |
| 72 | import org.jfree.data.statistics.MultiValueCategoryDataset; | |
| 73 | ||
| 74 | /** | |
| 75 | * A renderer that handles the multiple values from a | |
| 76 | * {@link MultiValueCategoryDataset} by plotting a shape for each value for | |
| 77 | * each given item in the dataset. The example shown here is generated by | |
| 78 | * the ScatterRendererDemo1.java program included in the | |
| 79 | * JFreeChart Demo Collection: | |
| 80 | *

 | |
| 81 | *  | |
| 83 | * | |
| 84 | * @since 1.0.7 | |
| 85 | */ | |
| 86 | public class ScatterRenderer extends AbstractCategoryItemRenderer | |
| 87 | implements Cloneable, PublicCloneable, Serializable { | |
| 88 | ||
| 89 | /** | |
| 90 | * A table of flags that control (per series) whether or not shapes are | |
| 91 | * filled. | |
| 92 | */ | |
| 93 | private BooleanList seriesShapesFilled; | |
| 94 | ||
| 95 | /** | |
| 96 | * The default value returned by the getShapeFilled() method. | |
| 97 | */ | |
| 98 | private boolean baseShapesFilled; | |
| 99 | ||
| 100 | /** | |
| 101 | * A flag that controls whether the fill paint is used for filling | |
| 102 | * shapes. | |
| 103 | */ | |
| 104 | private boolean useFillPaint; | |
| 105 | ||
| 106 | /** | |
| 107 | * A flag that controls whether outlines are drawn for shapes. | |
| 108 | */ | |
| 109 | private boolean drawOutlines; | |
| 110 | ||
| 111 | /** | |
| 112 | * A flag that controls whether the outline paint is used for drawing shape | |
| 113 | * outlines - if not, the regular series paint is used. | |
| 114 | */ | |
| 115 | private boolean useOutlinePaint; | |
| 116 | ||
| 117 | /** | |
| 118 | * A flag that controls whether or not the x-position for each item is | |
| 119 | * offset within the category according to the series. | |
| 120 | */ | |
| 121 | private boolean useSeriesOffset; | |
| 122 | ||
| 123 | /** | |
| 124 | * The item margin used for series offsetting - this allows the positioning | |
| 125 | * to match the bar positions of the {@link BarRenderer} class. | |
| 126 | */ | |
| 127 | private double itemMargin; | |
| 128 | ||
| 129 | /** | |
| 130 | * Constructs a new renderer. | |
| 131 | */ | |
| 132 | public ScatterRenderer() { | |
| 133 | this.seriesShapesFilled = new BooleanList(); | |
| 134 | this.baseShapesFilled = true; | |
| 135 | this.useFillPaint = false; | |
| 136 | this.drawOutlines = false; | |
| 137 | this.useOutlinePaint = false; | |
| 138 | this.useSeriesOffset = true; | |
| 139 | this.itemMargin = 0.20; | |
| 140 | } | |
| 141 | ||
| 142 | /** | |
| 143 | * Returns the flag that controls whether or not the x-position for each | |
| 144 | * data item is offset within the category according to the series. | |
| 145 | * | |
| 146 | * @return A boolean. | |
| 147 | * | |
| 148 | * @see #setUseSeriesOffset(boolean) | |
| 149 | */ | |
| 150 | public boolean getUseSeriesOffset() { | |
| 151 |
1
1. getUseSeriesOffset : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return this.useSeriesOffset; |
| 152 | } | |
| 153 | ||
| 154 | /** | |
| 155 | * Sets the flag that controls whether or not the x-position for each | |
| 156 | * data item is offset within its category according to the series, and | |
| 157 | * sends a {@link RendererChangeEvent} to all registered listeners. | |
| 158 | * | |
| 159 | * @param offset the offset. | |
| 160 | * | |
| 161 | * @see #getUseSeriesOffset() | |
| 162 | */ | |
| 163 | public void setUseSeriesOffset(boolean offset) { | |
| 164 | this.useSeriesOffset = offset; | |
| 165 |
1
1. setUseSeriesOffset : removed call to org/jfree/chart/renderer/category/ScatterRenderer::fireChangeEvent → SURVIVED |
fireChangeEvent(); |
| 166 | } | |
| 167 | ||
| 168 | /** | |
| 169 | * Returns the item margin, which is the gap between items within a | |
| 170 | * category (expressed as a percentage of the overall category width). | |
| 171 | * This can be used to match the offset alignment with the bars drawn by | |
| 172 | * a {@link BarRenderer}). | |
| 173 | * | |
| 174 | * @return The item margin. | |
| 175 | * | |
| 176 | * @see #setItemMargin(double) | |
| 177 | * @see #getUseSeriesOffset() | |
| 178 | */ | |
| 179 | public double getItemMargin() { | |
| 180 |
1
1. getItemMargin : replaced return of double value with -(x + 1) for org/jfree/chart/renderer/category/ScatterRenderer::getItemMargin → NO_COVERAGE |
return this.itemMargin; |
| 181 | } | |
| 182 | ||
| 183 | /** | |
| 184 | * Sets the item margin, which is the gap between items within a category | |
| 185 | * (expressed as a percentage of the overall category width), and sends | |
| 186 | * a {@link RendererChangeEvent} to all registered listeners. | |
| 187 | * | |
| 188 | * @param margin the margin (0.0 <= margin < 1.0). | |
| 189 | * | |
| 190 | * @see #getItemMargin() | |
| 191 | * @see #getUseSeriesOffset() | |
| 192 | */ | |
| 193 | public void setItemMargin(double margin) { | |
| 194 |
4
1. setItemMargin : changed conditional boundary → NO_COVERAGE 2. setItemMargin : changed conditional boundary → NO_COVERAGE 3. setItemMargin : negated conditional → NO_COVERAGE 4. setItemMargin : negated conditional → NO_COVERAGE |
if (margin < 0.0 || margin >= 1.0) { |
| 195 | throw new IllegalArgumentException("Requires 0.0 <= margin < 1.0."); | |
| 196 | } | |
| 197 | this.itemMargin = margin; | |
| 198 |
1
1. setItemMargin : removed call to org/jfree/chart/renderer/category/ScatterRenderer::fireChangeEvent → NO_COVERAGE |
fireChangeEvent(); |
| 199 | } | |
| 200 | ||
| 201 | /** | |
| 202 | * Returns true if outlines should be drawn for shapes, and | |
| 203 | * false otherwise. | |
| 204 | * | |
| 205 | * @return A boolean. | |
| 206 | * | |
| 207 | * @see #setDrawOutlines(boolean) | |
| 208 | */ | |
| 209 | public boolean getDrawOutlines() { | |
| 210 |
1
1. getDrawOutlines : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return this.drawOutlines; |
| 211 | } | |
| 212 | ||
| 213 | /** | |
| 214 | * Sets the flag that controls whether outlines are drawn for | |
| 215 | * shapes, and sends a {@link RendererChangeEvent} to all registered | |
| 216 | * listeners. | |
| 217 | *
 | |
| 218 | * In some cases, shapes look better if they do NOT have an outline, but | |
| 219 | * this flag allows you to set your own preference. | |
| 220 | * | |
| 221 | * @param flag the flag. | |
| 222 | * | |
| 223 | * @see #getDrawOutlines() | |
| 224 | */ | |
| 225 | public void setDrawOutlines(boolean flag) { | |
| 226 | this.drawOutlines = flag; | |
| 227 |
1
1. setDrawOutlines : removed call to org/jfree/chart/renderer/category/ScatterRenderer::fireChangeEvent → SURVIVED |
fireChangeEvent(); |
| 228 | } | |
| 229 | ||
| 230 | /** | |
| 231 | * Returns the flag that controls whether the outline paint is used for | |
| 232 | * shape outlines. If not, the regular series paint is used. | |
| 233 | * | |
| 234 | * @return A boolean. | |
| 235 | * | |
| 236 | * @see #setUseOutlinePaint(boolean) | |
| 237 | */ | |
| 238 | public boolean getUseOutlinePaint() { | |
| 239 |
1
1. getUseOutlinePaint : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return this.useOutlinePaint; |
| 240 | } | |
| 241 | ||
| 242 | /** | |
| 243 | * Sets the flag that controls whether the outline paint is used for shape | |
| 244 | * outlines, and sends a {@link RendererChangeEvent} to all registered | |
| 245 | * listeners. | |
| 246 | * | |
| 247 | * @param use the flag. | |
| 248 | * | |
| 249 | * @see #getUseOutlinePaint() | |
| 250 | */ | |
| 251 | public void setUseOutlinePaint(boolean use) { | |
| 252 | this.useOutlinePaint = use; | |
| 253 |
1
1. setUseOutlinePaint : removed call to org/jfree/chart/renderer/category/ScatterRenderer::fireChangeEvent → SURVIVED |
fireChangeEvent(); |
| 254 | } | |
| 255 | ||
| 256 | // SHAPES FILLED | |
| 257 | ||
| 258 | /** | |
| 259 | * Returns the flag used to control whether or not the shape for an item | |
| 260 | * is filled. The default implementation passes control to the | |
| 261 | * getSeriesShapesFilled method. You can override this method | |
| 262 | * if you require different behaviour. | |
| 263 | * | |
| 264 | * @param series the series index (zero-based). | |
| 265 | * @param item the item index (zero-based). | |
| 266 | * @return A boolean. | |
| 267 | */ | |
| 268 | public boolean getItemShapeFilled(int series, int item) { | |
| 269 |
1
1. getItemShapeFilled : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return getSeriesShapesFilled(series); |
| 270 | } | |
| 271 | ||
| 272 | /** | |
| 273 | * Returns the flag used to control whether or not the shapes for a series | |
| 274 | * are filled. | |
| 275 | * | |
| 276 | * @param series the series index (zero-based). | |
| 277 | * @return A boolean. | |
| 278 | */ | |
| 279 | public boolean getSeriesShapesFilled(int series) { | |
| 280 | Boolean flag = this.seriesShapesFilled.getBoolean(series); | |
| 281 |
1
1. getSeriesShapesFilled : negated conditional → NO_COVERAGE |
if (flag != null) { |
| 282 |
1
1. getSeriesShapesFilled : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return flag.booleanValue(); |
| 283 | } | |
| 284 | else { | |
| 285 |
1
1. getSeriesShapesFilled : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return this.baseShapesFilled; |
| 286 | } | |
| 287 | ||
| 288 | } | |
| 289 | ||
| 290 | /** | |
| 291 | * Sets the 'shapes filled' flag for a series and sends a | |
| 292 | * {@link RendererChangeEvent} to all registered listeners. | |
| 293 | * | |
| 294 | * @param series the series index (zero-based). | |
| 295 | * @param filled the flag. | |
| 296 | */ | |
| 297 | public void setSeriesShapesFilled(int series, Boolean filled) { | |
| 298 |
1
1. setSeriesShapesFilled : removed call to org/jfree/chart/util/BooleanList::setBoolean → NO_COVERAGE |
this.seriesShapesFilled.setBoolean(series, filled); |
| 299 |
1
1. setSeriesShapesFilled : removed call to org/jfree/chart/renderer/category/ScatterRenderer::fireChangeEvent → NO_COVERAGE |
fireChangeEvent(); |
| 300 | } | |
| 301 | ||
| 302 | /** | |
| 303 | * Sets the 'shapes filled' flag for a series and sends a | |
| 304 | * {@link RendererChangeEvent} to all registered listeners. | |
| 305 | * | |
| 306 | * @param series the series index (zero-based). | |
| 307 | * @param filled the flag. | |
| 308 | */ | |
| 309 | public void setSeriesShapesFilled(int series, boolean filled) { | |
| 310 |
1
1. setSeriesShapesFilled : removed call to org/jfree/chart/util/BooleanList::setBoolean → KILLED |
this.seriesShapesFilled.setBoolean(series, Boolean.valueOf(filled)); |
| 311 |
1
1. setSeriesShapesFilled : removed call to org/jfree/chart/renderer/category/ScatterRenderer::fireChangeEvent → SURVIVED |
fireChangeEvent(); |
| 312 | } | |
| 313 | ||
| 314 | /** | |
| 315 | * Returns the base 'shape filled' attribute. | |
| 316 | * | |
| 317 | * @return The base flag. | |
| 318 | */ | |
| 319 | public boolean getBaseShapesFilled() { | |
| 320 |
1
1. getBaseShapesFilled : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return this.baseShapesFilled; |
| 321 | } | |
| 322 | ||
| 323 | /** | |
| 324 | * Sets the base 'shapes filled' flag and sends a | |
| 325 | * {@link RendererChangeEvent} to all registered listeners. | |
| 326 | * | |
| 327 | * @param flag the flag. | |
| 328 | */ | |
| 329 | public void setBaseShapesFilled(boolean flag) { | |
| 330 | this.baseShapesFilled = flag; | |
| 331 |
1
1. setBaseShapesFilled : removed call to org/jfree/chart/renderer/category/ScatterRenderer::fireChangeEvent → SURVIVED |
fireChangeEvent(); |
| 332 | } | |
| 333 | ||
| 334 | /** | |
| 335 | * Returns true if the renderer should use the fill paint | |
| 336 | * setting to fill shapes, and false if it should just | |
| 337 | * use the regular paint. | |
| 338 | * | |
| 339 | * @return A boolean. | |
| 340 | */ | |
| 341 | public boolean getUseFillPaint() { | |
| 342 |
1
1. getUseFillPaint : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return this.useFillPaint; |
| 343 | } | |
| 344 | ||
| 345 | /** | |
| 346 | * Sets the flag that controls whether the fill paint is used to fill | |
| 347 | * shapes, and sends a {@link RendererChangeEvent} to all | |
| 348 | * registered listeners. | |
| 349 | * | |
| 350 | * @param flag the flag. | |
| 351 | */ | |
| 352 | public void setUseFillPaint(boolean flag) { | |
| 353 | this.useFillPaint = flag; | |
| 354 |
1
1. setUseFillPaint : removed call to org/jfree/chart/renderer/category/ScatterRenderer::fireChangeEvent → SURVIVED |
fireChangeEvent(); |
| 355 | } | |
| 356 | ||
| 357 | /** | |
| 358 | * Returns the range of values the renderer requires to display all the | |
| 359 | * items from the specified dataset. This takes into account the range | |
| 360 | * between the min/max values, possibly ignoring invisible series. | |
| 361 | * | |
| 362 | * @param dataset the dataset (null permitted). | |
| 363 | * | |
| 364 | * @return The range (or null if the dataset is | |
| 365 | * null or empty). | |
| 366 | */ | |
| 367 | public Range findRangeBounds(CategoryDataset dataset) { | |
| 368 |
1
1. findRangeBounds : mutated return of Object value for org/jfree/chart/renderer/category/ScatterRenderer::findRangeBounds to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return findRangeBounds(dataset, true); |
| 369 | } | |
| 370 | ||
| 371 | /** | |
| 372 | * Draw a single data item. | |
| 373 | * | |
| 374 | * @param g2 the graphics device. | |
| 375 | * @param state the renderer state. | |
| 376 | * @param dataArea the area in which the data is drawn. | |
| 377 | * @param plot the plot. | |
| 378 | * @param domainAxis the domain axis. | |
| 379 | * @param rangeAxis the range axis. | |
| 380 | * @param dataset the dataset. | |
| 381 | * @param row the row index (zero-based). | |
| 382 | * @param column the column index (zero-based). | |
| 383 | * @param selected is the item selected? | |
| 384 | * @param pass the pass index. | |
| 385 | */ | |
| 386 | public void drawItem(Graphics2D g2, CategoryItemRendererState state, | |
| 387 | Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, | |
| 388 | ValueAxis rangeAxis, CategoryDataset dataset, int row, int column, | |
| 389 | boolean selected, int pass) { | |
| 390 | ||
| 391 | // do nothing if item is not visible | |
| 392 |
1
1. drawItem : negated conditional → NO_COVERAGE |
if (!getItemVisible(row, column)) { |
| 393 | return; | |
| 394 | } | |
| 395 | int visibleRow = state.getVisibleSeriesIndex(row); | |
| 396 |
2
1. drawItem : changed conditional boundary → NO_COVERAGE 2. drawItem : negated conditional → NO_COVERAGE |
if (visibleRow < 0) { |
| 397 | return; | |
| 398 | } | |
| 399 | int visibleRowCount = state.getVisibleSeriesCount(); | |
| 400 | ||
| 401 | PlotOrientation orientation = plot.getOrientation(); | |
| 402 | ||
| 403 | MultiValueCategoryDataset d = (MultiValueCategoryDataset) dataset; | |
| 404 | List values = d.getValues(row, column); | |
| 405 |
1
1. drawItem : negated conditional → NO_COVERAGE |
if (values == null) { |
| 406 | return; | |
| 407 | } | |
| 408 | int valueCount = values.size(); | |
| 409 |
3
1. drawItem : changed conditional boundary → NO_COVERAGE 2. drawItem : Changed increment from 1 to -1 → NO_COVERAGE 3. drawItem : negated conditional → NO_COVERAGE |
for (int i = 0; i < valueCount; i++) { |
| 410 | // current data point... | |
| 411 | double x1; | |
| 412 |
1
1. drawItem : negated conditional → NO_COVERAGE |
if (this.useSeriesOffset) { |
| 413 | x1 = domainAxis.getCategorySeriesMiddle(column, | |
| 414 | dataset.getColumnCount(), visibleRow, visibleRowCount, | |
| 415 | this.itemMargin, dataArea, plot.getDomainAxisEdge()); | |
| 416 | } | |
| 417 | else { | |
| 418 | x1 = domainAxis.getCategoryMiddle(column, getColumnCount(), | |
| 419 | dataArea, plot.getDomainAxisEdge()); | |
| 420 | } | |
| 421 | Number n = (Number) values.get(i); | |
| 422 | double value = n.doubleValue(); | |
| 423 | double y1 = rangeAxis.valueToJava2D(value, dataArea, | |
| 424 | plot.getRangeAxisEdge()); | |
| 425 | ||
| 426 | Shape shape = getItemShape(row, column, selected); | |
| 427 |
1
1. drawItem : negated conditional → NO_COVERAGE |
if (orientation == PlotOrientation.HORIZONTAL) { |
| 428 | shape = ShapeUtilities.createTranslatedShape(shape, y1, x1); | |
| 429 | } | |
| 430 |
1
1. drawItem : negated conditional → NO_COVERAGE |
else if (orientation == PlotOrientation.VERTICAL) { |
| 431 | shape = ShapeUtilities.createTranslatedShape(shape, x1, y1); | |
| 432 | } | |
| 433 |
1
1. drawItem : negated conditional → NO_COVERAGE |
if (getItemShapeFilled(row, column)) { |
| 434 |
1
1. drawItem : negated conditional → NO_COVERAGE |
if (this.useFillPaint) { |
| 435 |
1
1. drawItem : removed call to java/awt/Graphics2D::setPaint → NO_COVERAGE |
g2.setPaint(getItemFillPaint(row, column, selected)); |
| 436 | } | |
| 437 | else { | |
| 438 |
1
1. drawItem : removed call to java/awt/Graphics2D::setPaint → NO_COVERAGE |
g2.setPaint(getItemPaint(row, column, selected)); |
| 439 | } | |
| 440 |
1
1. drawItem : removed call to java/awt/Graphics2D::fill → NO_COVERAGE |
g2.fill(shape); |
| 441 | } | |
| 442 |
1
1. drawItem : negated conditional → NO_COVERAGE |
if (this.drawOutlines) { |
| 443 |
1
1. drawItem : negated conditional → NO_COVERAGE |
if (this.useOutlinePaint) { |
| 444 |
1
1. drawItem : removed call to java/awt/Graphics2D::setPaint → NO_COVERAGE |
g2.setPaint(getItemOutlinePaint(row, column, selected)); |
| 445 | } | |
| 446 | else { | |
| 447 |
1
1. drawItem : removed call to java/awt/Graphics2D::setPaint → NO_COVERAGE |
g2.setPaint(getItemPaint(row, column, selected)); |
| 448 | } | |
| 449 |
1
1. drawItem : removed call to java/awt/Graphics2D::setStroke → NO_COVERAGE |
g2.setStroke(getItemOutlineStroke(row, column, selected)); |
| 450 |
1
1. drawItem : removed call to java/awt/Graphics2D::draw → NO_COVERAGE |
g2.draw(shape); |
| 451 | } | |
| 452 | } | |
| 453 | ||
| 454 | } | |
| 455 | ||
| 456 | /** | |
| 457 | * Returns a legend item for a series. | |
| 458 | * | |
| 459 | * @param datasetIndex the dataset index (zero-based). | |
| 460 | * @param series the series index (zero-based). | |
| 461 | * | |
| 462 | * @return The legend item. | |
| 463 | */ | |
| 464 | public LegendItem getLegendItem(int datasetIndex, int series) { | |
| 465 | ||
| 466 | CategoryPlot cp = getPlot(); | |
| 467 |
1
1. getLegendItem : negated conditional → NO_COVERAGE |
if (cp == null) { |
| 468 |
1
1. getLegendItem : mutated return of Object value for org/jfree/chart/renderer/category/ScatterRenderer::getLegendItem to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return null; |
| 469 | } | |
| 470 | ||
| 471 |
2
1. getLegendItem : negated conditional → NO_COVERAGE 2. getLegendItem : negated conditional → NO_COVERAGE |
if (isSeriesVisible(series) && isSeriesVisibleInLegend(series)) { |
| 472 | CategoryDataset dataset = cp.getDataset(datasetIndex); | |
| 473 | String label = getLegendItemLabelGenerator().generateLabel( | |
| 474 | dataset, series); | |
| 475 | String description = label; | |
| 476 | String toolTipText = null; | |
| 477 |
1
1. getLegendItem : negated conditional → NO_COVERAGE |
if (getLegendItemToolTipGenerator() != null) { |
| 478 | toolTipText = getLegendItemToolTipGenerator().generateLabel( | |
| 479 | dataset, series); | |
| 480 | } | |
| 481 | String urlText = null; | |
| 482 |
1
1. getLegendItem : negated conditional → NO_COVERAGE |
if (getLegendItemURLGenerator() != null) { |
| 483 | urlText = getLegendItemURLGenerator().generateLabel( | |
| 484 | dataset, series); | |
| 485 | } | |
| 486 | Shape shape = lookupLegendShape(series); | |
| 487 | Paint paint = lookupSeriesPaint(series); | |
| 488 |
1
1. getLegendItem : negated conditional → NO_COVERAGE |
Paint fillPaint = (this.useFillPaint |
| 489 | ? getItemFillPaint(series, 0, false) : paint); | |
| 490 | boolean shapeOutlineVisible = this.drawOutlines; | |
| 491 |
1
1. getLegendItem : negated conditional → NO_COVERAGE |
Paint outlinePaint = (this.useOutlinePaint |
| 492 | ? getItemOutlinePaint(series, 0, false) : paint); | |
| 493 | Stroke outlineStroke = lookupSeriesOutlineStroke(series); | |
| 494 | LegendItem result = new LegendItem(label, description, toolTipText, | |
| 495 | urlText, true, shape, getItemShapeFilled(series, 0), | |
| 496 | fillPaint, shapeOutlineVisible, outlinePaint, outlineStroke, | |
| 497 | false, new Line2D.Double(-7.0, 0.0, 7.0, 0.0), | |
| 498 | getItemStroke(series, 0, false), getItemPaint(series, 0, | |
| 499 | false)); | |
| 500 |
1
1. getLegendItem : removed call to org/jfree/chart/LegendItem::setLabelFont → NO_COVERAGE |
result.setLabelFont(lookupLegendTextFont(series)); |
| 501 | Paint labelPaint = lookupLegendTextPaint(series); | |
| 502 |
1
1. getLegendItem : negated conditional → NO_COVERAGE |
if (labelPaint != null) { |
| 503 |
1
1. getLegendItem : removed call to org/jfree/chart/LegendItem::setLabelPaint → NO_COVERAGE |
result.setLabelPaint(labelPaint); |
| 504 | } | |
| 505 |
1
1. getLegendItem : removed call to org/jfree/chart/LegendItem::setDataset → NO_COVERAGE |
result.setDataset(dataset); |
| 506 |
1
1. getLegendItem : removed call to org/jfree/chart/LegendItem::setDatasetIndex → NO_COVERAGE |
result.setDatasetIndex(datasetIndex); |
| 507 |
1
1. getLegendItem : removed call to org/jfree/chart/LegendItem::setSeriesKey → NO_COVERAGE |
result.setSeriesKey(dataset.getRowKey(series)); |
| 508 |
1
1. getLegendItem : removed call to org/jfree/chart/LegendItem::setSeriesIndex → NO_COVERAGE |
result.setSeriesIndex(series); |
| 509 |
1
1. getLegendItem : mutated return of Object value for org/jfree/chart/renderer/category/ScatterRenderer::getLegendItem to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return result; |
| 510 | } | |
| 511 |
1
1. getLegendItem : mutated return of Object value for org/jfree/chart/renderer/category/ScatterRenderer::getLegendItem to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return null; |
| 512 | ||
| 513 | } | |
| 514 | ||
| 515 | /** | |
| 516 | * Tests this renderer for equality with an arbitrary object. | |
| 517 | * | |
| 518 | * @param obj the object (null permitted). | |
| 519 | * @return A boolean. | |
| 520 | */ | |
| 521 | public boolean equals(Object obj) { | |
| 522 |
1
1. equals : negated conditional → KILLED |
if (obj == this) { |
| 523 |
1
1. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return true; |
| 524 | } | |
| 525 |
1
1. equals : negated conditional → KILLED |
if (!(obj instanceof ScatterRenderer)) { |
| 526 |
1
1. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return false; |
| 527 | } | |
| 528 | ScatterRenderer that = (ScatterRenderer) obj; | |
| 529 |
1
1. equals : negated conditional → KILLED |
if (!ObjectUtilities.equal(this.seriesShapesFilled, |
| 530 | that.seriesShapesFilled)) { | |
| 531 |
1
1. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED |
return false; |
| 532 | } | |
| 533 |
1
1. equals : negated conditional → KILLED |
if (this.baseShapesFilled != that.baseShapesFilled) { |
| 534 |
1
1. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED |
return false; |
| 535 | } | |
| 536 |
1
1. equals : negated conditional → KILLED |
if (this.useFillPaint != that.useFillPaint) { |
| 537 |
1
1. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED |
return false; |
| 538 | } | |
| 539 |
1
1. equals : negated conditional → KILLED |
if (this.drawOutlines != that.drawOutlines) { |
| 540 |
1
1. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED |
return false; |
| 541 | } | |
| 542 |
1
1. equals : negated conditional → KILLED |
if (this.useOutlinePaint != that.useOutlinePaint) { |
| 543 |
1
1. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED |
return false; |
| 544 | } | |
| 545 |
1
1. equals : negated conditional → KILLED |
if (this.useSeriesOffset != that.useSeriesOffset) { |
| 546 |
1
1. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED |
return false; |
| 547 | } | |
| 548 |
1
1. equals : negated conditional → KILLED |
if (this.itemMargin != that.itemMargin) { |
| 549 |
1
1. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return false; |
| 550 | } | |
| 551 |
1
1. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED |
return super.equals(obj); |
| 552 | } | |
| 553 | ||
| 554 | /** | |
| 555 | * Returns an independent copy of the renderer. | |
| 556 | * | |
| 557 | * @return A clone. | |
| 558 | * | |
| 559 | * @throws CloneNotSupportedException should not happen. | |
| 560 | */ | |
| 561 | public Object clone() throws CloneNotSupportedException { | |
| 562 | ScatterRenderer clone = (ScatterRenderer) super.clone(); | |
| 563 | clone.seriesShapesFilled | |
| 564 | = (BooleanList) this.seriesShapesFilled.clone(); | |
| 565 |
1
1. clone : mutated return of Object value for org/jfree/chart/renderer/category/ScatterRenderer::clone to ( if (x != null) null else throw new RuntimeException ) → KILLED |
return clone; |
| 566 | } | |
| 567 | ||
| 568 | /** | |
| 569 | * Provides serialization support. | |
| 570 | * | |
| 571 | * @param stream the output stream. | |
| 572 | * @throws java.io.IOException if there is an I/O error. | |
| 573 | */ | |
| 574 | private void writeObject(ObjectOutputStream stream) throws IOException { | |
| 575 |
1
1. writeObject : removed call to java/io/ObjectOutputStream::defaultWriteObject → KILLED |
stream.defaultWriteObject(); |
| 576 | ||
| 577 | } | |
| 578 | ||
| 579 | /** | |
| 580 | * Provides serialization support. | |
| 581 | * | |
| 582 | * @param stream the input stream. | |
| 583 | * @throws java.io.IOException if there is an I/O error. | |
| 584 | * @throws ClassNotFoundException if there is a classpath problem. | |
| 585 | */ | |
| 586 | private void readObject(ObjectInputStream stream) | |
| 587 | throws IOException, ClassNotFoundException { | |
| 588 |
1
1. readObject : removed call to java/io/ObjectInputStream::defaultReadObject → KILLED |
stream.defaultReadObject(); |
| 589 | ||
| 590 | } | |
| 591 | ||
| 592 | } | |
Mutations | ||
| 151 |
1.1 |
|
| 165 |
1.1 |
|
| 180 |
1.1 |
|
| 194 |
1.1 2.2 3.3 4.4 |
|
| 198 |
1.1 |
|
| 210 |
1.1 |
|
| 227 |
1.1 |
|
| 239 |
1.1 |
|
| 253 |
1.1 |
|
| 269 |
1.1 |
|
| 281 |
1.1 |
|
| 282 |
1.1 |
|
| 285 |
1.1 |
|
| 298 |
1.1 |
|
| 299 |
1.1 |
|
| 310 |
1.1 |
|
| 311 |
1.1 |
|
| 320 |
1.1 |
|
| 331 |
1.1 |
|
| 342 |
1.1 |
|
| 354 |
1.1 |
|
| 368 |
1.1 |
|
| 392 |
1.1 |
|
| 396 |
1.1 2.2 |
|
| 405 |
1.1 |
|
| 409 |
1.1 2.2 3.3 |
|
| 412 |
1.1 |
|
| 427 |
1.1 |
|
| 430 |
1.1 |
|
| 433 |
1.1 |
|
| 434 |
1.1 |
|
| 435 |
1.1 |
|
| 438 |
1.1 |
|
| 440 |
1.1 |
|
| 442 |
1.1 |
|
| 443 |
1.1 |
|
| 444 |
1.1 |
|
| 447 |
1.1 |
|
| 449 |
1.1 |
|
| 450 |
1.1 |
|
| 467 |
1.1 |
|
| 468 |
1.1 |
|
| 471 |
1.1 2.2 |
|
| 477 |
1.1 |
|
| 482 |
1.1 |
|
| 488 |
1.1 |
|
| 491 |
1.1 |
|
| 500 |
1.1 |
|
| 502 |
1.1 |
|
| 503 |
1.1 |
|
| 505 |
1.1 |
|
| 506 |
1.1 |
|
| 507 |
1.1 |
|
| 508 |
1.1 |
|
| 509 |
1.1 |
|
| 511 |
1.1 |
|
| 522 |
1.1 |
|
| 523 |
1.1 |
|
| 525 |
1.1 |
|
| 526 |
1.1 |
|
| 529 |
1.1 |
|
| 531 |
1.1 |
|
| 533 |
1.1 |
|
| 534 |
1.1 |
|
| 536 |
1.1 |
|
| 537 |
1.1 |
|
| 539 |
1.1 |
|
| 540 |
1.1 |
|
| 542 |
1.1 |
|
| 543 |
1.1 |
|
| 545 |
1.1 |
|
| 546 |
1.1 |
|
| 548 |
1.1 |
|
| 549 |
1.1 |
|
| 551 |
1.1 |
|
| 565 |
1.1 |
|
| 575 |
1.1 |
|
| 588 |
1.1 |


--- layout: page title: About header-img: "img/about-bg.png" ---
Just a guy looking to be enlightened in the world of code.


Oceanic Exchanges brings together a consortium of cultural historians, computational linguists, literary scholars, digital curators and humanists, and computer scientists who each bring skills from previous successful projects.
Primary Contacts
- Ryan Cordell (OcEx Project Director) - Assistant Professor of English in the NULab for Texts, Maps, and Networks, Northeastern University
- Lara Rose (Assistant Project Manager) - PhD Student, Northeastern University
National Teams
Deutschland - funded by Deutsche Forschungsgemeinschaft (DFG)
- Marc Priewe (PI) - Professor of American Literature & Culture, Institute for Literary Studies (ILW), Universität Stuttgart
- Clemens Neudecker - Researcher Digital Libraries & Digital Humanities, Staatsbibliothek zu Berlin & Europeana Newspapers
- Sebastian Padó - Professor, Institute for Natural Language Processing (IMS), Universität Stuttgart
- Steffen Koch - Researcher, Institute for Visualization and Interactive Systems (VIS), Universität Stuttgart
- Martin Riedl - Postdoctoral Researcher, Institute of Natural Language Processing, Universität Stuttgart
- Jana Keck – Doctoral Researcher, American Literature & Culture, Institute for Literary Studies (ILW), Universität Stuttgart
México - funded by Consejo Nacional de Ciencia y Tecnología (CONACYT)
- Isabel Galina Russell (Co-PI) - Full-time Researcher, Universidad Nacional Autónoma de México
- Ernesto Priani Siasó (Co-PI) - Professor, Faculty of Philosophy and Letters, Universidad Nacional Autónoma de México
- Miriam Peña Pimentel - Postdoctoral Researcher, Universidad Nacional Autónoma de México
- Adan Lerma - PhD Student, Universidad Nacional Autónoma de México
- Rocío Castellanos Rueda - Postdoctoral Researcher, Universidad Nacional Autónoma de México
- Angélica Estefanía González Manzo - Student, Universidad Nacional Autónoma de México
- Laura Angélica López Méndez - Student, Universidad Nacional Autónoma de México
- Juan Manuel Rodríguez Martínez - Student, Universidad Nacional Autónoma de México
Nederland - funded by Nederlandse Organisatie voor Wetenschappelijk Onderzoek (NWO)
- Jaap Verheul (PI) - Associate Professor of Cultural History, Universiteit Utrecht
- Lorella Viola - Postdoctoral Researcher, Universiteit Utrecht
- Hanneke Takken - Postdoctoral Researcher, Universiteit Utrecht
Suomi - funded by Suomen Akatemia (AKA)
- Hannu Salmi (PI) - Academy Professor, Turun Yliopisto
- Asko Nivala - Postdoctoral Researcher, Turun Yliopisto
- Mila Oiva - Postdoctoral Researcher, Turun Yliopisto
- Otto Latva - PhD Candidate, Turun Yliopisto
United Kingdom - funded by Arts & Humanities Research Council and Economic and Social Research Council (AHRC/ESRC)
- Melodee Beals (Co-PI) - Lecturer in Digital History, Loughborough University
- Julianne Nyhan (Co-PI) - Senior Lecturer (Associate Professor) in Digital Information Studies (Department of Information Studies), University College London
- Melissa Terras - Professor of Digital Cultural Heritage in the College of Arts, Humanities, and Social Sciences & Chair, Center for Digital Cultural Heritage, University of Edinburgh
- James Hetherington - Head of Research Software Development for High-Processing Computing in Research IT Services, University College London
- Raquel Alegre - Research Software Developer for High-Processing Computing in Research IT Services, University College London
- Tessa Hauswedell - Teaching Fellow, University College London
- Roma Klapaukh - Research Software Developer for Research IT Services (High Processing Computing), University College London
- Olivia Mitchell - Post-Graduate Researcher, Loughborough University
United States of America - funded by Institute of Museum and Library Services (IMLS)
- Ryan Cordell (Co-PI) - Assistant Professor of English in the NULab for Texts, Maps, and Networks, Northeastern University
- David Smith (Co-PI) - Assistant Professor, College of Computer and Information Science, Northeastern University
- Paul Fyfe - Associate Professor of English, North Carolina State University
- Elizabeth Lorang - Associate Professor of Libraries and Humanities Librarian, University of Nebraska-Lincoln
- Leen-Kiat Soh - Associate Professor with the Department of Computer Science and Engineering, University of Nebraska-Lincoln
- Lara Rose - PhD Student, Northeastern University
- Chulwoo (Mike) Pack - PhD Student, University of Nebraska-Lincoln
- Ye Liu - PhD Student, North Carolina State University
- Jamie Parker - PhD Candidate, Northeastern University
Project Advisory Board
TBD


We design a new car from the ground up every year. The team maximizes vehicle handling by driving design off of the suspension points. Every part is 3D modeled in CAD to allow for precise geometry and packaging. Further analysis is conducted using finite element analysis to optimize strength while minimizing weight.
We build the parts that we design. Team members have the opportunity to learn more by working in a full machine shop with manual and CNC machines, rapid prototyping machines and waterjet cutters. By manufacturing precision racing parts, team members apply the “design for manufacturing” principle. Finding the balance between geometry optimization and available tools allows the team to develop a sense of what is possible and where innovation lies.
Building the car is only half of the process. Upon completion of various systems, we validate the design through component and vehicle testing. Custom electronics are used to relay data to the team that help tune the vehicle and improve the driver’s ability.
The vehicle’s handling and efficiency is drastically improved via weight reduction. MY17 weighs in at 230 kilograms withoutdriver, and has a 100kW Emrax motor that outputs 240 Nm of torque to allow the driver to reach 70 mph quicker than you can read this sentence. To reach maximum performance, the suspension uses 4-way adjustable coilovers to allow the car to sit an inch off the ground, and slick racing tires allow the driver to experience up to 1.5 G’s of lateral acceleration mid-turn.
MIT first entered the Formula SAE competition when two freshmen founded the team in 2001. Since MIT first stepped foot on the race track in 2003, the team has steadily learned more and improved its performance. From the humble beginnings of a 97th place finish in 2003 and a 41st place finish in 2004, the team used its experiences to eventually achieve a 2nd place overall at FSAE Electric in 2017.
The team is always striving for innovation and improvements. Armed with a strong cohort of young engineers, the team is engineering MY18 with the intent of preparing for a major design leap that will debut in 2019.
One of our goals this year is to predict the lap time when the car still only exists on a computer screen so that we can tune the car virtually, and arrive at the exact stiffness, weight, and power requirements that we need for the car to perform well. In order to do this we are improving our data collection by doubling the number of onboard sensors to record everything from power draw to lateral acceleration and brake temperature.
The R&D team is looking to change several steel components to carbon fiber. Carbon-reinforced materials are used extensively in motorsports, because of their incredible strength and low weight. This is all leading up to a transition to a carbon fiber half-monocoque for Model Year 19. Additionally our existing rear wheel drive setup is being rigorously tested to determine the peak performance and limiting factors in our powertrain so that we can determine how we will pursue four wheel drive on MY19.
The car is a complex machine made of many mechanical and electrical subsystems. Team members work in various engineering disciplines according to their skills or interests. This results in a diverse spread of skills from statics and fluids to microelectronics and controls.
Our car's electronics are designed with safety and reliability in mind. We build system components such as battery management and VCU logs in house to give us full control of parts selection and form factor which improved reliability and performance.
The drivetrain was designed with three significant goals in mind: lightweight, powerful, and serviceable. We moved from two motors to one Emrax 228 MV and a Drexler limited slip differential and a Unitek Bamocar D3 400/400 motor controller to accomplish this.
MATLAB analysis of smaller and lighter deep groove wheel bearings led to a wider profile for the uprights in order to maintain reasonable radial loads. Uprights themselves were 3-axis CNC machined from aircraft-grade aluminum and built with an integrated camber adjustment mechanism.
The tractive system was designed for safety, reliability, and performance. It’s powered by a custom built pack producing a peak voltage of 300V and containing 7.02 kWh of energy. The entire pack is separated into 6 polycarbonate modules that allow for quick interchanges if issues arise.
The MY17 aero package has three times the downforce of the MY16 design with only a 45% increase in total drag. This resulted from an actuated upper element and front wing’s gurney flaps on the endplates and strakes on the underside of the wing.
The annual Formula SAE electric vehicle competition was held by the Society of Automotive Engineers at the Lincoln Airpark. The team arrived in Lincoln, Nebraska having not driven through a checkered flag since 2012. In the weekend’s first dynamic event, MIT placed 5th in Acceleration. The following two events, Skid Pad and Autocross, resulted in competitive 3rd place efforts. Finishing the weekend strong, suspension lead Will Harvey (‘18) clocked the fastest EV lap of the Endurance event at 83.7 seconds before handing the car off to team captain Luis Mora (‘18), who powered the car to a strong 2nd place. With cost, business, and design scores factored in, the team placed 2nd overall in the EV category!
MY15 was the team’s first completed running electric vehicle, allowing for preliminary testing and data acquisition. It featured a newly designed aerodynamics package, the first in team history.
The two year build cycle from 2012 - 2013 was the end of a era and the start of a new adventure: the team would build an internal combustion car for the last time. The team successfully competed in the 2012 Formula SAE Michigan competition, placing 16th out of 120 teams. The team again placed in the top 5 for its fuel economy, with its ethanol fueled car, as well as top 5 for its cost report score. MY12 was also able to impress the judges with its custom intake, fully adjustable suspension, and modified 4-cylinder engine.
The team switched to a two year cycle to allow for more development and testing, which proved to be a great advantage for design and development. MIT was able to finish 8th overall in the 2010 FSAE West competition, the best in MIT’s history since its founding in 2001. The team’s highest ranking event was fuel economy, where the ethanol fueled car finished in 2nd place.


Variables in Project.meta
bake allows you to use
user defined
predefined
environment
variables in your Project.meta file. Every environment and predefined variable can be overwritten by the user. If a variable is not found at all, it will be set to an empty string (see below how to change that default behaviour).
Using variables
Variables can be used using the following syntax:
$(ABC)
The variable ABC will be substituted by its value, therefore a real life usage would look something like this:
IncludeDir "$(ABC)"
User defined variables
There are two ways to create user defined variables.
The variable is defined with the –set command line option:
User@Host:~$ bake ... --set MyVar="Hello world!"
The variable is defined directly in the Project.meta file.
Set MyVar, value: "Hello world!"
Set MyVar, cmd: "ruby calcVar.rb"
In the latter one the variable is set to the output of the command.
Predefined bake environment variables
Variable |
Description |
Example |
|---|---|---|
$(MainConfigName) |
Evaluates to the main config name |
Debug |
$(MainProjectName) |
Evaluates to the main project name |
bootloader |
$(ConfigName) |
Evaluates to the config name |
lib |
$(ProjectName) |
Evaluates to the project name |
canDriver |
$(ProjectDir) |
Evaluates to the full path of the project directory |
C:/Root/MyProject |
$(MainProjectDir) |
Evaluates to the full path of the root projec directory |
C:/Root/Main |
$(OutputDir) |
Evaluates to the full path of the output directory of the current config |
build/lib_bootloader_Debug |
$(OutputDir,projName,confName) |
Evaluates to the output dir of a specific config |
build/lib_some_Debug |
$(WorkingDir) |
Directory from which bake is called |
c:/Workspaces/Project |
$(OriginalDir) |
Directory of the containing meta file. Useful for relative paths from Adapt files. |
c:/Root/admin/adapt/coverage |
$(ArtifactName) |
Evaluates to the artifact. |
bootloader_1.0.elf |
$(ArtifactNameBase) |
Evaluates to the base artifact name (Without file exension) |
bootloader_1.0 |
$(Time) |
Evaluates to the current time |
2012-12-24 20:00:00 +0200 |
$(Hostname) |
Evaluates to the hostname |
MY_COMPUTER |
$(Uid) |
CRC32 over relative path to MainProjectDir plus MainConfigName, e.g. “../libs/utils,Debug” |
03FAB429 |
$(CPPPath) |
Evaluates to the base path of the c++ compiler |
/usr/bin |
$(CPath) |
Evaluates to the base path of the c compiler |
/usr/bin |
$(ASMPath) |
Evaluates to the base path of the assembler |
/usr/bin |
$(ArchiverPath) |
Evaluates to the base path of the archiver |
/usr/bin |
$(LinkerPath) |
Evaluates to the base path of the linker |
/usr/bin |
$(ToolchainName) |
Names of the used DefaultToolchain |
GCC |
$(/) |
Evalutes to the directory path seperator of the current platform |
Windows: \, Other: / |
$(:) |
Evaluates to the path variable seperator of the current platform |
Windows: ;, Other: : |
$(QacActive) |
Evaluates to “yes” if QAC is running (via bakeqac), otherwise “no”. |
yes, no |
Environment variables
Usually used if system dependent stuff is needed like path to a specific tool etc.
Nested variables
It is also possible to nest variables.
Example:
$(ABC$(DEF)GH)
Complex variables
bake supports three complex variables:
$(OutputDir, <project name>, <config name>)
e.g.:
$(OutputDir, MyGreatLib, Debug)
This will evaluate to the output directory of a specific configuration.
$(ProjectDir, <project name>)
This will evaluate to the directory of a specific project.
$(FilterArguments, <filterName>)
If a filter is specified, the argument of the filter is returned.
Example:
cmd: “bake … –do run=–gtest_repeat=2”
Project.meta: $(FilterArguments, –gtest_repeat)
result: 2
Mandatory variables
If a variable is not found at all, it will be set to an empty string. This can be changed to an error with a “!” sign:
$(PATH_TO_ABC!)
$(OutputDir!, application, Debug)
For convenience, the “!” can be used on every parameter (which means exactly the same as using on the first parameter).
$(OutputDir, application!, Debug)
$(OutputDir, application, Debug!)
Notes and warnings
Equal variables in the main config:
Variable |
Is equal to |
|---|---|
$(MainConfigName) |
$(ConfigName) |
$(MainProjectName) |
$(ProjectName) |
Warning
Variables in Dependency definitions are not allowed!


Python Installation Guide¶
The programming language Python has a number of packages associated with it and we recommend installing the Conda package management system to help maintain your Python environment.
Note
these install instructions will install a Python3 default environment with a Python2 backup.
If there is an old version of anaconda you can remove it with
~$ rm -rf ~/anaconda*
Download the image or install script from https://www.anaconda.com/download/
On Ubuntu¶
install via the command line
~$ bash ~/Downloads/Anaconda3-4.3.1-Linux-x86_64.sh
Answer yes to the path adding question
Restart terminal
On OSX¶
Run the installer on the downloaded image
Answer yes to the path adding question
restart terminal
On Windows¶
Ensure that you install the
Anaconda installer for Windows
for Python 3Double-click the .exe file
Follow the instructions on the screen
If you are unsure about any setting, accept the defaults. You can change them later. When installation is finished, from the Start menu, open the Anaconda Prompt.
https://conda.io/docs/user-guide/install/windows.html
Then run this to create a working python 2 environment¶
~$ conda create -n py2 python=2 anaconda
To activate the python 2 environment
~$ source activate py2
To toggle back to a Python3 environment
~$ source deactivate py2
Then ensure you can run Jupyter with Py2¶
~$ source activate py2
~$ conda install notebook ipykernel
~$ ipython kernel install --user
Keeping conda up-to-date¶
~$ conda update conda
~$ conda update --all


HTML tutorials:
HTML Tutorial
CSS Tutorial
Scripting tutorials:
JavaScript
VBScript
XML tutorials:
XML
XSL
Note:
IE8 supports these properties only if a !DOCTYPE is specified.


What is the Wakashan AI Consortium?
The International Wakashan AI Consortium is a team of Indigenous engineers and language teachers committed to the preservation of Indigenous languages - most pressingly, those within the Wakashan language family. We believe that technologies such as automatic speech recognition (ASR) and natural language processing (NLP) have an important role to play keeping our cultures alive and strong. We also believe that language data must be handled with care and be used only for purposes explicitly approved by the communities that hold them sacred.
As recent winners of the Indigenous Communities Fellowship through MIT Solve, you can read more about our mission and long-term plans here. If you have any comments or questions, feel free to fill out this google form and we will get back to you as soon as possible!


virtualstory's live-demos
self-stuffs
layout
one-column-layout
two-column-layout
three-column-layout
tabs
tab


Beard-os from Sonoma County!! With riffs that destroy walls, vocals that would frighten a bear in the best way possible, and musicianship of the highest caliber, OVER THE FALLS paired with Sell The Heart for their 2011 album YES, HAVE SOME. Comprised of Bret Fontaine (guitar/vocals), Ryan Alderman (drums), Chris Rodgers (vocals) and Tim Bastianon (bass/vocals), these fellas have released one other full length and an EP, which can be found HERE. For fans of the mighty Clutch, Faith No More, ZZ Top, and of course PRIMUS.


{% extends 'study/base.html' %} {% load bootstrap4 %} {% block content %}
Studying for vocabulary tests has always been a hassle. Existing platforms are never sufficient, making you waste time remembering exact wordings of definitions you already know, and leaving less time for the words you need to learn. We, the creators of Quill, recognized this issue and quickly responded to create a revolutionary platform to change the way of test preparation.
{% endblock %}


{% extends "base.html" %} {% block title %}HackTX API Directory{% endblock %} {% block content %}
Company's Name
Link of Company
Please input image name. Make sure it's in the /img/partners directory Ex. capital-one.jpg
Input key words for search. Delmit by ','. Ex. 'Blockchain,Mobile,Dev,Web'
Input words from search keywords above. Delmit by ','. Ex. 'Blockchain,Mobile,Dev,Web'
Company Description
Prize Name
Prize


Inspiration
Breast cancer is the most common form of cancer in women, and invasive ductal carcinoma (IDC) is the most common form of breast cancer. Accurately identifying and categorizing breast cancer subtypes is an important clinical task, and Machine Learning techniques can be used to save time and reduce error.
Model test accuracy: 90.05%
Invasive Ductal Carcinoma (IDC)
Invasive ductal carcinoma (IDC), also known as infiltrating ductal carcinoma, is cancer that began growing in a milk duct and has invaded the fibrous or fatty tissue of the breast outside of the duct. IDC is the most common form of breast cancer, representing 80 percent of all breast cancer diagnoses


19\02\2021
HTML is just simply the absolute bare bones on a web page and looks very plain. It is like going to the supermarket and all the biscuits have a plain white wrapper, but to know what they are someone just wrote in black pen the type of biscuit on the outside. A biscuit has the sole purpose of being edible. In CSS it allows the primary purpose of styling. This includes styling of text or choosing background colour to the html elements known as a node. We think of a tree who just has boring brown branches, but each spring new leaves with different colours and shapes are chosen, and the gardener decides to fill the gaps in the top, middle, and bottom for visitors to admire.
The term control flow refers to the orders which the instructions in your program are executed. The control flow can use statements to direct decision making, looping and execute blocks of code from top to bottom and follow the order in which they appear to us. Loops repeat something which will continue until the condition is met as specified for example the conditions become true.  You start with the first dish and wash it in the sink, its clean, then you take the next dish and wash that one which goes in the drainer, you wash another dish in the sink and keep going until the end when the last dish is put in the drainer.
DOM stands for document object model and is a hierarchal tree structure, which gives a structural representation of HTML and uses HTML elements upon which the Dom operates.
In essence the DOM represents a web page which can be manipulated once the web page is opened in the browser or window. The HTML gives the hierarchical structure a path for the DOM to interact with other coding languages such as HTML, CSS and JavaScript. So, the analogy is a tree in my garden with roots as the window and a trunk which acts as the document. The trunk allows us to climb up and access more content in the top of the tree by having more branches with more nodes (elements).
Data such as numbers or strings defined as characters can be stored in an array which is declared by [ ]; and then the data put inside so it is all in one place. Example: Important to remember zero-based indexing and specify an entry in the array. Value of the 1st element is 50.
Option one is bracket notation and the other is .notation to access properties of objects. You can use bracket notation for other positions within an array as shown below where we access “d” within the first name Ada.
If the property of an object your trying to access has a space in its name use [ ] like below.
Var testObject = { “ the drink” : “veggies” var the drink Value= testObject [“the drink”]You can also use dot notation from an array to access the related value.
We want to retrieve a value “shooting guard”.
Another example is shown below
Var testObject = {Functions are block of code that executes in order to do a task which is specific as it invokes action such as calculating a lot of numbers, for example stock taking plants at a garden centre. A manager requires accuracy for the stock evaluation report. We need a function which allows a person to scan a code and then put how many plants there are and repeat this function for all plants with a code. Now, this function can scan the code and take the numbers inputted by staff then do a count of stock.


{% extends "dev/base.html" %} {% load i18n %} {% block htitle %}SPARCS SSO Test Service{% endblock %} {% block content %}
If unregister url is empty, the service is immediately unregistered without any check.


{% extends "layout.html" %} {% block content %}
Text Content:
Previously Uploaded Image:
Replace Image: {% else %} {{ form.image_file.label(class="form-control-label") }} {% endif %} {% if form.image_file.errors %} {{ form.image_file(class="btn btn-outline-info") }}


| timer = any valid timer handle |
|
Returns the total number of timer ticks since the timer was created using CreateTimer , or ResetTimer was called.
See also: CreateTimer, ResetTimer, PauseTimer, ResumeTimer, FreeTimer. |
|
; create a window
WinHandle=CreateWindow("Timer Functions",100,100,200,150,0,25) ; and create a couple of buttons buttonReset=CreateButton("Reset Timer",10,10,180,20,WinHandle) buttonPause=CreateButton("Pause Timer",10,40,180,20,WinHandle) ; and create our timer (one hundred ticks per second) timer = CreateTimer(100) ; and now a loop to demonstrate it in action Repeat event=WaitEvent() ; exit when we receive a Window Close event If event=$803 Then End ; reset / pause / resume the timer if the user hits the buttons If event=$401 Then If EventSource()=buttonReset Then ResetTimer timer If EventSource()=buttonPause Then If GadgetText(buttonPause)="Pause Timer" Then PauseTimer timer SetGadgetText buttonPause,"Resume Timer" Else ResumeTimer timer SetGadgetText buttonPause,"Pause Timer" End If End If End If ; update the screen on timer tick If event=$4001 Then time# = TimerTicks(timer)/100.0 SetStatusText WinHandle,"Ticks : " + TimerTicks(timer) + ", Time : " + time + " seconds" End If Forever End ; bye! |


Please consider to contribute some rules to make BBScan more efficient. BBScan v 1.2
Current Scan finished in 20 min 3.20 seconds.


Man stabs wife before setting house on fire, police say
by KNOENEW YORK (WABC/CNN) - New York police say a man stabbed his wife and then set their house on fire.
Firefighters pulled the man from the home in Staten Island Saturday. He is now in critical condition.
Police say his wife escaped the home after her husband attacked her. She is in stable condition.
Copyright 2019 WABC via CNN. All rights reserved.


The project will happen at the second half of the semester. The goal of the project is to give you some realistic experience of Haskell development and pair programming. You are expected to work in pairs and spend at least 30 hours in the project.
- Tue, 10/10: Project Registration
- Tue, 10/17: Project Proposal
- Tue, 11/07: Project Updates
- Tue, 12/05: Project Presentation
Project Ideas
You can implement any Haskell project you wish. If you think your idea is unrealistic, discuss it with the instructor or the TA. Here are some ideas:
- Games
- A strategy game against the human, e.g., chess.
- A puzzle solver, e.g., sudoku.
- A real game using Functional Reactive Programming (haskanoid).
- Applications
- A web or database application (Yesod).
- A Machine Learning implementation.
- Libraries
- An efficient implementation of a data structure, e.g., string matching, red-black trees.
- Any library you think is missing from the Haskell ecosystem.
- Theory and Logic
- A parser, type-checker, and/or interpreter for lambda-calculus.
- A prover of propositional logic.
- Liquid Haskell:Correctness of bird-style transformations.
Project Evaluation
The project will be evaluated based on the following criteria:
- collaboration: the project will be built on github and all members should contribute equally.
- library usage: the project should use existing libraries of the hackage ecosystem.
- reproduction: the project should be easily installed via cabal or stack.
- unit testing: the project should pass unit tests that are implemented either manually or using quickcheck. The tests should be automatically checked via Travis CI or Circle CI.
- [optional] verification: optionally you can use Liquid Haskell to check validity of your code.
- presentation: make sure to clearly present your goals and your implementation.
Tue, 10/10: Project Registration
You need to create a github
repository for your project, write a Readme.md
file that describes your goals and write your names and the github link to the this document.

Tue, 11/07: Project Updates
You will give a 5 min description of your progress:
- What challenges (if any) did you have so far and how did you solve them?
- Do you expect to meet your goals until the deadline?
- How are your goals adapted?


{% load static %} {% block content %} {% if user.is_authenticated %} Hi {{ user.username }}! {% endif %} {% endblock %}
Safely helps women to navigate routes in a safe manner by providing three main features: safe routes, timer alert and SOS alerts to near ones.
Allows users to mark a place as Unsafe, and displays safer routes, with timer alerts for emergency
If you're already a member, Log In to the site.


Package agents
Class IntelligenceAgent
- java.lang.Object
-
- agents.IntelligenceAgent
-
public class IntelligenceAgent extends java.lang.Object
-
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description void
addScout(int unitID)
This function adds a unit to the scout listvoid
addWatchedPoint(bwapi.Position p)
Finds and adds chokePoints to an arrayListjava.lang.Boolean
attackingEnemyBase()
Checks if the players is attacking the enemy basejava.lang.Boolean
beingAttacked()
Checks if the players bases is being attackedvoid
changeBaseLoc(int newBaseLoc)
Changes BaseLoc variable to provided valuevoid
findEnemyBase(bwapi.Unit scout, bwta.BaseLocation basePos)
Sends a scout to attack possible enemy base positionsbwapi.Unit
getAvailableUnit(bwapi.Player self, bwapi.UnitType type)
Returns an available unit of typebwapi.Unit
getAvailableWorker(bwapi.Player self)
Returns a worker that is not a scoutint
getBaseLoc()
int
getBuildingUnitsOfType(bwapi.Player self, bwapi.UnitType type)
Returns the total amount of buildings of typejava.util.List<bwapi.Unit>
getCombatUnits(bwapi.Player self)
Get the current combat units that exist to attack with.java.util.ArrayList<CombatUnitStatus>
getCombatUnitStatuses()
Gets a list of friendly combat unit statusesjava.util.HashSet<bwapi.Position>
getEnemyBuildingMemory()
Returns the current enemyBuildingMemorybwapi.Race
getEnemyRace()
bwapi.Game
getGame()
GameStatus
getGameStatus()
Get the currentGameStatus
float
getGasProductionRate()
Gets the gas production ratestatic IntelligenceAgent
getInstance(bwapi.Game game)
float
getMineralProductionRate()
Gets the mineral production ratebwapi.UnitType
getMostCommonCombatUnit()
Get the most common combat unit of the players armyint
getNumBases()
Gets the number of friendly basesint
getNumEnemyBases()
Get number of enemy basesint
getNumEnemyWorkers()
Get the number of enemy workersint
getNumWorkers()
Get the number of workers for the AI plannerint
getOrderedMineralUse()
bwapi.Race
getPlayerRace()
int
getPopulationCapacity()
int
getPopulationUsed()
bwapi.Player
getSelf()
int
getTimeSinceLastScout()
Gets the number of frames since last scout was sentint[][]
getTrainingCapacity()
bwapi.Unit
getUnit(bwapi.Player self, bwapi.UnitType type)
Returns a Unitjava.util.HashMap<bwapi.UnitType,java.lang.Integer>
getUnitMemory()
int
getUnitMemoryValue(bwapi.UnitType type)
Used to get the value mapped by the key of typejava.util.List<bwapi.Unit>
getUnitsListOfType(bwapi.UnitType type)
Returns a list of units of typeint
getUnitsOfType(bwapi.Player self, bwapi.UnitType type)
Returns the total count of units of typebwapi.Unit
getUnitWithoutType(bwapi.Game game, bwapi.Player self, bwapi.UnitType target, bwapi.UnitType type, int radius)
Returns a unit of type target that has no units of type type in the specified radiusboolean
isScout(int unitID)
Returns true if unit with unitID is scout false otherwiseboolean
isUnitInRadius(bwapi.Game game, bwapi.Position position, int radius, bwapi.UnitType type)
True if unit of type is within radius of positionbwapi.Position
nextBaseLocationToCheck(bwapi.Game game)
void
onUnitDestroy(bwapi.Unit unit)
void
onUnitShow(bwapi.Unit unit)
protected void
setAttacking(boolean setTo)
let the intel agent tell ask if we're attacking.void
setScoutTimer()
Marks the current frame count as the last scout timevoid
tabulateUnits(bwapi.Player self)
Clears current unitMemory and usesupdateUnitMemory(bwapi.UnitType, int)
to add all trained units to hashmapboolean
unitExists(bwapi.UnitType type)
Checks if player has units of type typevoid
updateEnemyBuildingMemory(bwapi.Game game)
Updates hashset of enemy building locations
-
-
-
Method Detail
-
getInstance
public static IntelligenceAgent getInstance(bwapi.Game game)
-
getSelf
public bwapi.Player getSelf()
- Returns:
- the player
-
getGame
public bwapi.Game getGame()
- Returns:
- the game
-
getUnitMemory
public java.util.HashMap<bwapi.UnitType,java.lang.Integer> getUnitMemory()
- Returns:
- the HashMap of UnitTypes and number of Units of the respective UnitType.
-
tabulateUnits
public void tabulateUnits(bwapi.Player self)
Clears current unitMemory and usesupdateUnitMemory(bwapi.UnitType, int)
to add all trained units to hashmap- Parameters:
self
- Player assigned to the bot
-
unitExists
public boolean unitExists(bwapi.UnitType type)
Checks if player has units of type type- Parameters:
type
- UnitType to check for- Returns:
- True if unit of type type exists
-
getUnitMemoryValue
public int getUnitMemoryValue(bwapi.UnitType type)
Used to get the value mapped by the key of type- Parameters:
type
- Unit type to search the list for- Returns:
- value mapped by the key of type
-
isScout
public boolean isScout(int unitID)
Returns true if unit with unitID is scout false otherwise- Parameters:
unitID
- Unit that should be checked- Returns:
- True if unit is scout
-
addScout
public void addScout(int unitID)
This function adds a unit to the scout list- Parameters:
unitID
- ID number of the unit to add
-
changeBaseLoc
public void changeBaseLoc(int newBaseLoc)
Changes BaseLoc variable to provided value- Parameters:
newBaseLoc
- new value of BaseLoc
-
getBaseLoc
public int getBaseLoc()
- Returns:
- the current value of baseLoc
-
updateEnemyBuildingMemory
public void updateEnemyBuildingMemory(bwapi.Game game)
Updates hashset of enemy building locations- Parameters:
game
- Game value assigned at game start
-
onUnitDestroy
public void onUnitDestroy(bwapi.Unit unit)
-
onUnitShow
public void onUnitShow(bwapi.Unit unit)
-
findEnemyBase
public void findEnemyBase(bwapi.Unit scout, bwta.BaseLocation basePos)
Sends a scout to attack possible enemy base positions- Parameters:
scout
- Unit that is a scoutbasePos
- Possible location of a base to scout
-
getEnemyBuildingMemory
public java.util.HashSet<bwapi.Position> getEnemyBuildingMemory()
Returns the current enemyBuildingMemory- Returns:
- The current enemyBuildingMemory
-
addWatchedPoint
public void addWatchedPoint(bwapi.Position p)
Finds and adds chokePoints to an arrayList- Parameters:
p
- Position to watch
-
getUnitsOfType
public int getUnitsOfType(bwapi.Player self, bwapi.UnitType type)
Returns the total count of units of type- Parameters:
self
- Player assigned to the bottype
- UnitType to get the count of- Returns:
- The count of units of type
-
getUnitsListOfType
public java.util.List<bwapi.Unit> getUnitsListOfType(bwapi.UnitType type)
Returns a list of units of type- Parameters:
type
- UnitType to get the list of- Returns:
- Returns a list of all units of type type
-
getOrderedMineralUse
public int getOrderedMineralUse()
-
isUnitInRadius
public boolean isUnitInRadius(bwapi.Game game, bwapi.Position position, int radius, bwapi.UnitType type)
True if unit of type is within radius of position- Parameters:
game
- Game value assigned at game startposition
- Position of the center pointradius
- Value of the Radiustype
- UnitType to search the radius for- Returns:
- Returns true if unit of type is within the radius of position
-
getCombatUnits
public java.util.List<bwapi.Unit> getCombatUnits(bwapi.Player self)
Get the current combat units that exist to attack with.- Parameters:
self
- the Player- Returns:
- a List of fighting Units.
-
getUnitWithoutType
public bwapi.Unit getUnitWithoutType(bwapi.Game game, bwapi.Player self, bwapi.UnitType target, bwapi.UnitType type, int radius)
Returns a unit of type target that has no units of type type in the specified radius- Parameters:
game
- Game value assigned at game startself
- Player assigned to the bottarget
- UnitType to use as the anchor for the radiustype
- UnitType to check radius forradius
- Size of radius from the target unit- Returns:
- A unit of type target with no units of type type in the radius
-
getAvailableUnit
public bwapi.Unit getAvailableUnit(bwapi.Player self, bwapi.UnitType type)
Returns an available unit of type- Parameters:
self
- Player assigned to the bottype
- UnitType to search for availability- Returns:
- Available unit of type type
-
getAvailableWorker
public bwapi.Unit getAvailableWorker(bwapi.Player self)
Returns a worker that is not a scout- Parameters:
self
- Player assigned to the bot- Returns:
- Available worker unit
-
getUnit
public bwapi.Unit getUnit(bwapi.Player self, bwapi.UnitType type)
Returns a Unit- Parameters:
self
- Player assigned to the bottype
- UnitType to search for- Returns:
- Unit of type type
-
getBuildingUnitsOfType
public int getBuildingUnitsOfType(bwapi.Player self, bwapi.UnitType type)
Returns the total amount of buildings of type- Parameters:
self
- Player assigned to the bottype
- UnitType to get the count of- Returns:
- Total count of building unit of type type
-
nextBaseLocationToCheck
public bwapi.Position nextBaseLocationToCheck(bwapi.Game game)
-
getNumWorkers
public int getNumWorkers()
Get the number of workers for the AI planner- Returns:
- int, # workers the player owns.
-
getMineralProductionRate
public float getMineralProductionRate()
Gets the mineral production rate- Returns:
- float, the current mineral production rate
-
getGasProductionRate
public float getGasProductionRate()
Gets the gas production rate- Returns:
- float, the current gas production rate
-
getNumBases
public int getNumBases()
Gets the number of friendly bases- Returns:
- number of bases controlled by the player
-
setScoutTimer
public void setScoutTimer()
Marks the current frame count as the last scout time
-
getTimeSinceLastScout
public int getTimeSinceLastScout()
Gets the number of frames since last scout was sent- Returns:
- the number of frames since a scout was last sent
-
getCombatUnitStatuses
public java.util.ArrayList<CombatUnitStatus> getCombatUnitStatuses()
Gets a list of friendly combat unit statuses- Returns:
- An ArrayList containing the
CombatUnitStatus
of each combat unit
-
getNumEnemyWorkers
public int getNumEnemyWorkers()
Get the number of enemy workers- Returns:
- the number of known workers controlled by the enemy
-
getNumEnemyBases
public int getNumEnemyBases()
Get number of enemy bases- Returns:
- the number of bases controlled by the enemy player
-
getMostCommonCombatUnit
public bwapi.UnitType getMostCommonCombatUnit()
Get the most common combat unit of the players army- Returns:
- The UnitType of the most common combat unit controlled by the player
-
setAttacking
protected void setAttacking(boolean setTo)
let the intel agent tell ask if we're attacking.- Parameters:
setTo
- boolean, weather or not we are taking an attack action.
-
attackingEnemyBase
public java.lang.Boolean attackingEnemyBase()
Checks if the players is attacking the enemy base- Returns:
- true if the players is attacking the enemy base, false otherwise
-
beingAttacked
public java.lang.Boolean beingAttacked()
Checks if the players bases is being attacked- Returns:
- true if the player's base is being attacked, false otherwise
-
getPlayerRace
public bwapi.Race getPlayerRace()
- Returns:
- the player's race
-
getEnemyRace
public bwapi.Race getEnemyRace()
- Returns:
- the enemy's race
-
getGameStatus
public GameStatus getGameStatus()
Get the currentGameStatus
- Returns:
- return a
GameStatus
describing the current game
-
getTrainingCapacity
public int[][] getTrainingCapacity()
- Returns:
- A two-dimensional array of the form [workers[used, avail] , ground[used, avail], combat air[used, avail], support air[used, avail]]
-
getPopulationCapacity
public int getPopulationCapacity()
- Returns:
- the maximum number of units that can currently exist.
-
getPopulationUsed
public int getPopulationUsed()
- Returns:
- the total number of units that currently exist.
-
-


WRITE(1) BSD General Commands Manual WRITE(1) NAME write — send a message to another user SYNOPSIS write user [tty] DESCRIPTION The write utility allows you to communicate with other users, by copying lines from your terminal to theirs. When you run the write command, the user you are writing to gets a message of the form: Message from yourname@yourhost on yourtty at hh:mm ... Any further lines you enter will be copied to the specified user's termi‐ nal. If the other user wants to reply, they must run write as well. When you are done, type an end-of-file or interrupt character. The other user will see the message ‘EOF’ indicating that the conversation is over. You can prevent people (other than the super-user) from writing to you with the mesg(1) command. If the user you want to write to is logged in on more than one terminal, you can specify which terminal to write to by specifying the terminal name as the second operand to the write command. Alternatively, you can let write select one of the terminals - it will pick the one with the shortest idle time. This is so that if the user is logged in at work and also dialed up from home, the message will go to the right place. The traditional protocol for writing to someone is that the string ‘-o’, either at the end of a line or on a line by itself, means that it is the other person's turn to talk. The string ‘oo’ means that the person believes the conversation to be over. SEE ALSO mesg(1), talk(1), wall(1), who(1) HISTORY A write command appeared in Version 1 AT&T UNIX. BUGS The sender's LC_CTYPE setting is used to determine which characters are safe to write to a terminal, not the receiver's (which write has no way of knowing). The write utility does not recognize multibyte characters. BSD July 17, 2004 BSD


{{unreferenced|date=March 2013}} {{Infobox prepared food | name = Hallulla | image = | caption = Hallula (left) and marraqueta (right) | alternate_name = | country = Chile | region = | creator = | course = | type = Bread | served = | main_ingredient = Wheat flour, yeast, vegetable shortening or butter | variations = | calories = | other = }}
Hallulla ({{IPA-es|aˈʎuʎa}}, approximately like {{respell|ah|YU|yə}}; from the Hebrew challah) is a popular bread in Chile. The hallulla is a flat round bread baked with vegetable (but sometimes also animal) shortening and is used for several traditional Chilean sandwiches. A typical white hallulla is similar in taste and texture to a scone, but is circular and larger, and more often used with savoury rather than sweet fillings.
The traditional recipe includes: wheat flour, yeast, sugar, salt, vegetable shortening, milk and water.
{{portal|Food}} {{cuisine of Chile}} {{Chilean bread}}
{{chile-cuisine-stub}} {{bread-stub}}


Common issues for users of IE6+ is image caching. All version of IE6 share this issue -
the same image can be fetched from server multiple times ( based on server response and
settings of browser ), such can cause can cause performance issues for both server and client.
Starting from dhtmlxTree 1.5, special image loading mode available, it can be enabled by
tree.enableIEImageFix(true);
In such mode IE load images through CSS, instead of native IMG elements. As result problem
solved for most version of IE6 ( still can occur in some version of IE6 SP1 )
Benefits of "IE Image Fix" mode
- Images cached on client
- About 1.5 times loading speed improvement in FF
Disadvantages of "IE Image Fix" mode
- About 1.5 times loading speed decreasing in IE


Which template should be used for help center homepage.
How many articles should each category display in help center homepage.
How many child categories should each parent category display in help center homepage.
This will hide categories with less then two articles from help center homepage to prevent gaps.
How many items (maximum) should be displayed in help center search page.
In what way should help center articles be ordered by default.
This will hide footer from all help center pages.
Whether "Submit a Request" link on article pages should be hidden.
Import and export help center data (articles, categories, images, tags) in a .zip file for backup or migration.