---
layout: post
title: Authorization and users management in rails
published: true
tags: [rails, devise, cancan, admin]
type: post
status: publish
---
Updated at 14/04/2012
The goal of this tutorial is to realize a rails application with:
- A public area whith register, logout and login functionalities
- An admin area where the admin can delete/insert/update the users and their roles
- The possibility to allowed/denied some parts of the application in relation to the user role
- An internal area for the registered user's, where they are allowed to edit their username and password
- A different redirect after the login, based on the user's role
The whole code is available on this github repo.
After creating a new rails application, install devise and cancan, add this two lines to your Gemfile
{% highlight ruby %}
gem "devise"
gem "cancan"
{% endhighlight ruby %}
Then run 'bundle update'.
Setting up devise
Install devise in your application with the command 'rails generate devise:install', read carefully the messages for the setup. Follow the Hello rails paragraph to create a dummy controller and remove the default index page. Now, we have to define a root
{% highlight ruby %}
root :to => "home#index"
{% endhighlight ruby %}
define a default url option for the "recovery email" in the config/environments/development.rb file(remember to change this value when you are ready to go in production)
{% highlight ruby %}
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
{% endhighlight ruby %}
Let's create our model to define the users. Try to avoid strange names, "User" is good enough. Then run the migration
{% highlight ruby %}
rails generate devise User
rake db:migrate
{% endhighlight ruby %}
Add a username field to your model and generate the views.
{% highlight ruby %}
rails g migration AddUsernameToUsers username:string
rake db:migrate
rails g devise:views
{% endhighlight ruby %}
now add this two lines to your routes.rb file
{% highlight ruby %}
devise_for :users, :path_names => {:sign_in => "login", :sign_out => "logout"}, :path => "d"
resources :users
{% endhighlight ruby %}
Remember to add the username field to the attr_accessible in your user model. Try to run the command 'rake routes' to see all the new routes created by Devise. in order to display the links "login", "logout" and "register", add these lines to your views/layout/application.html.erb file. Pay attention to the "method post" in the logout button.
{% highlight erb %}
<% flash.each do |name, msg| %>
<%= content_tag :div, msg, :id => "flash_#{name}" if msg.is_a?(String) %>
<% end %>
<% if user_signed_in? %>
<% #link_to "My Profile", user_root_path%>
<%= link_to('Logout', destroy_user_session_path, :method=>'delete') %>
<%end%>
{% endhighlight erb %}
Add your user to the system through the http://<IP_ADDRESS>:3000/users/sign_up page. Try to login and logout. If you have problems, check another time this tutorial.
You are the admin
Let's say that only a logged user can acces to the admin area. First of all, we have to define an admin area. Add this lines to your routes.rb file
{% highlight ruby %}
namespace :admin do
match '/' => 'users#index'
resources :users
end
{% endhighlight ruby %}
Then copy the file app/views/layout/application.html.erb to app/views/layout/admin.html.erb
Second, we need to create an admin_controller in app/controller/admin
{% highlight ruby %}
class Admin::AdminController < ApplicationController
layout "admin"
before_filter :authenticate_user!
def current_ability
@current_ability ||= AdminAbility.new(current_user)
end
end
{% endhighlight ruby %}
We need also to create an admin/users_controller.rb and the related views in views/admin/users to manage the users. You can find the whole code on the github repo of this example, copy these files from there.
Comment the "#load_and_authorize_resource" lines in the controllers/admin/users_controller.rb file, we are going to see later what this line is used to. Sign in and go to this address: http://<IP_ADDRESS>:3000/admin/users. You will see your user and the links to edit/delete it. But if you click on they, you will receive an error, cause we have no roles
Add roles to rule the world
Generate 2 migrations to add the roles table and set up an HABTM relationship with the user table. Edit the migration like follow, thanks Tony Amoyal for your tutorial:
{% highlight ruby %}
class CreateRoles < ActiveRecord::Migration
def self.up
create_table :roles do |t|
t.string :name
t.timestamps
end
end
def self.down
drop_table :roles
end
end
class UsersHaveAndBelongToManyRoles < ActiveRecord::Migration
def self.up
create_table :roles_users, :id => false do |t|
t.references :role, :user
end
end
def self.down
drop_table :roles_users
end
end
{% endhighlight ruby %}
Check the presence of these two tables in your db, if you are using sqlite
{% highlight bash %}
rails db
sqlite > .tables
{% endhighlight bash %}
Create the Role model and add the HABTM relationship to the user model
{% highlight ruby %}
# User Model
class User < ActiveRecord::Base
has_and_belongs_to_many :roles
....
# Role model
class Role < ActiveRecord::Base
has_and_belongs_to_many :users
end
{% endhighlight ruby %}
Now add 3 roles in your Roles table using the console.
{% highlight bash %}
rails console
irb(main):001:0> r = Role.new(:name => "Admin")
irb(main):002:0> r.save
irb(main):003:0> r = Role.new(:name => "Registered")
irb(main):004:0> r.save
irb(main):005:0> r = Role.new(:name => "Robbers")
irb(main):006:0> r.save
{% endhighlight bash %}
add :role_ids to the attr_accesible fields in your user model. Add also the following lines.
In the first block we define a method to check the users role, in the second we assign a default role for the users that will register to the website, in this case, the role with id 2, "Registered".
{% highlight ruby %}
before_save :setup_role
def role?(role)
return !!self.roles.find_by_name(role.to_s.camelize)
end
# Default role is "Registered"
def setup_role
if self.role_ids.empty?
self.role_ids = [2]
end
end
{% endhighlight ruby %}
Now login and edit you User, check the Admin checkbox to promote you as admin of your website.
Then logout and create another user through the sign up form. Login with it and try to access the admin area. Wait a moment, you are now a Registered user, you should not reach the /admin area. What's happen?
The problem is that the admin area authentication is performed with devise, that only checks if a user is logged or not. We have to use CanCan to be sure that only the admin can reach the admin area. Generate an ability class and copy it in the models folder, with the name admin_ablity
{% highlight ruby %}
rails g cancan:ability
cp app/models/ability.rb app/models/admin_ability.rb
{% endhighlight ruby %}
Edit this class as follow
{% highlight ruby %}
class AdminAbility
include CanCan::Ability
def initialize(user)
if user.role? :admin
can :manage, :all
end
end
end
{% endhighlight ruby %}
Edit your app/controller/application_controller.rb to define a method to handle the "Access Denied" exception.
{% highlight ruby %}
class ApplicationController < ActionController::Base
protect_from_forgery
def has_role?(current_user, role)
return !!current_user.roles.find_by_name(role.to_s.camelize)
end
rescue_from CanCan::AccessDenied do |exception|
redirect_to root_url, :alert => exception.message
end
end
{% endhighlight ruby %}
Now we have to tell to the controllers/admin/admin_controller file to check the role of this user.
{% highlight ruby %}
class Admin::AdminController < ApplicationController
layout "admin"
before_filter :verify_admin
def verify_admin
:authenticate_user!
redirect_to root_url unless has_role?(current_user, 'admin')
end
def current_ability
@current_ability ||= AdminAbility.new(current_user)
end
end
{% endhighlight ruby %}
Now, if you try to access the admin area with a user that is not an Admin, you will redirect to the root. Only the admin has the ability to visit the admin area, and this ability is defined in the admin_ability class. Now we will define the ability to create a post, only the Registered User are allowed to do it, the Robbers can only read. First of all, create a Robbers user and generate a dummy post controller. Remember to define to define two association in the user and post model. A user HasMany posts, a post BelongTo a user.
{% highlight ruby %}
rails generate scaffold Post title:string content:text user_id:integer
{% endhighlight ruby %}
Now open the model/ability.rb class and write this lines. We will see later what the Profile stand for
{% highlight ruby %}
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user
if user.role? :admin
can :manage, :all
elsif user.role? :registered
can :manage, Post do |post|
post.try(:owner) == user
end
else
can :read, :all
end
end
end
{% endhighlight ruby %}
Now login as a robbers and try to create a Post. Yes, you can do it. To avoid this, you'll need to add this line at the beginning of the post controller
{% highlight ruby %}
class PostsController < ApplicationController
load_and_authorize_resource
{% endhighlight ruby %}
Edit my profile
Now we want to allow every user (yes, also the robbers) to edit their username and password. In this case, I will create the profile controller with only one action (dashboard) 'cause i find it useful, and it is pretty a standard in every application. maybe in the future you will add more action to this controller, like a public profile action, or something similar. But to edit the user, i will use the devise logic. We have to create the Profile controller and the dashboard profile view. Copy the profile stuff from the github repo.
Now, we have to edit the route file to inform rails about the profiles controller and to define a user_root, that will be used in the profile_controller.
{% highlight ruby %}
Authuser::Application.routes.draw do
root :to => "home#index"
match '/profiles/dashboard' => 'profiles#dashboard', :as => :user_root
devise_for :users, :path_names => {:sign_in => "login", :sign_out => "logout"}
resources :profiles, :only => [:dashboard]
namespace :admin do
match '/' => 'users#index'
resources :users
end
resources :posts
end
{% endhighlight ruby %}
Change your application layout and add a "my profile link"
{% highlight erb %}
<% if user_signed_in? %>
<%= link_to "My Profile", user_root_path%>
<%= link_to('Logout', destroy_user_session_path, :method=>'delete') %>
<%else%>
<%= link_to('Login', new_user_session_path) %>
<%= link_to('Register', new_user_registration_path) %>
<%end%>
{% endhighlight erb %}
Now, if you log as an admin you will redirect to /admin/users, if you login as Robbers or Registered user you will redirect to the dashboard. The method is rough, and I don't like it, but it works. Check it in the profiles controller.


POSTMAN ALWAYS RINGS TWICE, THE (director:Tay Garnett; screenwriter: from a novel by James M. Cain/Harry Ruskin/Niven Busch; cinematographer: Sidney Wagner; cast: Lana Turner (Cora Smith), John Garfield (Frank Chambers), Cecil Kellaway (Nick Smith), Hume Cronyn (Arthur Keats), Leon Ames (DA Kyle Sackett), Cameron Grant (Willie), Alan Reed (Ezra Liam Kennedy), Audrey Totter (Madge Gorland), 1946)
Reviewed by Dennis Schwartz
Frank Chambers (John Garfield) is a drifter from San Francisco with itchy feet, who is given a lift by the local DA Kyle Sackett (Ames). He comes to a small California town, Twin Oaks, and spots a Man Wanted sign by a gas-station/diner, which is run by Nick Smith (Cecil Kellaway). The owner is very eager to have him work there, but Frank is not impressed with the place, that is, until he gets a load of his much younger wife, Cora Smith (Lana Turner). She is a knock-out, who appears in tight shorts. Upon seeing him, she rolls her lipstick on the floor toward him, this sets the sexual tone of the film. He, thusly, decides to stay as a station attendant and handyman, working for little money but getting free room and board.
The sexual tension between the two is there from the beginning, but builds as the two can't avoid the attraction they have for each other. Nick seems to be blind to what is going on; he treats her as if she was his possession and doesn't really listen to what she is saying to him. He is not the sort of guy that a hot girl like Cora marries, unless she is running away from something. What she wanted was the respect that comes from a stable marriage. Soon, she confesses to Frank that she doesn't love her husband. The two make one attempt to run away together by hitching, but Cora decides she doesn't want to start life again with nothing and returns to the diner.
 But the two lovers bungle the murder, and Nick is only severely injured. The two have to contend with a suspicious DA, who questions them, but doesn't have any evidence to charge them with anything.
When Nick is in the hospital, the two have the best week they ever had. But when he comes home from the hospital, Frank can't stand it and heads for Los Angeles.
But he can't forget her, returning to the diner with Nick, who amazingly still doesn't have a clue as to what's going on behind his back. In any case, Nick is delighted that he found a buyer for the place at a huge profit, and tells Cora that he is taking her to Santa Barbara, where she can take care of his dying sister.
Frank decides to take advantage that Nick likes to get drunk, as the three ride together to Santa Barbara, planning to use the excuse that he killed himself while driving impaired.  But he gets stuck in the car and can't jump, going down the hill with the car. Frank somehow recovers, only to be confronted by the DA Sackett, who tells him that there was a $10,000 insurance policy on Nick, as he turns the lovers against each other. He tricks the confused Frank into getting him to sign a statement against Cora.
Her attorney, Keats (Hume), manages to get her off, thusly winning a $100 bet with the DA, by having her plead to a manslaughter charge and receiving only probation. But the fireworks between the lovers is only beginning, as both feel betrayed and unsure of what to do.
At first, Cora keeps Frank at a distance, as she takes that insurance money to open the kind of classy diner she always wanted to. When she goes back to Iowa for her mother's funeral, the frustrated Frank picks-up another waitress (Totter) and romances her for a week in Mexico. Cora finds out about this on her return and is fuming.
The only sensible thing the lovers could do, is separate from one another, but they are trapped by their destiny and fatalistically stay together. The magic in the film is in the chemical reaction between Garfield and Lana, their performances are sizzling. The James Cain hard-boiled novel, about lust, deceit, betrayal, and murder becomes a classical noir tale of a love that has to go beyond the bounds of reason, one that can't be resolved in normal terms. The lovers can't let go of what has always trapped them: the insecurity of Cora, who wants something in life that can give her dignity, something that has always eluded her; and Frank, who is caught in his own seduction, too weak-minded to see how warped his judgment has become. The reason the film is so provocative, is that it hits below the belt, where the lovers were most vulnerable. That when they finally do realize that they are in love, it is too late for it to count anymore. They have messed up their lives and can't escape from that fate.
John Garfield, as the condemned man, trying to make sense of what happened to him, narrates the story, while awaiting execution. He has gone too far afield to evoke any sympathy for his plight.
REVIEWED ON 2/16/2000 GRADE: A
Dennis Schwartz: "Ozus' World Movie Reviews"
http://www.sover.net/~ozus
<EMAIL_ADDRESS>© ALL RIGHTS RESERVED DENNIS SCHWARTZ
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


[§353F-6] Executive secretary; staff. The department of public safety shall appoint an executive secretary and additional staff as necessary to carry out the functions of the commission. All staff shall be appointed without regard to chapter 76. [L 1993, c 343, pt of §2; am L 2000, c 253, §150]


Ingredients
- 4 or 5 thicc pork chops
- 1 egg, beaten
- 1/2 cup panko bread crumbs
- Bacon fat or olive oil
- 1/2 sweet yellow onion, cut into thin strips
- Garlic salt and pepper to taste
Instructions
Preheat the oven to 425°. Thaw the chops if needed. Beat the egg in a small bowl, adding a splash of milk and garlic salt and pepper to taste.
In a medium cast-iron skillet, heat the bacon fat over medium-high heat. Once the fat is smoking, dip the chops in the egg mixture, coat in bread crumbs and add to skillet. Add the onions. Sear the chops until just charred on each side.
If your skillet isn't oven-proof, transfer the skillet contents to an oven-safe dish. Bake for 10 minutes, then flip. Bake for 10-15 minutes more, or until an internal thermometer registers 160°.


Any subclass of {@link oajr.servlet.BasicRestServlet} and {@link oajr.servlet.BasicRestObject} gets an auto-generated Swagger UI when performing an OPTIONS
request with Accept:text/html due to the following method:
| @RestGet(
| path="/api/*",
| summary="Swagger documentation",
| description="Swagger documentation for this resource."
| )
| @HtmlDocConfig(
| // Should override config annotations defined on class.
| rank=10,
| // Override the nav links for the swagger page.
| navlinks={
| "back: servlet:/",
| "json: servlet:/?Accept=text/json&plainText=true"
| },
| // Never show aside contents of page inherited from class.
| aside="NONE"
| )
| @BeanConfig(
| // POJO swaps to apply to all serializers/parsers on this method.
| swaps={
| // Use the SwaggerUI swap when rendering Swagger beans.
| // This is a per-media-type swap that only applies to text/html requests.
| SwaggerUI.class
| }
| )
| @Override /* BasicRestOperations */
| public Swagger getSwagger(RestRequest req) {
| return req.getSwagger().orElseThrow(NotFound::new);
| }
The underlying mechanics are simple.
The {@link oajr.servlet.BasicRestServlet#getSwagger(RestRequest)} method returns a {@link oaj.dto.swagger.Swagger} bean
consisting of information gathered from annotations and other sources.
Then that bean is swapped for a {@link oaj.dto.swagger.ui.SwaggerUI} bean when rendered as HTML.
Note that to have your resource create Swagger UI, you must either extend from one of the basic resource classes or provide
your own @RestOp-annotated method that returns a {@link oaj.dto.swagger.Swagger} object and a {@link oaj.dto.swagger.ui.SwaggerUI} swap.


| All projects share one version of the dependency. | |
| At least one project has a differing version of the dependency. |
| Number of sub-projects: | 15 |
|---|---|
| Number of dependencies (NOD): | 56 |
| Number of unique artifacts (NOA): | 60 |
| Number of SNAPSHOT artifacts (NOS): | 0 |
| Convergence (NOD/NOA): | 93% |
| Ready for Release (100% Convergence and no SNAPSHOTS): | Error You do not have 100% convergence. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


Swap Model Variants
This demonstrates the use of the glTF materials
variants extension which allows multiple materials and textures
to be packed with a single geometry in a GLB. Our API exposes these
variant names as availableVariants
and you can select
one using the variantName
attribute. This is similar
functionality to the lower-level scene-graph API below, but in that
case it is up to you to choose the right texture URL, rather than
having that information stored in the GLB. Note: setting variantName
to null
reverts to the initial material.


SantaTracker.Live
SantaTracker.Live is currently under development. Please comeback soon
SantaTracker,Live is planned to release Dcember 1st, come back then!


PUBLICATIONSSaadawi GM, Tseytin E, Legowski E, Jukic D, Castine M, and Crowley RS. A natural language intelligent tutoring system for training pathologists: implementation and evaluation. Adv Health Sci Educ Theory Pract. 2007 Oct 13; [Epub ahead of print] Crowley RS, Legowski E, Medvedeva, OM, Tseytlin E, Roh E and Jukic D. Evaluation of an Intelligent Tutoring System in Pathology: Effects of External Representation on Performance Gains, Metacognition, and Acceptance. JAMIA 2007 14(2):182-190; Yudelson MV, Medvedeva OP, and Crowley RS. Stepwise Multifactor Approach to Student Model Evaluation in a Complex Cognitive Domain, Accepted by User Modeling and User Adapted Interaction, December 2007 Yudelson MV, Medvedeva O, Legowski E, Castine M, Jukic D, and Crowley RS. Mining student learning data to develop high lever pedagogic strategy in a medical ITS. Educ Data Mining Workshop Proc AAAI 2006 Educational Data Mining 21st Natl Conf Artificial Intell. Boston, MA. Technical Report WS-06-05. AAAI press:82-90. Crowley R, Gryzbicki D. Intelligent medical training systems (editorial). Artifil Intell Med 2006, Sept. 38(1):1-4 Crowley RS, Legowski E, Medvedeva O, Tseytlin E. An ITS for medical classification problem-solving: Effects of tutoring and representations. Proceedings of the 12th International Conference on Artificial Intelligence (AIED05), Amsterdam, The Netherlands Crowley RS, Tseytlin E, Jukic D. ReportTutor - an intelligent tutoring system that uses a natural language interface. Proc AMIA Symp 2005: 171-175. Saadawi GM, Legowski E, Medvedeva O, Chavan G, Crowley RS. A method for automated detection of usability problems from client user interface events. Proc AMIA Symp 2005:654-658. Crowley RS, Medvedeva O. An intelligent tutoring system for visual classification problem solving. Artifil Intell Med, 2006 Jan; 36(1):85-117. Medvedeva O, Chavan G, Crowley RS. A data collection framework for capturing ITS data based on an agent communication standard. Proceedings of the 20th Annual Meeting of the American Association for Artificial Intelligence, 2005, Pittsburgh, PA Crowley RS, Fujita K, and Medvedeva OP. Next Generation Teaching Systems using Virtual Slides, in Gu Jiang, Ogilvie R (eds). The Virtual Slide and Virtual Microscope for Teaching, Diagnosis and Research, CRC Press. 2004 Crowley RS and Medvedeva OP. A General Architecture for Intelligent Tutoring of Diagnostic Classification Problem Solving. Proc AMIA Symp, 2003: 185-189. Crowley RS, Medvedeva O and Jukic D. SlideTutor - A model-tracing Intelligent Tutoring System for teaching microscopic diagnosis. IOS Press: Proceedings of the 11th International Conference on Artificial Intelligence in Education. Sydney, Australia, 2003. Crowley RS, Naus GJ, Stewart J, and Friedman CP. Development of Visual Diagnostic Expertise in Pathology - An Information Processing Study. J Am Med Inform Assoc, 2003 10(1):39-51.. Crowley RS, Naus GJ, and Friedman CP. Development of visual diagnostic expertise in Pathology. Proc AMIA Symp 2001:125-129. Crowley RS, Gadd CS, Naus G, Becich M, Lowe HJ. Defining the role of anatomic pathology images in the multimedia electronic medical record--a preliminary report. Proc AMIA Symp 2000:161-5
|
ABSTRACTSThompson A, Chavan G, Crowley RS, Binder S. Authoring of a dermatopathology virtual slide set for pathology resident education via t a web-based interactive system for remote annotation of slides and creation of corresponding clinical cases. American Society of Dermatopathology Annual Meeting, October 20-23, 2005, Seattle, Washington Crowley RS, Tobias J. The CAP checklist common data elements - a multipurpose set of CDEs in pathology. caBIG Annual Meeting, April 12-13, 2005, Bethesda, MD Chavan G, Crowley RS. Creating educational content for virtual slides with an authoring and management system. APIII 2004, Pittsburgh, PA, October 6-8, 2004. Crowley RS, Medvedeva O, Legowski E, Tseytlin E, Chavan G, Jukic D. Formative evaluation of SlideTutor - an intelligent tutoring system in pathology. APIII 2004, Pittsburgh, PA October 6-8, 2004. Medvedeva O, Crowley RS. Reasoning in a Tutoring System: Transforming Knowledge to Teaching. 7 th Annual Protégé Conference, Bethesda, MD. July 7-9, 2004. Medvedeva O, Tseytlin E, Crowley RS. Integrating Protégé into an Intelligent Medical Training System. 7 th Annual Protégé Conference, Bethesda, MD. July 7-9, 2004. >Fujita K. and Crowley RS. The Virtual Slide Set – A Curriculum Development System for Digital Microscopy. Proc AMIA Symp, 2003: 846. Crowley RS, and Monaco V. Development of a model-tracing intelligent tutor in diagnostic pathology. Proc AMIA Symp, 2001: 805. Crowley RS. The Cognitive Basis for an Intelligent Tutor in Diagnostic Pathology. Advancing Pathology Informatics, Imaging and the Internet, Pittsburgh, PA, 2001. Archives of Pathology and Laboratory Medicine. Crowley RS and Friedman CP. Development of an Intelligent Tutoring System in Diagnostic Pathology. Science 2001. University of Pittsburgh, September 12-14, 2001. Crowley RS. Creating a Diagnostic Trace: A Methodology to Study Visual Search, Knowledge Representation, and Medical Reasoning in Microscopic Diagnosis. Advancing Pathology Informatics, Imaging and the Internet, Pittsburgh, PA, 1999. Archives of Pathology and Laboratory Medicine 124 (6) p 812, 1999. |
PRESENTATIONSGrzybicki D, Crowley R, Jukic D, Raab S, Medvedeva O, Tseytlin E, Castine M. Development and evaluation of a cognitive simulator for improving diagnostic proficiency of generalist, community-based pathologists for malignant melanoma. 25th Annual Research Meeting, June 8-10, 2008, Washington, DC. [PPT] Crowley RS. The Slide Tutor Project—An Intelligent Medical Training System for Visual Diagnosis. Medical Education Grand Rounds, University of Pittsburgh, 2007 [PPT] Medvedeva O. ITS Data Collection Framework. Capturing data based on agent communication standard. Educational Data Mining Workshop, 20th AAAI-05 Conference, Pittsburgh, PA. July 10, 2005. [PPT] Medvedeva O, Tseytlin E, Crowley RS.Integrating Protégé into an Intelligent Medical Training System. 7th Annual Protégé Conference, Bethesda, MD. July 7-9, 2004. [PPT] Medvedeva O, Crowley RS. Reasoning in a Tutoring System: Transforming Knowledge to Teaching. 7th Annual Protégé Conference, Bethesda, MD. July 7-9, 2004. [PPT] Cognitive Tutoring System for Visual Diagnostic Classification. Vanderbilt University Department of Medical Informatics – Informatics Seminar, Nashville TN, April 7, 2004 [PDF] Medvedeva O, Crowley RS. Protégé as Professor: Development of an Intelligent Tutoring System With Protégé-2000. 6th International Protege Workshop, Manchester, England. July 7-9, 2003. [PPT] SlideTutor – An Intelligent Medical Training System. Annual Leo Kaplan Lecture in Anatomic Pathology. Cedars Sinai Medical Center, Los Angeles CA, March 14, 2003. A Virtual Slide Based Intelligent Tutor. Virtual Slide Symposium. November 23-25. Medical University of South Carolina. [PDF] Building from cognitive data: A model of visual diagnostic expertise in Pathology in service of an Intelligent Tutoring System. National Library of Medicine – Annual Fellows Meeting, Washington DC. July 17, 2001. [PDF] |


The Water In Brooklyn
Body wants to give, but give
for want. Lays the arms out
like oars. Nothing else
smells like the ocean save for your hair
after salt has tied into. Fingers
of the Navy Yard Basin make a pass
at the BQE. By East Mill, Body
pulls a tooth from its mother,
her mouth the rigid shore. Says
when none of us were happy
we went to the creeks, separate
like corners. We are arrows
in the same animal. Infidelity
has always tempted us.
We’ll both sleep alone tonight. I wore
this lipstick for myself.


Created by Josh Bavari / @jbavari
Demo time!
Think the systems all being tools in a toolshed. Each tool is used differently. Some focused on strictly atomic tasks. Others focused on one pass through. No tool is wrong, just different approaches.
Grunt has a plugin to run Gulp tasks, and Gulp has a plugin to run Grunt tasks.
Each tool has strengths and weaknesses. Your job will be to identify which tool may be best suited for your needs.
//Install grunt command line tools
npm install -g grunt-cli
//Specify plugins by saving to package.json file
npm install grunt-contrib-uglify --save-dev
npm install grunt-contrib-concat --save-dev
grunt.initConfig({
our_file_list: ['./src/js/{Models,Controllers}/*.js', './src/js/index.js'],
uglify: {
build: {
src: 'js/reveal.js',
dest: 'js/reveal.min.js'
},
all: {
files: {
'js/compiled/file.js': '<%= our_file_list %>',
}
}
},
concat: {
dist: {
src: ['js/reveal.min.js', 'js/compiled/file.js'],
dest: 'dist/built.js',
},
}
});
{
"name": "my-project-name",
"version": "0.1.0",
"devDependencies": {
"grunt": "~0.4.5",
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-nodeunit": "~0.3.3",
"grunt-contrib-uglify": "~0.4.0"
}
}
//Run all uglify targets
grunt uglify
//Execute uglify, but only the all target
grunt uglify:all
//Install grunt command line tools
npm install -g gulp
//Specify plugins by saving to package.json file
npm install --save-dev gulp-uglify
npm install --save-dev gulp-concat
var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
gulp.task('scripts', function() {
// Minify and copy all JavaScript (except vendor scripts)
return gulp.src(paths.scripts)
.pipe(uglify())
.pipe(concat('all.min.js'))
.pipe(gulp.dest('build/js'));
});
//Run all uglify targets
gulp scripts
Havent used long enough to form any
The first build system widely used and available. Uses skeletons (like scaffolding) to create app directory structure.
//Create new skeleton of angular app
brunch new https://github.com/scotch/angular-brunch-seed myapp
//Install bower packages (css/js/etc)
bower install
//tell Brunch to watch your project and incrementally rebuild it when source files are changed
brunch watch --server
//builds a project for distribution. By default it enables minification
brunch build --production
Mainly focused on Ember.js apps, and ships with Ember CLI


I just made a first run at some tools in Paste Script for installing web applications.
The idea is a two-phase installation; first you install the package distribution and ask it to write out a sample configuration. Then you edit the configuration. Then you ask the application to set itself up (maybe setting up databases, making directories, etc).
This is not unlike a fancier-seeming system where there's a web interface or GUI or whatnot; except all that interaction is encapsulated in editing a text configuration file. I think this is a good technique because (a) it much much easier to implement, (b) it is consistent with later maintenance, (c) it uses a powerful native UI that many people are comfortable with (the text editor), and (d) it requires very little work for an application to support.
So, in the trunk you can do:
$ paster prepare-app \ -f http://pythonpaste.org/package_index.html \ PasteHelloWorld helloworld.ini $ edit helloworld.ini $ paster setup-app helloworld.ini
You can also combine this all into:
$ paster prepare-app \ --edit --setup \ -f http://pythonpaste.org/package_index.html \ PasteHelloWorld helloworld.ini
Which will immediately open the configuration file in your editor, and when you are done editing it will set up the application. (And prepare-app also installs the application with easy_install, so it really can be just one step).
This is a pretty early prototype, really, so I'm still very interested in feedback on even the most minor details. Like, what should these commands be called?
Also, people lay out their systems differently. I have a vague concept of a "system configuration" which will determine some basics about what goes where. But it's very vague. Ideally I'm hoping that hosting companies could setup such a configuration so that everything Just Works for users, including system hooks to be run on installation and whatnot. Now that I think about it, that probably means entirely new system-specific command-line options as well.
I've also written a simple class for setting up applications, so that you can add this to your application's setup.py:
setup(... entry_points=""" [paste.app_install] main = paste.script.appinstall:Installer """)
This will look for a template configuration file in MyPackage.egg-info/paste_deploy_config.ini_tmpl (a Cheetah template, actually), and run mypackage.websetup.setup_config() on setup, and probably more things over time.
At some point I also plan to add such a generic setup class to SQLObject, so that a SQLObject-using application will be able to automatically set up its database on installation, as well as upgrade its database later (these classes should be reentrant, so you can run paster setup-app config_file.ini at any time to confirm and apply any new things to be setup).


|
add_metadata()
|
Add meta data to extracted data |
|
add_rsq()
|
Estimate r-square of each association |
|
allele_frequency()
|
Estimate allele frequency from SNP |
|
available_outcomes()
|
Get list of studies with available GWAS summary statistics through API |
|
clump_data()
|
Perform LD clumping on SNP data |
|
combine_all_mrresults()
|
Combine all mr results |
|
combine_data()
|
Combine data |
|
contingency()
|
Obtain 2x2 contingency table from marginal parameters and odds ratio |
|
convert_outcome_to_exposure()
|
Convert outcome data to exposure data |
|
dat_to_MRInput()
|
Convert TwoSampleMR format to MendelianRandomization format |
|
dat_to_RadialMR()
|
Convert dat to RadialMR format |
|
default_parameters()
|
List of parameters for use with MR functions |
|
directionality_test()
|
Perform MR Steiger test of directionality |
|
effective_n()
|
Estimate the effective sample size in a case control study |
|
enrichment()
|
Perform enrichment analysis |
|
enrichment_method_list()
|
Get list of available p-value enrichment methods |
|
estimate_trait_sd()
|
Estimate trait SD by obtaining beta estimates from z-scores and finding the ratio with original beta values |
|
extract_instruments()
|
Find instruments for use in MR from the MR Base database |
|
extract_outcome_data()
|
Supply the output from read_exposure_data and all the SNPs therein will be queried against the requested outcomes in remote database using API. |
|
fishers_combined_test()
|
Fisher's combined test |
|
forest_plot()
|
Forest plot for multiple exposures and multiple outcomes |
|
forest_plot_1_to_many()
|
1-to-many forest plot |
|
forest_plot_basic2()
|
A basic forest plot |
|
format_1_to_many()
|
Format MR results for a 1-to-many forest plot |
|
format_aries_mqtl()
|
Get data from methylation QTL results |
|
format_data()
|
Read exposure or outcome data |
|
format_gtex_eqtl()
|
Get data from eQTL catalog into correct format |
|
format_gwas_catalog()
|
Get data selected from GWAS catalog into correct format |
|
format_metab_qtls()
|
Get data from metabolomic QTL results |
|
format_mr_results()
|
Format MR results for forest plot |
|
format_proteomic_qtls()
|
Get data from proteomic QTL results |
|
generate_odds_ratios()
|
Generate odds ratios |
|
get_population_allele_frequency()
|
Estimate the allele frequency in population from case/control summary data |
|
get_p_from_r2n()
|
Calculate p-value from rsq and sample size |
|
get_r_from_bsen()
|
Estimate Rsq from beta, standard error and sample size |
|
get_r_from_lor()
|
Estimate proportion of variance of liability explained by SNP in general population |
|
get_r_from_pn()
|
Calculate variance explained from p vals and sample size |
|
get_se()
|
Get SE from effect size and pval |
|
harmonise_data()
|
Harmonise the alleles and effects between the exposure and outcome |
|
harmonise_ld_dat()
|
Harmonise LD matrix against summary data |
|
Isq()
|
I-square calculation |
|
ldsc_h2()
|
Univariate LDSC |
|
ldsc_rg()
|
Bivariate LDSC |
|
ld_matrix()
|
Get LD matrix for list of SNPs |
|
make_dat()
|
Convenient function to create a harmonised dataset |
|
mr()
|
Perform all Mendelian randomization tests |
|
mr_density_plot()
|
Density plot |
|
mr_egger_regression()
|
Egger's regression for Mendelian randomization |
|
mr_egger_regression_bootstrap()
|
Run bootstrap to generate standard errors for MR |
|
mr_forest_plot()
|
Forest plot |
|
mr_funnel_plot()
|
Funnel plot |
|
mr_heterogeneity()
|
Get heterogeneity statistics |
|
mr_ivw()
|
Inverse variance weighted regression |
|
mr_ivw_fe()
|
Inverse variance weighted regression (fixed effects) |
|
mr_ivw_mre()
|
Inverse variance weighted regression (multiplicative random effects model) |
|
mr_ivw_radial()
|
Radial IVW analysis |
|
mr_leaveoneout()
|
Leave one out sensitivity analysis |
|
mr_leaveoneout_plot()
|
Plot results from leaveoneout analysis |
|
mr_median()
|
MR median estimators |
|
mr_meta_fixed()
|
Perform 2 sample IV using fixed effects meta analysis and delta method for standard errors |
|
mr_meta_fixed_simple()
|
Perform 2 sample IV using simple standard error |
|
mr_meta_random()
|
Perform 2 sample IV using random effects meta analysis and delta method for standard errors |
|
mr_method_list()
|
Get list of available MR methods |
|
mr_mode()
|
MR mode estimators |
|
mr_moe()
|
Mixture of experts |
|
mr_penalised_weighted_median()
|
Penalised weighted median MR |
|
mr_pleiotropy_test()
|
Test for horizontal pleiotropy in MR analysis |
|
mr_raps()
|
Robust adjusted profile score |
|
mr_report()
|
Generate MR report |
|
mr_rucker()
|
MR Rucker framework |
|
mr_rucker_bootstrap()
|
Run rucker with bootstrap estimates |
|
mr_rucker_cooksdistance()
|
MR Rucker with outliers automatically detected and removed |
|
mr_rucker_jackknife()
|
Run rucker with jackknife estimates |
|
mr_scatter_plot()
|
Create scatter plot with lines showing the causal estimate for different MR tests |
|
mr_sign()
|
MR sign test |
|
mr_simple_median()
|
Simple median method |
|
mr_simple_mode()
|
MR simple mode estimator |
|
mr_simple_mode_nome()
|
MR simple mode estimator (NOME) |
|
mr_singlesnp()
|
Perform 2 sample MR on each SNP individually |
|
mr_steiger()
|
MR Steiger test of directionality |
|
mr_steiger2()
|
MR Steiger test of directionality |
|
mr_two_sample_ml()
|
Maximum likelihood MR method |
|
mr_uwr()
|
Unweighted regression |
|
mr_wald_ratio()
|
Perform 2 sample IV using Wald ratio. |
|
mr_weighted_median()
|
Weighted median method |
|
mr_weighted_mode()
|
MR weighted mode estimator |
|
mr_weighted_mode_nome()
|
MR weighted mode estimator (NOME) |
|
mr_wrapper()
|
Perform full set of MR analyses |
|
mv_basic()
|
Perform basic multivariable MR |
|
mv_extract_exposures()
|
Extract exposure variables for multivariable MR |
|
mv_extract_exposures_local()
|
Attempt to perform MVMR using local data |
|
mv_harmonise_data()
|
Harmonise exposure and outcome for multivariable MR |
|
mv_ivw()
|
Perform IVW multivariable MR |
|
mv_lasso_feature_selection()
|
Apply LASSO feature selection to mvdat object |
|
mv_multiple()
|
Perform IVW multivariable MR |
|
mv_residual()
|
Perform basic multivariable MR |
|
mv_subset()
|
Perform multivariable MR on subset of features |
|
power_prune()
|
Power prune |
|
read_exposure_data()
|
Read exposure data |
|
read_outcome_data()
|
Read outcome data |
|
run_mrmix()
|
Perform MRMix analysis on harmonised dat object |
|
run_mr_presso()
|
Wrapper for MR-PRESSO |
|
size.prune()
|
Size prune |
|
sort_1_to_many()
|
Sort results for 1-to-many forest plot |
|
split_exposure()
|
Split exposure column |
|
split_outcome()
|
Split outcome column |
|
standardise_units()
|
Try to standardise continuous traits to be in standard deviation units |
|
steiger_filtering()
|
Steiger filtering function |
|
steiger_sensitivity()
|
Evaluate the Steiger test's sensitivity to measurement error |
|
subset_on_method()
|
Subset MR-results on method |
|
trim()
|
Trim function to remove leading and trailing blank spaces |
|
TwoSampleMR-package
|
TwoSampleMR: Two Sample MR functions and interface to MR Base database |
|
weighted_median()
|
Weighted median method |
|
weighted_median_bootstrap()
|
Calculate standard errors for weighted median method using bootstrap |


User Interface Component Model
In addition to the lifecycle description, an overview of JavaServer Faces architecture provides better understanding of the technology.
JavaServer Faces components are the building blocks of a JavaServer Faces view. A component can be a user interface (UI) component or a non-UI component.
JavaServer Faces UI components are configurable, reusable elements that compose the user interfaces of JavaServer Faces applications. A component can be simple, such as a button, or can be compound, such as a table, composed of multiple components.
JavaServer Faces technology provides a rich, flexible component architecture that includes the following:
A set of UIComponent classes for specifying the state and behavior of UI components
A rendering model that defines how to render the components in various ways
An event and listener model that defines how to handle component events
A conversion model that defines how to register data converters onto a component
A validation model that defines how to register validators onto a component
This section briefly describes each of these pieces of the component architecture.
User Interface Component Classes
JavaServer Faces technology provides a set of UI component classes and associated behavioral interfaces that specify all the UI component functionality, such as holding component state, maintaining a reference to objects, and driving event handling and rendering for a set of standard components.
The component classes are completely extensible, allowing component writers to create their own custom components. See Chapter 13, Creating Custom UI Components and Other Custom Objects for more information.
The abstract base class for all components is javax.faces.component.UIComponent. JavaServer Faces UI component classes extend the UIComponentBase class (a subclass of UIComponent), which defines the default state and behavior of a component. The following set of component classes is included with JavaServer Faces technology:
UIColumn: Represents a single column of data in a UIData component.
UICommand: Represents a control that fires actions when activated.
UIData: Represents a data binding to a collection of data represented by a DataModel instance.
UIForm: Represents an input form to be presented to the user. Its child components represent (among other things) the input fields to be included when the form is submitted. This component is analogous to the form tag in HTML.
UIInput: Takes data input from a user. This class is a subclass of UIOutput.
UIOutcomeTarget: Displays a hyperlink in the form of a link or a button.
UISelectBoolean: Allows a user to set a boolean value on a control by selecting or deselecting it. This class is a subclass of the UIInput class.
UISelectMany: Allows a user to select multiple items from a group of items. This class is a subclass of the UIInput class.
UISelectOne: Allows a user to select one item from a group of items. This class is a subclass of the UIInput class.
UIViewParameter: Represents the query parameters in a request. This class is a subclass of the UIInput class.
In addition to extending UIComponentBase, the component classes also implement one or more behavioral interfaces, each of which defines certain behavior for a set of components whose classes implement the interface.
These behavioral interfaces are as follows:
ActionSource: Indicates that the component can fire an action event. This interface is intended for use with components based on JavaServer Faces technology 1.1_01 and earlier versions. This interface is deprecated in JavaServer Faces 2.
ActionSource2: Extends ActionSource, and therefore provides the same functionality. However, it allows components to use the EL when they are referencing methods that handle action events.
EditableValueHolder: Extends ValueHolder and specifies additional features for editable components, such as validation and emitting value-change events.
NamingContainer: Mandates that each component rooted at this component have a unique ID.
StateHolder: Denotes that a component has state that must be saved between requests.
ValueHolder: Indicates that the component maintains a local value as well as the option of accessing data in the model tier.
SystemEventListenerHolder: Maintains a list of SystemEventListener instances for each type of SystemEvent defined by that class.
ClientBehaviorHolder: Adds the ability to attach ClientBehavior instances such as a reusable script.
UICommand implements ActionSource2 and StateHolder. UIOutput and component classes that extend UIOutput implement StateHolder and ValueHolder. UIInput and component classes that extend UIInput implement EditableValueHolder, StateHolder, and ValueHolder. UIComponentBase implements StateHolder.
Only component writers will need to use the component classes and behavioral interfaces directly. Page authors and application developers will use a standard component by including a tag that represents it on a page. Most of the components can be rendered in different ways on a page. For example, a UICommand component can be rendered as a button or a hyperlink.
The next section explains how the rendering model works and how page authors can choose to render the components by selecting the appropriate tags.
Component Rendering Model
The JavaServer Faces component architecture is designed such that the functionality of the components is defined by the component classes, whereas the component rendering can be defined by a separate renderer class. This design has several benefits, including:
Component writers can define the behavior of a component once but create multiple renderers, each of which defines a different way to render the component to the same client or to different clients.
Page authors and application developers can change the appearance of a component on the page by selecting the tag that represents the appropriate combination of component and renderer.
A render kit defines how component classes map to component tags that are appropriate for a particular client. The JavaServer Faces implementation includes a standard HTML render kit for rendering to an HTML client.
The render kit defines a set of Renderer classes for each component that it supports. Each Renderer class defines a different way to render the particular component to the output defined by the render kit. For example, a UISelectOne component has three different renderers. One of them renders the component as a set of radio buttons. Another renders the component as a combo box. The third one renders the component as a list box. Similarly, a UICommand component can be rendered as a button or a hyperlink, using the commandButton or commandLink tag. The command part of each tag corresponds to the UICommand class, specifying the functionality, which is to fire an action. The Button and Link parts of the tags each correspond to a separate Renderer class, which defines how the component appears on the page.
Each custom tag defined in the standard HTML render kit is composed of the component functionality (defined in the UIComponent class) and the rendering attributes (defined by the Renderer class).
The section Adding Components to a Page Using HTML Tags lists all supported component tags and describes how to use the tags in an example.
The JavaServer Faces implementation provides a custom tag library for rendering components in HTML.
Conversion Model
A JavaServer Faces application can optionally associate a component with server-side object data. This object is a JavaBeans component, such as a managed bean. An application gets and sets the object data for a component by calling the appropriate object properties for that component.
When a component is bound to an object, the application has two views of the component’s data:
The model view, in which data is represented as data types, such as int or long.
The presentation view, in which data is represented in a manner that can be read or modified by the user. For example, a java.util.Date might be represented as a text string in the format mm/dd/yy or as a set of three text strings.
The JavaServer Faces implementation automatically converts component data between these two views when the bean property associated with the component is of one of the types supported by the component’s data. For example, if a UISelectBoolean component is associated with a bean property of type java.lang.Boolean, the JavaServer Faces implementation will automatically convert the component’s data from String to Boolean. In addition, some component data must be bound to properties of a particular type. For example, a UISelectBoolean component must be bound to a property of type boolean or java.lang.Boolean.
Sometimes you might want to convert a component’s data to a type other than a standard type, or you might want to convert the format of the data. To facilitate this, JavaServer Faces technology allows you to register a Converter implementation on UIOutput components and components whose classes subclass UIOutput. If you register the Converter implementation on a component, the Converter implementation converts the component’s data between the two views.
You can either use the standard converters supplied with the JavaServer Faces implementation or create your own custom converter. Custom converter creation is covered in Chapter 13, Creating Custom UI Components and Other Custom Objects.
Event and Listener Model
The JavaServer Faces event and listener model is similar to the JavaBeans event model in that it has strongly typed event classes and listener interfaces that an application can use to handle events generated by components.
The JavaServer Faces specification defines three types of events: application events, system events and data-model events.
Application events are tied to a particular application and are generated by a UIComponent. They represent the standard events available in previous versions of JavaServer Faces technology.
An Event object identifies the component that generated the event and stores information about the event. To be notified of an event, an application must provide an implementation of the Listener class and must register it on the component that generates the event. When the user activates a component, such as by clicking a button, an event is fired. This causes the JavaServer Faces implementation to invoke the listener method that processes the event.
JavaServer Faces supports two kinds of application events: action events and value-change events.
An action event (class ActionEvent) occurs when the user activates a component that implements ActionSource. These components include buttons and hyperlinks.
A value-change event (class ValueChangeEvent) occurs when the user changes the value of a component represented by UIInput or one of its subclasses. An example is selecting a check box, an action that results in the component’s value changing to true. The component types that can generate these types of events are the UIInput, UISelectOne, UISelectMany, and UISelectBoolean components. Value-change events are fired only if no validation errors were detected.
Depending on the value of the immediate property (see The immediate Attribute) of the component emitting the event, action events can be processed during the invoke application phase or the apply request values phase, and value-change events can be processed during the process validations phase or the apply request values phase.
System events are generated by an Object rather than a UIComponent. They are generated during the execution of an application at predefined times. They are applicable to the entire application rather than to a specific component.
A data-model event occurs when a new row of a UIData component is selected.
There are two ways to cause your application to react to action events or value-change events that are emitted by a standard component:
Implement an event listener class to handle the event and register the listener on the component by nesting either a valueChangeListener tag or an actionListener tag inside the component tag.
Implement a method of a managed bean to handle the event and refer to the method with a method expression from the appropriate attribute of the component’s tag.
See Implementing an Event Listener for information on how to implement an event listener. See Registering Listeners on Components for information on how to register the listener on a component.
See Writing a Method to Handle an Action Event and Writing a Method to Handle a Value-Change Event for information on how to implement managed bean methods that handle these events.
See Referencing a Managed Bean Method for information on how to refer to the managed bean method from the component tag.
When emitting events from custom components, you must implement the appropriate Event class and manually queue the event on the component in addition to implementing an event listener class or a managed bean method that handles the event. Handling Events for Custom Components explains how to do this.
Validation Model
JavaServer Faces technology supports a mechanism for validating the local data of editable components (such as text fields). This validation occurs before the corresponding model data is updated to match the local value.
Like the conversion model, the validation model defines a set of standard classes for performing common data validation checks. The JavaServer Faces core tag library also defines a set of tags that correspond to the standard Validator implementations. See Using the Standard Validators for a list of all the standard validation classes and corresponding tags.
Most of the tags have a set of attributes for configuring the validator’s properties, such as the minimum and maximum allowable values for the component’s data. The page author registers the validator on a component by nesting the validator’s tag within the component’s tag.
In addition to validators that are registered on the component, you can declare a default validator which is registered on all UIInput components in the application. For more information on default validators, see Using Default Validators.
The validation model also allows you to create your own custom validator and corresponding tag to perform custom validation. The validation model provides two ways to implement custom validation:
Implement a Validator interface that performs the validation.
Implement a managed bean method that performs the validation.
If you are implementing a Validator interface, you must also:
Register the Validator implementation with the application.
Create a custom tag or use a validator tag to register the validator on the component.
In the previously described standard validation model, the validator is defined for each input component on a page. The Bean Validation model allows the validator to be applied to all fields in a page. See Using Bean Validation and Chapter 49, Bean Validation: Advanced Topics for more information on Bean Validation.
Navigation Model
The JavaServer Faces navigation model makes it easy to define page navigation and to handle any additional processing that is needed to choose the sequence in which pages are loaded.
In JavaServer Faces technology, navigation is a set of rules for choosing the next page or view to be displayed after an application action, such as when a button or hyperlink is clicked.
Navigation can be implicit or user-defined. Implicit navigation comes into play when user-defined navigation rules are not available. For more information on implicit navigation, see Implicit Navigation Rules.
User-defined navigation rules are declared in zero or more application configuration resource files, such as faces-config.xml, by using a set of XML elements. The default structure of a navigation rule is as follows:
<navigation-rule> <description></description <from-view-id></from-view-id> <navigation-case> <from-action></from-action> <from-outcome></from-outcome> <if></if> <to-view-id></to-view-id> </navigation-case> </navigation-rule>
User-defined navigation is handled as follows:
Define the rules in the application configuration resource file.
Refer to an outcome String from the button or hyperlink component’s action attribute. This outcome String is used by the JavaServer Faces implementation to select the navigation rule.
Here is an example navigation rule:
<navigation-rule> <from-view-id>/greeting.xhtml</from-view-id> <navigation-case> <from-outcome>success</from-outcome> <to-view-id>/response.xhtml</to-view-id> </navigation-case> </navigation-rule>
This rule states that when a command component (such as a commandButton or a commandLink) on greeting.xhtml is activated, the application will navigate from the greeting.xhtml page to the response.xhtml page if the outcome referenced by the button component’s tag is success. Here is the commandButton tag from greeting.xhtml that specifies a logical outcome of success:
<h:commandButton id="submit" action="success" value="Submit" />
As the example demonstrates, each navigation-rule element defines how to get from one page (specified in the from-view-id element) to the other pages of the application. The navigation-rule elements can contain any number of navigation-case elements, each of which defines the page to open next (defined by to-view-id) based on a logical outcome (defined by from-outcome) .
In more complicated applications, the logical outcome can also come from the return value of an action method in a managed bean. This method performs some processing to determine the outcome. For example, the method can check whether the password the user entered on the page matches the one on file. If it does, the method might return success; otherwise, it might return failure. An outcome of failure might result in the logon page being reloaded. An outcome of success might cause the page displaying the user’s credit card activity to open. If you want the outcome to be returned by a method on a bean, you must refer to the method using a method expression, with the action attribute, as shown by this example:
<h:commandButton id="submit" action="#{userNumberBean.getOrderStatus}" value="Submit" />
When the user clicks the button represented by this tag, the corresponding component generates an action event. This event is handled by the default ActionListener instance, which calls the action method referenced by the component that triggered the event. The action method returns a logical outcome to the action listener.
The listener passes the logical outcome and a reference to the action method that produced the outcome to the default NavigationHandler. The NavigationHandler selects the page to display next by matching the outcome or the action method reference against the navigation rules in the application configuration resource file by the following process:
The NavigationHandler selects the navigation rule that matches the page currently displayed.
It matches the outcome or the action method reference that it received from the default ActionListener with those defined by the navigation cases.
It tries to match both the method reference and the outcome against the same navigation case.
If the previous step fails, the navigation handler attempts to match the outcome.
Finally, the navigation handler attempts to match the action method reference if the previous two attempts failed.
If no navigation case is matched, it displays the same view again.
When the NavigationHandler achieves a match, the render response phase begins. During this phase, the page selected by the NavigationHandler will be rendered.
For more information on how to define navigation rules, see Configuring Navigation Rules.
For more information on how to implement action methods to handle navigation, see Writing a Method to Handle an Action Event.
For more information on how to reference outcomes or action methods from component tags, see Referencing a Method That Performs Navigation.


10 - UI and Combat
EditNow we want to show the player what's going on. So we need to have some kind of HUD on the screen to tell them what their current/max health is, and how many coins they have. For the health icon you can use this image , or make your own. Make sure you save this in assets/images
.
We'll start by making a new
HUD
class which will hold all our HUD elements:package; import flixel.FlxBasic; import flixel.FlxG; import flixel.FlxSprite; import flixel.group.FlxTypedGroup; import flixel.text.FlxText; import flixel.util.FlxColor; using flixel.util.FlxSpriteUtil; class HUD extends FlxTypedGroup<FlxSprite> { private var _sprBack:FlxSprite; private var _txtHealth:FlxText; private var _txtMoney:FlxText; private var _sprHealth:FlxSprite; private var _sprMoney:FlxSprite; public function new() { super(); _sprBack = new FlxSprite().makeGraphic(FlxG.width, 20, FlxColor.BLACK); _sprBack.drawRect(0, 19, FlxG.width, 1, FlxColor.WHITE); _txtHealth = new FlxText(16, 2, 0, "3 / 3", 8); _txtHealth.setBorderStyle(SHADOW, FlxColor.GRAY, 1, 1); _txtMoney = new FlxText(0, 2, 0, "0", 8); _txtMoney.setBorderStyle(SHADOW, FlxColor.GRAY, 1, 1); _sprHealth = new FlxSprite(4, _txtHealth.y + (_txtHealth.height/2) - 4, AssetPaths.health__png); _sprMoney = new FlxSprite(FlxG.width - 12, _txtMoney.y + (_txtMoney.height/2) - 4, AssetPaths.coin__png); _txtMoney.alignment = RIGHT; _txtMoney.x = _sprMoney.x - _txtMoney.width - 4; add(_sprBack); add(_sprHealth); add(_sprMoney); add(_txtHealth); add(_txtMoney); forEach(function(spr:FlxSprite) { spr.scrollFactor.set(0, 0); }); } public function updateHUD(Health:Int = 0, Money:Int = 0):Void { _txtHealth.text = Std.string(Health) + " / 3"; _txtMoney.text = Std.string(Money); _txtMoney.x = _sprMoney.x - _txtMoney.width - 4; } }
This class extends
FlxTypedGroup<FlxSprite>
so that it can hold all of ourFlxSprite
objects. It is composed of 5 different items: a background (black, with a 1-pixel thick white line along the bottom), 2FlxText
objects: 1 for health, and 1 for money, and twoFlxSprite
objects, for the icons to go next to theFlxText
objects. At the end of our constructor, we have aforEach()
call - we use this to iterate through each of the items in this group, and it just sets theirscrollFactor.x
andscrollFactor.y
to 0, meaning, even if the camera scrolls, all of these items will stay at the same position relative to the screen.Finally, we have a function that we can call from anywhere to tell the
HUD
what it should display.Now let's get it to work and have it update whenever we pick up a coin. In your
PlayState
, add this to the top of the class:private var _hud:HUD; private var _money:Int = 0; private var _health:Int = 3;
In
create()
, beforesuper.create()
, add:_hud = new HUD(); add(_hud);
Finally, in the
playerTouchCoin()
function we added earlier, somewhere inside theif
-statement, add:_money++; _hud.updateHUD(_health, _money);
Go ahead and test out your game, and the HUD should update each time you pick up a coin!
If we had a way to 'hurt' the player, we could also update the health on the HUD… but in order to do that, we need to figure out how we're going to do combat!
Let's begin by establishing what we want our combat system to achieve. First, we're not going to be making the next Final Fantasy game here, this is just a basic demonstration to show how a few different elements can work. So, I think all we want to do is have a simple interface that appears when the player touches an enemy that shows the player's health, and the enemy's health (in a health bar, for obfuscation), and gives the player 2 options: FIGHT
or FLEE
.
If they choose to fight, we'll roll some random chance checks to see if the player hits the enemy, and if the enemy hits the player - a hit will do 1 damage. Once the enemy dies, we'll continue on. If they choose to flee, we'll do a check to see if they do flee or not - if they do, the interface closes and the enemy will be stunned for a few seconds so the player can move away. If they fail to flee, the enemy will get a free hit against the player. We'll also show the damage and misses on the interface.
This all seems simple enough, but it's actually going to require several components working together to make it work. It's the most complicated piece of our game so far.
The first component will be our
CombatHUD
class. This is a pretty big class - it's going to do most of the heavy lifting with our combat logic. You can see the complete class here:Take some time to read through it to see how it works, then add it to your project. You will need to add a small function to our
Enemy
class as well:public function changeEnemy(EType:Int):Void { if (etype != EType) { etype = EType; loadGraphic("assets/images/enemy-" + etype + ".png", true, 16, 16); } }
Next, we need to get our
CombatHUD
into ourPlayState
. Add this to the top of thePlayState
class:private var _inCombat:Bool = false; private var _combatHud:CombatHUD;
Move down to
create()
, and, after we add the HUD, and before we callsuper.create()
, add:_combatHud = new CombatHUD(); add(_combatHud);
Go down to our
update()
, and change it so that we're ONLY checking for collisions and overlaps when we're not in combat. Everything after thesuper.update()
should look like this:if (!_inCombat) { FlxG.collide(_player, _mWalls); FlxG.overlap(_player, _grpCoins, playerTouchCoin); FlxG.collide(_grpEnemies, _mWalls); _grpEnemies.forEachAlive(checkEnemyVision); FlxG.overlap(_player, _grpEnemies, playerTouchEnemy); } else { if (!_combatHud.visible) { _health = _combatHud.playerHealth; _hud.updateHUD(_health, _money); if (_combatHud.outcome == VICTORY) { _combatHud.e.kill(); } else { _combatHud.e.flicker(); } _inCombat = false; _player.active = true; _grpEnemies.active = true; } }
So, we're adding a check to see if the player touches an enemy. If they do, we'll call a callback to see if we should start combat or not.
If we're in combat, we're simply going to keep checking to see if the combat HUD is still visible - once it becomes invisible, we know that combat has finished, and we can determine the outcome. If the outcome is
VICTORY
(one of our four enum values), we will kill the enemy, but if the player fled the battle, we will make the enemy flicker, to show that the player is safe from fighting it again for a short amount of time.Next, lets add the functions to handle the player touching an enemy:
private function playerTouchEnemy(P:Player, E:Enemy):Void { if (P.alive && P.exists && E.alive && E.exists && !E.isFlickering()) { startCombat(E); } } private function startCombat(E:Enemy):Void { _inCombat = true; _player.active = false; _grpEnemies.active = false; _combatHud.initCombat(_health, E); }
All we're doing here is verify that both the player and the enemy are alive and exist, as well as that the enemy is not flickering (flickering enemies are those we've just fled from). If so, we start combat.
The
startCombat()
function simply sets ourinCombat
flag (so we know not to do collisions), and sets the player and all the enemies to inactive, so they no longer update.Finally, we call
initCombat()
in ourCombatHUD
, which initializes it and makes it start working.Finally, we want enemies that are flickering to not move - they should act kind of stunned for a second after the enemy flees.
In the
Enemy
class, underupdate()
, add:if (isFlickering()) return;
At the very top, before doing anything else in that function.
You will also need to add
using flixel.util.FlxSpriteUtil;
to the top of the
Enemy
class.
And that should do it! Test out your game and make sure that it works!
Next, we'll cover winning and losing and setting up all our different states.


@***************************************************************************** * Page with form to create new Publisher * * Copyright 2012 MIT Libraries * * @author richardrodgers * *****************************************************************************@ @(pub: Publisher, pubForm: Form[Publisher])(implicit hubContext: HubContext) @import helper._ @main("New Publisher - TopicHub") {
Choose a category that best describes the type of publisher, or 'other' if none fits.
Fill in the fields at left making sure that you select a 'pubId' that:
Put the full name in the name field, and add a terse description in the next one.
Add a URL to your main site in the link field, and a URL for a logo if you have one.


;
LifeLine Vibe
Contact LifeLine Vibe Today
<EMAIL_ADDRESS>Phone:<PHONE_NUMBER>
Home
About Us
Services
Contact
Our Team
Event Calender


This is an archive of my favorite (non published) stories and fanfictions.
This uses keyword tag searching that is separated by a comma. For fandoms just type the name. Have a look at the stories tags to get an idea of how they work to search them.
NOTE: If this does not work on your browser then it does not support ES6 and you should update.


Tweet Away
A web social media application to waste away time!
Welcome Back!
Name
Message
Post
Clear
Welcome
Please Sign In
Enter your name
Sign In


UI element samples
Dialog Box
Expand Collapse
Expandable FAB
Expandable FAB with FLIP
Expandable FAB with Inverse matrix transforms
Bottom navigaion


Fits linear, non-linear, and user-defined mixed effects regression models following the framework developed by Crowther (2017) <arXiv:1710.02223>. 'merlin' can fit multivariate outcome models of any type, each of which could be repeatedly measured (longitudinal), with any number of levels, and with any number of random effects at each level. Standard distributions/models available include the Bernoulli, Gaussian, Poisson, beta, negative-binomial, and time-to-event/survival models include the exponential, Gompertz, Royston-Parmar, Weibull and general hazard model. 'merlin' provides a flexible predictor syntax, allowing the user to define variables, random effects, spline and fractional polynomial functions, functions of other outcome models, and any interaction between each of them. Non-linear and time-dependent effects are seamlessly incorporated into the predictor. 'merlin' allows multivariate normal random effects, which are integrated out using Gaussian quadrature or Monte-Carlo integration. Note, 'merlin' is based on the 'Stata' package of the same name, described in Crowther (2018) <arXiv:1806.01615>.
| Version: | 0.0.1 |
| Depends: | R (≥ 2.10) |
| Imports: | statmod, stats, survival, randtoolbox, MASS |
| Suggests: | knitr, rmarkdown, testthat |
| Published: | 2018-08-16 |
| Author: | Emma Martin [aut], Alessandro Gasparini [aut], Michael Crowther [aut, cre] |
| Maintainer: | Michael Crowther <michael.crowther at le.ac.uk> |
| License: | GPL (≥ 3) |
| URL: | https://www.mjcrowther.co.uk/software/merlin |
| NeedsCompilation: | no |
| Materials: | NEWS |
| CRAN checks: | merlin results |
| Reference manual: | merlin.pdf |
| Vignettes: |
merlin |
| Package source: | merlin_0.0.1.tar.gz |
| Windows binaries: | r-devel: merlin_0.0.1.zip, r-release: merlin_0.0.1.zip, r-oldrel: merlin_0.0.1.zip |
| OS X binaries: | r-release: merlin_0.0.1.tgz, r-oldrel: merlin_0.0.1.tgz |
Please use the canonical form https://CRAN.R-project.org/package=merlin to link to this page.


Cramer’s Rule
问题描述 :
Background
Consider a system of linear equations, here three equations of three variables x1, x2, x3. The general form looks something like this, with given numbers aij and bi:
a11x1 + a12x2 + a13x3 = b1
a21x1 + a22x2 + a23x3 = b2
a31x1 + a32x2 + a33x3 = b3
Or, using matrices and vectors:
According to Cramer’s rule, the solution can be given in terms of determinants, i.e.
xi =det(Ai)/det(A)
where Ai is the matrix obtained from A by replacing the i-th column with the vector b. For 3 * 3 determinants,you can use the following simple formula to calculate the determinant:
Obviously, Cramer’s rule only works for det(A) != 0. One can show that the system has a unique solution if and only if det(A) != 0. Otherwise, the system has either no solution or infinitely many solutions.
Please note that one would not use Cramer’s rule to solve a large system of linear equations, simply because calculating a single determinant is as time-consuming as solving the complete system by a more efficient algorithm.
Problem
Given a system of three linear equations in three variables, use Cramer’s rule to find the unique solution if it exists. More precisely, calculate the determinants of the Ai and of A and decide by looking at det(A) whether the system has a unique solution. If it does, calculate the solution according to Cramer’s rule.
Consider a system of linear equations, here three equations of three variables x1, x2, x3. The general form looks something like this, with given numbers aij and bi:
a21x1 + a22x2 + a23x3 = b2
a31x1 + a32x2 + a33x3 = b3
Or, using matrices and vectors:
According to Cramer’s rule, the solution can be given in terms of determinants, i.e.
where Ai is the matrix obtained from A by replacing the i-th column with the vector b. For 3 * 3 determinants,you can use the following simple formula to calculate the determinant:
Obviously, Cramer’s rule only works for det(A) != 0. One can show that the system has a unique solution if and only if det(A) != 0. Otherwise, the system has either no solution or infinitely many solutions.
Please note that one would not use Cramer’s rule to solve a large system of linear equations, simply because calculating a single determinant is as time-consuming as solving the complete system by a more efficient algorithm.
Problem
Given a system of three linear equations in three variables, use Cramer’s rule to find the unique solution if it exists. More precisely, calculate the determinants of the Ai and of A and decide by looking at det(A) whether the system has a unique solution. If it does, calculate the solution according to Cramer’s rule.
输入:
The first line contains the number of scenarios.
For each scenario, you are given three lines corresponding to the three equations, with the coefficients of the matrix A and the coordinates of the vector b arranged as follows:
a11 a12 a13 b1
a21 a22 a23 b2
a31 a32 a33 b3
All numbers are integers in the range {−1000, . . . , 1000}. They are separated by single blanks.
For each scenario, you are given three lines corresponding to the three equations, with the coefficients of the matrix A and the coordinates of the vector b arranged as follows:
a21 a22 a23 b2
a31 a32 a33 b3
All numbers are integers in the range {−1000, . . . , 1000}. They are separated by single blanks.
输出:
For each scenario print three lines. In the first line, print the determinants of A1, A2, A3, and A, as integers and separated by single blanks. In the second line, print (depending on det(A)) either “No unique solution” or “Unique solution: “, followed by the values of x1, x2, x3 with three digits after the decimal point,again separated from each other by a single blank. For solutions xi with -0.0005 < xi < 0.0005 always print "0.000" instead of the "-0.000" that your print command might come up with. The third line is empty.
样例输入:
3 4 0 0 1 0 2 0 2 0 0 1 4 1 2 3 1 1 1 1 2 2 2 2 3 1 0 0 1 0 1 0 0 0 0 -1 0
样例输出:
2 8 32 8 Unique solution: 0.250 1.000 4.000 1 -2 1 0 No unique solution -1 0 0 -1 Unique solution: 1.000 0.000 0.000
解题代码:
//* @author popop0p0popo import java.util.*; import java.io.*; import java.text.*; import java.math.*; public class Main{ public static void main(String[] args){ Scanner scanner=new Scanner(new BufferedReader(new InputStreamReader(System.in))); int n=scanner.nextInt(); BigInteger[][] a; BigInteger[] b; BigInteger aa,aa1,aa2,aa3; for (int i=0;i< n ;i++ ){ a=new BigInteger[3][3]; b=new BigInteger[3]; for (int j=0;j< 3 ;j++ ){ for (int k=0;k< 3 ;k++ ){ a[j][k]=scanner.nextBigInteger(); } b[j]=scanner.nextBigInteger(); } aa=a[0][0].multiply(a[1][1].multiply(a[2][2]).add(a[1][2].multiply(a[2][1]).negate())). add((a[0][1].multiply(a[1][0].multiply(a[2][2]). add(a[1][2].multiply(a[2][0]).negate()))).negate()). add(a[0][2].multiply(a[1][0].multiply(a[2][1]). add(a[1][1].multiply(a[2][0]).negate()))); aa1=b[0].multiply(a[1][1].multiply(a[2][2]).add(a[1][2].multiply(a[2][1]).negate())). add((a[0][1].multiply(b[1].multiply(a[2][2]). add(a[1][2].multiply(b[2]).negate()))).negate()). add(a[0][2].multiply(b[1].multiply(a[2][1]). add(a[1][1].multiply(b[2]).negate()))); aa2=a[0][0].multiply(b[1].multiply(a[2][2]).add(a[1][2].multiply(b[2]).negate())). add((b[0].multiply(a[1][0].multiply(a[2][2]). add(a[1][2].multiply(a[2][0]).negate()))).negate()). add(a[0][2].multiply(a[1][0].multiply(b[2]). add(b[1].multiply(a[2][0]).negate()))); aa3=a[0][0].multiply(a[1][1].multiply(b[2]).add(b[1].multiply(a[2][1]).negate())). add((a[0][1].multiply(a[1][0].multiply(b[2]). add(b[1].multiply(a[2][0]).negate()))).negate()). add(b[0].multiply(a[1][0].multiply(a[2][1]). add(a[1][1].multiply(a[2][0]).negate()))); System.out.println(aa1+" "+aa2+" "+aa3+" "+aa); if (aa.equals(BigInteger.ZERO)){ System.out.println("No unique solution"); } else{ DecimalFormat df=new DecimalFormat("0.000"); BigDecimal x1=new BigDecimal(aa1.toString()); BigDecimal x2=new BigDecimal(aa2.toString()); BigDecimal x3=new BigDecimal(aa3.toString()); BigDecimal x=new BigDecimal(aa.toString()); BigDecimal xx1=x1.divide(x,6,BigDecimal.ROUND_HALF_UP); BigDecimal xx2=x2.divide(x,6,BigDecimal.ROUND_HALF_UP); BigDecimal xx3=x3.divide(x,6,BigDecimal.ROUND_HALF_UP); System.out.println("Unique solution: "+df.format(xx1)+" "+df.format(xx2)+" "+df.format(xx3)); } System.out.println(); } } }
(adsbygoogle = window.adsbygoogle || []).push({});
学算法中的数据结构学到一定程度会乐此不疲的，比如其中的2－3树，类似的红黑树，我甚至可以自己写个逻辑文件系统结构来。
已更正。
我觉得是D哎……
居然看懂了
题本身没错，但是HDOJ放题目的时候，前面有个题目解释了什么是XXX定律。
这里直接放了这个题目，肯定没几个人明白是干啥
算法是程序的灵魂，算法分简单和复杂，如果不搞大数据类，程序员了解一下简单点的算法也是可以的，但是会算法的一定要会编程才行，程序员不一定要会算法，利于自己项目需要的可以简单了解。
这张页面太松散拉，重新编辑一下，弄紧凑一点。
辛苦了，顶
妈呀！这个Dijkstra模板好长OwQ！
可以用公式。主要为了说明动态规划，如果要打表的话，这种方法也是较简单和高效的
受益匪浅！！
已更正。
额，不对应吧
我得邮箱cwqbupt@qq.com


A helper method makes plotting indicators simple. Further information about the charting API can be found in the documentation below.
Plot<T>(string chart, params IndicatorBase<T>[] indicators) where T : BaseData
Note that not all indicators share the same base type(T) so may not work together.
//Plot array of indicator objects; extending "Indicator" type. Plot("Indicators", sma, rsi); //Plot array of indicator objects; extending "TradeBarIndicator" type. Plot("Indicators", atr, aroon); //For complex plotting it might be easiest to simply plot your indicators individually.
#Plot array of indicator objects; extending "Indicator" type. self.Plot("Indicators", sma, rsi); #Plot array of indicator objects; extending "TradeBarIndicator" type. self.Plot("Indicators", atr, aroon); #Currently, there is a limit of 4 indicators for each Plot call #For complex plotting it might be easiest to simply plot your indicators individually.


opacity
sampling
particles
lower distance bound
higher distance bound
noise
velocity
Draw Paths
Color Change
Background Change
Clear Canvas
<
-30secs
+30secs
>


{include file="public/headercn"} {include file="public/navcn"} {include file="public/mobileheaderen"}
{$page}


<ruby>
tag. <ruby>
allows webpages to show ruby characters,
which are annotations usually displayed above Asian (fullwidth)
language characters, such as kanji. An example is the Japanese word for
ruby characters:
The unfortunate thing, as is the case with most modern HTML features,
is that browser support is sparse. One case is when the annotation is
identical to the base text. It serves no purpose, and can be hidden.
Firefox implements this functionality, but other browsers do not. A
workaround is to use the <rp>
element, which stands for ruby parentheses, but can be used for any extra text which should show up in browsers without ruby character support. If we write <rt><rp>り</rp>
in place of <rt>り
,
the symbol り will only appear as part of the hiragana spelling ふりがな
when ruby characters are not supported. This works because the <rt>
element is empty, which means the base symbol has no annotation. If we
“turn off” ruby characters by writing some CSS, we can demonstrate the
workaround:
<style>
.noruby rt { display: inline; font-size: 100%; }
.noruby rp { display: inline; }
</style>
<ruby><rb>振<rb>り<rb>仮<rb>名<rp>「</rp><rt>ふ<rt><rp>り</rp><rt>が<rt>な<rp>」</rp></ruby>
<br>
<ruby class="noruby"><rb>振<rb>り<rb>仮<rb>名<rp>「</rp><rt>ふ<rt><rp>り</rp><rt>が<rt>な<rp>」</rp></ruby>
Produces the following:
Note that the markup is identical except the class applied to <ruby>
. The markup is also quite verbose, which is a shame, but a lot of meaning is packed in. At least </rb>
and </rt>
can be omitted.


Tree edges are edges in the depth-first forest Gπ. Edge (u,v) is a tree edge if v was first discovered by exploring edge (u,v).


Use this dialog to set the current font for the currently selected editor window.
Moves the selected objects to the front of the drawing list. The objects will then appear to be above objects that aren't selected.
Moves the selected objects to the back of the drawing list. The objects will then appear to be below objects that aren't selected.
If this item is checked, the selected objects are rendered as a final pass over the top of the hex grid. It's a kind of pseudo-fourth drawing layer. This is very useful for placing tables and the like over the grid lines.
This dialog is used to control at what board scale views (full, half, or small) the selected objects will be visible. The dialog can also be used to force a bitmap image to be rendered at its standard pixel size at a single board scale.
This command suspends enforcement of the options selected by the Set Scale Visibility menu command.
This command toggles the use of the snap grid. You can also temporarily suspend the snap grid by holding the Ctrl key while you are dragging an object.
Presents the board properties dialog for the currently selected board editor view.
If this option is checked, the currently selected drawing tool will remain selected after the drawing operation is completed. Otherwise, the selection tool is automatically selected.
This command applies the current tile edits to the master copy of the tile. You cannot undo this operation.
This command discards the edits of the current tile. You cannot undo this operation.
Rotates the currently selected tile by a multiple of 90 degrees.
Use this command to resize the currently selected tile.
This command draws a hex shaped masked area on the currently selected tile. It's used to make it easier to see what areas of the tile are actually displayed when placed in a hex grid cell.


UX-designer and frontend developer. Taking photos of everything I find interesting and shares some thought in chronicles.
Find Out MoreI´ve worked both as a UX-designer and a journalist and besides that I have also spent a lot of time doing other things as well, from photography to being editor in chief at Norrlands Nations magazine (which me and my team won best magazine for two semester in a row!). Go check out my LinkedIn if you are interested in more details.
Go to LinkedIn!


This form of attack is an attempt to discover the key with which a document has been encrypted when one already knows the plaintext and the encrypted text. In a chosen-plaintext attack, any number of plaintext-encrypted text pairs can be generated.
By contrast, for a ciphertext-only attack knowledge of the plaintext is not necessary.